1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
|
OMAP HSI API's How To
=====================
The MIPI High Speed Synchronous Serial Interface (HSI) is a high speed
communication interface that is used for connecting OMAP to a cellular modem
engine.
It is specified by the MIPI alliance (www.mipi.org). An introduction to the
MIPI HSI working group can be found here: http://www.mipi.org/wgoverview.shtml
The HSI interface supports full duplex communication over multiple channels and
is capable of reaching speeds up to 200 Mbit/s.
The OMAP HSI driver supports both OMAP MIPI HSI (as defined in
MIPI documentation mipi_HSI-PL_specification_v01-01-00a.pdf) and OMAP SSI
devices through different device files, and a generic SW driver.
Please refer to the MIPI specifications for more details on this device.
I OMAP HSI driver API overview
-----------------------------
A) HSI Bus, HSI channels and protocol drivers overview.
The OMAP HSI driver implements the low-level support for the HSI device. It
abstracts device specifics and provides a simple interface inside the kernel
for data transmission on the HSI channels.
The OMAP HSI driver does not implement any communication protocol.
The SW layers using the OMAP HSI driver may implement a communication protocol
if required, and are commonly called 'protocol drivers' in this document.
The OMAP HSI abstracts the concept of HSI channels by creating an HSI bus and
attaching HSI channel devices to it. (see Figure 1)
Protocol drivers will then claim one or more HSI channels, after registering
with the OMAP HSI driver.
+---------------------+ +----------------+
+ HSI channel device + + HSI protocol +
+ (omap_hsi.pX-cY) + <-------+ driver +
+---------------------+ +----------------+
| |
(/sys/bus/hsi/devices/omap_hsi.pX-cy) (/sys/bus/hsi/drivers/hsi_protocol)
| |
+----------------------------------------------------------------+
+ HSI bus +
+----------------------------------------------------------------+
Figure 1.
(NOTE: omap_hsi.pX-cY represents the HSI channel Y on port X from the omap_hsi
device)
B) Data transfers
The OMAP HSI driver exports an asynchronous interface for sending and receiving
data over the HSI channels. Protocol drivers will register a set of read and
write completion callbacks for each HSI channel they use.
Protocol drivers call hsi_write/hsi_read functions to signal the OMAP HSI driver
that is willing to write/read data to/from a channel. Transfers are completed
only when the OMAP HSI driver calls the completion callback.
An HSI channel can simultaneously have both a read and a write request
pending, however, requests cannot be queued.
It is safe to call hsi_write/hsi_read functions inside the callback functions.
In fact, a protocol driver should normally re-issue the read request from within
the read callback, in order to not miss any incoming messages.
Note on read / write operations:
A read or write is performed using a HSI internal DMA channel, unless the size
of data to transmit is one 32bits Word, where the transmission is directly
managed through interrupts.
C) Error handling
HSI is a multi channel interface but the channels share the same physical wires.
Therefore, any transmission error potentially affects all the protocol drivers
that sit on top of the HSI driver. Whenever an error occurs, it is broadcast
to all protocol drivers.
Errors are signaled to the protocol drivers through the port_event callback.
Completion callbacks functions are only called when a transfer has success.
D) Supported modes of operation
The driver supports stream and frame transmission modes and synchronized and
pipelined data flows.
The driver implements the HSI support for the core MPU and not for the
potential co-processors.
II OMAP HSI API's
-----------------
A) Include
#include<linux/hsi_driver_if.h>
B) int hsi_register_driver(struct hsi_device_driver *driver);
Description: Register an HSI protocol driver
Parameter: A protocol driver declaration (see struct hsi_device_driver)
C) void hsi_unregister_driver(struct hsi_device_driver *driver);
Description: Unregister an HSI protocol driver
Parameter: A protocol driver declaration (see struct hsi_device_driver)
D) int hsi_open(struct hsi_device *dev);
Description: Open an HSI device channel
Parameter: The HSI channel
E) int hsi_write(struct hsi_device *dev, u32 *addr, unsigned int size);
Description: Send data through an HSI channel. The transfer is only completed
when the write_complete callback is called
Parameters:
- dev: HSI channel
- addr: pointer to the data to send
- size: number of 32-bit words to be sent
F) void hsi_write_cancel(struct hsi_device *dev);
Description: Cancel current pending write operation
Parameters: HSI channel
G) int hsi_read(struct hsi_device *dev, u32 *addr, unsigned int size);
Description: Receive data through an HSI channel. The transfer is only
completed when the read_complete callback is called
Parameters:
- dev: HSI channel
- addr: pointer where to store the data
- size: number of 32-bit words to be read
H) void hsi_read_cancel(struct hsi_device *dev);
Description: Cancel current pending read operation
Parameters: HSI channel
I) void hsi_poll(struct hsi_device *dev);
Description: Enables data interrupt on frame reception
Parameters: HSI channel
J) void hsi_unpoll(struct hsi_device *dev);
Description: Disables data interrupt on frame reception
Parameters: HSI channel
K) int hsi_ioctl(struct hsi_device *dev, unsigned int command, void *arg);
Description: Apply some control command to the port associated to the given
HSI channel
Parameters:
- dev: HSI channel
- command: command to execute
- arg: parameter for the control command
Commands:
- HSI_IOCTL_ACWAKE_DOWN:
Description: Unset HSI wakeup line (acwake) for the channel
Parameters: None
- HSI_IOCTL_ACWAKE_UP:
Description: Set HSI wakeup line (acwake) for the channel
Parameters: None
- HSI_IOCTL_SEND_BREAK:
Description: Send a HW BREAK frame in FRAME mode
Parameters: None
- HSI_IOCTL_GET_ACWAKE:
Description: Get HST ACWAKE line status
Parameters: Pointer to a u32 variable to return result
(Result: 0 means ACWAKE DOWN, other result means ACWAKE UP)
- HSI_IOCTL_FLUSH_RX:
Description: Force the HSR to idle state
Parameters: None
- HSI_IOCTL_FLUSH_TX:
Description: Force the HST to idle state
Parameters: None
Notes:
HSI: HST FIFO Flush not possible on HSI. Warning is printed in
the HSI case.
- HSI_IOCTL_GET_CAWAKE:
Description: Get CAWAKE (HSR) line status
Parameters: Pointer to a u32 variable to return result
(Result: 0 means CAWAKE DOWN, other result means CAWAKE UP)
- HSI_IOCTL_SET_RX:
Description: Set HSR configuration
Parameters: Pointer to a hsr_ctx structure describing
configurable HSR parameters (mode, frame size, channels,
data flow type, bit-rate divisor, counters)
Notes:
HSI: A special value (0x1000) can be passed as bit-rate divisor
to request the HSR so switch to auto-divisor mode (in this mode,
the HSR can receive at any speed, but the error detection is
deactivated). To exit this RX auto-divisor mode, a new divisor
must be programmed for HSI (can be 0), and the error-detection
is re-enabled.
SSI: The same special 0x1000 value is used to deactivate the SSR
timeout counter. This counter can be re-enabled by programming
the 0x1001 value as bit-rate divisor. The SSI does not accept
any other SSR bit-rate divisor values.
- HSI_IOCTL_GET_RX:
Description: Get HSR configuration
Parameters: Pointer to a hsr_ctx structure describing
configurable HSR parameters (mode, frame size, channels,
data flow type, bit-rate divisor, counters)
- HSI_IOCTL_SET_TX:
Description: Set HST configuration
Parameters: Pointer to a hst_ctx structure describing
configurable HST parameters (mode, frame size, divisor,
arb_mode, channels, data flow type)
Note: flow type is not used in HST.
- HSI_IOCTL_GET_TX:
Description: Get HST configuration
Parameters: Pointer to a hst_ctx structure describing
configurable SSR parameters (mode, frame size, divisor,
arb_mode, channels, data flow type)
Note: flow type is not used in HST.
Note that the Rx and Tx transmission speeds are configured through the
bit-rate divisor parameters. The HSI driver user shall take care of the
functional clock provided to the HSI and program the divisors
accordingly. Depending on the required speed and HSI device, some
constraints on OPP may have to be handled. This shall be managed by the
HSI driver user.
- HSI_IOCTL_SW_RESET:
Description: Force a Reset of HSI block and HSI DMA engine
Parameters: None
- HSI_IOCTL_GET_FIFO_OCCUPANCY:
Description: Get amount of words in RX FIFO
Parameters: Pointer to a size_t variable to return result
- HSI_IOCTL_SET_WAKE_RX_3WIRES_MODE:
Description: Set the 3 wires mode and the AC_READY to 1.
Parameters: None
- HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE:
Description: Set the 4 wires mode.
Parameters: None
L) void hsi_close(struct hsi_device *dev);
Description: Close an HSI channel
Parameters: The HSI channel to close
M) Callback configuration functions:
void hsi_set_read_cb(struct hsi_device *dev,
void (*read_cb)(struct hsi_device *dev, unsigned int size));
void hsi_set_write_cb(struct hsi_device *dev,
void (*write_cb)(struct hsi_device *dev, unsigned int size));
void hsi_set_port_event_cb(struct hsi_device *dev,
void (*port_event_cb)(struct hsi_device *dev,
unsigned int event, void *arg));
Description: Set the read, write and port-event callbacks for the HSI channel.
These functions are usually called in the probe function of the HSI protocol
driver to set completion callbacks for the asynchronous read and write
transfer, and manage the other HSI events.
Parameters:
- dev: HSI channel
- read_cb: Pointer to a callback function to signal that a read transfer
is completed. size is the number of words (32bits) received.
- write_cb: Pointer to a callback function to signal that a write
transfer is completed. size is the number of words (32bits) sent.
- port_event_cb: Pointer to a callback function to signal that a HSI
event has happened (events can be: Break frame detected, error,
cawake-up, cawake-down or HSR-data-available).
N) struct hsi_device_driver
Description: Protocol drivers pass this struct to the hsi_register_driver
function in order to register with the OMAP HSI driver. Among other things it
tells the OMAP HSI driver which channels the protocol driver wants to allocate
for its use
Declaration:
struct hsi_device_driver {
unsigned long ctrl_mask;
unsigned long ch_mask[HSI_MAX_PORTS];
int (*probe)(struct hsi_device *dev);
int (*remove)(struct hsi_device *dev);
int (*suspend)(struct hsi_device *dev,
pm_message_t mesg);
int (*resume)(struct hsi_device *dev);
struct device_driver driver;
};
Fields description:
ctrl_mask: HSI block ids to use
ch_mask[HSI_MAX_PORTS]: HSI channels to use
probe: Probe function
Parameters: HSI channel
remove: Remove function
Parameters: HSI channel
Example:
static struct hsi_device_driver hsi_protocol_driver = {
.ctrl_mask = ANY_HSI_CONTROLLER,
.ch_mask[0] = CHANNEL(0) | CHANNEL(1),
.probe = hsi_proto_probe,
.remove = __devexit_p(hsi_proto_remove),
.driver = {
.name = "hsi_protocol",
},
};
O) HSI RX configuration
Structure given in argument to HSI_IOCTL_SET_RX and HSI_IOCTL_GET_RX is :
struct hsi_tx_config {
__u32 mode; /* Stream:1, Frame:2 */
__u32 flow; /* Kept for Legacy: flow is not used for HST */
__u32 frame_size; /* HSI: 31, SSI: <= 31 */
__u32 channels; /* 1, 2, 4, 8, 16(HSI only) */
__u32 divisor; /* HSI: <= 0xFF, SSI: <= 0x7F */
__u32 arb_mode; /* Round Robin: 0, Priority: 1 */
};
P) HSI TX configuration
Structure given in argument to HSI_IOCTL_SET_TX and HSI_IOCTL_GET_TX is :
struct hsi_rx_config {
__u32 mode; /* Stream:1, Frame:2 */
__u32 flow; /* Synchronized:0, Pipelined:1. No Real-time support */
__u32 frame_size; /* HSI: 31, SSI: <= 31 */
__u32 channels; /* 1, 2, 4, 8, 16(HSI only) */
__u32 divisor; /* Auto mode:0x1000, HSI: <= 0xFF, SSI: <= 0x7F, Deactivate Auto mode (SSI only): 0x1001 */
__u32 counters; /* HSI: FB[31..24], TB[23..20], FT[19..0] / SSI: FT[8..0] */
};
III) FUTURE WORK
----------------
- Move to generic framework
- hsi-char documentation
=================================================
Acknowledgements: The OMAP HSI driver is based on OMAP SSI driver, written by
Carlos Chinea <carlos.chinea@nokia.com>.
Contact: Sebastien Jan <s-jan@ti.com>
Contact: Djamil Elaidi <d-elaidi@ti.com>
Copyright (C) 2008 Nokia Corporation.
Copyright (C) 2011 Texas Instruments, Inc.
|