summaryrefslogtreecommitdiff
path: root/drivers/mmc/am654_sdhci.c
diff options
context:
space:
mode:
authorFaiz Abbas <faiz_abbas@ti.com>2019-06-10 22:13:31 +0300
committerTom Rini <trini@konsulko.com>2019-07-17 18:12:08 +0300
commit3a1a0dfc395e9f09e18fc103383e55d59c63f263 (patch)
treedd3c221c45207941fe9fad6eb666bd046af86816 /drivers/mmc/am654_sdhci.c
parent0e80dda32c8d724c2a98dbbfb2f1e59762788f15 (diff)
downloadu-boot-3a1a0dfc395e9f09e18fc103383e55d59c63f263.tar.xz
arm64: dts: k3: Sync sdhci0 node from kernel and change driver name
Sync the sdhci0 node from kernel. This changes the compatible that is required to be there in the driver. Change the same for the SD card node which is not yet supported in kernel. This also syncs the main_pmx0 node as a side effect. Also change the name of the driver to match the compatible in kernel. Signed-off-by: Faiz Abbas <faiz_abbas@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/mmc/am654_sdhci.c')
-rw-r--r--drivers/mmc/am654_sdhci.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
new file mode 100644
index 0000000000..2d08fe3347
--- /dev/null
+++ b/drivers/mmc/am654_sdhci.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Texas Instruments' K3 SD Host Controller Interface
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <power-domain.h>
+#include <sdhci.h>
+
+#define AM654_SDHCI_MIN_FREQ 400000
+
+struct am654_sdhci_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+ unsigned int f_max;
+};
+
+static int am654_sdhci_probe(struct udevice *dev)
+{
+ struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+ struct power_domain sdhci_pwrdmn;
+ struct clk clk;
+ unsigned long clock;
+ int ret;
+
+ ret = power_domain_get_by_index(dev, &sdhci_pwrdmn, 0);
+ if (ret) {
+ dev_err(dev, "failed to get power domain\n");
+ return ret;
+ }
+
+ ret = power_domain_on(&sdhci_pwrdmn);
+ if (ret) {
+ dev_err(dev, "Power domain on failed\n");
+ return ret;
+ }
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret) {
+ dev_err(dev, "failed to get clock\n");
+ return ret;
+ }
+
+ clock = clk_get_rate(&clk);
+ if (IS_ERR_VALUE(clock)) {
+ dev_err(dev, "failed to get rate\n");
+ return clock;
+ }
+
+ host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
+ SDHCI_QUIRK_BROKEN_R1B;
+
+ host->max_clk = clock;
+
+ ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
+ AM654_SDHCI_MIN_FREQ);
+ host->mmc = &plat->mmc;
+ if (ret)
+ return ret;
+ host->mmc->priv = host;
+ host->mmc->dev = dev;
+ upriv->mmc = host->mmc;
+
+ return sdhci_probe(dev);
+}
+
+static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
+{
+ struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+
+ host->name = dev->name;
+ host->ioaddr = (void *)dev_read_addr(dev);
+ host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
+ plat->f_max = dev_read_u32_default(dev, "max-frequency", 0);
+
+ return 0;
+}
+
+static int am654_sdhci_bind(struct udevice *dev)
+{
+ struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+
+ return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id am654_sdhci_ids[] = {
+ { .compatible = "ti,am654-sdhci-5.1" },
+ { }
+};
+
+U_BOOT_DRIVER(am654_sdhci_drv) = {
+ .name = "am654_sdhci",
+ .id = UCLASS_MMC,
+ .of_match = am654_sdhci_ids,
+ .ofdata_to_platdata = am654_sdhci_ofdata_to_platdata,
+ .ops = &sdhci_ops,
+ .bind = am654_sdhci_bind,
+ .probe = am654_sdhci_probe,
+ .priv_auto_alloc_size = sizeof(struct sdhci_host),
+ .platdata_auto_alloc_size = sizeof(struct am654_sdhci_plat),
+};