diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 878f867c627..96ce1ac8609 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -553,6 +553,17 @@ config MMC_SDHCI_BCMSTB If unsure, say N. +config MMC_SDHCI_BFLB + tristate "SDHCI support for the Bouffalo Lab SDH controller" + depends on MMC_SDHCI + help + This selects the Bouffalo Lab SDH controller. + + If you have a Bouffalo Lab platform with SD or MMC devices, + say Y here. + + If unsure, say N. + config MMC_SDHCI_CADENCE bool "SDHCI support for the Cadence SD/SDIO/eMMC controller" depends on BLK && DM_MMC diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 3a664c2ebbb..9cffddcf66b 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o obj-$(CONFIG_MMC_SDHCI_ATMEL) += atmel_sdhci.o obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o +obj-$(CONFIG_MMC_SDHCI_BFLB) += bflb_sdhci.o obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o obj-$(CONFIG_MMC_SDHCI_AM654) += am654_sdhci.o obj-$(CONFIG_MMC_SDHCI_IPROC) += iproc_sdhci.o diff --git a/drivers/mmc/bflb_sdhci.c b/drivers/mmc/bflb_sdhci.c new file mode 100644 index 00000000000..f48102cac24 --- /dev/null +++ b/drivers/mmc/bflb_sdhci.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include + +struct bflb_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +static int bflb_sdhci_bind(struct udevice *dev) +{ + struct bflb_sdhci_plat *plat = dev_get_plat(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static int bflb_sdhci_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct bflb_sdhci_plat *plat = dev_get_plat(dev); + struct sdhci_host *host = dev_get_priv(dev); + struct clk clk; + int ret; + + host->name = dev->name; + host->ioaddr = dev_remap_addr(dev); + if (!host->ioaddr) + return -ENOMEM; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + ret = clk_enable(&clk); + if (ret) + return ret; + + host->max_clk = clk_get_rate(&clk); + if (IS_ERR_VALUE(host->max_clk)) { + ret = host->max_clk; + goto err_clk_disable; + } + + host->mmc = &plat->mmc; + host->mmc->dev = dev; + host->mmc->priv = host; + upriv->mmc = &plat->mmc; + + ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); + if (ret) + goto err_clk_disable; + + ret = sdhci_probe(dev); + if (ret) + goto err_clk_disable; + + return 0; + +err_clk_disable: + clk_disable(&clk); + + return ret; +} + +static const struct udevice_id bflb_sdhci_match[] = { + { .compatible = "bflb,bl808-sdhci" }, + { } +}; + +U_BOOT_DRIVER(bflb_sdhci) = { + .name = "bflb_sdhci", + .id = UCLASS_MMC, + .of_match = bflb_sdhci_match, + .bind = bflb_sdhci_bind, + .probe = bflb_sdhci_probe, + .priv_auto = sizeof(struct sdhci_host), + .plat_auto = sizeof(struct bflb_sdhci_plat), + .ops = &sdhci_ops, +};