Mainline:Exynos 4/EMMC and SDHCI: Difference between revisions
No edit summary |
No edit summary |
||
Line 7: | Line 7: | ||
Converting from those structs: | Converting from those structs: | ||
== <code>exynos4_mshc_pdata</code> == | |||
'''Only if your device has <code>CONFIG_EXYNOS4_DEV_MSHC</code> enabled.''' | '''Only if your device has <code>CONFIG_EXYNOS4_DEV_MSHC</code> enabled.''' | ||
Line 15: | Line 15: | ||
* <code>int_power_gpio</code>: note down the GPIO and read on to “Regulator” section. | * <code>int_power_gpio</code>: note down the GPIO and read on to “Regulator” section. | ||
== <code>exynos_dwmci_pdata</code> == | |||
'''Only if your device has <code>CONFIG_EXYNOS4_DEV_DWMCI</code> enabled.''' | '''Only if your device has <code>CONFIG_EXYNOS4_DEV_DWMCI</code> enabled.''' | ||
Line 30: | Line 30: | ||
* Clocks are already set up | * Clocks are already set up | ||
== Pinctrl == | |||
Pinctrl may need to be set up according to width; see <code>exynos_dwmci_cfg_gpio</code> for DWMCI, <code>arch/arm/mach-exynos/setup-mshci-gpio.c</code> for MSHCI. There are premade pinctrl defaults <code>sdX_bus1</code>, <code>sdX_bus4</code> and <code>sdX_bus8</code> for width 1, 4 and 8 respectively (see midas DTSI for an example). | Pinctrl may need to be set up according to width; see <code>exynos_dwmci_cfg_gpio</code> for DWMCI, <code>arch/arm/mach-exynos/setup-mshci-gpio.c</code> for MSHCI. There are premade pinctrl defaults <code>sdX_bus1</code>, <code>sdX_bus4</code> and <code>sdX_bus8</code> for width 1, 4 and 8 respectively (see midas DTSI for an example). | ||
Line 36: | Line 36: | ||
Replace <code>X</code> with 0 or 4, depending on the contents of <code>exynos_dwmci_cfg_gpio</code> (or equivalent <code>.cfg_gpio</code> member of <code>exynos_dwmci_pdata</code> struct) function: if for width 8 it does <code>s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));</code>, then 4, else 0. (The only difference between these two is the pin-function that’s set, see <code>exynos4x12-pinctrl.dtsi</code>.) In width 8, add both <code>bus4</code> and <code>bus8</code> (each has 4 pins, coming together to 8 pins total). | Replace <code>X</code> with 0 or 4, depending on the contents of <code>exynos_dwmci_cfg_gpio</code> (or equivalent <code>.cfg_gpio</code> member of <code>exynos_dwmci_pdata</code> struct) function: if for width 8 it does <code>s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));</code>, then 4, else 0. (The only difference between these two is the pin-function that’s set, see <code>exynos4x12-pinctrl.dtsi</code>.) In width 8, add both <code>bus4</code> and <code>bus8</code> (each has 4 pins, coming together to 8 pins total). | ||
== Regulator == | |||
This depends on your device. Midas has a <code>VMEM_VDD_2.8V</code> regulator in its PMIC, your device might have something similar - check schematics. This will have to be enabled by the GPIO listed as <code>int_power_gpio</code> in your <code>exynos4_mshc_pdata</code> struct, probably <code>gpk0-2</code>. | This depends on your device. Midas has a <code>VMEM_VDD_2.8V</code> regulator in its PMIC, your device might have something similar - check schematics. This will have to be enabled by the GPIO listed as <code>int_power_gpio</code> in your <code>exynos4_mshc_pdata</code> struct, probably <code>gpk0-2</code>. | ||
Line 42: | Line 42: | ||
If you’re unsure, or if there’s no such regulator in your case, then you can create a <code>regulator-fixed</code> with a min/max voltage of 2.8V and enabled/disabled by said GPIO, and give <code>sdX_cd</code> pinctrl to it, or ignore it entirely and give the <code>sdX_cd</code> pinctrl to the <code>mshc_0</code> node. | If you’re unsure, or if there’s no such regulator in your case, then you can create a <code>regulator-fixed</code> with a min/max voltage of 2.8V and enabled/disabled by said GPIO, and give <code>sdX_cd</code> pinctrl to it, or ignore it entirely and give the <code>sdX_cd</code> pinctrl to the <code>mshc_0</code> node. | ||
== Timing values == | |||
Timing values are written to the <code>clksel</code> register on the MMC host, at offset <code>0x9c</code>. The timing values in mainline are the <code>sample</code> and <code>drive</code> values respectively. | Timing values are written to the <code>clksel</code> register on the MMC host, at offset <code>0x9c</code>. The timing values in mainline are the <code>sample</code> and <code>drive</code> values respectively. |
Latest revision as of 17:45, 21 January 2025
This page contains notes regarding porting downstream kernel SDHCI/EMMC data to mainline.
Main EMMC node is mshc_0
; the data for it is stored in structs exynos_dwmci_pdata
and exynos4_mshc_pdata
.
See Documentation/devicetree/bindings/mmc/mmc-controller.yaml
.
Converting from those structs:
exynos4_mshc_pdata
Only if your device has CONFIG_EXYNOS4_DEV_MSHC
enabled.
cd_type
: probably S3C_MSHCI_CD_PERMANENT, in which case,non-removable;
caps
: see mmc-controller.yaml, they’re pretty much the sameint_power_gpio
: note down the GPIO and read on to “Regulator” section.
exynos_dwmci_pdata
Only if your device has CONFIG_EXYNOS4_DEV_DWMCI
enabled.
quirks
:DW_MCI_QUIRK_BROKEN_CARD_DETECTION
->broken-cd;
DW_MCI_QUIRK_HIGHSPEED
->cap-mmc-highspeed
bus_hz
->clock-frequency: <FIXME>;
caps
: see mmc-controller.yaml, they’re pretty much the sameMMC_CAP_CMD23
is enabled by default, no need to add itMMC_CAP_8_BIT_DATA
isbus-width = <8>;
detect_delay_ms
->card-detect-delay = <FIXME>;
fifo-depth
->fifo-depth = <0xFIXME>;
(note: 0x80 is default, so skip this if it’s 0x80 on your device)- Clocks are already set up
Pinctrl
Pinctrl may need to be set up according to width; see exynos_dwmci_cfg_gpio
for DWMCI, arch/arm/mach-exynos/setup-mshci-gpio.c
for MSHCI. There are premade pinctrl defaults sdX_bus1
, sdX_bus4
and sdX_bus8
for width 1, 4 and 8 respectively (see midas DTSI for an example).
Replace X
with 0 or 4, depending on the contents of exynos_dwmci_cfg_gpio
(or equivalent .cfg_gpio
member of exynos_dwmci_pdata
struct) function: if for width 8 it does s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
, then 4, else 0. (The only difference between these two is the pin-function that’s set, see exynos4x12-pinctrl.dtsi
.) In width 8, add both bus4
and bus8
(each has 4 pins, coming together to 8 pins total).
Regulator
This depends on your device. Midas has a VMEM_VDD_2.8V
regulator in its PMIC, your device might have something similar - check schematics. This will have to be enabled by the GPIO listed as int_power_gpio
in your exynos4_mshc_pdata
struct, probably gpk0-2
.
If you’re unsure, or if there’s no such regulator in your case, then you can create a regulator-fixed
with a min/max voltage of 2.8V and enabled/disabled by said GPIO, and give sdX_cd
pinctrl to it, or ignore it entirely and give the sdX_cd
pinctrl to the mshc_0
node.
Timing values
Timing values are written to the clksel
register on the MMC host, at offset 0x9c
. The timing values in mainline are the sample
and drive
values respectively.
For tab3 downstream, they seem to be set in arch/arm/mach-exynos/dev-dwmci.c
, and are the same for all devices.
For MSHCI, the values are hardcoded in drivers/mmc/host/mshci.c
line 1252 and onwards.
DDR value is for DDR_50 mode, SDR is for non-DDR_50. Both of the aforementioned files have ifs for checking this.
To decode a CLKSEL value, run this python script
value = 0x00010001 # CHANGE THIS
print("Sample:", (clksel_val >> 0) & 7)
print("Drive:", (clksel_val >> 8) & 7)
print("Divider:", (clksel_val >> 16) & 7)
However, the sample value seems to be tuned at runtime using the built-in tune function. Unclear how this works yet, TODO.
Divider is samsung,dw-mshc-ciu-div
, but is ignored for Exynos4412 anyways, TODO? See drivers/mmc/host/dw_mmc-exynos.c
in mainline. Sample and drive are passed to the timing values in that order.
…Our best bet is probably to get those values from a running device, somehow…