12 #include <linux/module.h>
23 #define NUM_PINS(x) (x + 2)
25 #define SDMMC_CLKSEL 0x09C
26 #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0)
27 #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16)
28 #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24)
29 #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7)
30 #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \
31 SDMMC_CLKSEL_CCLK_DRIVE(y) | \
32 SDMMC_CLKSEL_CCLK_DIVIDER(z))
34 #define SDMMC_CMD_USE_HOLD_REG BIT(29)
36 #define EXYNOS4210_FIXED_CIU_CLK_DIV 2
37 #define EXYNOS4412_FIXED_CIU_CLK_DIV 4
54 static struct dw_mci_exynos_compatible {
59 .compatible =
"samsung,exynos4210-dw-mshc",
62 .compatible =
"samsung,exynos4412-dw-mshc",
65 .compatible =
"samsung,exynos5250-dw-mshc",
70 static int dw_mci_exynos_priv_init(
struct dw_mci *
host)
77 dev_err(host->
dev,
"mem alloc failed for private data\n");
81 for (idx = 0; idx <
ARRAY_SIZE(exynos_compat); idx++) {
83 exynos_compat[idx].compatible))
84 priv->
ctrl_type = exynos_compat[idx].ctrl_type;
91 static int dw_mci_exynos_setup_clock(
struct dw_mci *host)
105 static void dw_mci_exynos_prepare_command(
struct dw_mci *host,
u32 *cmdr)
118 static void dw_mci_exynos_set_ios(
struct dw_mci *host,
struct mmc_ios *ios)
128 static int dw_mci_exynos_parse_dt(
struct dw_mci *host)
136 of_property_read_u32(np,
"samsung,dw-mshc-ciu-div", &div);
140 "samsung,dw-mshc-sdr-timing", timing, 2);
147 "samsung,dw-mshc-ddr-timing", timing, 2);
155 static int dw_mci_exynos_setup_bus(
struct dw_mci *host,
164 for (idx = 0; idx <
NUM_PINS(bus_width); idx++) {
165 gpio = of_get_gpio(slot_np, idx);
166 if (!gpio_is_valid(gpio)) {
167 dev_err(host->
dev,
"invalid gpio: %d\n", gpio);
173 dev_err(host->
dev,
"gpio [%d] request failed\n", gpio);
178 gpio = of_get_named_gpio(slot_np,
"wp-gpios", 0);
179 if (gpio_is_valid(gpio)) {
191 gpio = of_get_named_gpio(slot_np,
"samsung,cd-pinmux-gpio", 0);
192 if (gpio_is_valid(gpio)) {
194 dev_err(host->
dev,
"gpio [%d] request failed\n", gpio);
203 static unsigned long exynos5250_dwmmc_caps[4] = {
212 .caps = exynos5250_dwmmc_caps,
213 .init = dw_mci_exynos_priv_init,
214 .setup_clock = dw_mci_exynos_setup_clock,
215 .prepare_command = dw_mci_exynos_prepare_command,
216 .set_ios = dw_mci_exynos_set_ios,
217 .parse_dt = dw_mci_exynos_parse_dt,
218 .setup_bus = dw_mci_exynos_setup_bus,
221 static const struct of_device_id dw_mci_exynos_match[] = {
222 { .compatible =
"samsung,exynos5250-dw-mshc",
223 .data = &exynos5250_drv_data, },
234 drv_data = match->
data;
242 .name =
"dwmmc_exynos",