18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci========================== 48c2ecf20Sopenharmony_ciMHI (Modem Host Interface) 58c2ecf20Sopenharmony_ci========================== 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciThis document provides information about the MHI protocol. 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciOverview 108c2ecf20Sopenharmony_ci======== 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ciMHI is a protocol developed by Qualcomm Innovation Center, Inc. It is used 138c2ecf20Sopenharmony_ciby the host processors to control and communicate with modem devices over high 148c2ecf20Sopenharmony_cispeed peripheral buses or shared memory. Even though MHI can be easily adapted 158c2ecf20Sopenharmony_cito any peripheral buses, it is primarily used with PCIe based devices. MHI 168c2ecf20Sopenharmony_ciprovides logical channels over the physical buses and allows transporting the 178c2ecf20Sopenharmony_cimodem protocols, such as IP data packets, modem control messages, and 188c2ecf20Sopenharmony_cidiagnostics over at least one of those logical channels. Also, the MHI 198c2ecf20Sopenharmony_ciprotocol provides data acknowledgment feature and manages the power state of the 208c2ecf20Sopenharmony_cimodems via one or more logical channels. 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciMHI Internals 238c2ecf20Sopenharmony_ci============= 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ciMMIO 268c2ecf20Sopenharmony_ci---- 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciMMIO (Memory mapped IO) consists of a set of registers in the device hardware, 298c2ecf20Sopenharmony_ciwhich are mapped to the host memory space by the peripheral buses like PCIe. 308c2ecf20Sopenharmony_ciFollowing are the major components of MMIO register space: 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ciMHI control registers: Access to MHI configurations registers 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ciMHI BHI registers: BHI (Boot Host Interface) registers are used by the host 358c2ecf20Sopenharmony_cifor downloading the firmware to the device before MHI initialization. 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciChannel Doorbell array: Channel Doorbell (DB) registers used by the host to 388c2ecf20Sopenharmony_cinotify the device when there is new work to do. 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciEvent Doorbell array: Associated with event context array, the Event Doorbell 418c2ecf20Sopenharmony_ci(DB) registers are used by the host to notify the device when new events are 428c2ecf20Sopenharmony_ciavailable. 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ciDebug registers: A set of registers and counters used by the device to expose 458c2ecf20Sopenharmony_cidebugging information like performance, functional, and stability to the host. 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ciData structures 488c2ecf20Sopenharmony_ci--------------- 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciAll data structures used by MHI are in the host system memory. Using the 518c2ecf20Sopenharmony_ciphysical interface, the device accesses those data structures. MHI data 528c2ecf20Sopenharmony_cistructures and data buffers in the host system memory regions are mapped for 538c2ecf20Sopenharmony_cithe device. 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ciChannel context array: All channel configurations are organized in channel 568c2ecf20Sopenharmony_cicontext data array. 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ciTransfer rings: Used by the host to schedule work items for a channel. The 598c2ecf20Sopenharmony_citransfer rings are organized as a circular queue of Transfer Descriptors (TD). 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ciEvent context array: All event configurations are organized in the event context 628c2ecf20Sopenharmony_cidata array. 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ciEvent rings: Used by the device to send completion and state transition messages 658c2ecf20Sopenharmony_cito the host 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ciCommand context array: All command configurations are organized in command 688c2ecf20Sopenharmony_cicontext data array. 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciCommand rings: Used by the host to send MHI commands to the device. The command 718c2ecf20Sopenharmony_cirings are organized as a circular queue of Command Descriptors (CD). 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ciChannels 748c2ecf20Sopenharmony_ci-------- 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciMHI channels are logical, unidirectional data pipes between a host and a device. 778c2ecf20Sopenharmony_ciThe concept of channels in MHI is similar to endpoints in USB. MHI supports up 788c2ecf20Sopenharmony_cito 256 channels. However, specific device implementations may support less than 798c2ecf20Sopenharmony_cithe maximum number of channels allowed. 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciTwo unidirectional channels with their associated transfer rings form a 828c2ecf20Sopenharmony_cibidirectional data pipe, which can be used by the upper-layer protocols to 838c2ecf20Sopenharmony_citransport application data packets (such as IP packets, modem control messages, 848c2ecf20Sopenharmony_cidiagnostics messages, and so on). Each channel is associated with a single 858c2ecf20Sopenharmony_citransfer ring. 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ciTransfer rings 888c2ecf20Sopenharmony_ci-------------- 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ciTransfers between the host and device are organized by channels and defined by 918c2ecf20Sopenharmony_ciTransfer Descriptors (TD). TDs are managed through transfer rings, which are 928c2ecf20Sopenharmony_cidefined for each channel between the device and host and reside in the host 938c2ecf20Sopenharmony_cimemory. TDs consist of one or more ring elements (or transfer blocks):: 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci [Read Pointer (RP)] ----------->[Ring Element] } TD 968c2ecf20Sopenharmony_ci [Write Pointer (WP)]- [Ring Element] 978c2ecf20Sopenharmony_ci - [Ring Element] 988c2ecf20Sopenharmony_ci --------->[Ring Element] 998c2ecf20Sopenharmony_ci [Ring Element] 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ciBelow is the basic usage of transfer rings: 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci* Host allocates memory for transfer ring. 1048c2ecf20Sopenharmony_ci* Host sets the base pointer, read pointer, and write pointer in corresponding 1058c2ecf20Sopenharmony_ci channel context. 1068c2ecf20Sopenharmony_ci* Ring is considered empty when RP == WP. 1078c2ecf20Sopenharmony_ci* Ring is considered full when WP + 1 == RP. 1088c2ecf20Sopenharmony_ci* RP indicates the next element to be serviced by the device. 1098c2ecf20Sopenharmony_ci* When the host has a new buffer to send, it updates the ring element with 1108c2ecf20Sopenharmony_ci buffer information, increments the WP to the next element and rings the 1118c2ecf20Sopenharmony_ci associated channel DB. 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ciEvent rings 1148c2ecf20Sopenharmony_ci----------- 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ciEvents from the device to host are organized in event rings and defined by Event 1178c2ecf20Sopenharmony_ciDescriptors (ED). Event rings are used by the device to report events such as 1188c2ecf20Sopenharmony_cidata transfer completion status, command completion status, and state changes 1198c2ecf20Sopenharmony_cito the host. Event rings are the array of EDs that resides in the host 1208c2ecf20Sopenharmony_cimemory. EDs consist of one or more ring elements (or transfer blocks):: 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci [Read Pointer (RP)] ----------->[Ring Element] } ED 1238c2ecf20Sopenharmony_ci [Write Pointer (WP)]- [Ring Element] 1248c2ecf20Sopenharmony_ci - [Ring Element] 1258c2ecf20Sopenharmony_ci --------->[Ring Element] 1268c2ecf20Sopenharmony_ci [Ring Element] 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ciBelow is the basic usage of event rings: 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci* Host allocates memory for event ring. 1318c2ecf20Sopenharmony_ci* Host sets the base pointer, read pointer, and write pointer in corresponding 1328c2ecf20Sopenharmony_ci channel context. 1338c2ecf20Sopenharmony_ci* Both host and device has a local copy of RP, WP. 1348c2ecf20Sopenharmony_ci* Ring is considered empty (no events to service) when WP + 1 == RP. 1358c2ecf20Sopenharmony_ci* Ring is considered full of events when RP == WP. 1368c2ecf20Sopenharmony_ci* When there is a new event the device needs to send, the device updates ED 1378c2ecf20Sopenharmony_ci pointed by RP, increments the RP to the next element and triggers the 1388c2ecf20Sopenharmony_ci interrupt. 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ciRing Element 1418c2ecf20Sopenharmony_ci------------ 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ciA Ring Element is a data structure used to transfer a single block 1448c2ecf20Sopenharmony_ciof data between the host and the device. Transfer ring element types contain a 1458c2ecf20Sopenharmony_cisingle buffer pointer, the size of the buffer, and additional control 1468c2ecf20Sopenharmony_ciinformation. Other ring element types may only contain control and status 1478c2ecf20Sopenharmony_ciinformation. For single buffer operations, a ring descriptor is composed of a 1488c2ecf20Sopenharmony_cisingle element. For large multi-buffer operations (such as scatter and gather), 1498c2ecf20Sopenharmony_cielements can be chained to form a longer descriptor. 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciMHI Operations 1528c2ecf20Sopenharmony_ci============== 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ciMHI States 1558c2ecf20Sopenharmony_ci---------- 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ciMHI_STATE_RESET 1588c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~ 1598c2ecf20Sopenharmony_ciMHI is in reset state after power-up or hardware reset. The host is not allowed 1608c2ecf20Sopenharmony_cito access device MMIO register space. 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ciMHI_STATE_READY 1638c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~ 1648c2ecf20Sopenharmony_ciMHI is ready for initialization. The host can start MHI initialization by 1658c2ecf20Sopenharmony_ciprogramming MMIO registers. 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ciMHI_STATE_M0 1688c2ecf20Sopenharmony_ci~~~~~~~~~~~~ 1698c2ecf20Sopenharmony_ciMHI is running and operational in the device. The host can start channels by 1708c2ecf20Sopenharmony_ciissuing channel start command. 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ciMHI_STATE_M1 1738c2ecf20Sopenharmony_ci~~~~~~~~~~~~ 1748c2ecf20Sopenharmony_ciMHI operation is suspended by the device. This state is entered when the 1758c2ecf20Sopenharmony_cidevice detects inactivity at the physical interface within a preset time. 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ciMHI_STATE_M2 1788c2ecf20Sopenharmony_ci~~~~~~~~~~~~ 1798c2ecf20Sopenharmony_ciMHI is in low power state. MHI operation is suspended and the device may 1808c2ecf20Sopenharmony_cienter lower power mode. 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ciMHI_STATE_M3 1838c2ecf20Sopenharmony_ci~~~~~~~~~~~~ 1848c2ecf20Sopenharmony_ciMHI operation stopped by the host. This state is entered when the host suspends 1858c2ecf20Sopenharmony_ciMHI operation. 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ciMHI Initialization 1888c2ecf20Sopenharmony_ci------------------ 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ciAfter system boots, the device is enumerated over the physical interface. 1918c2ecf20Sopenharmony_ciIn the case of PCIe, the device is enumerated and assigned BAR-0 for 1928c2ecf20Sopenharmony_cithe device's MMIO register space. To initialize the MHI in a device, 1938c2ecf20Sopenharmony_cithe host performs the following operations: 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci* Allocates the MHI context for event, channel and command arrays. 1968c2ecf20Sopenharmony_ci* Initializes the context array, and prepares interrupts. 1978c2ecf20Sopenharmony_ci* Waits until the device enters READY state. 1988c2ecf20Sopenharmony_ci* Programs MHI MMIO registers and sets device into MHI_M0 state. 1998c2ecf20Sopenharmony_ci* Waits for the device to enter M0 state. 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ciMHI Data Transfer 2028c2ecf20Sopenharmony_ci----------------- 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ciMHI data transfer is initiated by the host to transfer data to the device. 2058c2ecf20Sopenharmony_ciFollowing are the sequence of operations performed by the host to transfer 2068c2ecf20Sopenharmony_cidata to device: 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci* Host prepares TD with buffer information. 2098c2ecf20Sopenharmony_ci* Host increments the WP of the corresponding channel transfer ring. 2108c2ecf20Sopenharmony_ci* Host rings the channel DB register. 2118c2ecf20Sopenharmony_ci* Device wakes up to process the TD. 2128c2ecf20Sopenharmony_ci* Device generates a completion event for the processed TD by updating ED. 2138c2ecf20Sopenharmony_ci* Device increments the RP of the corresponding event ring. 2148c2ecf20Sopenharmony_ci* Device triggers IRQ to wake up the host. 2158c2ecf20Sopenharmony_ci* Host wakes up and checks the event ring for completion event. 2168c2ecf20Sopenharmony_ci* Host updates the WP of the corresponding event ring to indicate that the 2178c2ecf20Sopenharmony_ci data transfer has been completed successfully. 2188c2ecf20Sopenharmony_ci 219