1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2017 Intel Corporation 4 */ 5 #include <common.h> 6 #include <dm.h> 7 #include <dm/device.h> 8 #include <linux/io.h> 9 #include <linux/sizes.h> 10 #include <malloc.h> 11 #include <mmc.h> 12 #include <sdhci.h> 13 14 #define SDHCI_TANGIER_FMAX 200000000 15 #define SDHCI_TANGIER_FMIN 400000 16 17 struct sdhci_tangier_plat { 18 struct mmc_config cfg; 19 struct mmc mmc; 20 void __iomem *ioaddr; 21 }; 22 23 static int sdhci_tangier_bind(struct udevice *dev) 24 { 25 struct sdhci_tangier_plat *plat = dev_get_platdata(dev); 26 27 return sdhci_bind(dev, &plat->mmc, &plat->cfg); 28 } 29 30 static int sdhci_tangier_probe(struct udevice *dev) 31 { 32 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 33 struct sdhci_tangier_plat *plat = dev_get_platdata(dev); 34 struct sdhci_host *host = dev_get_priv(dev); 35 fdt_addr_t base; 36 int ret; 37 38 base = devfdt_get_addr(dev); 39 if (base == FDT_ADDR_T_NONE) 40 return -EINVAL; 41 42 plat->ioaddr = devm_ioremap(dev, base, SZ_1K); 43 if (!plat->ioaddr) 44 return -ENOMEM; 45 46 host->name = dev->name; 47 host->ioaddr = plat->ioaddr; 48 host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | 49 SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD; 50 51 /* MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195 */ 52 host->voltages = MMC_VDD_165_195; 53 54 ret = sdhci_setup_cfg(&plat->cfg, host, SDHCI_TANGIER_FMAX, 55 SDHCI_TANGIER_FMIN); 56 if (ret) 57 return ret; 58 59 upriv->mmc = &plat->mmc; 60 host->mmc = &plat->mmc; 61 host->mmc->priv = host; 62 63 return sdhci_probe(dev); 64 } 65 66 static const struct udevice_id sdhci_tangier_match[] = { 67 { .compatible = "intel,sdhci-tangier" }, 68 { /* sentinel */ } 69 }; 70 71 U_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, 78 .priv_auto_alloc_size = sizeof(struct sdhci_host), 79 .platdata_auto_alloc_size = sizeof(struct sdhci_tangier_plat), 80 }; 81