
On 14-02-03 05:12 PM, Jaehoon Chung wrote:
On 02/04/2014 06:03 AM, Darwin Rambo wrote:
Add support for the Kona SDHCI found on Broadcom mobile SoCs.
Signed-off-by: Darwin Rambo drambo@broadcom.com Reviewed-by: Steve Rae srae@broadcom.com Reviewed-by: Tim Kryger tkryger@linaro.org
drivers/mmc/Makefile | 1 + drivers/mmc/kona_sdhci.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 drivers/mmc/kona_sdhci.c
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index e793ed9..931922b 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o obj-$(CONFIG_SDHCI) += sdhci.o obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o +obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o diff --git a/drivers/mmc/kona_sdhci.c b/drivers/mmc/kona_sdhci.c new file mode 100644 index 0000000..69e6f17 --- /dev/null +++ b/drivers/mmc/kona_sdhci.c @@ -0,0 +1,125 @@ +/*
- Copyright 2013 Broadcom Corporation. All rights reserved.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <malloc.h> +#include <sdhci.h> +#include <asm/errno.h> +#include <asm/kona-common/clk.h>
+#define SDHCI_CORECTRL_OFFSET 0x00008000 +#define SDHCI_CORECTRL_EN 0x01 +#define SDHCI_CORECTRL_RESET 0x02
+#define SDHCI_CORESTAT_OFFSET 0x00008004 +#define SDHCI_CORESTAT_CD_SW 0x01
+#define SDHCI_COREIMR_OFFSET 0x00008008 +#define SDHCI_COREIMR_IP 0x01
+static int init_mmc_core(struct sdhci_host *host)
I think that function name is used to "_kona_". This function isn't general mmc function, right?
Correct. I should rename it to init_kona_mmc_core(). Thanks.
Best Regards, Jaehoon Chung
+{
- unsigned int mask;
- unsigned int timeout;
- if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) {
printf("%s: sd host controller reset error\n", __func__);
return 1;
- }
- /* For kona a hardware reset before anything else. */
- mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET) | SDHCI_CORECTRL_RESET;
- sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
- /* Wait max 100 ms */
- timeout = 1000;
- do {
if (timeout == 0) {
printf("%s: reset timeout error\n", __func__);
return 1;
}
timeout--;
udelay(100);
- } while (0 ==
(sdhci_readl(host, SDHCI_CORECTRL_OFFSET) &
SDHCI_CORECTRL_RESET));
- /* Clear the reset bit. */
- mask = mask & ~SDHCI_CORECTRL_RESET;
- sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
- udelay(10);
- /* Enable AHB clock */
- mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET);
- sdhci_writel(host, mask | SDHCI_CORECTRL_EN, SDHCI_CORECTRL_OFFSET);
- /* Enable interrupts */
- sdhci_writel(host, SDHCI_COREIMR_IP, SDHCI_COREIMR_OFFSET);
- /* Make sure Card is detected in controller */
- mask = sdhci_readl(host, SDHCI_CORESTAT_OFFSET);
- sdhci_writel(host, mask | SDHCI_CORESTAT_CD_SW, SDHCI_CORESTAT_OFFSET);
BTW I think that this is a good spot to test and wait for CARD_PRESENT with timeout. I should add it here. This avoids timing issues if the core code tries to power up the card before it is recognized. Thanks.
- return 0;
+}
+int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks) +{
- int ret = 0;
- u32 max_clk;
- void *reg_base;
- struct sdhci_host *host = NULL;
- host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
- if (!host) {
printf("%s: sdhci host malloc fail!\n", __func__);
return -ENOMEM;
- }
- switch (dev_index) {
- case 0:
reg_base = (void *)CONFIG_SYS_SDIO_BASE0;
ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO0_MAX_CLK,
&max_clk);
break;
- case 1:
reg_base = (void *)CONFIG_SYS_SDIO_BASE1;
ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO1_MAX_CLK,
&max_clk);
break;
- case 2:
reg_base = (void *)CONFIG_SYS_SDIO_BASE2;
ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO2_MAX_CLK,
&max_clk);
break;
- case 3:
reg_base = (void *)CONFIG_SYS_SDIO_BASE3;
ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO3_MAX_CLK,
&max_clk);
break;
- default:
printf("%s: sdio dev index %d not supported\n",
__func__, dev_index);
ret = -EINVAL;
- }
- if (ret)
return ret;
- host->name = "kona-sdhci";
- host->ioaddr = reg_base;
- host->quirks = quirks;
- host->host_caps = MMC_MODE_HC;
- if (init_mmc_core(host))
return -EINVAL;
- if (quirks & SDHCI_QUIRK_REG32_RW)
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
- else
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
- add_sdhci(host, max_clk, min_clk);
- return ret;
+}