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 <asm/arch/hardware.h> 10 #include <common.h> 11 #include <dm.h> 12 #include <dt-structs.h> 13 #include <libfdt.h> 14 #include <malloc.h> 15 #include <mapmem.h> 16 #include <sdhci.h> 17 #include <clk.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 /* 400KHz is max freq for card ID etc. Use that as min */ 21 #define EMMC_MIN_FREQ 400000 22 23 struct rockchip_sdhc_plat { 24 #if CONFIG_IS_ENABLED(OF_PLATDATA) 25 struct dtd_rockchip_rk3399_sdhci_5_1 dtplat; 26 #endif 27 struct mmc_config cfg; 28 struct mmc mmc; 29 }; 30 31 struct rockchip_emmc_phy { 32 u32 emmcphy_con[7]; 33 u32 reserved; 34 u32 emmcphy_status; 35 }; 36 37 struct rockchip_sdhc { 38 struct sdhci_host host; 39 void *base; 40 struct rockchip_emmc_phy *phy; 41 }; 42 43 #define PHYCTRL_CALDONE_MASK 0x1 44 #define PHYCTRL_CALDONE_SHIFT 0x6 45 #define PHYCTRL_CALDONE_DONE 0x1 46 47 #define PHYCTRL_DLLRDY_MASK 0x1 48 #define PHYCTRL_DLLRDY_SHIFT 0x5 49 #define PHYCTRL_DLLRDY_DONE 0x1 50 51 #define PHYCTRL_FREQSEL_200M 0x0 52 #define PHYCTRL_FREQSEL_50M 0x1 53 #define PHYCTRL_FREQSEL_100M 0x2 54 #define PHYCTRL_FREQSEL_150M 0x3 55 56 #define KHz (1000) 57 #define MHz (1000 * KHz) 58 59 static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock) 60 { 61 u32 caldone, dllrdy, freqsel; 62 uint start; 63 64 writel(RK_CLRSETBITS(7 << 4, 0), &phy->emmcphy_con[6]); 65 writel(RK_CLRSETBITS(1 << 11, 1 << 11), &phy->emmcphy_con[0]); 66 writel(RK_CLRSETBITS(0xf << 7, 4 << 7), &phy->emmcphy_con[0]); 67 68 /* 69 * According to the user manual, calpad calibration 70 * cycle takes more than 2us without the minimal recommended 71 * value, so we may need a little margin here 72 */ 73 udelay(3); 74 writel(RK_CLRSETBITS(1, 1), &phy->emmcphy_con[6]); 75 76 /* 77 * According to the user manual, it asks driver to 78 * wait 5us for calpad busy trimming 79 */ 80 udelay(5); 81 caldone = readl(&phy->emmcphy_status); 82 caldone = (caldone >> PHYCTRL_CALDONE_SHIFT) & PHYCTRL_CALDONE_MASK; 83 if (caldone != PHYCTRL_CALDONE_DONE) { 84 debug("%s: caldone timeout.\n", __func__); 85 return; 86 } 87 88 /* Set the frequency of the DLL operation */ 89 if (clock < 75 * MHz) 90 freqsel = PHYCTRL_FREQSEL_50M; 91 else if (clock < 125 * MHz) 92 freqsel = PHYCTRL_FREQSEL_100M; 93 else if (clock < 175 * MHz) 94 freqsel = PHYCTRL_FREQSEL_150M; 95 else 96 freqsel = PHYCTRL_FREQSEL_200M; 97 98 /* Set the frequency of the DLL operation */ 99 writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]); 100 writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]); 101 102 start = get_timer(0); 103 104 do { 105 udelay(1); 106 dllrdy = readl(&phy->emmcphy_status); 107 dllrdy = (dllrdy >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK; 108 if (dllrdy == PHYCTRL_DLLRDY_DONE) 109 break; 110 } while (get_timer(start) < 50000); 111 112 if (dllrdy != PHYCTRL_DLLRDY_DONE) 113 debug("%s: dllrdy timeout.\n", __func__); 114 } 115 116 static void rk3399_emmc_phy_power_off(struct rockchip_emmc_phy *phy) 117 { 118 writel(RK_CLRSETBITS(1, 0), &phy->emmcphy_con[6]); 119 writel(RK_CLRSETBITS(1 << 1, 0), &phy->emmcphy_con[6]); 120 } 121 122 static int arasan_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) 123 { 124 struct rockchip_sdhc *priv = 125 container_of(host, struct rockchip_sdhc, host); 126 int cycle_phy = host->clock != clock && 127 clock > EMMC_MIN_FREQ; 128 129 if (cycle_phy) 130 rk3399_emmc_phy_power_off(priv->phy); 131 132 sdhci_set_clock(host, clock); 133 134 if (cycle_phy) 135 rk3399_emmc_phy_power_on(priv->phy, clock); 136 137 return 0; 138 } 139 140 static struct sdhci_ops arasan_sdhci_ops = { 141 .set_clock = arasan_sdhci_set_clock, 142 }; 143 144 static int arasan_get_phy(struct udevice *dev) 145 { 146 struct rockchip_sdhc *priv = dev_get_priv(dev); 147 148 #if CONFIG_IS_ENABLED(OF_PLATDATA) 149 priv->phy = (struct rockchip_emmc_phy *)0xff77f780; 150 #else 151 int phy_node, grf_node; 152 fdt_addr_t grf_base, grf_phy_offset; 153 154 phy_node = fdtdec_lookup_phandle(gd->fdt_blob, 155 dev_of_offset(dev), "phys"); 156 if (phy_node <= 0) { 157 debug("Not found emmc phy device\n"); 158 return -ENODEV; 159 } 160 161 grf_node = fdt_parent_offset(gd->fdt_blob, phy_node); 162 if (grf_node <= 0) { 163 debug("Not found usb phy device\n"); 164 return -ENODEV; 165 } 166 167 grf_base = fdtdec_get_addr(gd->fdt_blob, grf_node, "reg"); 168 grf_phy_offset = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, 169 grf_node, phy_node, "reg", 0, NULL, false); 170 171 priv->phy = (struct rockchip_emmc_phy *)(grf_base + grf_phy_offset); 172 #endif 173 return 0; 174 } 175 176 static int arasan_sdhci_probe(struct udevice *dev) 177 { 178 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 179 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 180 struct rockchip_sdhc *prv = dev_get_priv(dev); 181 struct sdhci_host *host = &prv->host; 182 int max_frequency, ret; 183 struct clk clk; 184 185 #if CONFIG_IS_ENABLED(OF_PLATDATA) 186 struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat; 187 188 host->name = dev->name; 189 host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]); 190 host->host_caps |= MMC_MODE_8BIT; 191 max_frequency = dtplat->max_frequency; 192 ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk); 193 #else 194 max_frequency = dev_read_u32_default(dev, "max-frequency", 0); 195 switch (dev_read_u32_default(dev, "bus-width", 4)) { 196 case 8: 197 host->host_caps |= MMC_MODE_8BIT; 198 break; 199 case 4: 200 host->host_caps |= MMC_MODE_4BIT; 201 break; 202 case 1: 203 break; 204 default: 205 printf("Invalid \"bus-width\" value\n"); 206 return -EINVAL; 207 } 208 ret = clk_get_by_index(dev, 0, &clk); 209 #endif 210 if (!ret) { 211 ret = clk_set_rate(&clk, max_frequency); 212 if (IS_ERR_VALUE(ret)) 213 printf("%s clk set rate fail!\n", __func__); 214 } else { 215 printf("%s fail to get clk\n", __func__); 216 } 217 218 ret = arasan_get_phy(dev); 219 if (ret) 220 return ret; 221 222 host->ops = &arasan_sdhci_ops; 223 224 host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; 225 host->max_clk = max_frequency; 226 227 ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ); 228 229 host->mmc = &plat->mmc; 230 if (ret) 231 return ret; 232 host->mmc->priv = &prv->host; 233 host->mmc->dev = dev; 234 upriv->mmc = host->mmc; 235 236 return sdhci_probe(dev); 237 } 238 239 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) 240 { 241 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 242 struct sdhci_host *host = dev_get_priv(dev); 243 244 host->name = dev->name; 245 host->ioaddr = dev_read_addr_ptr(dev); 246 #endif 247 248 return 0; 249 } 250 251 static int rockchip_sdhci_bind(struct udevice *dev) 252 { 253 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 254 255 return sdhci_bind(dev, &plat->mmc, &plat->cfg); 256 } 257 258 static const struct udevice_id arasan_sdhci_ids[] = { 259 { .compatible = "arasan,sdhci-5.1" }, 260 { } 261 }; 262 263 U_BOOT_DRIVER(arasan_sdhci_drv) = { 264 .name = "rockchip_rk3399_sdhci_5_1", 265 .id = UCLASS_MMC, 266 .of_match = arasan_sdhci_ids, 267 .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata, 268 .ops = &sdhci_ops, 269 .bind = rockchip_sdhci_bind, 270 .probe = arasan_sdhci_probe, 271 .priv_auto_alloc_size = sizeof(struct rockchip_sdhc), 272 .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat), 273 }; 274