1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd 4 * 5 * Rockchip SD Host Controller Interface 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <dt-structs.h> 11 #include <linux/libfdt.h> 12 #include <malloc.h> 13 #include <mapmem.h> 14 #include <sdhci.h> 15 #include <clk.h> 16 17 /* 400KHz is max freq for card ID etc. Use that as min */ 18 #define EMMC_MIN_FREQ 400000 19 20 struct aspeed_sdhci_plat { 21 struct mmc_config cfg; 22 struct mmc mmc; 23 unsigned int f_max; 24 }; 25 26 struct aspeed_sdhci_priv { 27 struct sdhci_host *host; 28 struct clk clk; 29 }; 30 31 static int aspeed_sdhci_probe(struct udevice *dev) 32 { 33 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 34 struct aspeed_sdhci_plat *plat = dev_get_platdata(dev); 35 struct aspeed_sdhci_priv *prv = dev_get_priv(dev); 36 struct sdhci_host *host = prv->host; 37 unsigned long clock; 38 unsigned long f_max; 39 struct clk clk; 40 int ret; 41 #ifndef CONFIG_SPL_BUILD 42 int node = dev_of_offset(dev); 43 #endif 44 45 ret = clk_get_by_index(dev, 0, &clk); 46 if (ret < 0) { 47 pr_debug("%s: Can't get clock for %s: %d\n", __func__, dev->name, 48 ret); 49 } 50 51 clock = clk_get_rate(&clk); 52 if (IS_ERR_VALUE(clock)) { 53 dev_err(dev, "failed to get clock\n"); 54 return ret; 55 } 56 57 debug("%s: CLK %ld\n", __func__, clock); 58 59 #ifndef CONFIG_SPL_BUILD 60 //1: sd card pwr, 0: no pwr 61 gpio_request_by_name_nodev(offset_to_ofnode(node), "pwr-gpios", 0, 62 &host->pwr_gpio, GPIOD_IS_OUT); 63 if (dm_gpio_is_valid(&host->pwr_gpio)) { 64 printf("\n"); 65 dm_gpio_set_value(&host->pwr_gpio, 1); 66 if (ret) { 67 debug("MMC not configured\n"); 68 return ret; 69 } 70 } 71 72 //1: 3.3v, 0: 1.8v 73 gpio_request_by_name_nodev(offset_to_ofnode(node), "pwr-sw-gpios", 0, 74 &host->pwr_sw_gpio, GPIOD_IS_OUT); 75 76 if (dm_gpio_is_valid(&host->pwr_sw_gpio)) { 77 dm_gpio_set_value(&host->pwr_sw_gpio, 1); 78 if (ret) { 79 debug("MMC not configured\n"); 80 return ret; 81 } 82 } 83 #endif 84 // host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; 85 host->max_clk = clock; 86 f_max = dev_read_u32_default(dev, "max-frequency", clock); 87 88 host->bus_width = dev_read_u32_default(dev, "bus-width", 4); 89 90 if (host->bus_width == 8) 91 host->host_caps |= MMC_MODE_8BIT; 92 93 ret = sdhci_setup_cfg(&plat->cfg, host, f_max, EMMC_MIN_FREQ); 94 95 host->mmc = &plat->mmc; 96 if (ret) 97 return ret; 98 99 host->mmc->drv_type = dev_read_u32_default(dev, "sdhci-drive-type", 0); 100 host->mmc->priv = host; 101 host->mmc->dev = dev; 102 upriv->mmc = host->mmc; 103 104 return sdhci_probe(dev); 105 } 106 107 static int aspeed_sdhci_ofdata_to_platdata(struct udevice *dev) 108 { 109 struct aspeed_sdhci_priv *priv = dev_get_priv(dev); 110 111 priv->host = calloc(1, sizeof(struct sdhci_host)); 112 if (!priv->host) 113 return -1; 114 115 priv->host->name = dev->name; 116 priv->host->ioaddr = (void *)dev_read_addr(dev); 117 118 return 0; 119 } 120 121 static int aspeed_sdhci_bind(struct udevice *dev) 122 { 123 struct aspeed_sdhci_plat *plat = dev_get_platdata(dev); 124 125 return sdhci_bind(dev, &plat->mmc, &plat->cfg); 126 } 127 128 static const struct udevice_id aspeed_sdhci_ids[] = { 129 { .compatible = "aspeed,sdhci-ast2500" }, 130 { .compatible = "aspeed,sdhci-ast2600" }, 131 { .compatible = "aspeed,emmc-ast2600" }, 132 { } 133 }; 134 135 U_BOOT_DRIVER(aspeed_sdhci_drv) = { 136 .name = "aspeed_sdhci", 137 .id = UCLASS_MMC, 138 .of_match = aspeed_sdhci_ids, 139 .ofdata_to_platdata = aspeed_sdhci_ofdata_to_platdata, 140 .ops = &sdhci_ops, 141 .bind = aspeed_sdhci_bind, 142 .probe = aspeed_sdhci_probe, 143 .priv_auto_alloc_size = sizeof(struct aspeed_sdhci_priv), 144 .platdata_auto_alloc_size = sizeof(struct aspeed_sdhci_plat), 145 }; 146