Tom Rini | 53633a8 | 2024-02-29 12:33:36 -0500 | [diff] [blame^] | 1 | * TI Highspeed MMC host controller for OMAP and 66AK2G family. |
| 2 | |
| 3 | The Highspeed MMC Host Controller on TI OMAP and 66AK2G family |
| 4 | provides an interface for MMC, SD, and SDIO types of memory cards. |
| 5 | |
| 6 | This file documents differences between the core properties described |
| 7 | by mmc.txt and the properties used by the omap_hsmmc driver. |
| 8 | |
| 9 | Required properties: |
| 10 | -------------------- |
| 11 | - compatible: |
| 12 | Should be "ti,omap2-hsmmc", for OMAP2 controllers |
| 13 | Should be "ti,omap3-hsmmc", for OMAP3 controllers |
| 14 | Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0 |
| 15 | Should be "ti,omap4-hsmmc", for OMAP4 controllers |
| 16 | Should be "ti,am33xx-hsmmc", for AM335x controllers |
| 17 | Should be "ti,k2g-hsmmc", "ti,omap4-hsmmc" for 66AK2G controllers. |
| 18 | |
| 19 | SoC specific required properties: |
| 20 | --------------------------------- |
| 21 | The following are mandatory properties for OMAPs, AM33xx and AM43xx SoCs only: |
| 22 | - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1. |
| 23 | |
| 24 | The following are mandatory properties for 66AK2G SoCs only: |
| 25 | - power-domains:Should contain a phandle to a PM domain provider node |
| 26 | and an args specifier containing the MMC device id |
| 27 | value. This property is as per the binding, |
| 28 | Documentation/devicetree/bindings/soc/ti/sci-pm-domain.yaml |
| 29 | - clocks: Must contain an entry for each entry in clock-names. Should |
| 30 | be defined as per the he appropriate clock bindings consumer |
| 31 | usage in Documentation/devicetree/bindings/clock/ti,sci-clk.yaml |
| 32 | - clock-names: Shall be "fck" for the functional clock, |
| 33 | and "mmchsdb_fck" for the debounce clock. |
| 34 | |
| 35 | |
| 36 | Optional properties: |
| 37 | -------------------- |
| 38 | - ti,dual-volt: boolean, supports dual voltage cards |
| 39 | - <supply-name>-supply: phandle to the regulator device tree node |
| 40 | "supply-name" examples are "vmmc", |
| 41 | "vmmc_aux"(deprecated)/"vqmmc" etc |
| 42 | - ti,non-removable: non-removable slot (like eMMC) |
| 43 | - ti,needs-special-reset: Requires a special softreset sequence |
| 44 | - ti,needs-special-hs-handling: HSMMC IP needs special setting |
| 45 | for handling High Speed |
| 46 | - dmas: List of DMA specifiers with the controller specific |
| 47 | format as described in the generic DMA client |
| 48 | binding. A tx and rx specifier is required. |
| 49 | - dma-names: List of DMA request names. These strings correspond |
| 50 | 1:1 with the DMA specifiers listed in dmas. |
| 51 | The string naming is to be "rx" and "tx" for |
| 52 | RX and TX DMA requests, respectively. |
| 53 | |
| 54 | Examples: |
| 55 | |
| 56 | [hwmod populated DMA resources] |
| 57 | |
| 58 | mmc1: mmc@4809c000 { |
| 59 | compatible = "ti,omap4-hsmmc"; |
| 60 | reg = <0x4809c000 0x400>; |
| 61 | ti,hwmods = "mmc1"; |
| 62 | ti,dual-volt; |
| 63 | bus-width = <4>; |
| 64 | vmmc-supply = <&vmmc>; /* phandle to regulator node */ |
| 65 | ti,non-removable; |
| 66 | }; |
| 67 | |
| 68 | [generic DMA request binding] |
| 69 | |
| 70 | mmc1: mmc@4809c000 { |
| 71 | compatible = "ti,omap4-hsmmc"; |
| 72 | reg = <0x4809c000 0x400>; |
| 73 | ti,hwmods = "mmc1"; |
| 74 | ti,dual-volt; |
| 75 | bus-width = <4>; |
| 76 | vmmc-supply = <&vmmc>; /* phandle to regulator node */ |
| 77 | ti,non-removable; |
| 78 | dmas = <&edma 24 |
| 79 | &edma 25>; |
| 80 | dma-names = "tx", "rx"; |
| 81 | }; |
| 82 | |
| 83 | [workaround for missing swakeup on am33xx] |
| 84 | |
| 85 | This SOC is missing the swakeup line, it will not detect SDIO irq |
| 86 | while in suspend. |
| 87 | |
| 88 | ------ |
| 89 | | PRCM | |
| 90 | ------ |
| 91 | ^ | |
| 92 | swakeup | | fclk |
| 93 | | v |
| 94 | ------ ------- ----- |
| 95 | | card | -- CIRQ --> | hsmmc | -- IRQ --> | CPU | |
| 96 | ------ ------- ----- |
| 97 | |
| 98 | In suspend the fclk is off and the module is dysfunctional. Even register reads |
| 99 | will fail. A small logic in the host will request fclk restore, when an |
| 100 | external event is detected. Once the clock is restored, the host detects the |
| 101 | event normally. Since am33xx doesn't have this line it never wakes from |
| 102 | suspend. |
| 103 | |
| 104 | The workaround is to reconfigure the dat1 line as a GPIO upon suspend. To make |
| 105 | this work, we need to set the named pinctrl states "default" and "idle". |
| 106 | Prepare idle to remux dat1 as a gpio, and default to remux it back as sdio |
| 107 | dat1. The MMC driver will then toggle between idle and default state during |
| 108 | runtime. |
| 109 | |
| 110 | In summary: |
| 111 | 1. select matching 'compatible' section, see example below. |
| 112 | 2. specify pinctrl states "default" and "idle", "sleep" is optional. |
| 113 | 3. specify the gpio irq used for detecting sdio irq in suspend |
| 114 | |
| 115 | If configuration is incomplete, a warning message is emitted "falling back to |
| 116 | polling". Also check the "sdio irq mode" in /sys/kernel/debug/mmc0/regs. Mind |
| 117 | not every application needs SDIO irq, e.g. MMC cards. |
| 118 | |
| 119 | mmc1: mmc@48060100 { |
| 120 | compatible = "ti,am33xx-hsmmc"; |
| 121 | ... |
| 122 | pinctrl-names = "default", "idle", "sleep" |
| 123 | pinctrl-0 = <&mmc1_pins>; |
| 124 | pinctrl-1 = <&mmc1_idle>; |
| 125 | pinctrl-2 = <&mmc1_sleep>; |
| 126 | ... |
| 127 | interrupts-extended = <&intc 64 &gpio2 28 IRQ_TYPE_LEVEL_LOW>; |
| 128 | }; |
| 129 | |
| 130 | mmc1_idle : pinmux_cirq_pin { |
| 131 | pinctrl-single,pins = < |
| 132 | 0x0f8 0x3f /* GPIO2_28 */ |
| 133 | >; |
| 134 | }; |