1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 Linaro 4 * peter.griffin <peter.griffin@linaro.org> 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <dwmmc.h> 10 #include <errno.h> 11 #include <fdtdec.h> 12 #include <malloc.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 struct hi6220_dwmmc_plat { 17 struct mmc_config cfg; 18 struct mmc mmc; 19 }; 20 21 struct hi6220_dwmmc_priv_data { 22 struct dwmci_host host; 23 }; 24 25 static int hi6220_dwmmc_ofdata_to_platdata(struct udevice *dev) 26 { 27 struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); 28 struct dwmci_host *host = &priv->host; 29 30 host->name = dev->name; 31 host->ioaddr = (void *)devfdt_get_addr(dev); 32 host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 33 "bus-width", 4); 34 35 /* use non-removable property for differentiating SD card and eMMC */ 36 if (dev_read_bool(dev, "non-removable")) 37 host->dev_index = 0; 38 else 39 host->dev_index = 1; 40 41 host->priv = priv; 42 43 return 0; 44 } 45 46 static int hi6220_dwmmc_probe(struct udevice *dev) 47 { 48 struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev); 49 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 50 struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); 51 struct dwmci_host *host = &priv->host; 52 53 /* Use default bus speed due to absence of clk driver */ 54 host->bus_hz = 50000000; 55 56 dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000); 57 host->mmc = &plat->mmc; 58 59 host->mmc->priv = &priv->host; 60 upriv->mmc = host->mmc; 61 host->mmc->dev = dev; 62 63 return dwmci_probe(dev); 64 } 65 66 static int hi6220_dwmmc_bind(struct udevice *dev) 67 { 68 struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev); 69 int ret; 70 71 ret = dwmci_bind(dev, &plat->mmc, &plat->cfg); 72 if (ret) 73 return ret; 74 75 return 0; 76 } 77 78 static const struct udevice_id hi6220_dwmmc_ids[] = { 79 { .compatible = "hisilicon,hi6220-dw-mshc" }, 80 { } 81 }; 82 83 U_BOOT_DRIVER(hi6220_dwmmc_drv) = { 84 .name = "hi6220_dwmmc", 85 .id = UCLASS_MMC, 86 .of_match = hi6220_dwmmc_ids, 87 .ofdata_to_platdata = hi6220_dwmmc_ofdata_to_platdata, 88 .ops = &dm_dwmci_ops, 89 .bind = hi6220_dwmmc_bind, 90 .probe = hi6220_dwmmc_probe, 91 .priv_auto_alloc_size = sizeof(struct hi6220_dwmmc_priv_data), 92 .platdata_auto_alloc_size = sizeof(struct hi6220_dwmmc_plat), 93 }; 94