xref: /rk3399_rockchip-uboot/drivers/mmc/kona_sdhci.c (revision 3d6a5a4dfca25a202e356e4d63e89cdc6bd7255a)
17a9d0ad0SDarwin Rambo /*
27a9d0ad0SDarwin Rambo  * Copyright 2013 Broadcom Corporation.
37a9d0ad0SDarwin Rambo  *
47a9d0ad0SDarwin Rambo  * SPDX-License-Identifier:      GPL-2.0+
57a9d0ad0SDarwin Rambo  */
67a9d0ad0SDarwin Rambo 
77a9d0ad0SDarwin Rambo #include <common.h>
87a9d0ad0SDarwin Rambo #include <malloc.h>
97a9d0ad0SDarwin Rambo #include <sdhci.h>
107a9d0ad0SDarwin Rambo #include <asm/errno.h>
117a9d0ad0SDarwin Rambo #include <asm/kona-common/clk.h>
127a9d0ad0SDarwin Rambo 
137a9d0ad0SDarwin Rambo #define SDHCI_CORECTRL_OFFSET		0x00008000
147a9d0ad0SDarwin Rambo #define SDHCI_CORECTRL_EN		0x01
157a9d0ad0SDarwin Rambo #define SDHCI_CORECTRL_RESET		0x02
167a9d0ad0SDarwin Rambo 
177a9d0ad0SDarwin Rambo #define SDHCI_CORESTAT_OFFSET		0x00008004
187a9d0ad0SDarwin Rambo #define SDHCI_CORESTAT_CD_SW		0x01
197a9d0ad0SDarwin Rambo 
207a9d0ad0SDarwin Rambo #define SDHCI_COREIMR_OFFSET		0x00008008
217a9d0ad0SDarwin Rambo #define SDHCI_COREIMR_IP		0x01
227a9d0ad0SDarwin Rambo 
237a9d0ad0SDarwin Rambo static int init_kona_mmc_core(struct sdhci_host *host)
247a9d0ad0SDarwin Rambo {
257a9d0ad0SDarwin Rambo 	unsigned int mask;
267a9d0ad0SDarwin Rambo 	unsigned int timeout;
277a9d0ad0SDarwin Rambo 
287a9d0ad0SDarwin Rambo 	if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) {
297a9d0ad0SDarwin Rambo 		printf("%s: sd host controller reset error\n", __func__);
307a9d0ad0SDarwin Rambo 		return 1;
317a9d0ad0SDarwin Rambo 	}
327a9d0ad0SDarwin Rambo 
337a9d0ad0SDarwin Rambo 	/* For kona a hardware reset before anything else. */
347a9d0ad0SDarwin Rambo 	mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET) | SDHCI_CORECTRL_RESET;
357a9d0ad0SDarwin Rambo 	sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
367a9d0ad0SDarwin Rambo 
377a9d0ad0SDarwin Rambo 	/* Wait max 100 ms */
387a9d0ad0SDarwin Rambo 	timeout = 1000;
397a9d0ad0SDarwin Rambo 	do {
407a9d0ad0SDarwin Rambo 		if (timeout == 0) {
417a9d0ad0SDarwin Rambo 			printf("%s: reset timeout error\n", __func__);
427a9d0ad0SDarwin Rambo 			return 1;
437a9d0ad0SDarwin Rambo 		}
447a9d0ad0SDarwin Rambo 		timeout--;
457a9d0ad0SDarwin Rambo 		udelay(100);
467a9d0ad0SDarwin Rambo 	} while (0 ==
477a9d0ad0SDarwin Rambo 		 (sdhci_readl(host, SDHCI_CORECTRL_OFFSET) &
487a9d0ad0SDarwin Rambo 		  SDHCI_CORECTRL_RESET));
497a9d0ad0SDarwin Rambo 
507a9d0ad0SDarwin Rambo 	/* Clear the reset bit. */
517a9d0ad0SDarwin Rambo 	mask = mask & ~SDHCI_CORECTRL_RESET;
527a9d0ad0SDarwin Rambo 	sdhci_writel(host, mask, SDHCI_CORECTRL_OFFSET);
537a9d0ad0SDarwin Rambo 
547a9d0ad0SDarwin Rambo 	/* Enable AHB clock */
557a9d0ad0SDarwin Rambo 	mask = sdhci_readl(host, SDHCI_CORECTRL_OFFSET);
567a9d0ad0SDarwin Rambo 	sdhci_writel(host, mask | SDHCI_CORECTRL_EN, SDHCI_CORECTRL_OFFSET);
577a9d0ad0SDarwin Rambo 
587a9d0ad0SDarwin Rambo 	/* Enable interrupts */
597a9d0ad0SDarwin Rambo 	sdhci_writel(host, SDHCI_COREIMR_IP, SDHCI_COREIMR_OFFSET);
607a9d0ad0SDarwin Rambo 
617a9d0ad0SDarwin Rambo 	/* Make sure Card is detected in controller */
627a9d0ad0SDarwin Rambo 	mask = sdhci_readl(host, SDHCI_CORESTAT_OFFSET);
637a9d0ad0SDarwin Rambo 	sdhci_writel(host, mask | SDHCI_CORESTAT_CD_SW, SDHCI_CORESTAT_OFFSET);
647a9d0ad0SDarwin Rambo 
657a9d0ad0SDarwin Rambo 	/* Wait max 100 ms */
667a9d0ad0SDarwin Rambo 	timeout = 1000;
677a9d0ad0SDarwin Rambo 	while (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
687a9d0ad0SDarwin Rambo 		if (timeout == 0) {
697a9d0ad0SDarwin Rambo 			printf("%s: CARD DETECT timeout error\n", __func__);
707a9d0ad0SDarwin Rambo 			return 1;
717a9d0ad0SDarwin Rambo 		}
727a9d0ad0SDarwin Rambo 		timeout--;
737a9d0ad0SDarwin Rambo 		udelay(100);
747a9d0ad0SDarwin Rambo 	}
757a9d0ad0SDarwin Rambo 	return 0;
767a9d0ad0SDarwin Rambo }
777a9d0ad0SDarwin Rambo 
787a9d0ad0SDarwin Rambo int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
797a9d0ad0SDarwin Rambo {
807a9d0ad0SDarwin Rambo 	int ret = 0;
817a9d0ad0SDarwin Rambo 	u32 max_clk;
827a9d0ad0SDarwin Rambo 	void *reg_base;
837a9d0ad0SDarwin Rambo 	struct sdhci_host *host = NULL;
847a9d0ad0SDarwin Rambo 
857a9d0ad0SDarwin Rambo 	host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
867a9d0ad0SDarwin Rambo 	if (!host) {
877a9d0ad0SDarwin Rambo 		printf("%s: sdhci host malloc fail!\n", __func__);
887a9d0ad0SDarwin Rambo 		return -ENOMEM;
897a9d0ad0SDarwin Rambo 	}
907a9d0ad0SDarwin Rambo 	switch (dev_index) {
917a9d0ad0SDarwin Rambo 	case 0:
927a9d0ad0SDarwin Rambo 		reg_base = (void *)CONFIG_SYS_SDIO_BASE0;
937a9d0ad0SDarwin Rambo 		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO0_MAX_CLK,
947a9d0ad0SDarwin Rambo 				      &max_clk);
957a9d0ad0SDarwin Rambo 		break;
967a9d0ad0SDarwin Rambo 	case 1:
977a9d0ad0SDarwin Rambo 		reg_base = (void *)CONFIG_SYS_SDIO_BASE1;
987a9d0ad0SDarwin Rambo 		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO1_MAX_CLK,
997a9d0ad0SDarwin Rambo 				      &max_clk);
1007a9d0ad0SDarwin Rambo 		break;
1017a9d0ad0SDarwin Rambo 	case 2:
1027a9d0ad0SDarwin Rambo 		reg_base = (void *)CONFIG_SYS_SDIO_BASE2;
1037a9d0ad0SDarwin Rambo 		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO2_MAX_CLK,
1047a9d0ad0SDarwin Rambo 				      &max_clk);
1057a9d0ad0SDarwin Rambo 		break;
1067a9d0ad0SDarwin Rambo 	case 3:
1077a9d0ad0SDarwin Rambo 		reg_base = (void *)CONFIG_SYS_SDIO_BASE3;
1087a9d0ad0SDarwin Rambo 		ret = clk_sdio_enable(reg_base, CONFIG_SYS_SDIO3_MAX_CLK,
1097a9d0ad0SDarwin Rambo 				      &max_clk);
1107a9d0ad0SDarwin Rambo 		break;
1117a9d0ad0SDarwin Rambo 	default:
1127a9d0ad0SDarwin Rambo 		printf("%s: sdio dev index %d not supported\n",
1137a9d0ad0SDarwin Rambo 		       __func__, dev_index);
1147a9d0ad0SDarwin Rambo 		ret = -EINVAL;
1157a9d0ad0SDarwin Rambo 	}
116*3d6a5a4dSDarwin Rambo 	if (ret) {
117*3d6a5a4dSDarwin Rambo 		free(host);
1187a9d0ad0SDarwin Rambo 		return ret;
119*3d6a5a4dSDarwin Rambo 	}
1207a9d0ad0SDarwin Rambo 
1217a9d0ad0SDarwin Rambo 	host->name = "kona-sdhci";
1227a9d0ad0SDarwin Rambo 	host->ioaddr = reg_base;
1237a9d0ad0SDarwin Rambo 	host->quirks = quirks;
1247a9d0ad0SDarwin Rambo 	host->host_caps = MMC_MODE_HC;
1257a9d0ad0SDarwin Rambo 
126*3d6a5a4dSDarwin Rambo 	if (init_kona_mmc_core(host)) {
127*3d6a5a4dSDarwin Rambo 		free(host);
1287a9d0ad0SDarwin Rambo 		return -EINVAL;
129*3d6a5a4dSDarwin Rambo 	}
1307a9d0ad0SDarwin Rambo 
1317a9d0ad0SDarwin Rambo 	if (quirks & SDHCI_QUIRK_REG32_RW)
1327a9d0ad0SDarwin Rambo 		host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
1337a9d0ad0SDarwin Rambo 	else
1347a9d0ad0SDarwin Rambo 		host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
1357a9d0ad0SDarwin Rambo 
1367a9d0ad0SDarwin Rambo 	add_sdhci(host, max_clk, min_clk);
1377a9d0ad0SDarwin Rambo 	return ret;
1387a9d0ad0SDarwin Rambo }
139