Hi Chin, On Dec 31, 2013, at 2:26 AM, Chin Liang See wrote:
> 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 <cl...@altera.com> > Cc: Rajeshwari Shinde <rajeshwar...@samsung.com> > Cc: Jaehoon Chung <jh80.ch...@samsung.com> > Cc: Pantelis Antoniou <pa...@antoniou-consulting.com> > Cc: Wolfgang Denk <w...@denx.de> > --- > Changes for v3 > - Used structure instead macro for the register access > - Made drvsel and smpsel configurable > - Used better macro names > - Added a documentation on macro used to enable the driver > Changes for v2 > - Adding u-boot-mmc maintainer > --- > arch/arm/include/asm/arch-socfpga/dwmmc.h | 12 ++++ > arch/arm/include/asm/arch-socfpga/system_manager.h | 65 +++++++++++++++++++ > doc/README.socfpga | 53 +++++++++++++++ > drivers/mmc/Makefile | 1 + > drivers/mmc/socfpga_dw_mmc.c | 68 ++++++++++++++++++++ > 5 files changed, 199 insertions(+) > create mode 100644 arch/arm/include/asm/arch-socfpga/dwmmc.h > create mode 100644 doc/README.socfpga > create mode 100644 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 100644 > 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/arch/arm/include/asm/arch-socfpga/system_manager.h > b/arch/arm/include/asm/arch-socfpga/system_manager.h > index d965d25..838d210 100644 > --- a/arch/arm/include/asm/arch-socfpga/system_manager.h > +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h > @@ -19,4 +19,69 @@ extern unsigned long > sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM]; > > #define CONFIG_SYSMGR_PINMUXGRP_OFFSET (0x400) > > +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ > + ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) > + > +struct socfpga_system_manager { > + u32 siliconid1; > + u32 siliconid2; > + u32 _pad_0x8_0xf[2]; > + u32 wddbg; > + u32 bootinfo; > + u32 hpsinfo; > + u32 parityinj; > + u32 fpgaintfgrp_gbl; > + u32 fpgaintfgrp_indiv; > + u32 fpgaintfgrp_module; > + u32 _pad_0x2c_0x2f; > + u32 scanmgrgrp_ctrl; > + u32 _pad_0x34_0x3f[3]; > + u32 frzctrl_vioctrl; > + u32 _pad_0x44_0x4f[3]; > + u32 frzctrl_hioctrl; > + u32 frzctrl_src; > + u32 frzctrl_hwctrl; > + u32 _pad_0x5c_0x5f; > + u32 emacgrp_ctrl; > + u32 emacgrp_l3master; > + u32 _pad_0x68_0x6f[2]; > + u32 dmagrp_ctrl; > + u32 dmagrp_persecurity; > + u32 _pad_0x78_0x7f[2]; > + u32 iswgrp_handoff[8]; > + u32 _pad_0xa0_0xbf[8]; > + u32 romcodegrp_ctrl; > + u32 romcodegrp_cpu1startaddr; > + u32 romcodegrp_initswstate; > + u32 romcodegrp_initswlastld; > + u32 romcodegrp_bootromswstate; > + u32 __pad_0xd4_0xdf[3]; > + u32 romcodegrp_warmramgrp_enable; > + u32 romcodegrp_warmramgrp_datastart; > + u32 romcodegrp_warmramgrp_length; > + u32 romcodegrp_warmramgrp_execution; > + u32 romcodegrp_warmramgrp_crc; > + u32 __pad_0xf4_0xff[3]; > + u32 romhwgrp_ctrl; > + u32 _pad_0x104_0x107; > + u32 sdmmcgrp_ctrl; > + u32 sdmmcgrp_l3master; > + u32 nandgrp_bootstrap; > + u32 nandgrp_l3master; > + u32 usbgrp_l3master; > + u32 _pad_0x11c_0x13f[9]; > + u32 eccgrp_l2; > + u32 eccgrp_ocram; > + u32 eccgrp_usb0; > + u32 eccgrp_usb1; > + u32 eccgrp_emac0; > + u32 eccgrp_emac1; > + u32 eccgrp_dma; > + u32 eccgrp_can0; > + u32 eccgrp_can1; > + u32 eccgrp_nand; > + u32 eccgrp_qspi; > + u32 eccgrp_sdmmc; > +}; > + > #endif /* _SYSTEM_MANAGER_H_ */ > diff --git a/doc/README.socfpga b/doc/README.socfpga > new file mode 100644 > index 0000000..cfcbbfe > --- /dev/null > +++ b/doc/README.socfpga > @@ -0,0 +1,53 @@ > + > +-------------------------------------------- > +SOCFPGA Documentation for U-Boot and SPL > +-------------------------------------------- > + > +This README is about U-Boot and SPL support for Altera's ARM Cortex-A9MPCore > +based SOCFPGA. To know more about the hardware itself, please refer to > +www.altera.com. > + > + > +-------------------------------------------- > +socfpga_dw_mmc > +-------------------------------------------- > +Here are macro and detailed configuration required to enable DesignWare SDMMC > +controller support within SOCFPGA > + > +#define CONFIG_MMC > +-> To enable the SD MMC framework support > + > +#define CONFIG_SDMMC_BASE (SOCFPGA_SDMMC_ADDRESS) > +-> The base address of CSR register for DesignWare SDMMC controller > + > +#define CONFIG_GENERIC_MMC > +-> Enable the generic MMC driver > + > +#define CONFIG_SYS_MMC_MAX_BLK_COUNT 256 > +-> Using smaller max blk cnt to avoid flooding the limited stack in OCRAM > + > +#define CONFIG_DWMMC > +-> Enable the common DesignWare SDMMC controller framework > + > +#define CONFIG_SOCFPGA_DWMMC > +-> Enable the SOCFPGA specific driver for DesignWare SDMMC controller > + > +#define CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH 1024 > +-> The FIFO depth for SOCFPGA DesignWare SDMMC controller > + > +#define CONFIG_SOCFPGA_DWMMC_DRVSEL 3 > +-> Phase-shifted clock of sdmmc_clk for controller to drive command and data > to > +the card to meet hold time requirements. SD clock is running at 50MHz and > +drvsel is set to shift 135 degrees (3 * 45 degrees). With that, the hold time > +is 135 / 360 * 20ns = 7.5ns. > + > +#define CONFIG_SOCFPGA_DWMMC_SMPSEL 0 > +-> Phase-shifted clock of sdmmc_clk used to sample the command and data from > +the card > + > +#define CONFIG_SOCFPGA_DWMMC_BUS_WIDTH 4 > +-> Bus width of data line which either 1, 4 or 8 and based on board routing. > + > +#define CONFIG_SOCFPGA_DWMMC_BUS_HZ 50000000 > +-> The clock rate to controller. Do note the controller have a wrapper which > +divide the clock from PLL by 4. > 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 100644 > index 0000000..bc53a5d > --- /dev/null > +++ b/drivers/mmc/socfpga_dw_mmc.c > @@ -0,0 +1,68 @@ > +/* > + * (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> > +#include <asm/arch/clock_manager.h> > +#include <asm/arch/system_manager.h> > + > +static const struct socfpga_clock_manager *clock_manager_base = > + (void *)SOCFPGA_CLKMGR_ADDRESS; > +static const struct socfpga_system_manager *system_manager_base = > + (void *)SOCFPGA_SYSMGR_ADDRESS; > + > +static char *SOCFPGA_NAME = "SOCFPGA DWMMC"; > + > +static void socfpga_dwmci_clksel(struct dwmci_host *host) > +{ > + unsigned int drvsel; > + unsigned int smplsel; > + > + /* Disable SDMMC clock. */ > + clrbits_le32(&clock_manager_base->per_pll_en, > + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); > + > + /* Configures drv_sel and smpl_sel */ > + drvsel = CONFIG_SOCFPGA_DWMMC_DRVSEL; > + smplsel = CONFIG_SOCFPGA_DWMMC_SMPSEL; > + > + debug("%s: drvsel %d smplsel %d\n", __func__, drvsel, smplsel); > + writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), > + &system_manager_base->sdmmcgrp_ctrl); > + > + debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, > + readl(&system_manager_base->sdmmcgrp_ctrl)); > + > + /* Enable SDMMC clock */ > + setbits_le32(&clock_manager_base->per_pll_en, > + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); > +} > + > +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_SOCFPGA_DWMMC_BUS_HZ; > + host->fifoth_val = MSIZE(0x2) | > + RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | > + TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); > + > + return add_dwmci(host, host->bus_hz, 400000); > +} > + > -- > 1.7.9.5 > > Applied, thanks Acked-by: Pantelis Antoniou <pa...@antoniou-consulting.com> _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot