1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun========================== 4*4882a593SmuzhiyunMHI (Modem Host Interface) 5*4882a593Smuzhiyun========================== 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunThis document provides information about the MHI protocol. 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunOverview 10*4882a593Smuzhiyun======== 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunMHI is a protocol developed by Qualcomm Innovation Center, Inc. It is used 13*4882a593Smuzhiyunby the host processors to control and communicate with modem devices over high 14*4882a593Smuzhiyunspeed peripheral buses or shared memory. Even though MHI can be easily adapted 15*4882a593Smuzhiyunto any peripheral buses, it is primarily used with PCIe based devices. MHI 16*4882a593Smuzhiyunprovides logical channels over the physical buses and allows transporting the 17*4882a593Smuzhiyunmodem protocols, such as IP data packets, modem control messages, and 18*4882a593Smuzhiyundiagnostics over at least one of those logical channels. Also, the MHI 19*4882a593Smuzhiyunprotocol provides data acknowledgment feature and manages the power state of the 20*4882a593Smuzhiyunmodems via one or more logical channels. 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunMHI Internals 23*4882a593Smuzhiyun============= 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunMMIO 26*4882a593Smuzhiyun---- 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunMMIO (Memory mapped IO) consists of a set of registers in the device hardware, 29*4882a593Smuzhiyunwhich are mapped to the host memory space by the peripheral buses like PCIe. 30*4882a593SmuzhiyunFollowing are the major components of MMIO register space: 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunMHI control registers: Access to MHI configurations registers 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunMHI BHI registers: BHI (Boot Host Interface) registers are used by the host 35*4882a593Smuzhiyunfor downloading the firmware to the device before MHI initialization. 36*4882a593Smuzhiyun 37*4882a593SmuzhiyunChannel Doorbell array: Channel Doorbell (DB) registers used by the host to 38*4882a593Smuzhiyunnotify the device when there is new work to do. 39*4882a593Smuzhiyun 40*4882a593SmuzhiyunEvent Doorbell array: Associated with event context array, the Event Doorbell 41*4882a593Smuzhiyun(DB) registers are used by the host to notify the device when new events are 42*4882a593Smuzhiyunavailable. 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunDebug registers: A set of registers and counters used by the device to expose 45*4882a593Smuzhiyundebugging information like performance, functional, and stability to the host. 46*4882a593Smuzhiyun 47*4882a593SmuzhiyunData structures 48*4882a593Smuzhiyun--------------- 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunAll data structures used by MHI are in the host system memory. Using the 51*4882a593Smuzhiyunphysical interface, the device accesses those data structures. MHI data 52*4882a593Smuzhiyunstructures and data buffers in the host system memory regions are mapped for 53*4882a593Smuzhiyunthe device. 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunChannel context array: All channel configurations are organized in channel 56*4882a593Smuzhiyuncontext data array. 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunTransfer rings: Used by the host to schedule work items for a channel. The 59*4882a593Smuzhiyuntransfer rings are organized as a circular queue of Transfer Descriptors (TD). 60*4882a593Smuzhiyun 61*4882a593SmuzhiyunEvent context array: All event configurations are organized in the event context 62*4882a593Smuzhiyundata array. 63*4882a593Smuzhiyun 64*4882a593SmuzhiyunEvent rings: Used by the device to send completion and state transition messages 65*4882a593Smuzhiyunto the host 66*4882a593Smuzhiyun 67*4882a593SmuzhiyunCommand context array: All command configurations are organized in command 68*4882a593Smuzhiyuncontext data array. 69*4882a593Smuzhiyun 70*4882a593SmuzhiyunCommand rings: Used by the host to send MHI commands to the device. The command 71*4882a593Smuzhiyunrings are organized as a circular queue of Command Descriptors (CD). 72*4882a593Smuzhiyun 73*4882a593SmuzhiyunChannels 74*4882a593Smuzhiyun-------- 75*4882a593Smuzhiyun 76*4882a593SmuzhiyunMHI channels are logical, unidirectional data pipes between a host and a device. 77*4882a593SmuzhiyunThe concept of channels in MHI is similar to endpoints in USB. MHI supports up 78*4882a593Smuzhiyunto 256 channels. However, specific device implementations may support less than 79*4882a593Smuzhiyunthe maximum number of channels allowed. 80*4882a593Smuzhiyun 81*4882a593SmuzhiyunTwo unidirectional channels with their associated transfer rings form a 82*4882a593Smuzhiyunbidirectional data pipe, which can be used by the upper-layer protocols to 83*4882a593Smuzhiyuntransport application data packets (such as IP packets, modem control messages, 84*4882a593Smuzhiyundiagnostics messages, and so on). Each channel is associated with a single 85*4882a593Smuzhiyuntransfer ring. 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunTransfer rings 88*4882a593Smuzhiyun-------------- 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunTransfers between the host and device are organized by channels and defined by 91*4882a593SmuzhiyunTransfer Descriptors (TD). TDs are managed through transfer rings, which are 92*4882a593Smuzhiyundefined for each channel between the device and host and reside in the host 93*4882a593Smuzhiyunmemory. TDs consist of one or more ring elements (or transfer blocks):: 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun [Read Pointer (RP)] ----------->[Ring Element] } TD 96*4882a593Smuzhiyun [Write Pointer (WP)]- [Ring Element] 97*4882a593Smuzhiyun - [Ring Element] 98*4882a593Smuzhiyun --------->[Ring Element] 99*4882a593Smuzhiyun [Ring Element] 100*4882a593Smuzhiyun 101*4882a593SmuzhiyunBelow is the basic usage of transfer rings: 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun* Host allocates memory for transfer ring. 104*4882a593Smuzhiyun* Host sets the base pointer, read pointer, and write pointer in corresponding 105*4882a593Smuzhiyun channel context. 106*4882a593Smuzhiyun* Ring is considered empty when RP == WP. 107*4882a593Smuzhiyun* Ring is considered full when WP + 1 == RP. 108*4882a593Smuzhiyun* RP indicates the next element to be serviced by the device. 109*4882a593Smuzhiyun* When the host has a new buffer to send, it updates the ring element with 110*4882a593Smuzhiyun buffer information, increments the WP to the next element and rings the 111*4882a593Smuzhiyun associated channel DB. 112*4882a593Smuzhiyun 113*4882a593SmuzhiyunEvent rings 114*4882a593Smuzhiyun----------- 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunEvents from the device to host are organized in event rings and defined by Event 117*4882a593SmuzhiyunDescriptors (ED). Event rings are used by the device to report events such as 118*4882a593Smuzhiyundata transfer completion status, command completion status, and state changes 119*4882a593Smuzhiyunto the host. Event rings are the array of EDs that resides in the host 120*4882a593Smuzhiyunmemory. EDs consist of one or more ring elements (or transfer blocks):: 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun [Read Pointer (RP)] ----------->[Ring Element] } ED 123*4882a593Smuzhiyun [Write Pointer (WP)]- [Ring Element] 124*4882a593Smuzhiyun - [Ring Element] 125*4882a593Smuzhiyun --------->[Ring Element] 126*4882a593Smuzhiyun [Ring Element] 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunBelow is the basic usage of event rings: 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun* Host allocates memory for event ring. 131*4882a593Smuzhiyun* Host sets the base pointer, read pointer, and write pointer in corresponding 132*4882a593Smuzhiyun channel context. 133*4882a593Smuzhiyun* Both host and device has a local copy of RP, WP. 134*4882a593Smuzhiyun* Ring is considered empty (no events to service) when WP + 1 == RP. 135*4882a593Smuzhiyun* Ring is considered full of events when RP == WP. 136*4882a593Smuzhiyun* When there is a new event the device needs to send, the device updates ED 137*4882a593Smuzhiyun pointed by RP, increments the RP to the next element and triggers the 138*4882a593Smuzhiyun interrupt. 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunRing Element 141*4882a593Smuzhiyun------------ 142*4882a593Smuzhiyun 143*4882a593SmuzhiyunA Ring Element is a data structure used to transfer a single block 144*4882a593Smuzhiyunof data between the host and the device. Transfer ring element types contain a 145*4882a593Smuzhiyunsingle buffer pointer, the size of the buffer, and additional control 146*4882a593Smuzhiyuninformation. Other ring element types may only contain control and status 147*4882a593Smuzhiyuninformation. For single buffer operations, a ring descriptor is composed of a 148*4882a593Smuzhiyunsingle element. For large multi-buffer operations (such as scatter and gather), 149*4882a593Smuzhiyunelements can be chained to form a longer descriptor. 150*4882a593Smuzhiyun 151*4882a593SmuzhiyunMHI Operations 152*4882a593Smuzhiyun============== 153*4882a593Smuzhiyun 154*4882a593SmuzhiyunMHI States 155*4882a593Smuzhiyun---------- 156*4882a593Smuzhiyun 157*4882a593SmuzhiyunMHI_STATE_RESET 158*4882a593Smuzhiyun~~~~~~~~~~~~~~~ 159*4882a593SmuzhiyunMHI is in reset state after power-up or hardware reset. The host is not allowed 160*4882a593Smuzhiyunto access device MMIO register space. 161*4882a593Smuzhiyun 162*4882a593SmuzhiyunMHI_STATE_READY 163*4882a593Smuzhiyun~~~~~~~~~~~~~~~ 164*4882a593SmuzhiyunMHI is ready for initialization. The host can start MHI initialization by 165*4882a593Smuzhiyunprogramming MMIO registers. 166*4882a593Smuzhiyun 167*4882a593SmuzhiyunMHI_STATE_M0 168*4882a593Smuzhiyun~~~~~~~~~~~~ 169*4882a593SmuzhiyunMHI is running and operational in the device. The host can start channels by 170*4882a593Smuzhiyunissuing channel start command. 171*4882a593Smuzhiyun 172*4882a593SmuzhiyunMHI_STATE_M1 173*4882a593Smuzhiyun~~~~~~~~~~~~ 174*4882a593SmuzhiyunMHI operation is suspended by the device. This state is entered when the 175*4882a593Smuzhiyundevice detects inactivity at the physical interface within a preset time. 176*4882a593Smuzhiyun 177*4882a593SmuzhiyunMHI_STATE_M2 178*4882a593Smuzhiyun~~~~~~~~~~~~ 179*4882a593SmuzhiyunMHI is in low power state. MHI operation is suspended and the device may 180*4882a593Smuzhiyunenter lower power mode. 181*4882a593Smuzhiyun 182*4882a593SmuzhiyunMHI_STATE_M3 183*4882a593Smuzhiyun~~~~~~~~~~~~ 184*4882a593SmuzhiyunMHI operation stopped by the host. This state is entered when the host suspends 185*4882a593SmuzhiyunMHI operation. 186*4882a593Smuzhiyun 187*4882a593SmuzhiyunMHI Initialization 188*4882a593Smuzhiyun------------------ 189*4882a593Smuzhiyun 190*4882a593SmuzhiyunAfter system boots, the device is enumerated over the physical interface. 191*4882a593SmuzhiyunIn the case of PCIe, the device is enumerated and assigned BAR-0 for 192*4882a593Smuzhiyunthe device's MMIO register space. To initialize the MHI in a device, 193*4882a593Smuzhiyunthe host performs the following operations: 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun* Allocates the MHI context for event, channel and command arrays. 196*4882a593Smuzhiyun* Initializes the context array, and prepares interrupts. 197*4882a593Smuzhiyun* Waits until the device enters READY state. 198*4882a593Smuzhiyun* Programs MHI MMIO registers and sets device into MHI_M0 state. 199*4882a593Smuzhiyun* Waits for the device to enter M0 state. 200*4882a593Smuzhiyun 201*4882a593SmuzhiyunMHI Data Transfer 202*4882a593Smuzhiyun----------------- 203*4882a593Smuzhiyun 204*4882a593SmuzhiyunMHI data transfer is initiated by the host to transfer data to the device. 205*4882a593SmuzhiyunFollowing are the sequence of operations performed by the host to transfer 206*4882a593Smuzhiyundata to device: 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun* Host prepares TD with buffer information. 209*4882a593Smuzhiyun* Host increments the WP of the corresponding channel transfer ring. 210*4882a593Smuzhiyun* Host rings the channel DB register. 211*4882a593Smuzhiyun* Device wakes up to process the TD. 212*4882a593Smuzhiyun* Device generates a completion event for the processed TD by updating ED. 213*4882a593Smuzhiyun* Device increments the RP of the corresponding event ring. 214*4882a593Smuzhiyun* Device triggers IRQ to wake up the host. 215*4882a593Smuzhiyun* Host wakes up and checks the event ring for completion event. 216*4882a593Smuzhiyun* Host updates the WP of the corresponding event ring to indicate that the 217*4882a593Smuzhiyun data transfer has been completed successfully. 218*4882a593Smuzhiyun 219