From 270d1e72459f88eef1297c536001d45a0314cf40 Mon Sep 17 00:00:00 2001 From: Vandhiadevan Karunamoorthy Date: Mon, 9 May 2022 20:24:47 +0530 Subject: [PATCH] board: arm: devsoc: Add eMMC support This changes add 4-Bit eMMC flash support Change-Id: Iad789ba44aaa0e11da5f8c16dd0a07d2e80de682 Signed-off-by: Vandhiadevan Karunamoorthy --- arch/arm/dts/devsoc-emulation.dts | 1 + arch/arm/dts/devsoc-soc.dtsi | 4 + arch/arm/include/asm/arch-devsoc/clk.h | 18 ++++ board/devsoc/Kconfig | 4 + board/qca/arm/devsoc/clock.c | 39 ++++++++ board/qca/arm/devsoc/devsoc.c | 127 ++++++++++++++++++++++++- board/qca/arm/devsoc/devsoc.h | 3 + include/configs/devsoc.h | 21 ++++ 8 files changed, 216 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/devsoc-emulation.dts b/arch/arm/dts/devsoc-emulation.dts index cd0ac1d020..1aedb6805f 100644 --- a/arch/arm/dts/devsoc-emulation.dts +++ b/arch/arm/dts/devsoc-emulation.dts @@ -24,6 +24,7 @@ aliases { console = "/serial@78AF000"; nand = "/nand-controller@79B0000"; + mmc = "/sdhci@7804000"; }; console: serial@78AF000 { diff --git a/arch/arm/dts/devsoc-soc.dtsi b/arch/arm/dts/devsoc-soc.dtsi index 645ebe0f72..ee7bf3cbd3 100644 --- a/arch/arm/dts/devsoc-soc.dtsi +++ b/arch/arm/dts/devsoc-soc.dtsi @@ -80,4 +80,8 @@ reg = <0x79B0000 0x10000>; status = "disabled"; }; + + mmc: sdhci@7804000 { + compatible = "qcom,sdhci-msm"; + }; }; diff --git a/arch/arm/include/asm/arch-devsoc/clk.h b/arch/arm/include/asm/arch-devsoc/clk.h index 33a4c89905..576298330a 100644 --- a/arch/arm/include/asm/arch-devsoc/clk.h +++ b/arch/arm/include/asm/arch-devsoc/clk.h @@ -85,6 +85,24 @@ #define FB_CLK_BIT (1 << 4) #define UPDATE_EN 0x1 +/* + * GCC-SDCC Registers + */ + +#define GCC_SDCC1_BCR 0x01833000 +#define GCC_SDCC1_APPS_CMD_RCGR 0x01833004 +#define GCC_SDCC1_APPS_CFG_RCGR 0x01833008 +#define GCC_SDCC1_APPS_M 0x0183300C +#define GCC_SDCC1_APPS_N 0x01833010 +#define GCC_SDCC1_APPS_D 0x01833014 +#define GCC_SDCC1_APPS_CBCR 0x01833034 +#define GCC_SDCC1_AHB_CBCR 0x0183301C + +#ifdef CONFIG_QCA_MMC +void emmc_clock_init(void); +void emmc_clock_reset(void); +#endif + int uart_clock_config(struct ipq_serial_platdata *plat); #endif /*IPQ9574_CLK_H*/ diff --git a/board/devsoc/Kconfig b/board/devsoc/Kconfig index 3a9570601b..f91dca335d 100644 --- a/board/devsoc/Kconfig +++ b/board/devsoc/Kconfig @@ -20,4 +20,8 @@ config QPIC_SERIAL config UBI_WRITE bool "Enable ubi utilities" + +config MMC_FLASH + bool "Enable MMC flash support" + endif diff --git a/board/qca/arm/devsoc/clock.c b/board/qca/arm/devsoc/clock.c index 99399367c9..d3dff110f7 100644 --- a/board/qca/arm/devsoc/clock.c +++ b/board/qca/arm/devsoc/clock.c @@ -88,3 +88,42 @@ void qpic_set_clk_rate(unsigned int clk_rate, int blk_type, return; } #endif + +#ifdef CONFIG_QCA_MMC +void emmc_clock_init(void) +{ +#ifdef QCA_CLOCK_ENABLE + /* 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); + writel(readl(GCC_SDCC1_AHB_CBCR)|0x1, GCC_SDCC1_AHB_CBCR); + /* PLL0 - 192Mhz */ + writel(0x20B, GCC_SDCC1_APPS_CFG_RCGR); + /* Delay for clock operation complete */ + udelay(10); + writel(0x1, GCC_SDCC1_APPS_M); + /* check this M, N D value while debugging + * because as per clock tool the actual M, N, D + * values are M=1, N=FA, D=F9 + */ + 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); +#else + return; +#endif +} + +void emmc_clock_reset(void) +{ + writel(0x1, GCC_SDCC1_BCR); + udelay(10); + writel(0x0, GCC_SDCC1_BCR); +} +#endif diff --git a/board/qca/arm/devsoc/devsoc.c b/board/qca/arm/devsoc/devsoc.c index bd3c3d35a3..9f60eff0e1 100644 --- a/board/qca/arm/devsoc/devsoc.c +++ b/board/qca/arm/devsoc/devsoc.c @@ -28,6 +28,10 @@ #include #include #endif +#ifdef CONFIG_QCA_MMC +#include +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -45,6 +49,10 @@ unsigned int qpic_frequency = 0, qpic_phase = 0; extern unsigned int qpic_training_offset; #endif +#ifdef CONFIG_QCA_MMC +struct sdhci_host mmc_host; +#endif + void qca_serial_init(struct ipq_serial_platdata *plat) { int ret; @@ -66,16 +74,133 @@ void reset_board(void) run_command("reset", 0); } +/* + * Set the uuid in bootargs variable for mounting rootfilesystem + */ +#ifdef CONFIG_QCA_MMC int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, - bool gpt_flag) + bool gpt_flag) +{ + int ret, len; + block_dev_desc_t *blk_dev; + disk_partition_t disk_info; + + blk_dev = mmc_get_dev(mmc_host.dev_num); + if (!blk_dev) { + printf("Invalid block device name\n"); + return -EINVAL; + } + + if (buflen <= 0 || buflen > MAX_BOOT_ARGS_SIZE) + return -EINVAL; + +#ifdef CONFIG_PARTITION_UUIDS + ret = get_partition_info_efi_by_name(blk_dev, + part_name, &disk_info); + if (ret) { + printf("bootipq: unsupported partition name %s\n",part_name); + return -EINVAL; + } + if ((len = strlcpy(boot_args, "root=PARTUUID=", buflen)) >= buflen) + return -EINVAL; +#else + if ((len = strlcpy(boot_args, "rootfsname=", buflen)) >= buflen) + return -EINVAL; +#endif + boot_args += len; + buflen -= len; + +#ifdef CONFIG_PARTITION_UUIDS + if ((len = strlcpy(boot_args, disk_info.uuid, buflen)) >= buflen) + return -EINVAL; +#else + if ((len = strlcpy(boot_args, part_name, buflen)) >= buflen) + return -EINVAL; +#endif + boot_args += len; + buflen -= len; + + if (gpt_flag && strlcpy(boot_args, " gpt", buflen) >= buflen) + return -EINVAL; + + return 0; +} +#else +int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, + bool gpt_flag) { return 0; } +#endif + +#ifdef CONFIG_QCA_MMC +void mmc_iopad_config(struct sdhci_host *host) +{ + u32 val; + val = sdhci_readb(host, SDHCI_VENDOR_IOPAD); + /*set bit 15 & 16*/ + val |= 0x18000; + writel(val, host->ioaddr + SDHCI_VENDOR_IOPAD); +} + +void sdhci_bus_pwr_off(struct sdhci_host *host) +{ + u32 val; + + val = sdhci_readb(host, SDHCI_HOST_CONTROL); + sdhci_writeb(host,(val & (~SDHCI_POWER_ON)), SDHCI_POWER_CONTROL); +} + +__weak void board_mmc_deinit(void) +{ + /*since we do not have misc register in devsoc + * so simply return from this function + */ + return; +} +int board_mmc_init(bd_t *bis) +{ + int node, gpio_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; + } + + gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "mmc_gpio"); + if (node >= 0) + qca_gpio_init(gpio_node); + + 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_reset(); + udelay(10); + emmc_clock_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; +} +#else int board_mmc_init(bd_t *bis) { return 0; } +#endif __weak int ipq_get_tz_version(char *version_name, int buf_size) { diff --git a/board/qca/arm/devsoc/devsoc.h b/board/qca/arm/devsoc/devsoc.h index cd7c10a48c..fddb52fb71 100644 --- a/board/qca/arm/devsoc/devsoc.h +++ b/board/qca/arm/devsoc/devsoc.h @@ -31,6 +31,9 @@ extern const add_node_t add_fdt_node[]; #define BLSP1_UART0_BASE 0x078AF000 #define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000) +#define MSM_SDC1_BASE 0x7800000 +#define MSM_SDC1_SDHCI_BASE 0x7804000 + /* * weak function */ diff --git a/include/configs/devsoc.h b/include/configs/devsoc.h index ff02124096..f1f9c958f9 100644 --- a/include/configs/devsoc.h +++ b/include/configs/devsoc.h @@ -277,6 +277,27 @@ extern loff_t board_env_size; #define IPQ_UBI_VOL_WRITE_SUPPORT #endif +/* + * MMC configs + */ +#ifdef CONFIG_MMC_FLASH +#define 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 +#define CONFIG_EFI_PARTITION +/* +* eMMC controller support only 4-bit +* force SDHC driver to 4-bit mode +*/ +#define CONFIG_MMC_FORCE_CAP_4BIT_BUSWIDTH +#endif #undef CONFIG_BOOTM_NETBSD #undef CONFIG_BOOTM_PLAN9