1 /* 2 * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * Rockchip SD Host Controller Interface 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <dm.h> 11 #include <fdtdec.h> 12 #include <libfdt.h> 13 #include <malloc.h> 14 #include <sdhci.h> 15 16 /* 400KHz is max freq for card ID etc. Use that as min */ 17 #define EMMC_MIN_FREQ 400000 18 19 struct rockchip_sdhc_plat { 20 struct mmc_config cfg; 21 struct mmc mmc; 22 }; 23 24 struct rockchip_sdhc { 25 struct sdhci_host host; 26 void *base; 27 }; 28 29 static int arasan_sdhci_probe(struct udevice *dev) 30 { 31 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 32 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 33 struct rockchip_sdhc *prv = dev_get_priv(dev); 34 struct sdhci_host *host = &prv->host; 35 int ret; 36 u32 caps; 37 38 host->version = sdhci_readw(host, SDHCI_HOST_VERSION); 39 host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; 40 41 caps = sdhci_readl(host, SDHCI_CAPABILITIES); 42 ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, 43 caps, CONFIG_ROCKCHIP_SDHCI_MAX_FREQ, EMMC_MIN_FREQ, 44 host->version, host->quirks, 0); 45 46 host->mmc = &plat->mmc; 47 if (ret) 48 return ret; 49 host->mmc->priv = &prv->host; 50 host->mmc->dev = dev; 51 upriv->mmc = host->mmc; 52 53 return sdhci_probe(dev); 54 } 55 56 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) 57 { 58 struct sdhci_host *host = dev_get_priv(dev); 59 60 host->name = dev->name; 61 host->ioaddr = dev_get_addr_ptr(dev); 62 63 return 0; 64 } 65 66 static int rockchip_sdhci_bind(struct udevice *dev) 67 { 68 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 69 int ret; 70 71 ret = sdhci_bind(dev, &plat->mmc, &plat->cfg); 72 if (ret) 73 return ret; 74 75 return 0; 76 } 77 78 static const struct udevice_id arasan_sdhci_ids[] = { 79 { .compatible = "arasan,sdhci-5.1" }, 80 { } 81 }; 82 83 U_BOOT_DRIVER(arasan_sdhci_drv) = { 84 .name = "arasan_sdhci", 85 .id = UCLASS_MMC, 86 .of_match = arasan_sdhci_ids, 87 .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata, 88 .ops = &sdhci_ops, 89 .bind = rockchip_sdhci_bind, 90 .probe = arasan_sdhci_probe, 91 .priv_auto_alloc_size = sizeof(struct rockchip_sdhc), 92 .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat), 93 }; 94