blob: ae65c310b685024dcaa01e65ecf63c0b671c0194 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Felipe Balbib7567602017-02-20 14:24:14 +03002/*
3 * Copyright (c) 2017 Intel Corporation
Felipe Balbib7567602017-02-20 14:24:14 +03004 */
Felipe Balbib7567602017-02-20 14:24:14 +03005#include <dm.h>
6#include <dm/device.h>
7#include <linux/io.h>
8#include <linux/sizes.h>
9#include <malloc.h>
10#include <mmc.h>
11#include <sdhci.h>
12
13#define SDHCI_TANGIER_FMAX 200000000
14#define SDHCI_TANGIER_FMIN 400000
15
16struct sdhci_tangier_plat {
17 struct mmc_config cfg;
18 struct mmc mmc;
19 void __iomem *ioaddr;
20};
21
22static int sdhci_tangier_bind(struct udevice *dev)
23{
Simon Glassfa20e932020-12-03 16:55:20 -070024 struct sdhci_tangier_plat *plat = dev_get_plat(dev);
Felipe Balbib7567602017-02-20 14:24:14 +030025
26 return sdhci_bind(dev, &plat->mmc, &plat->cfg);
27}
28
29static int sdhci_tangier_probe(struct udevice *dev)
30{
31 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
Simon Glassfa20e932020-12-03 16:55:20 -070032 struct sdhci_tangier_plat *plat = dev_get_plat(dev);
Felipe Balbib7567602017-02-20 14:24:14 +030033 struct sdhci_host *host = dev_get_priv(dev);
34 fdt_addr_t base;
35 int ret;
36
Masahiro Yamadaa89b4de2020-07-17 14:36:48 +090037 base = dev_read_addr(dev);
Felipe Balbib7567602017-02-20 14:24:14 +030038 if (base == FDT_ADDR_T_NONE)
39 return -EINVAL;
40
41 plat->ioaddr = devm_ioremap(dev, base, SZ_1K);
42 if (!plat->ioaddr)
43 return -ENOMEM;
44
45 host->name = dev->name;
46 host->ioaddr = plat->ioaddr;
47 host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE |
48 SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD;
49
50 /* MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195 */
51 host->voltages = MMC_VDD_165_195;
52
Peng Fanb22bdd92019-08-06 02:48:04 +000053 host->mmc = &plat->mmc;
54 host->mmc->dev = dev;
Felipe Balbib7567602017-02-20 14:24:14 +030055 ret = sdhci_setup_cfg(&plat->cfg, host, SDHCI_TANGIER_FMAX,
56 SDHCI_TANGIER_FMIN);
57 if (ret)
58 return ret;
59
60 upriv->mmc = &plat->mmc;
Felipe Balbib7567602017-02-20 14:24:14 +030061 host->mmc->priv = host;
62
63 return sdhci_probe(dev);
64}
65
66static const struct udevice_id sdhci_tangier_match[] = {
67 { .compatible = "intel,sdhci-tangier" },
68 { /* sentinel */ }
69};
70
71U_BOOT_DRIVER(sdhci_tangier) = {
72 .name = "sdhci-tangier",
73 .id = UCLASS_MMC,
74 .of_match = sdhci_tangier_match,
75 .bind = sdhci_tangier_bind,
76 .probe = sdhci_tangier_probe,
77 .ops = &sdhci_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -070078 .priv_auto = sizeof(struct sdhci_host),
Simon Glass71fa5b42020-12-03 16:55:18 -070079 .plat_auto = sizeof(struct sdhci_tangier_plat),
Felipe Balbib7567602017-02-20 14:24:14 +030080};