Message ID | 1486055625-10095-5-git-send-email-patrice.chotard@st.com |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Hi Patrice, On 02/03/2017 02:13 AM, patrice.chotard@st.com wrote: > From: Patrice Chotard <patrice.chotard@st.com> > > Add SDHCI host controller found on STMicroelctronics SoCs Just wonder what is flashSS? Add the minor comments. > > Signed-off-by: Patrice Chotard <patrice.chotard@st.com> > --- > arch/arm/Kconfig | 2 + > arch/arm/include/asm/arch-stih410/sdhci.h | 69 +++++++++++++++ > drivers/mmc/Kconfig | 7 ++ > drivers/mmc/Makefile | 1 + > drivers/mmc/sti_sdhci.c | 140 ++++++++++++++++++++++++++++++ > 5 files changed, 219 insertions(+) > create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h > create mode 100644 drivers/mmc/sti_sdhci.c > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index b91a5b7..477f36b 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -987,6 +987,8 @@ config ARCH_STI > select CPU_V7 > select DM > select DM_SERIAL > + select BLK > + select DM_MMC > help > Support for STMicroelectronics STiH407/10 SoC family. > This SoC is used on Linaro 96Board STiH410-B2260 > diff --git a/arch/arm/include/asm/arch-stih410/sdhci.h b/arch/arm/include/asm/arch-stih410/sdhci.h > new file mode 100644 > index 0000000..f45b961 > --- /dev/null > +++ b/arch/arm/include/asm/arch-stih410/sdhci.h > @@ -0,0 +1,69 @@ > +/* > + * (C) Copyright 2017 Patrice Chotard <patrice.chotard@st.com> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef __STI_SDHCI_H__ > +#define __STI_SDHCI_H__ > + > +#define FLASHSS_MMC_CORE_CONFIG_1 0x400 > +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ BIT(24) > +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN BIT(12) > + > +#define STI_FLASHSS_MMC_CORE_CONFIG_1 \ > + (FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ | \ > + FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN) > + > +#define FLASHSS_MMC_CORE_CONFIG_2 0x404 > +#define FLASHSS_MMC_CORECFG_HIGH_SPEED BIT(28) > +#define FLASHSS_MMC_CORECFG_8BIT_EMMC BIT(20) > +#define MAX_BLK_LENGTH_1024 BIT(16) > +#define BASE_CLK_FREQ_200 0xc8 > + > + remove unnecessary white space. > +#define STI_FLASHSS_MMC_CORE_CONFIG2 \ > + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ > + FLASHSS_MMC_CORECFG_8BIT_EMMC | \ > + MAX_BLK_LENGTH_1024 | \ > + BASE_CLK_FREQ_200 << 0) > + > +#define STI_FLASHSS_SDCARD_CORE_CONFIG2 \ > + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ > + MAX_BLK_LENGTH_1024 | \ > + BASE_CLK_FREQ_200) > + > +#define FLASHSS_MMC_CORE_CONFIG_3 0x408 > +#define FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC BIT(28) > +#define FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT BIT(20) > +#define FLASHSS_MMC_CORECFG_3P3_VOLT BIT(8) > +#define FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT BIT(4) > +#define FLASHSS_MMC_CORECFG_SDMA BIT(0) > + > +#define STI_FLASHSS_MMC_CORE_CONFIG3 \ > + (FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC | \ > + FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ > + FLASHSS_MMC_CORECFG_3P3_VOLT | \ > + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ > + FLASHSS_MMC_CORECFG_SDMA) > + > +#define STI_FLASHSS_SDCARD_CORE_CONFIG3 \ > + (FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ > + FLASHSS_MMC_CORECFG_3P3_VOLT | \ > + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ > + FLASHSS_MMC_CORECFG_SDMA) > + > +#define FLASHSS_MMC_CORE_CONFIG_4 0x40c > +#define FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT BIT(20) > +#define FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT BIT(16) > +#define FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT BIT(12) > + > +#define STI_FLASHSS_MMC_CORE_CONFIG4 \ > + (FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT | \ > + FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT | \ > + FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT) > + > +#define ST_MMC_CCONFIG_REG_5 0x210 > +#define SYSCONF_MMC1_ENABLE_BIT 3 > + > +#endif /* _STI_SDHCI_H_ */ > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig > index 0c07781..dfdec27 100644 > --- a/drivers/mmc/Kconfig > +++ b/drivers/mmc/Kconfig > @@ -287,6 +287,13 @@ config MMC_SDHCI_SPEAR > > If unsure, say N. > > +config MMC_SDHCI_STI > + bool "SDHCI support for STMicroelectronics SoC" > + depends on MMC_SDHCI > + help > + This selects the Secure Digital Host Controller Interface (SDHCI) > + on STMicroelectronics STiH410 SoC. > + > config MMC_SDHCI_XENON > bool "SDHCI support for the Xenon SDHCI controller" > depends on MMC_SDHCI && DM_MMC && OF_CONTROL > diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile > index e78bd0d..fc24926 100644 > --- a/drivers/mmc/Makefile > +++ b/drivers/mmc/Makefile > @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_PIC32) += pic32_sdhci.o > obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o > obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o > obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o > +obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o > obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o > obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o > obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o > diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c > new file mode 100644 > index 0000000..7a76983 > --- /dev/null > +++ b/drivers/mmc/sti_sdhci.c > @@ -0,0 +1,140 @@ > +/* > + * Copyright (c) 2017 > + * Patrice Chotard <patrice.chotard@st.com> > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <mmc.h> > +#include <sdhci.h> > +#include <asm/arch/gpio.h> > +#include <asm/arch/sdhci.h> > +#include <asm/arch/sti.h> > +#include <asm/arch/syscfg.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +struct sti_sdhci_plat { > + struct mmc_config cfg; > + struct mmc mmc; > +}; > + > +/** > + * sti_mmc_core_config: configure the Arasan HC > + * @regbase: base address > + * @mmc_instance: mmc instance id > + * Description: this function is to configure the Arasan MMC HC. > + * This should be called when the system starts in case of, on the SoC, > + * it is needed to configure the host controller. > + * This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS > + * needs to be configured as MMC 4.5 to have full capabilities. > + * W/o these settings the SDHCI could configure and use the embedded controller > + * with limited features. > + */ > +static void sti_mmc_core_config(const u32 regbase, int mmc_instance) > +{ > + unsigned long *sysconf; > + > + /* only MMC1 has a reset line */ > + if (mmc_instance) { > + sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + > + ST_MMC_CCONFIG_REG_5); > + generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); > + } > + > + writel(STI_FLASHSS_MMC_CORE_CONFIG_1, > + regbase + FLASHSS_MMC_CORE_CONFIG_1); > + > + if (mmc_instance) { > + writel(STI_FLASHSS_MMC_CORE_CONFIG2, > + regbase + FLASHSS_MMC_CORE_CONFIG_2); > + writel(STI_FLASHSS_MMC_CORE_CONFIG3, > + regbase + FLASHSS_MMC_CORE_CONFIG_3); > + } else { > + writel(STI_FLASHSS_SDCARD_CORE_CONFIG2, > + regbase + FLASHSS_MMC_CORE_CONFIG_2); > + writel(STI_FLASHSS_SDCARD_CORE_CONFIG3, > + regbase + FLASHSS_MMC_CORE_CONFIG_3); > + } > + writel(STI_FLASHSS_MMC_CORE_CONFIG4, > + regbase + FLASHSS_MMC_CORE_CONFIG_4); > +} > + > +int sti_sdhci_probe(struct udevice *dev) Maybe static? > +{ > + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); > + struct sti_sdhci_plat *plat = dev_get_platdata(dev); > + struct sdhci_host *host = dev_get_priv(dev); > + int ret, count, mmc_instance; > + > + /* > + * identify current mmc instance, mmc1 has a reset, not mmc0 > + * MMC0 is wired to the SD slot, > + * MMC1 is wired on the high speed connector > + */ > + > + fdt_getprop(gd->fdt_blob, dev->of_offset, "resets", &count); > + if (count < 0) > + mmc_instance = 0; > + else > + mmc_instance = 1; > + > + sti_mmc_core_config((const u32) host->ioaddr, mmc_instance); > + > + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | > + SDHCI_QUIRK_32BIT_DMA_ADDR | > + SDHCI_QUIRK_NO_HISPD_BIT; Is your host controller broken the HISPD bit? Best Regards, Jaehoon Chung > + > + host->host_caps = MMC_MODE_DDR_52MHz; > + > + ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000); > + > + if (ret) > + return ret; > + > + host->mmc = &plat->mmc; > + host->mmc->priv = host; > + host->mmc->dev = dev; > + upriv->mmc = host->mmc; > + > + return sdhci_probe(dev); > +} > + > +static int sti_sdhci_ofdata_to_platdata(struct udevice *dev) > +{ > + struct sdhci_host *host = dev_get_priv(dev); > + > + host->name = strdup(dev->name); > + host->ioaddr = (void *)dev_get_addr(dev); > + > + host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, > + "bus-width", 4); > + > + return 0; > +} > + > +static int sti_sdhci_bind(struct udevice *dev) > +{ > + struct sti_sdhci_plat *plat = dev_get_platdata(dev); > + > + return sdhci_bind(dev, &plat->mmc, &plat->cfg); > +} > + > +static const struct udevice_id sti_sdhci_ids[] = { > + { .compatible = "st,sdhci" }, > + { } > +}; > + > +U_BOOT_DRIVER(sti_mmc) = { > + .name = "sti_sdhci", > + .id = UCLASS_MMC, > + .of_match = sti_sdhci_ids, > + .bind = sti_sdhci_bind, > + .ops = &sdhci_ops, > + .ofdata_to_platdata = sti_sdhci_ofdata_to_platdata, > + .probe = sti_sdhci_probe, > + .priv_auto_alloc_size = sizeof(struct sdhci_host), > + .platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat), > +}; >
Hi Jaehoon On 02/07/2017 11:42 AM, Jaehoon Chung wrote: > Hi Patrice, > > On 02/03/2017 02:13 AM, patrice.chotard@st.com wrote: >> From: Patrice Chotard <patrice.chotard@st.com> >> >> Add SDHCI host controller found on STMicroelctronics SoCs > > Just wonder what is flashSS? > Add the minor comments. On some ST SoCs, i.e. STiH407/STiH410, the MMC devices can live inside a dedicated flashSS sub-system that provides an extend subset of registers that can be used to configure the Arasan MMC/SD Host Controller. This means, that the SDHCI Arasan Controller can be configured to be eMMC4.5 or 4.3 spec compliant. W/o these settings the SDHCI will configure and use the MMC/SD controller with limited features e.g. PIO mode, no DMA, no HS etc. i will add a comments about that > >> >> Signed-off-by: Patrice Chotard <patrice.chotard@st.com> >> --- >> arch/arm/Kconfig | 2 + >> arch/arm/include/asm/arch-stih410/sdhci.h | 69 +++++++++++++++ >> drivers/mmc/Kconfig | 7 ++ >> drivers/mmc/Makefile | 1 + >> drivers/mmc/sti_sdhci.c | 140 ++++++++++++++++++++++++++++++ >> 5 files changed, 219 insertions(+) >> create mode 100644 arch/arm/include/asm/arch-stih410/sdhci.h >> create mode 100644 drivers/mmc/sti_sdhci.c >> >> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig >> index b91a5b7..477f36b 100644 >> --- a/arch/arm/Kconfig >> +++ b/arch/arm/Kconfig >> @@ -987,6 +987,8 @@ config ARCH_STI >> select CPU_V7 >> select DM >> select DM_SERIAL >> + select BLK >> + select DM_MMC >> help >> Support for STMicroelectronics STiH407/10 SoC family. >> This SoC is used on Linaro 96Board STiH410-B2260 >> diff --git a/arch/arm/include/asm/arch-stih410/sdhci.h b/arch/arm/include/asm/arch-stih410/sdhci.h >> new file mode 100644 >> index 0000000..f45b961 >> --- /dev/null >> +++ b/arch/arm/include/asm/arch-stih410/sdhci.h >> @@ -0,0 +1,69 @@ >> +/* >> + * (C) Copyright 2017 Patrice Chotard <patrice.chotard@st.com> >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +#ifndef __STI_SDHCI_H__ >> +#define __STI_SDHCI_H__ >> + >> +#define FLASHSS_MMC_CORE_CONFIG_1 0x400 >> +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ BIT(24) >> +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN BIT(12) >> + >> +#define STI_FLASHSS_MMC_CORE_CONFIG_1 \ >> + (FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ | \ >> + FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN) >> + >> +#define FLASHSS_MMC_CORE_CONFIG_2 0x404 >> +#define FLASHSS_MMC_CORECFG_HIGH_SPEED BIT(28) >> +#define FLASHSS_MMC_CORECFG_8BIT_EMMC BIT(20) >> +#define MAX_BLK_LENGTH_1024 BIT(16) >> +#define BASE_CLK_FREQ_200 0xc8 >> + >> + > > remove unnecessary white space. ok > >> +#define STI_FLASHSS_MMC_CORE_CONFIG2 \ >> + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ >> + FLASHSS_MMC_CORECFG_8BIT_EMMC | \ >> + MAX_BLK_LENGTH_1024 | \ >> + BASE_CLK_FREQ_200 << 0) >> + >> +#define STI_FLASHSS_SDCARD_CORE_CONFIG2 \ >> + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ >> + MAX_BLK_LENGTH_1024 | \ >> + BASE_CLK_FREQ_200) >> + >> +#define FLASHSS_MMC_CORE_CONFIG_3 0x408 >> +#define FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC BIT(28) >> +#define FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT BIT(20) >> +#define FLASHSS_MMC_CORECFG_3P3_VOLT BIT(8) >> +#define FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT BIT(4) >> +#define FLASHSS_MMC_CORECFG_SDMA BIT(0) >> + >> +#define STI_FLASHSS_MMC_CORE_CONFIG3 \ >> + (FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC | \ >> + FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ >> + FLASHSS_MMC_CORECFG_3P3_VOLT | \ >> + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ >> + FLASHSS_MMC_CORECFG_SDMA) >> + >> +#define STI_FLASHSS_SDCARD_CORE_CONFIG3 \ >> + (FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ >> + FLASHSS_MMC_CORECFG_3P3_VOLT | \ >> + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ >> + FLASHSS_MMC_CORECFG_SDMA) >> + >> +#define FLASHSS_MMC_CORE_CONFIG_4 0x40c >> +#define FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT BIT(20) >> +#define FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT BIT(16) >> +#define FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT BIT(12) >> + >> +#define STI_FLASHSS_MMC_CORE_CONFIG4 \ >> + (FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT | \ >> + FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT | \ >> + FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT) >> + >> +#define ST_MMC_CCONFIG_REG_5 0x210 >> +#define SYSCONF_MMC1_ENABLE_BIT 3 >> + >> +#endif /* _STI_SDHCI_H_ */ >> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig >> index 0c07781..dfdec27 100644 >> --- a/drivers/mmc/Kconfig >> +++ b/drivers/mmc/Kconfig >> @@ -287,6 +287,13 @@ config MMC_SDHCI_SPEAR >> >> If unsure, say N. >> >> +config MMC_SDHCI_STI >> + bool "SDHCI support for STMicroelectronics SoC" >> + depends on MMC_SDHCI >> + help >> + This selects the Secure Digital Host Controller Interface (SDHCI) >> + on STMicroelectronics STiH410 SoC. >> + >> config MMC_SDHCI_XENON >> bool "SDHCI support for the Xenon SDHCI controller" >> depends on MMC_SDHCI && DM_MMC && OF_CONTROL >> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile >> index e78bd0d..fc24926 100644 >> --- a/drivers/mmc/Makefile >> +++ b/drivers/mmc/Makefile >> @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_PIC32) += pic32_sdhci.o >> obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o >> obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o >> obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o >> +obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o >> obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o >> obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o >> obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o >> diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c >> new file mode 100644 >> index 0000000..7a76983 >> --- /dev/null >> +++ b/drivers/mmc/sti_sdhci.c >> @@ -0,0 +1,140 @@ >> +/* >> + * Copyright (c) 2017 >> + * Patrice Chotard <patrice.chotard@st.com> >> + * >> + * SPDX-License-Identifier: GPL-2.0 >> + */ >> + >> +#include <common.h> >> +#include <dm.h> >> +#include <mmc.h> >> +#include <sdhci.h> >> +#include <asm/arch/gpio.h> >> +#include <asm/arch/sdhci.h> >> +#include <asm/arch/sti.h> >> +#include <asm/arch/syscfg.h> >> + >> +DECLARE_GLOBAL_DATA_PTR; >> + >> +struct sti_sdhci_plat { >> + struct mmc_config cfg; >> + struct mmc mmc; >> +}; >> + >> +/** >> + * sti_mmc_core_config: configure the Arasan HC >> + * @regbase: base address >> + * @mmc_instance: mmc instance id >> + * Description: this function is to configure the Arasan MMC HC. >> + * This should be called when the system starts in case of, on the SoC, >> + * it is needed to configure the host controller. >> + * This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS >> + * needs to be configured as MMC 4.5 to have full capabilities. >> + * W/o these settings the SDHCI could configure and use the embedded controller >> + * with limited features. >> + */ >> +static void sti_mmc_core_config(const u32 regbase, int mmc_instance) >> +{ >> + unsigned long *sysconf; >> + >> + /* only MMC1 has a reset line */ >> + if (mmc_instance) { >> + sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + >> + ST_MMC_CCONFIG_REG_5); >> + generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); >> + } >> + >> + writel(STI_FLASHSS_MMC_CORE_CONFIG_1, >> + regbase + FLASHSS_MMC_CORE_CONFIG_1); >> + >> + if (mmc_instance) { >> + writel(STI_FLASHSS_MMC_CORE_CONFIG2, >> + regbase + FLASHSS_MMC_CORE_CONFIG_2); >> + writel(STI_FLASHSS_MMC_CORE_CONFIG3, >> + regbase + FLASHSS_MMC_CORE_CONFIG_3); >> + } else { >> + writel(STI_FLASHSS_SDCARD_CORE_CONFIG2, >> + regbase + FLASHSS_MMC_CORE_CONFIG_2); >> + writel(STI_FLASHSS_SDCARD_CORE_CONFIG3, >> + regbase + FLASHSS_MMC_CORE_CONFIG_3); >> + } >> + writel(STI_FLASHSS_MMC_CORE_CONFIG4, >> + regbase + FLASHSS_MMC_CORE_CONFIG_4); >> +} >> + >> +int sti_sdhci_probe(struct udevice *dev) > > Maybe static? yes, i will fix it > >> +{ >> + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); >> + struct sti_sdhci_plat *plat = dev_get_platdata(dev); >> + struct sdhci_host *host = dev_get_priv(dev); >> + int ret, count, mmc_instance; >> + >> + /* >> + * identify current mmc instance, mmc1 has a reset, not mmc0 >> + * MMC0 is wired to the SD slot, >> + * MMC1 is wired on the high speed connector >> + */ >> + >> + fdt_getprop(gd->fdt_blob, dev->of_offset, "resets", &count); >> + if (count < 0) >> + mmc_instance = 0; >> + else >> + mmc_instance = 1; >> + >> + sti_mmc_core_config((const u32) host->ioaddr, mmc_instance); >> + >> + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | >> + SDHCI_QUIRK_32BIT_DMA_ADDR | >> + SDHCI_QUIRK_NO_HISPD_BIT; > > Is your host controller broken the HISPD bit? Yes > > Best Regards, > Jaehoon Chung > >> + >> + host->host_caps = MMC_MODE_DDR_52MHz; >> + >> + ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000); >> + >> + if (ret) >> + return ret; >> + >> + host->mmc = &plat->mmc; >> + host->mmc->priv = host; >> + host->mmc->dev = dev; >> + upriv->mmc = host->mmc; >> + >> + return sdhci_probe(dev); >> +} >> + >> +static int sti_sdhci_ofdata_to_platdata(struct udevice *dev) >> +{ >> + struct sdhci_host *host = dev_get_priv(dev); >> + >> + host->name = strdup(dev->name); >> + host->ioaddr = (void *)dev_get_addr(dev); >> + >> + host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, >> + "bus-width", 4); >> + >> + return 0; >> +} >> + >> +static int sti_sdhci_bind(struct udevice *dev) >> +{ >> + struct sti_sdhci_plat *plat = dev_get_platdata(dev); >> + >> + return sdhci_bind(dev, &plat->mmc, &plat->cfg); >> +} >> + >> +static const struct udevice_id sti_sdhci_ids[] = { >> + { .compatible = "st,sdhci" }, >> + { } >> +}; >> + >> +U_BOOT_DRIVER(sti_mmc) = { >> + .name = "sti_sdhci", >> + .id = UCLASS_MMC, >> + .of_match = sti_sdhci_ids, >> + .bind = sti_sdhci_bind, >> + .ops = &sdhci_ops, >> + .ofdata_to_platdata = sti_sdhci_ofdata_to_platdata, >> + .probe = sti_sdhci_probe, >> + .priv_auto_alloc_size = sizeof(struct sdhci_host), >> + .platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat), >> +}; >> >
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b91a5b7..477f36b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -987,6 +987,8 @@ config ARCH_STI select CPU_V7 select DM select DM_SERIAL + select BLK + select DM_MMC help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260 diff --git a/arch/arm/include/asm/arch-stih410/sdhci.h b/arch/arm/include/asm/arch-stih410/sdhci.h new file mode 100644 index 0000000..f45b961 --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sdhci.h @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2017 Patrice Chotard <patrice.chotard@st.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __STI_SDHCI_H__ +#define __STI_SDHCI_H__ + +#define FLASHSS_MMC_CORE_CONFIG_1 0x400 +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ BIT(24) +#define FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN BIT(12) + +#define STI_FLASHSS_MMC_CORE_CONFIG_1 \ + (FLASHSS_MMC_CORECFG_TIMEOUT_CLK_UNIT_MHZ | \ + FLASHSS_MMC_CORECFG_TIMEOUT_CLK_FREQ_MIN) + +#define FLASHSS_MMC_CORE_CONFIG_2 0x404 +#define FLASHSS_MMC_CORECFG_HIGH_SPEED BIT(28) +#define FLASHSS_MMC_CORECFG_8BIT_EMMC BIT(20) +#define MAX_BLK_LENGTH_1024 BIT(16) +#define BASE_CLK_FREQ_200 0xc8 + + +#define STI_FLASHSS_MMC_CORE_CONFIG2 \ + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ + FLASHSS_MMC_CORECFG_8BIT_EMMC | \ + MAX_BLK_LENGTH_1024 | \ + BASE_CLK_FREQ_200 << 0) + +#define STI_FLASHSS_SDCARD_CORE_CONFIG2 \ + (FLASHSS_MMC_CORECFG_HIGH_SPEED | \ + MAX_BLK_LENGTH_1024 | \ + BASE_CLK_FREQ_200) + +#define FLASHSS_MMC_CORE_CONFIG_3 0x408 +#define FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC BIT(28) +#define FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_3P3_VOLT BIT(8) +#define FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT BIT(4) +#define FLASHSS_MMC_CORECFG_SDMA BIT(0) + +#define STI_FLASHSS_MMC_CORE_CONFIG3 \ + (FLASHSS_MMC_CORECFG_SLOT_TYPE_EMMC | \ + FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ + FLASHSS_MMC_CORECFG_3P3_VOLT | \ + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ + FLASHSS_MMC_CORECFG_SDMA) + +#define STI_FLASHSS_SDCARD_CORE_CONFIG3 \ + (FLASHSS_MMC_CORECFG_ASYNCH_INTR_SUPPORT | \ + FLASHSS_MMC_CORECFG_3P3_VOLT | \ + FLASHSS_MMC_CORECFG_SUSP_RES_SUPPORT | \ + FLASHSS_MMC_CORECFG_SDMA) + +#define FLASHSS_MMC_CORE_CONFIG_4 0x40c +#define FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT BIT(20) +#define FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT BIT(16) +#define FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT BIT(12) + +#define STI_FLASHSS_MMC_CORE_CONFIG4 \ + (FLASHSS_MMC_CORECFG_D_DRIVER_SUPPORT | \ + FLASHSS_MMC_CORECFG_C_DRIVER_SUPPORT | \ + FLASHSS_MMC_CORECFG_A_DRIVER_SUPPORT) + +#define ST_MMC_CCONFIG_REG_5 0x210 +#define SYSCONF_MMC1_ENABLE_BIT 3 + +#endif /* _STI_SDHCI_H_ */ diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0c07781..dfdec27 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -287,6 +287,13 @@ config MMC_SDHCI_SPEAR If unsure, say N. +config MMC_SDHCI_STI + bool "SDHCI support for STMicroelectronics SoC" + depends on MMC_SDHCI + help + This selects the Secure Digital Host Controller Interface (SDHCI) + on STMicroelectronics STiH410 SoC. + config MMC_SDHCI_XENON bool "SDHCI support for the Xenon SDHCI controller" depends on MMC_SDHCI && DM_MMC && OF_CONTROL diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index e78bd0d..fc24926 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_PIC32) += pic32_sdhci.o obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o +obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c new file mode 100644 index 0000000..7a76983 --- /dev/null +++ b/drivers/mmc/sti_sdhci.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard <patrice.chotard@st.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <sdhci.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sdhci.h> +#include <asm/arch/sti.h> +#include <asm/arch/syscfg.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +/** + * sti_mmc_core_config: configure the Arasan HC + * @regbase: base address + * @mmc_instance: mmc instance id + * Description: this function is to configure the Arasan MMC HC. + * This should be called when the system starts in case of, on the SoC, + * it is needed to configure the host controller. + * This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS + * needs to be configured as MMC 4.5 to have full capabilities. + * W/o these settings the SDHCI could configure and use the embedded controller + * with limited features. + */ +static void sti_mmc_core_config(const u32 regbase, int mmc_instance) +{ + unsigned long *sysconf; + + /* only MMC1 has a reset line */ + if (mmc_instance) { + sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + + ST_MMC_CCONFIG_REG_5); + generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); + } + + writel(STI_FLASHSS_MMC_CORE_CONFIG_1, + regbase + FLASHSS_MMC_CORE_CONFIG_1); + + if (mmc_instance) { + writel(STI_FLASHSS_MMC_CORE_CONFIG2, + regbase + FLASHSS_MMC_CORE_CONFIG_2); + writel(STI_FLASHSS_MMC_CORE_CONFIG3, + regbase + FLASHSS_MMC_CORE_CONFIG_3); + } else { + writel(STI_FLASHSS_SDCARD_CORE_CONFIG2, + regbase + FLASHSS_MMC_CORE_CONFIG_2); + writel(STI_FLASHSS_SDCARD_CORE_CONFIG3, + regbase + FLASHSS_MMC_CORE_CONFIG_3); + } + writel(STI_FLASHSS_MMC_CORE_CONFIG4, + regbase + FLASHSS_MMC_CORE_CONFIG_4); +} + +int sti_sdhci_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sti_sdhci_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); + int ret, count, mmc_instance; + + /* + * identify current mmc instance, mmc1 has a reset, not mmc0 + * MMC0 is wired to the SD slot, + * MMC1 is wired on the high speed connector + */ + + fdt_getprop(gd->fdt_blob, dev->of_offset, "resets", &count); + if (count < 0) + mmc_instance = 0; + else + mmc_instance = 1; + + sti_mmc_core_config((const u32) host->ioaddr, mmc_instance); + + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | + SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_NO_HISPD_BIT; + + host->host_caps = MMC_MODE_DDR_52MHz; + + ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000); + + if (ret) + return ret; + + host->mmc = &plat->mmc; + host->mmc->priv = host; + host->mmc->dev = dev; + upriv->mmc = host->mmc; + + return sdhci_probe(dev); +} + +static int sti_sdhci_ofdata_to_platdata(struct udevice *dev) +{ + struct sdhci_host *host = dev_get_priv(dev); + + host->name = strdup(dev->name); + host->ioaddr = (void *)dev_get_addr(dev); + + host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "bus-width", 4); + + return 0; +} + +static int sti_sdhci_bind(struct udevice *dev) +{ + struct sti_sdhci_plat *plat = dev_get_platdata(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static const struct udevice_id sti_sdhci_ids[] = { + { .compatible = "st,sdhci" }, + { } +}; + +U_BOOT_DRIVER(sti_mmc) = { + .name = "sti_sdhci", + .id = UCLASS_MMC, + .of_match = sti_sdhci_ids, + .bind = sti_sdhci_bind, + .ops = &sdhci_ops, + .ofdata_to_platdata = sti_sdhci_ofdata_to_platdata, + .probe = sti_sdhci_probe, + .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat), +};