From a3e8c22011e9b00e356c9f216ed886e524ca24c3 Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Mon, 22 Sep 2014 18:26:03 +0800 Subject: mmc: sunxi: add SDHC support for sun6i/sun7i/sun8i Allwinner A20/A23/A31's SD/MMC host support SDHC High Capacity feature. Signed-off-by: Wills Wang Signed-off-by: Hans de Goede --- drivers/mmc/sunxi_mmc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index d4e574fe19..bc2c4b302b 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -361,6 +361,9 @@ int sunxi_mmc_init(int sdc_no) cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; cfg->host_caps = MMC_MODE_4BIT; cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; +#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN7I) || defined(CONFIG_SUN8I) + cfg->host_caps |= MMC_MODE_HC; +#endif cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->f_min = 400000; -- cgit v1.2.1 From 1d1bd42eb08b267a0884a0fa04483daeda169f6d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 3 Oct 2014 20:16:26 +0800 Subject: ARM: sunxi-mmc: Add mmc support for sun6i / A31 The mmc hardware on sun6i has an extra reset control that needs to be de-asserted prior to usage. Also the FIFO address is different. Signed-off-by: Hans de Goede [wens@csie.org: use setbits_le32 for reset control, drop obsolete changes, rewrite different FIFO address handling, add commit message] Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- drivers/mmc/sunxi_mmc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index bc2c4b302b..8f4b50ba98 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -19,7 +19,6 @@ struct sunxi_mmc_host { unsigned mmc_no; uint32_t *mclkreg; - unsigned database; unsigned fatal_err; unsigned mod_clk; struct sunxi_mmc *reg; @@ -57,7 +56,6 @@ static int mmc_resource_init(int sdc_no) printf("Wrong mmc number %d\n", sdc_no); return -1; } - mmchost->database = (unsigned int)mmchost->reg + 0x100; mmchost->mmc_no = sdc_no; return 0; @@ -75,6 +73,11 @@ static int mmc_clk_io_on(int sdc_no) /* config ahb clock */ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); +#if defined(CONFIG_SUN6I) + /* unassert reset */ + setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); +#endif + /* config mod clock */ pll_clk = clock_get_pll6(); /* should be close to 100 MHz but no more, so round up */ @@ -194,9 +197,9 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) } if (reading) - buff[i] = readl(mmchost->database); + buff[i] = readl(&mmchost->reg->fifo); else - writel(buff[i], mmchost->database); + writel(buff[i], &mmchost->reg->fifo); } return 0; -- cgit v1.2.1 From cd82113a98e152b34e727718b729d0c5be44da99 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Oct 2014 20:29:26 +0200 Subject: sunxi: Add mmc card-detect functionality Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mmc/sunxi_mmc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 8f4b50ba98..b47376a793 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include struct sunxi_mmc_host { unsigned mmc_no; @@ -346,10 +348,29 @@ out: return error; } +static int sunxi_mmc_getcd(struct mmc *mmc) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + int cd_pin = -1; + + switch (mmchost->mmc_no) { + case 0: cd_pin = sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN); break; + case 1: cd_pin = sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN); break; + case 2: cd_pin = sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN); break; + case 3: cd_pin = sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN); break; + } + + if (cd_pin == -1) + return 1; + + return !gpio_direction_input(cd_pin); +} + static const struct mmc_ops sunxi_mmc_ops = { .send_cmd = mmc_send_cmd, .set_ios = mmc_set_ios, .init = mmc_core_init, + .getcd = sunxi_mmc_getcd, }; int sunxi_mmc_init(int sdc_no) -- cgit v1.2.1 From e79c7c881047ca99191cc79b6d83ec64b898cd9b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Oct 2014 21:13:54 +0200 Subject: sunxi: When we've both mmc0 and mmc2, detect from which one we're booting sunxi SOCs can boot from both mmc0 and mmc2, detect from which one we're booting, and make that one "mmc dev 0" so that a single u-boot binary can be used for both the onboard eMMC and for external sdcards. When we're booting from mmc2, we make it dev 0 because that is where the SPL will load the tertiary payload (the actual u-boot binary in our case) from, see: common/spl/spl_mmc.c, which has dev 0 hardcoded everywhere. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mmc/sunxi_mmc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index b47376a793..d3b1039cfe 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -373,7 +373,7 @@ static const struct mmc_ops sunxi_mmc_ops = { .getcd = sunxi_mmc_getcd, }; -int sunxi_mmc_init(int sdc_no) +struct mmc *sunxi_mmc_init(int sdc_no) { struct mmc_config *cfg = &mmc_host[sdc_no].cfg; @@ -396,8 +396,5 @@ int sunxi_mmc_init(int sdc_no) mmc_resource_init(sdc_no); mmc_clk_io_on(sdc_no); - if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL) - return -1; - - return 0; + return mmc_create(cfg, &mmc_host[sdc_no]); } -- cgit v1.2.1 From e637b30b9c9f454427e7277eddb6b1f489f3bbc8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Oct 2014 16:47:43 +0800 Subject: mmc: sunxi: Add support for sun8i (A23) The Allwinner A23 SoC has reset controls like the A31 (sun6i). The FIFO address is also the same as sun6i. Re-use code added for sun6i. Signed-off-by: Chen-Yu Tsai Acked-by: Ian Campbell --- drivers/mmc/sunxi_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index d3b1039cfe..16592e3d7c 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -75,7 +75,7 @@ static int mmc_clk_io_on(int sdc_no) /* config ahb clock */ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); -#if defined(CONFIG_SUN6I) +#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) /* unassert reset */ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); #endif -- cgit v1.2.1