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