Mainline:Exynos 4/EMMC and SDHCI
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…