mmc: synquacer: Add SynQuacer F_SDH30 SDHCI driver
[platform/kernel/u-boot.git] / drivers / mmc / f_sdh30.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Socionext F_SDH30 eMMC driver
4  * Copyright 2021 Linaro Ltd.
5  * Copyright 2021 Socionext, Inc.
6  */
7
8 #include <common.h>
9 #include <clk.h>
10 #include <dm.h>
11 #include <malloc.h>
12 #include <sdhci.h>
13
14 struct f_sdh30_plat {
15         struct mmc_config cfg;
16         struct mmc mmc;
17 };
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 static int f_sdh30_sdhci_probe(struct udevice *dev)
22 {
23         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
24         struct f_sdh30_plat *plat = dev_get_plat(dev);
25         struct sdhci_host *host = dev_get_priv(dev);
26         int ret;
27
28         ret = mmc_of_parse(dev, &plat->cfg);
29         if (ret)
30                 return ret;
31
32         host->mmc = &plat->mmc;
33         host->mmc->dev = dev;
34         host->mmc->priv = host;
35
36         ret = sdhci_setup_cfg(&plat->cfg, host, 200000000, 400000);
37         if (ret)
38                 return ret;
39
40         upriv->mmc = host->mmc;
41
42         mmc_set_clock(host->mmc, host->mmc->cfg->f_min, MMC_CLK_ENABLE);
43
44         return sdhci_probe(dev);
45 }
46
47 static int f_sdh30_of_to_plat(struct udevice *dev)
48 {
49         struct sdhci_host *host = dev_get_priv(dev);
50
51         host->name = strdup(dev->name);
52         host->ioaddr = dev_read_addr_ptr(dev);
53         host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
54         host->index = dev_read_u32_default(dev, "index", 0);
55
56         return 0;
57 }
58
59 static int f_sdh30_bind(struct udevice *dev)
60 {
61         struct f_sdh30_plat *plat = dev_get_plat(dev);
62
63         return sdhci_bind(dev, &plat->mmc, &plat->cfg);
64 }
65
66 static const struct udevice_id f_sdh30_mmc_ids[] = {
67         { .compatible = "fujitsu,mb86s70-sdhci-3.0" },
68         { }
69 };
70
71 U_BOOT_DRIVER(f_sdh30_drv) = {
72         .name           = "f_sdh30_sdhci",
73         .id             = UCLASS_MMC,
74         .of_match       = f_sdh30_mmc_ids,
75         .of_to_plat     = f_sdh30_of_to_plat,
76         .ops            = &sdhci_ops,
77         .bind           = f_sdh30_bind,
78         .probe          = f_sdh30_sdhci_probe,
79         .priv_auto      = sizeof(struct sdhci_host),
80         .plat_auto      = sizeof(struct f_sdh30_plat),
81 };