[U-Boot] [PATCH] socfpga/dwmmc: Adding DesignWare MMC driver support for SOCFPGA

To add the DesignWare MMC driver support for Altera SOCFPGA. It required information such as clocks and bus width from platform specific files (SOCFPGA handoff files)
Signed-off-by: Chin Liang See clsee@altera.com Cc: Rajeshwari Shinde rajeshwari.s@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Andy Fleming afleming@freescale.com --- arch/arm/include/asm/arch-socfpga/dwmmc.h | 12 +++++ drivers/mmc/Makefile | 1 + drivers/mmc/socfpga_dw_mmc.c | 72 +++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100755 arch/arm/include/asm/arch-socfpga/dwmmc.h create mode 100755 drivers/mmc/socfpga_dw_mmc.c
diff --git a/arch/arm/include/asm/arch-socfpga/dwmmc.h b/arch/arm/include/asm/arch-socfpga/dwmmc.h new file mode 100755 index 0000000..945eb64 --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/dwmmc.h @@ -0,0 +1,12 @@ +/* + * (C) Copyright 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SOCFPGA_DWMMC_H_ +#define _SOCFPGA_DWMMC_H_ + +extern int socfpga_dwmmc_init(u32 regbase, int bus_width, int index); + +#endif /* _SOCFPGA_SDMMC_H_ */ diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 1ed26ca..e793ed9 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o obj-$(CONFIG_DWMMC) += dw_mmc.o obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o +obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o else diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c new file mode 100755 index 0000000..554f51b --- /dev/null +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <dwmmc.h> +#include <asm/arch/dwmmc.h> + +#define CLKMGR_PERPLLGRP_EN_REG (SOCFPGA_CLKMGR_ADDRESS + 0xA0) +#define CLKMGR_SDMMC_CLK_ENABLE (1 << 8) +#define SYSMGR_SDMMCGRP_CTRL_REG (SOCFPGA_SYSMGR_ADDRESS + 0x108) +#define SYSMGR_SDMMC_CTRL_GET_DRVSEL(x) (((x) >> 0) & 0x7) +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ + ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) + +static char *SOCFPGA_NAME = "SOCFPGA DWMMC"; + +static void socfpga_dwmci_clksel(struct dwmci_host *host) +{ + unsigned int en; + unsigned int drvsel; + unsigned int smplsel; + + /* Disable SDMMC clock. */ + en = readl(CLKMGR_PERPLLGRP_EN_REG); + en &= ~CLKMGR_SDMMC_CLK_ENABLE; + writel(en, CLKMGR_PERPLLGRP_EN_REG); + + /* Configures drv_sel and smpl_sel */ + drvsel = 3; + smplsel = 0; + + debug("%s: drvsel %d smplsel %d\n", __FUNCTION__, drvsel, smplsel); + writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), + SYSMGR_SDMMCGRP_CTRL_REG); + + debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __FUNCTION__, + readl(SYSMGR_SDMMCGRP_CTRL_REG)); + /* Enable SDMMC clock */ + en = readl(CLKMGR_PERPLLGRP_EN_REG); + en |= CLKMGR_SDMMC_CLK_ENABLE; + writel(en, CLKMGR_PERPLLGRP_EN_REG); +} + +int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) +{ + struct dwmci_host *host = NULL; + host = calloc(sizeof(struct dwmci_host), 1); + if (!host) { + printf("dwmci_host calloc fail!\n"); + return 1; + } + + host->name = SOCFPGA_NAME; + host->ioaddr = (void *)regbase; + host->buswidth = bus_width; + host->clksel = socfpga_dwmci_clksel; + host->dev_index = index; + /* fixed clock divide by 4 which due to the SDMMC wrapper */ + host->bus_hz = CONFIG_DWMMC_BUS_HZ; + host->fifoth_val = MSIZE(0x2) | + RX_WMARK(CONFIG_DWMMC_FIFO_DEPTH / 2 - 1) | + TX_WMARK(CONFIG_DWMMC_FIFO_DEPTH / 2); + + add_dwmci(host, host->bus_hz, 400000); + + return 0; +} +
participants (1)
-
Chin Liang See