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