board: arm: devsoc: Add eMMC support

This changes add 4-Bit eMMC flash support

Change-Id: Iad789ba44aaa0e11da5f8c16dd0a07d2e80de682
Signed-off-by: Vandhiadevan Karunamoorthy <quic_vkarunam@quicinc.com>
This commit is contained in:
Vandhiadevan Karunamoorthy 2022-05-09 20:24:47 +05:30
parent 107bdb49b0
commit 270d1e7245
8 changed files with 216 additions and 1 deletions

View file

@ -24,6 +24,7 @@
aliases {
console = "/serial@78AF000";
nand = "/nand-controller@79B0000";
mmc = "/sdhci@7804000";
};
console: serial@78AF000 {

View file

@ -80,4 +80,8 @@
reg = <0x79B0000 0x10000>;
status = "disabled";
};
mmc: sdhci@7804000 {
compatible = "qcom,sdhci-msm";
};
};

View file

@ -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*/

View file

@ -20,4 +20,8 @@ config QPIC_SERIAL
config UBI_WRITE
bool "Enable ubi utilities"
config MMC_FLASH
bool "Enable MMC flash support"
endif

View file

@ -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

View file

@ -28,6 +28,10 @@
#include <asm/arch-qca-common/qpic_nand.h>
#include <nand.h>
#endif
#ifdef CONFIG_QCA_MMC
#include <mmc.h>
#include <sdhci.h>
#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)
{

View file

@ -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
*/

View file

@ -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