183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2447da58bSPeter Griffin /* 3447da58bSPeter Griffin * (C) Copyright 2015 Linaro 4447da58bSPeter Griffin * peter.griffin <peter.griffin@linaro.org> 5447da58bSPeter Griffin */ 6447da58bSPeter Griffin 7447da58bSPeter Griffin #include <common.h> 8*6240e64fSManivannan Sadhasivam #include <dm.h> 9447da58bSPeter Griffin #include <dwmmc.h> 10*6240e64fSManivannan Sadhasivam #include <errno.h> 11*6240e64fSManivannan Sadhasivam #include <fdtdec.h> 12447da58bSPeter Griffin #include <malloc.h> 13447da58bSPeter Griffin 14*6240e64fSManivannan Sadhasivam DECLARE_GLOBAL_DATA_PTR; 15447da58bSPeter Griffin 16*6240e64fSManivannan Sadhasivam struct hi6220_dwmmc_plat { 17*6240e64fSManivannan Sadhasivam struct mmc_config cfg; 18*6240e64fSManivannan Sadhasivam struct mmc mmc; 19*6240e64fSManivannan Sadhasivam }; 20447da58bSPeter Griffin 21*6240e64fSManivannan Sadhasivam struct hi6220_dwmmc_priv_data { 22*6240e64fSManivannan Sadhasivam struct dwmci_host host; 23*6240e64fSManivannan Sadhasivam }; 24447da58bSPeter Griffin 25*6240e64fSManivannan Sadhasivam static int hi6220_dwmmc_ofdata_to_platdata(struct udevice *dev) 26447da58bSPeter Griffin { 27*6240e64fSManivannan Sadhasivam struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); 28*6240e64fSManivannan Sadhasivam struct dwmci_host *host = &priv->host; 29447da58bSPeter Griffin 30*6240e64fSManivannan Sadhasivam host->name = dev->name; 31*6240e64fSManivannan Sadhasivam host->ioaddr = (void *)devfdt_get_addr(dev); 32*6240e64fSManivannan Sadhasivam host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 33*6240e64fSManivannan Sadhasivam "bus-width", 4); 34447da58bSPeter Griffin 35*6240e64fSManivannan Sadhasivam /* use non-removable property for differentiating SD card and eMMC */ 36*6240e64fSManivannan Sadhasivam if (dev_read_bool(dev, "non-removable")) 37*6240e64fSManivannan Sadhasivam host->dev_index = 0; 38*6240e64fSManivannan Sadhasivam else 39*6240e64fSManivannan Sadhasivam host->dev_index = 1; 40*6240e64fSManivannan Sadhasivam 41*6240e64fSManivannan Sadhasivam host->priv = priv; 42*6240e64fSManivannan Sadhasivam 43447da58bSPeter Griffin return 0; 44447da58bSPeter Griffin } 45447da58bSPeter Griffin 46*6240e64fSManivannan Sadhasivam static int hi6220_dwmmc_probe(struct udevice *dev) 47447da58bSPeter Griffin { 48*6240e64fSManivannan Sadhasivam struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev); 49*6240e64fSManivannan Sadhasivam struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 50*6240e64fSManivannan Sadhasivam struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev); 51*6240e64fSManivannan Sadhasivam struct dwmci_host *host = &priv->host; 52447da58bSPeter Griffin 53*6240e64fSManivannan Sadhasivam /* Use default bus speed due to absence of clk driver */ 54*6240e64fSManivannan Sadhasivam host->bus_hz = 50000000; 55*6240e64fSManivannan Sadhasivam 56*6240e64fSManivannan Sadhasivam dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000); 57*6240e64fSManivannan Sadhasivam host->mmc = &plat->mmc; 58*6240e64fSManivannan Sadhasivam 59*6240e64fSManivannan Sadhasivam host->mmc->priv = &priv->host; 60*6240e64fSManivannan Sadhasivam upriv->mmc = host->mmc; 61*6240e64fSManivannan Sadhasivam host->mmc->dev = dev; 62*6240e64fSManivannan Sadhasivam 63*6240e64fSManivannan Sadhasivam return dwmci_probe(dev); 64447da58bSPeter Griffin } 65447da58bSPeter Griffin 66*6240e64fSManivannan Sadhasivam static int hi6220_dwmmc_bind(struct udevice *dev) 67*6240e64fSManivannan Sadhasivam { 68*6240e64fSManivannan Sadhasivam struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev); 69*6240e64fSManivannan Sadhasivam int ret; 70447da58bSPeter Griffin 71*6240e64fSManivannan Sadhasivam ret = dwmci_bind(dev, &plat->mmc, &plat->cfg); 72*6240e64fSManivannan Sadhasivam if (ret) 73*6240e64fSManivannan Sadhasivam return ret; 74*6240e64fSManivannan Sadhasivam 75*6240e64fSManivannan Sadhasivam return 0; 76447da58bSPeter Griffin } 77*6240e64fSManivannan Sadhasivam 78*6240e64fSManivannan Sadhasivam static const struct udevice_id hi6220_dwmmc_ids[] = { 79*6240e64fSManivannan Sadhasivam { .compatible = "hisilicon,hi6220-dw-mshc" }, 80*6240e64fSManivannan Sadhasivam { } 81*6240e64fSManivannan Sadhasivam }; 82*6240e64fSManivannan Sadhasivam 83*6240e64fSManivannan Sadhasivam U_BOOT_DRIVER(hi6220_dwmmc_drv) = { 84*6240e64fSManivannan Sadhasivam .name = "hi6220_dwmmc", 85*6240e64fSManivannan Sadhasivam .id = UCLASS_MMC, 86*6240e64fSManivannan Sadhasivam .of_match = hi6220_dwmmc_ids, 87*6240e64fSManivannan Sadhasivam .ofdata_to_platdata = hi6220_dwmmc_ofdata_to_platdata, 88*6240e64fSManivannan Sadhasivam .ops = &dm_dwmci_ops, 89*6240e64fSManivannan Sadhasivam .bind = hi6220_dwmmc_bind, 90*6240e64fSManivannan Sadhasivam .probe = hi6220_dwmmc_probe, 91*6240e64fSManivannan Sadhasivam .priv_auto_alloc_size = sizeof(struct hi6220_dwmmc_priv_data), 92*6240e64fSManivannan Sadhasivam .platdata_auto_alloc_size = sizeof(struct hi6220_dwmmc_plat), 93*6240e64fSManivannan Sadhasivam }; 94