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 #include <clk.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 /* 400KHz is max freq for card ID etc. Use that as min */ 19 #define EMMC_MIN_FREQ 400000 20 21 struct rockchip_sdhc_plat { 22 struct mmc_config cfg; 23 struct mmc mmc; 24 }; 25 26 struct rockchip_sdhc { 27 struct sdhci_host host; 28 void *base; 29 }; 30 31 static int arasan_sdhci_probe(struct udevice *dev) 32 { 33 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 34 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 35 struct rockchip_sdhc *prv = dev_get_priv(dev); 36 struct sdhci_host *host = &prv->host; 37 int max_frequency, ret; 38 struct clk clk; 39 40 41 max_frequency = fdtdec_get_int(gd->fdt_blob, dev->of_offset, 42 "max-frequency", 0); 43 ret = clk_get_by_index(dev, 0, &clk); 44 if (!ret) { 45 ret = clk_set_rate(&clk, max_frequency); 46 if (IS_ERR_VALUE(ret)) 47 printf("%s clk set rate fail!\n", __func__); 48 } else { 49 printf("%s fail to get clk\n", __func__); 50 } 51 52 host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; 53 54 ret = sdhci_setup_cfg(&plat->cfg, host, max_frequency, 55 EMMC_MIN_FREQ); 56 57 host->mmc = &plat->mmc; 58 if (ret) 59 return ret; 60 host->mmc->priv = &prv->host; 61 host->mmc->dev = dev; 62 upriv->mmc = host->mmc; 63 64 return sdhci_probe(dev); 65 } 66 67 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) 68 { 69 struct sdhci_host *host = dev_get_priv(dev); 70 71 host->name = dev->name; 72 host->ioaddr = dev_get_addr_ptr(dev); 73 74 return 0; 75 } 76 77 static int rockchip_sdhci_bind(struct udevice *dev) 78 { 79 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 80 81 return sdhci_bind(dev, &plat->mmc, &plat->cfg); 82 } 83 84 static const struct udevice_id arasan_sdhci_ids[] = { 85 { .compatible = "arasan,sdhci-5.1" }, 86 { } 87 }; 88 89 U_BOOT_DRIVER(arasan_sdhci_drv) = { 90 .name = "arasan_sdhci", 91 .id = UCLASS_MMC, 92 .of_match = arasan_sdhci_ids, 93 .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata, 94 .ops = &sdhci_ops, 95 .bind = rockchip_sdhci_bind, 96 .probe = arasan_sdhci_probe, 97 .priv_auto_alloc_size = sizeof(struct rockchip_sdhc), 98 .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat), 99 }; 100