blob: 928789936b37523aeab9e96dc95f7126aec77b6f [file] [log] [blame]
Nitesh Gupta35b8ea62019-10-31 10:45:54 +05301Overview of Linux kernel MHI support
2====================================
3
4Modem-Host Interface (MHI)
5=========================
6MHI used by the host to control and communicate with modem over high speed
7peripheral bus. Even though MHI can be easily adapt to any peripheral buses,
8primarily used with PCIe based devices. The host has one or more PCIe root
9ports connected to modem device. The host has limited access to device memory
10space, including register configuration and control the device operation.
11Data transfers are invoked from the device.
12
13All data structures used by MHI are in the host system memory. Using PCIe
14interface, the device accesses those data structures. MHI data structures and
15data buffers in the host system memory regions are mapped for device.
16
17Memory spaces
18-------------
19PCIe Configurations : Used for enumeration and resource management, such as
20interrupt and base addresses. This is done by mhi control driver.
21
22MMIO
23----
24MHI MMIO : Memory mapped IO consists of set of registers in the device hardware,
25which are mapped to the host memory space through PCIe base address register
26(BAR)
27
28MHI control registers : Access to MHI configurations registers
29(struct mhi_controller.regs).
30
31MHI BHI register: Boot host interface registers (struct mhi_controller.bhi) used
32for firmware download before MHI initialization.
33
34Channel db array : Doorbell registers (struct mhi_chan.tre_ring.db_addr) used by
35host to notify device there is new work to do.
36
37Event db array : Associated with event context array
38(struct mhi_event.ring.db_addr), host uses to notify device free events are
39available.
40
41Data structures
42---------------
43Host memory : Directly accessed by the host to manage the MHI data structures
44and buffers. The device accesses the host memory over the PCIe interface.
45
46Channel context array : All channel configurations are organized in channel
47context data array.
48
49struct __packed mhi_chan_ctxt;
50struct mhi_ctxt.chan_ctxt;
51
52Transfer rings : Used by host to schedule work items for a channel and organized
53as a circular queue of transfer descriptors (TD).
54
55struct __packed mhi_tre;
56struct mhi_chan.tre_ring;
57
58Event context array : All event configurations are organized in event context
59data array.
60
61struct mhi_ctxt.er_ctxt;
62struct __packed mhi_event_ctxt;
63
64Event rings: Used by device to send completion and state transition messages to
65host
66
67struct mhi_event.ring;
68struct __packed mhi_tre;
69
70Command context array: All command configurations are organized in command
71context data array.
72
73struct __packed mhi_cmd_ctxt;
74struct mhi_ctxt.cmd_ctxt;
75
76Command rings: Used by host to send MHI commands to device
77
78struct __packed mhi_tre;
79struct mhi_cmd.ring;
80
81Transfer rings
82--------------
83MHI channels are logical, unidirectional data pipes between host and device.
84Each channel associated with a single transfer ring. The data direction can be
85either inbound (device to host) or outbound (host to device). Transfer
86descriptors are managed by using transfer rings, which are defined for each
87channel between device and host and resides in the host memory.
88
89Transfer ring Pointer: Transfer Ring Array
90[Read Pointer (RP)] ----------->[Ring Element] } TD
91[Write Pointer (WP)]- [Ring Element]
92 - [Ring Element]
93 --------->[Ring Element]
94 [Ring Element]
95
961. Host allocate memory for transfer ring
972. Host sets base, read pointer, write pointer in corresponding channel context
983. Ring is considered empty when RP == WP
994. Ring is considered full when WP + 1 == RP
1004. RP indicates the next element to be serviced by device
1014. When host new buffer to send, host update the Ring element with buffer
102 information
1035. Host increment the WP to next element
1046. Ring the associated channel DB.
105
106Event rings
107-----------
108Events from the device to host are organized in event rings and defined in event
109descriptors. Event rings are array of EDs that resides in the host memory.
110
111Transfer ring Pointer: Event Ring Array
112[Read Pointer (RP)] ----------->[Ring Element] } ED
113[Write Pointer (WP)]- [Ring Element]
114 - [Ring Element]
115 --------->[Ring Element]
116 [Ring Element]
117
1181. Host allocate memory for event ring
1192. Host sets base, read pointer, write pointer in corresponding channel context
1203. Both host and device has local copy of RP, WP
1213. Ring is considered empty (no events to service) when WP + 1 == RP
1224. Ring is full of events when RP == WP
1234. RP - 1 = last event device programmed
1244. When there is a new event device need to send, device update ED pointed by RP
1255. Device increment RP to next element
1266. Device trigger and interrupt
127
128Example Operation for data transfer:
129
1301. Host prepare TD with buffer information
1312. Host increment Chan[id].ctxt.WP
1323. Host ring channel DB register
1334. Device wakes up process the TD
1345. Device generate a completion event for that TD by updating ED
1356. Device increment Event[id].ctxt.RP
1367. Device trigger MSI to wake host
1378. Host wakes up and check event ring for completion event
1389. Host update the Event[i].ctxt.WP to indicate processed of completion event.
139
140Time sync
141---------
142To synchronize two applications between host and external modem, MHI provide
143native support to get external modems free running timer value in a fast
144reliable method. MHI clients do not need to create client specific methods to
145get modem time.
146
147When client requests modem time, MHI host will automatically capture host time
148at that moment so clients are able to do accurate drift adjustment.
149
150Example:
151
152Client request time @ time T1
153
154Host Time: Tx
155Modem Time: Ty
156
157Client request time @ time T2
158Host Time: Txx
159Modem Time: Tyy
160
161Then drift is:
162Tyy - Ty + <drift> == Txx - Tx
163
164Clients are free to implement their own drift algorithms, what MHI host provide
165is a way to accurately correlate host time with external modem time.
166
167To avoid link level latencies, controller must support capabilities to disable
168any link level latency.
169
170During Time capture host will:
171 1. Capture host time
172 2. Trigger doorbell to capture modem time
173
174It's important time between Step 2 to Step 1 is deterministic as possible.
175Therefore, MHI host will:
176 1. Disable any MHI related to low power modes.
177 2. Disable preemption
178 3. Request bus master to disable any link level latencies. Controller
179 should disable all low power modes such as L0s, L1, L1ss.
180
181MHI States
182----------
183
184enum MHI_STATE {
185MHI_STATE_RESET : MHI is in reset state, POR state. Host is not allowed to
186 access device MMIO register space.
187MHI_STATE_READY : Device is ready for initialization. Host can start MHI
188 initialization by programming MMIO
189MHI_STATE_M0 : MHI is in fully active state, data transfer is active
190MHI_STATE_M1 : Device in a suspended state
191MHI_STATE_M2 : MHI in low power mode, device may enter lower power mode.
192MHI_STATE_M3 : Both host and device in suspended state. PCIe link is not
193 accessible to device.
194
195MHI Initialization
196------------------
197
1981. After system boots, the device is enumerated over PCIe interface
1992. Host allocate MHI context for event, channel and command arrays
2003. Initialize context array, and prepare interrupts
2013. Host waits until device enter READY state
2024. Program MHI MMIO registers and set device into MHI_M0 state
2035. Wait for device to enter M0 state
204
205Linux Software Architecture
206===========================
207
208MHI Controller
209--------------
210MHI controller is also the MHI bus master. In charge of managing the physical
211link between host and device. Not involved in actual data transfer. At least
212for PCIe based buses, for other type of bus, we can expand to add support.
213
214Roles:
2151. Turn on PCIe bus and configure the link
2162. Configure MSI, SMMU, and IOMEM
2173. Allocate struct mhi_controller and register with MHI bus framework
2182. Initiate power on and shutdown sequence
2193. Initiate suspend and resume
220
221Usage
222-----
223
2241. Allocate control data structure by calling mhi_alloc_controller()
2252. Initialize mhi_controller with all the known information such as:
226 - Device Topology
227 - IOMMU window
228 - IOMEM mapping
229 - Device to use for memory allocation, and of_node with DT configuration
230 - Configure asynchronous callback functions
2313. Register MHI controller with MHI bus framework by calling
232 of_register_mhi_controller()
233
234After successfully registering controller can initiate any of these power modes:
235
2361. Power up sequence
237 - mhi_prepare_for_power_up()
238 - mhi_async_power_up()
239 - mhi_sync_power_up()
2402. Power down sequence
241 - mhi_power_down()
242 - mhi_unprepare_after_power_down()
2433. Initiate suspend
244 - mhi_pm_suspend()
2454. Initiate resume
246 - mhi_pm_resume()
247
248MHI Devices
249-----------
250Logical device that bind to maximum of two physical MHI channels. Once MHI is in
251powered on state, each supported channel by controller will be allocated as a
252mhi_device.
253
254Each supported device would be enumerated under
255/sys/bus/mhi/devices/
256
257struct mhi_device;
258
259MHI Driver
260----------
261Each MHI driver can bind to one or more MHI devices. MHI host driver will bind
262mhi_device to mhi_driver.
263
264All registered drivers are visible under
265/sys/bus/mhi/drivers/
266
267struct mhi_driver;
268
269Usage
270-----
271
2721. Register driver using mhi_driver_register
2732. Before sending data, prepare device for transfer by calling
274 mhi_prepare_for_transfer
2753. Initiate data transfer by calling mhi_queue_transfer
2764. After finish, call mhi_unprepare_from_transfer to end data transfer