2 * Copyright 2013 Broadcom Corporation.
4 * SPDX-License-Identifier: GPL-2.0+
10 #include <linux/errno.h>
11 #include <asm/kona-common/clk.h>
13 #define SDHCI_CORECTRL_OFFSET 0x00008000
14 #define SDHCI_CORECTRL_EN 0x01
15 #define SDHCI_CORECTRL_RESET 0x02
17 #define SDHCI_CORESTAT_OFFSET 0x00008004
18 #define SDHCI_CORESTAT_CD_SW 0x01
20 #define SDHCI_COREIMR_OFFSET 0x00008008
21 #define SDHCI_COREIMR_IP 0x01
23 static int init_kona_mmc_core(struct sdhci_host *host)
28 if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) {
29 printf("%s: sd host controller reset error\n", __func__);
33 /* For kona a hardware reset before anything else. */
34 mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET) | SDHCI_CORECTRL_RESET;
35 sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
41 printf("%s: reset timeout error\n", __func__);
47 (sdhci_readl(host, SDHCI_CORECTRL_OFFSET) &
48 SDHCI_CORECTRL_RESET));
50 /* Clear the reset bit. */
51 mask = mask & ~SDHCI_CORECTRL_RESET;
52 sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
54 /* Enable AHB clock */
55 mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET);
56 sdhci_writel(host, mask | SDHCI_CORECTRL_EN, SDHCI_CORECTRL_OFFSET);
58 /* Enable interrupts */
59 sdhci_writel(host, SDHCI_COREIMR_IP, SDHCI_COREIMR_OFFSET);
61 /* Make sure Card is detected in controller */
62 mask = sdhci_readl(host, SDHCI_CORESTAT_OFFSET);
63 sdhci_writel(host, mask | SDHCI_CORESTAT_CD_SW, SDHCI_CORESTAT_OFFSET);
67 while (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
69 printf("%s: CARD DETECT timeout error\n", __func__);
78 int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
83 struct sdhci_host *host = NULL;
85 host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
87 printf("%s: sdhci host malloc fail!\n", __func__);
92 reg_base = (void *)CONFIG_SYS_SDIO_BASE0;
93 ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO0_MAX_CLK,
97 reg_base = (void *)CONFIG_SYS_SDIO_BASE1;
98 ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO1_MAX_CLK,
102 reg_base = (void *)CONFIG_SYS_SDIO_BASE2;
103 ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO2_MAX_CLK,
107 reg_base = (void *)CONFIG_SYS_SDIO_BASE3;
108 ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO3_MAX_CLK,
112 printf("%s: sdio dev index %d not supported\n",
113 __func__, dev_index);
121 host->name = "kona-sdhci";
122 host->ioaddr = reg_base;
123 host->quirks = quirks;
124 host->max_clk = max_clk;
126 if (init_kona_mmc_core(host)) {
131 add_sdhci(host, 0, min_clk);