Pavankumar Kondeti | 38e508c | 2014-02-24 14:53:31 +0530 | [diff] [blame] | 1 | Introduction |
| 2 | ============ |
| 3 | |
| 4 | USB UICC connectivity is required for MSM8x12. This SoC has only 1 USB |
| 5 | controller which is used for peripheral mode and charging. Hence an external |
| 6 | USB host controller over SPI is used to connect a USB UICC card. ICE40 FPGA |
| 7 | based SPI to IC-USB (Inter-Chip USB) bridge chip is used. |
| 8 | |
| 9 | The ICE40 Host controller driver (ice40-hcd) is registered as a SPI protocol |
| 10 | driver and interacts with the SPI subsystem on one side and interacts with the |
| 11 | USB core on the other side. |
| 12 | |
| 13 | Hardware description |
| 14 | ==================== |
| 15 | |
| 16 | The ICE40 devices are SRAM-based FPGAs. The SRAM memory cells are volatile, |
| 17 | meaning that once power is removed from the device, its configuration is lost |
| 18 | and must be reloaded on the next power-up. An on-chip non-volatile configuration |
| 19 | memory or an external SPI flash are not used to store the configuration data due |
| 20 | to increased power consumption. Instead, the software loads the configuration |
| 21 | data through SPI interface after powering up the bridge chip. Once the |
| 22 | configuration data is programmed successfully, the bridge chip will be ready for |
| 23 | the USB host controller operations. |
| 24 | |
| 25 | The ICE40 device has an interrupt signal apart from the standard SPI signals |
| 26 | CSn, SCLK, MOSI and MISO. It has support for 25 to 50 MHz frequencies. The |
| 27 | maximum operating frequency during configuration loading is 25 MHz. |
| 28 | |
| 29 | The bridge chip requires two power supplies, SPI_VCC (1.8v - 3.3v) and VCC_CORE |
| 30 | (1.2v). The SPI_VCC manages the SPI slave portion and VCC_CORE manages the USB |
| 31 | serial engine (SIE) portion. It requires a 19.2 MHz reference clock and a |
| 32 | 32 MHz clock is required for remote wakeup detection during suspend. |
| 33 | |
| 34 | The configuration loading sequence: |
| 35 | |
| 36 | - Assert the RSTn pin. This keeps bridge chip in reset state after downloading |
| 37 | the configuration data. |
| 38 | - The bridge chip samples the SPI interface chip select pin during power-up and |
| 39 | enters SPI slave mode if it is low. Drive the chip select pin low before |
| 40 | powering up the bridge chip. |
| 41 | - Power-up the bridge chip by enabling SPI_VCC and VCC_CORE |
| 42 | - De-assert the chip select pin after 50 usec. |
| 43 | - Transfer the configuration data over SPI. Note that the bridge chip requires |
| 44 | 49 dummy clock cycles after sending the data. |
| 45 | - The bridge chip indicates the status of the configuration loading via config |
| 46 | done pin. It may take 50 usec to assert this pin. |
| 47 | |
| 48 | The 19.2 MHz clock should be supplied before de-asserting the RSTn pin. A PLL |
| 49 | is used to generate a 48MHz clock signal that then creates a 12MHz clock signal |
| 50 | by a divider. When the PLLOK bit is set in USB Transfer Result register, it |
| 51 | indicates that the PLL output is locked to the input reference clock. When it |
| 52 | is 0, it indicates that the PLL is out of lock. It is recommended to assert the |
| 53 | RSTn pin to re-synchronize the PLL to the reference clock when the PLL loses |
| 54 | lock. The chip will be ready for the USB host controller operations after it is |
| 55 | brought out of reset and PLL is synchronized to the reference clock. |
| 56 | |
| 57 | The software is responsible for initiating all the USB host transfers by writing |
| 58 | the associated registers. The SIE in the bridge chip performs the USB host |
| 59 | operations via the IC-USB bus based on the registers set by the software. The |
| 60 | USB transfer results as well as the bus status like the peripheral connection, |
| 61 | disconnection, resume, etc. are notified to software through the interrupt and |
| 62 | the internal registers. |
| 63 | |
| 64 | The bridge chip provides the DP & DM pull-down resistor control to the software. |
| 65 | The pull-down resistors are enabled automatically after the power up to force |
| 66 | the SE0 condition on the bus. The software is required to disable these |
| 67 | resistors before driving the reset on the bus. Control, Bulk and Interrupt |
| 68 | transfers are supported. The data toggling states are not maintained in the |
| 69 | hardware and should be serviced by the software. The bridge chip returns |
| 70 | one of the following values for a USB transaction (SETUP/IN/OUT) via Transfer |
| 71 | result register. |
| 72 | |
| 73 | xSUCCESS: Successful transfer. |
| 74 | xBUSY: The SIE is busy with a USB transfer. |
| 75 | xPKTERR: Packet Error (stuff, EOP). |
| 76 | xPIDERR: PID check bits are incorrect. |
| 77 | xNAK: Device returned NAK. This is not an error condition for IN/OUT. But it |
| 78 | is an error condition for SETUP. |
| 79 | xSTALL: Device returned STALL. |
| 80 | xWRONGPID: Wrong PID is received. For example a IN transaction is attempted on |
| 81 | OUT endpoint. |
| 82 | xCRCERR: CRC error. |
| 83 | xTOGERR: Toggle bit error. The SIE returns ACK when the toggle mismatch happens |
| 84 | for IN transaction and returns this error code. Software should discard the |
| 85 | data as it was received already in the previous transaction. |
| 86 | xBADLEN: Too big packet size received. |
| 87 | xTIMEOUT: Device failed to respond in time. |
| 88 | |
| 89 | Software description |
| 90 | ==================== |
| 91 | |
| 92 | This driver is compiled as a module and is loaded by the userspace after |
| 93 | getting the UICC card insertion event from the modem processor. The module is |
| 94 | unloaded upon the UICC card removal. |
| 95 | |
| 96 | This driver registers as a SPI protocol driver. The SPI controller driver |
| 97 | manages the chip select pin. This pin needs to be driven low before powering |
| 98 | up the bridge chip. Hence this pin settings are overridden temporarily during |
| 99 | the bridge chip power-up sequence. The original settings are restored before |
| 100 | sending the configuration data to the bridge chip which acts as a SPI slave. |
| 101 | Both pinctl and gpiomux framework allow this type of use case. |
| 102 | |
| 103 | The configuration data file is stored on the eMMC card. Firmware class API |
| 104 | request_firmware() is used to read the configuration data file. The |
| 105 | configuration data is then sent to the bridge chip via SPI interface. The |
| 106 | bridge chip asserts the config done pin once the configuration is completed. |
| 107 | |
| 108 | The driver registers as a Full Speed (USB 1.1) HCD. The following methods |
| 109 | are implemented that are part of hc_drive struct: |
| 110 | |
| 111 | reset: It is called one time by the core during HCD registration. The |
| 112 | default address 0 is programmed and the line state is sampled to check if any |
| 113 | device is connected. If any device is connected, the port flags are updated |
| 114 | accordingly. As the module is loaded after the UICC card is inserted, the |
| 115 | device would be present at this time. |
| 116 | |
| 117 | start: This method is called one time by the core during HCD registration. |
| 118 | The bridge chip is programmed to transmit the SOFs. |
| 119 | |
| 120 | stop: The method is called one time by the core during HCD deregistration. |
| 121 | The bridge chip is programmed to stop transmitting the SOFs. |
| 122 | |
| 123 | hub_control: This method is called by the core to manage the Root HUB. The |
| 124 | hardware does not maintain port state. The software maintain the port |
| 125 | state and provide the information to the core when required. The following |
| 126 | HUB class requests are supported. |
| 127 | |
| 128 | - GetHubDescriptor: The HUB descriptor is sent to the core. Only 1 port |
| 129 | is present. Over current protection and port power control are not supported. |
| 130 | - SetPortFeature: The device reset and suspend are supported. The The DP & DM |
| 131 | pull-down resistors are disabled before driving the reset as per the IC-USB |
| 132 | spec. The reset signaling is stopped when the core queries the port status. |
| 133 | - GetPortStatus: The device connection status is sent to the core. If a reset |
| 134 | is in progress, it is stopped before returning the port status. |
| 135 | - ClearPortFeature: The device resume (clear suspend) is supported. |
| 136 | |
| 137 | urb_enqueue: This method is called by the core to initiate a USB Control/Bulk |
| 138 | transfer. If the endpoint private context is not present, it will be created to |
| 139 | hold the endpoint number, host endpoint structure, transaction error count, halt |
| 140 | state and unlink state. The URB is attached to the endpoint URB list. If the |
| 141 | endpoint is not active, it is attached to the asynchronous schedule list and the |
| 142 | work is scheduled to traverse this list. The traversal algorithm is explained |
| 143 | later in this document. |
| 144 | |
| 145 | urb_dequeue: This method is called by the core when an URB is unlinked. If the |
| 146 | endpoint is not active, the URB is unlinked immediately. Otherwise the endpoint |
| 147 | is marked for unlink and URB is unlinked from the asynchronous schedule work. |
| 148 | |
| 149 | bus_suspend: This method is called by the core during root hub suspend. The SOFs |
| 150 | are already stopped during the port suspend which happens before root hub |
| 151 | suspend. Assert the RSTn pin to put the bridge chip in reset state and stop XO |
| 152 | (19.2 MHz) clock. |
| 153 | |
| 154 | bus_resume: This method is called by the core during root hub resume. Turn on |
| 155 | the XO clock and de-assert the RSTn signal to bring the chip out of reset. |
| 156 | |
| 157 | endpoint_disable: This method is called by the core during the device |
| 158 | disconnect. All the URB are unlinked by this time, so free the endpoint private |
| 159 | structure. |
| 160 | |
| 161 | Asynchronous scheduling: |
| 162 | |
| 163 | All the active endpoints are queued to the asynchronous schedule list. A worker |
| 164 | thread iterates over this circular list and process the URBs. Processing an URB |
| 165 | involves initiating multiple SETUP/IN/OUT transactions and checking the result. |
| 166 | After receiving the DATA/ACK, the toggle bit is inverted. |
| 167 | |
| 168 | A URB is finished when any of the following events occur: |
| 169 | |
| 170 | - The entire data is received for an OUT endpoint or a short packet is received |
| 171 | for an IN endpoint. |
| 172 | - The endpoint is stalled by the device. -EPIPE is returned. |
| 173 | - Transaction error is occurred consecutively 3 times. -EPROTO is returned. |
| 174 | - A NAK received for a SETUP transaction. |
| 175 | - The URB is unlinked. |
| 176 | |
| 177 | The next transaction is issued on the next endpoint (if available) irrespective |
| 178 | of the result of the current transaction. But the IN/OUT transaction of data |
| 179 | or status phase is attempted immediately after the SETUP transaction for a |
| 180 | control endpoint. If a NAK is received for this transaction, the control |
| 181 | transfer is resumed next time when the control endpoint is encountered in the |
| 182 | asynchronous schedule list. This is to give the control transfers priority |
| 183 | over the bulk transfers. |
| 184 | |
| 185 | The endpoint is marked as halted when a URB is finished due to transaction |
| 186 | errors or stall condition. The halted endpoint is removed from the asynchronous |
| 187 | schedule list. It will be added again next time when a URB is enqueued on this |
| 188 | endpoint. |
| 189 | |
| 190 | This driver provides debugfs interface and exports a file called "command" under |
| 191 | <debugfs root>/ice40 directory. The following strings can be echoed to this |
| 192 | file. |
| 193 | |
| 194 | "poll": If the device is connected after the module is loaded, it will not be |
| 195 | detected automatically. The bus is sampled when this string is echoed. If a |
| 196 | device is connected, port flags are updated and core is notified about the |
| 197 | device connect event. |
| 198 | |
| 199 | "rwtest": Function Address register is written and read back to validate the |
| 200 | contents. This should NOT be used while the usb device is connected. This is |
| 201 | strictly for debugging purpose. |
| 202 | |
| 203 | "dump": Dumps all the register values to the kernel log buffer. |
| 204 | |
| 205 | Design Goals: |
| 206 | ============= |
| 207 | |
| 208 | - Handle errors gracefully. Implement retry mechanism for transaction errors, |
| 209 | memory failures. Mark HCD as dead for serious errors like SPI transaction |
| 210 | errors to avoid further interactions with the attached USB device. |
| 211 | - Keep the asynchronous schedule algorithm simple and efficient. Take advantage |
| 212 | of the static configuration of the USB device. UICC cards has only CCID and Mass |
| 213 | storage interfaces. These interface protocol allows only 1 active transfer on |
| 214 | either in or out endpoint. |
| 215 | - Add trace points to capture USB transactions. |
| 216 | |
| 217 | Driver parameters |
| 218 | ================= |
| 219 | |
| 220 | The driver is compiled as a module and it accepts the configuration data file |
| 221 | name as a module param called "firmware". The default configuration file name |
| 222 | is "ice40.bin". |
| 223 | |
| 224 | Config options |
| 225 | ============== |
| 226 | |
| 227 | Set CONFIG_USB_SL811_HCD to m to compile this driver as a module. The driver |
| 228 | should not be compiled statically, because the configuration data is not |
| 229 | available during kernel boot. |
| 230 | |
| 231 | To do |
| 232 | ===== |
| 233 | |
| 234 | - The bridge chip has 2 IN FIFO and 2 OUT FIFO. Implement double buffering. |
| 235 | - The bridge chip has an interrupt to indicate the transaction (IN/OUT) |
| 236 | completion. The current implementation uses polling for simplicity and to avoid |
| 237 | interrupt latencies. Evaluate interrupt approach. |
| 238 | - The bridge chip can be completely power collapsed during suspend to avoid |
| 239 | leakage currents. As the bridge chip does not have any non-volatile memory, |
| 240 | the configuration data needs to be loaded during resume. This method has higher |
| 241 | power savings with higher resume latencies. Evaluate this approach. |
| 242 | - Implement Interrupt transfers if required. |
| 243 | - The request_firmware() API copies the configuration data file to the kernel |
| 244 | virtual memory. This memory can't be used for DMA. The current implementation |
| 245 | copies this data into contiguous physical memory which is allocated via |
| 246 | kmalloc. If this memory allocation fails, try to allocate multiple pages |
| 247 | and submit the SPI message with multiple transfers. |