diff --git a/arch/arm/dts/ipq6018-emulation.dts b/arch/arm/dts/ipq6018-emulation.dts index 68a9d512ec..14c590a1e1 100644 --- a/arch/arm/dts/ipq6018-emulation.dts +++ b/arch/arm/dts/ipq6018-emulation.dts @@ -20,6 +20,7 @@ aliases { console = "/serial@78af000"; + mmc = "/sdhci@7804000"; }; serial@78af000 { compatible = "qca,ipq-uartdm"; @@ -41,4 +42,9 @@ status = "ok"; nand_gpio {}; }; + + mmc: sdhci@7804000 { + compatible = "qcom,sdhci-msm"; + }; + }; diff --git a/board/qca/arm/ipq6018/ipq6018.c b/board/qca/arm/ipq6018/ipq6018.c index 7162965c94..ee17b1b4d7 100644 --- a/board/qca/arm/ipq6018/ipq6018.c +++ b/board/qca/arm/ipq6018/ipq6018.c @@ -21,8 +21,11 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; +struct sdhci_host mmc_host; void uart2_configure_mux(void) { @@ -128,6 +131,85 @@ void reset_crashdump(void) return; } +void emmc_clock_config() +{ + /* Enable root clock generator */ + writel(readl(GCC_SDCC1_APPS_CBCR)|0x1, GCC_SDCC1_APPS_CBCR); + /* Add 10us delay for CLK_OFF to get cleared */ + udelay(10); + /* PLL0 - 192Mhz */ + writel(0x20B, GCC_SDCC1_APPS_CFG_RCGR); + /* Delay for clock operation complete */ + udelay(10); + writel(0x1, GCC_SDCC1_APPS_M); + writel(0xFC, GCC_SDCC1_APPS_N); + writel(0xFD, GCC_SDCC1_APPS_D); + /* Delay for clock operation complete */ + udelay(10); + /* Update APPS_CMD_RCGR to reflect source selection */ + writel(readl(GCC_SDCC1_APPS_CMD_RCGR)|0x1, GCC_SDCC1_APPS_CMD_RCGR); + /* Add 10us delay for clock update to complete */ + udelay(10); +} + +void emmc_clock_disable(void) +{ + /* Clear divider */ + writel(0x0, GCC_SDCC1_MISC); +} + +void board_mmc_deinit(void) +{ + emmc_clock_disable(); +} + +void emmc_clock_reset(void) +{ + writel(0x1, GCC_SDCC1_BCR); + udelay(10); + writel(0x0, GCC_SDCC1_BCR); +} + +void emmc_sdhci_init(void) +{ + writel(readl(MSM_SDC1_BASE) | (1 << 7), MSM_SDC1_BASE); //SW_RST + udelay(10); +} +int board_mmc_init(bd_t *bis) +{ + int node; + int ret = 0; + qca_smem_flash_info_t *sfi = &qca_smem_flash_info; + + node = fdt_path_offset(gd->fdt_blob, "mmc"); + if (node < 0) { + printf("sdhci: Node Not found, skipping initialization\n"); + return -1; + } + + mmc_host.ioaddr = (void *)MSM_SDC1_SDHCI_BASE; + mmc_host.voltages = MMC_VDD_165_195; + mmc_host.version = SDHCI_SPEC_300; + mmc_host.cfg.part_type = PART_TYPE_EFI; + mmc_host.quirks = SDHCI_QUIRK_BROKEN_VOLTAGE; + + emmc_clock_disable(); + emmc_clock_reset(); + udelay(10); + emmc_clock_config(); + emmc_sdhci_init(); + + if (add_sdhci(&mmc_host, 200000000, 400000)) { + printf("add_sdhci fail!\n"); + return -1; + } + + if (!ret && sfi->flash_type == SMEM_BOOT_MMC_FLASH) { + ret = board_mmc_env_init(mmc_host); + } + + return ret; +} void board_nand_init(void) { #ifdef CONFIG_QCA_SPI diff --git a/board/qca/arm/ipq6018/ipq6018.h b/board/qca/arm/ipq6018/ipq6018.h index 5875c75ea5..d67ef0e161 100644 --- a/board/qca/arm/ipq6018/ipq6018.h +++ b/board/qca/arm/ipq6018/ipq6018.h @@ -18,8 +18,18 @@ #include #include -#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203c -#define GCC_SDCC1_BCR 0x01842000 +/* + * GCC-SDCC Registers + */ +#define GCC_SDCC1_MISC 0x1842020 +#define GCC_SDCC1_APPS_CBCR 0x1842018 +#define GCC_SDCC1_APPS_CFG_RCGR 0x1842008 +#define GCC_SDCC1_APPS_CMD_RCGR 0x1842004 +#define GCC_SDCC1_APPS_M 0x184200C +#define GCC_SDCC1_APPS_N 0x1842010 +#define GCC_SDCC1_APPS_D 0x1842014 +#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203c +#define GCC_SDCC1_BCR 0x01842000 #define GCC_BLSP1_UART2_APPS_CFG_RCGR 0x01803038 #define GCC_BLSP1_UART2_APPS_M 0x0180303C @@ -106,4 +116,7 @@ typedef enum { SMEM_MAX_SIZE = SMEM_SPI_FLASH_ADDR_LEN + 1, } smem_mem_type_t; +#define MSM_SDC1_BASE 0x7800000 +#define MSM_SDC1_SDHCI_BASE 0x7804000 + #endif /* _IPQ6018_CDP_H_ */ diff --git a/configs/ipq6018_defconfig b/configs/ipq6018_defconfig index 9f09eaa51e..95aa85c3fa 100644 --- a/configs/ipq6018_defconfig +++ b/configs/ipq6018_defconfig @@ -100,6 +100,8 @@ CONFIG_CMD_NFS=y # # CONFIG_CMD_TIME is not set CONFIG_CMD_MISC=y +CONFIG_CMD_PART=y +CONFIG_PARTITION_UUIDS=y # CONFIG_CMD_TIMER is not set # diff --git a/include/configs/ipq6018.h b/include/configs/ipq6018.h index 5cc53af4e9..da85c44eb5 100644 --- a/include/configs/ipq6018.h +++ b/include/configs/ipq6018.h @@ -138,6 +138,23 @@ extern loff_t board_env_size; #define CONFIG_EFI_PARTITION #define CONFIG_QCA_BAM 1 +/* + * MMC configs + */ +#define CONFIG_QCA_MMC + +#ifdef CONFIG_QCA_MMC +#define CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_SDHCI +#define CONFIG_SDHCI_QCA +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SDHCI_SUPPORT +#define CONFIG_MMC_ADMA +#endif + /* * NAND Flash Configs