1 /* 2 * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <clk.h> 9 #include <fdtdec.h> 10 #include <mmc.h> 11 #include <dm.h> 12 #include <linux/compat.h> 13 #include <linux/dma-direction.h> 14 #include <linux/io.h> 15 #include <linux/sizes.h> 16 #include <power/regulator.h> 17 #include <asm/unaligned.h> 18 19 #include "tmio-common.h" 20 21 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 22 23 /* SCC registers */ 24 #define RENESAS_SDHI_SCC_DTCNTL 0x800 25 #define RENESAS_SDHI_SCC_DTCNTL_TAPEN BIT(0) 26 #define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT 16 27 #define RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK 0xff 28 #define RENESAS_SDHI_SCC_TAPSET 0x804 29 #define RENESAS_SDHI_SCC_DT2FF 0x808 30 #define RENESAS_SDHI_SCC_CKSEL 0x80c 31 #define RENESAS_SDHI_SCC_CKSEL_DTSEL BIT(0) 32 #define RENESAS_SDHI_SCC_RVSCNTL 0x810 33 #define RENESAS_SDHI_SCC_RVSCNTL_RVSEN BIT(0) 34 #define RENESAS_SDHI_SCC_RVSREQ 0x814 35 #define RENESAS_SDHI_SCC_RVSREQ_RVSERR BIT(2) 36 #define RENESAS_SDHI_SCC_SMPCMP 0x818 37 #define RENESAS_SDHI_SCC_TMPPORT2 0x81c 38 39 #define RENESAS_SDHI_MAX_TAP 3 40 41 static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv) 42 { 43 u32 reg; 44 45 /* Initialize SCC */ 46 tmio_sd_writel(priv, 0, TMIO_SD_INFO1); 47 48 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 49 reg &= ~TMIO_SD_CLKCTL_SCLKEN; 50 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 51 52 /* Set sampling clock selection range */ 53 tmio_sd_writel(priv, 0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT, 54 RENESAS_SDHI_SCC_DTCNTL); 55 56 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL); 57 reg |= RENESAS_SDHI_SCC_DTCNTL_TAPEN; 58 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_DTCNTL); 59 60 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); 61 reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL; 62 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); 63 64 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 65 reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 66 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 67 68 tmio_sd_writel(priv, 0x300 /* scc_tappos */, 69 RENESAS_SDHI_SCC_DT2FF); 70 71 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 72 reg |= TMIO_SD_CLKCTL_SCLKEN; 73 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 74 75 /* Read TAPNUM */ 76 return (tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL) >> 77 RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) & 78 RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK; 79 } 80 81 static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) 82 { 83 u32 reg; 84 85 /* Reset SCC */ 86 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 87 reg &= ~TMIO_SD_CLKCTL_SCLKEN; 88 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 89 90 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); 91 reg &= ~RENESAS_SDHI_SCC_CKSEL_DTSEL; 92 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); 93 94 reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); 95 reg |= TMIO_SD_CLKCTL_SCLKEN; 96 tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); 97 98 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 99 reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 100 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 101 102 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 103 reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 104 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 105 } 106 107 static void renesas_sdhi_prepare_tuning(struct tmio_sd_priv *priv, 108 unsigned long tap) 109 { 110 /* Set sampling clock position */ 111 tmio_sd_writel(priv, tap, RENESAS_SDHI_SCC_TAPSET); 112 } 113 114 static unsigned int renesas_sdhi_compare_scc_data(struct tmio_sd_priv *priv) 115 { 116 /* Get comparison of sampling data */ 117 return tmio_sd_readl(priv, RENESAS_SDHI_SCC_SMPCMP); 118 } 119 120 static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv, 121 unsigned int tap_num, unsigned int taps, 122 unsigned int smpcmp) 123 { 124 unsigned long tap_cnt; /* counter of tuning success */ 125 unsigned long tap_set; /* tap position */ 126 unsigned long tap_start;/* start position of tuning success */ 127 unsigned long tap_end; /* end position of tuning success */ 128 unsigned long ntap; /* temporary counter of tuning success */ 129 unsigned long match_cnt;/* counter of matching data */ 130 unsigned long i; 131 bool select = false; 132 u32 reg; 133 134 /* Clear SCC_RVSREQ */ 135 tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ); 136 137 /* Merge the results */ 138 for (i = 0; i < tap_num * 2; i++) { 139 if (!(taps & BIT(i))) { 140 taps &= ~BIT(i % tap_num); 141 taps &= ~BIT((i % tap_num) + tap_num); 142 } 143 if (!(smpcmp & BIT(i))) { 144 smpcmp &= ~BIT(i % tap_num); 145 smpcmp &= ~BIT((i % tap_num) + tap_num); 146 } 147 } 148 149 /* 150 * Find the longest consecutive run of successful probes. If that 151 * is more than RENESAS_SDHI_MAX_TAP probes long then use the 152 * center index as the tap. 153 */ 154 tap_cnt = 0; 155 ntap = 0; 156 tap_start = 0; 157 tap_end = 0; 158 for (i = 0; i < tap_num * 2; i++) { 159 if (taps & BIT(i)) 160 ntap++; 161 else { 162 if (ntap > tap_cnt) { 163 tap_start = i - ntap; 164 tap_end = i - 1; 165 tap_cnt = ntap; 166 } 167 ntap = 0; 168 } 169 } 170 171 if (ntap > tap_cnt) { 172 tap_start = i - ntap; 173 tap_end = i - 1; 174 tap_cnt = ntap; 175 } 176 177 /* 178 * If all of the TAP is OK, the sampling clock position is selected by 179 * identifying the change point of data. 180 */ 181 if (tap_cnt == tap_num * 2) { 182 match_cnt = 0; 183 ntap = 0; 184 tap_start = 0; 185 tap_end = 0; 186 for (i = 0; i < tap_num * 2; i++) { 187 if (smpcmp & BIT(i)) 188 ntap++; 189 else { 190 if (ntap > match_cnt) { 191 tap_start = i - ntap; 192 tap_end = i - 1; 193 match_cnt = ntap; 194 } 195 ntap = 0; 196 } 197 } 198 if (ntap > match_cnt) { 199 tap_start = i - ntap; 200 tap_end = i - 1; 201 match_cnt = ntap; 202 } 203 if (match_cnt) 204 select = true; 205 } else if (tap_cnt >= RENESAS_SDHI_MAX_TAP) 206 select = true; 207 208 if (select) 209 tap_set = ((tap_start + tap_end) / 2) % tap_num; 210 else 211 return -EIO; 212 213 /* Set SCC */ 214 tmio_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET); 215 216 /* Enable auto re-tuning */ 217 reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); 218 reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN; 219 tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); 220 221 return 0; 222 } 223 224 int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) 225 { 226 struct tmio_sd_priv *priv = dev_get_priv(dev); 227 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 228 struct mmc *mmc = upriv->mmc; 229 unsigned int tap_num; 230 unsigned int taps = 0, smpcmp = 0; 231 int i, ret = 0; 232 u32 caps; 233 234 /* Only supported on Renesas RCar */ 235 if (!(priv->caps & TMIO_SD_CAP_RCAR_UHS)) 236 return -EINVAL; 237 238 /* clock tuning is not needed for upto 52MHz */ 239 if (!((mmc->selected_mode == MMC_HS_200) || 240 (mmc->selected_mode == UHS_SDR104) || 241 (mmc->selected_mode == UHS_SDR50))) 242 return 0; 243 244 tap_num = renesas_sdhi_init_tuning(priv); 245 if (!tap_num) 246 /* Tuning is not supported */ 247 goto out; 248 249 if (tap_num * 2 >= sizeof(taps) * 8) { 250 dev_err(dev, 251 "Too many taps, skipping tuning. Please consider updating size of taps field of tmio_mmc_host\n"); 252 goto out; 253 } 254 255 /* Issue CMD19 twice for each tap */ 256 for (i = 0; i < 2 * tap_num; i++) { 257 renesas_sdhi_prepare_tuning(priv, i % tap_num); 258 259 /* Force PIO for the tuning */ 260 caps = priv->caps; 261 priv->caps &= ~TMIO_SD_CAP_DMA_INTERNAL; 262 263 ret = mmc_send_tuning(mmc, opcode, NULL); 264 265 priv->caps = caps; 266 267 if (ret == 0) 268 taps |= BIT(i); 269 270 ret = renesas_sdhi_compare_scc_data(priv); 271 if (ret == 0) 272 smpcmp |= BIT(i); 273 274 mdelay(1); 275 } 276 277 ret = renesas_sdhi_select_tuning(priv, tap_num, taps, smpcmp); 278 279 out: 280 if (ret < 0) { 281 dev_warn(dev, "Tuning procedure failed\n"); 282 renesas_sdhi_reset_tuning(priv); 283 } 284 285 return ret; 286 } 287 #endif 288 289 static int renesas_sdhi_set_ios(struct udevice *dev) 290 { 291 int ret = tmio_sd_set_ios(dev); 292 293 mdelay(10); 294 295 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 296 struct tmio_sd_priv *priv = dev_get_priv(dev); 297 298 renesas_sdhi_reset_tuning(priv); 299 #endif 300 301 return ret; 302 } 303 304 static const struct dm_mmc_ops renesas_sdhi_ops = { 305 .send_cmd = tmio_sd_send_cmd, 306 .set_ios = renesas_sdhi_set_ios, 307 .get_cd = tmio_sd_get_cd, 308 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 309 .execute_tuning = renesas_sdhi_execute_tuning, 310 #endif 311 }; 312 313 #define RENESAS_GEN2_QUIRKS TMIO_SD_CAP_RCAR_GEN2 314 #define RENESAS_GEN3_QUIRKS \ 315 TMIO_SD_CAP_64BIT | TMIO_SD_CAP_RCAR_GEN3 | TMIO_SD_CAP_RCAR_UHS 316 317 static const struct udevice_id renesas_sdhi_match[] = { 318 { .compatible = "renesas,sdhi-r8a7790", .data = RENESAS_GEN2_QUIRKS }, 319 { .compatible = "renesas,sdhi-r8a7791", .data = RENESAS_GEN2_QUIRKS }, 320 { .compatible = "renesas,sdhi-r8a7792", .data = RENESAS_GEN2_QUIRKS }, 321 { .compatible = "renesas,sdhi-r8a7793", .data = RENESAS_GEN2_QUIRKS }, 322 { .compatible = "renesas,sdhi-r8a7794", .data = RENESAS_GEN2_QUIRKS }, 323 { .compatible = "renesas,sdhi-r8a7795", .data = RENESAS_GEN3_QUIRKS }, 324 { .compatible = "renesas,sdhi-r8a7796", .data = RENESAS_GEN3_QUIRKS }, 325 { .compatible = "renesas,sdhi-r8a77965", .data = RENESAS_GEN3_QUIRKS }, 326 { .compatible = "renesas,sdhi-r8a77970", .data = RENESAS_GEN3_QUIRKS }, 327 { .compatible = "renesas,sdhi-r8a77995", .data = RENESAS_GEN3_QUIRKS }, 328 { /* sentinel */ } 329 }; 330 331 static int renesas_sdhi_probe(struct udevice *dev) 332 { 333 struct tmio_sd_priv *priv = dev_get_priv(dev); 334 u32 quirks = dev_get_driver_data(dev); 335 struct fdt_resource reg_res; 336 struct clk clk; 337 DECLARE_GLOBAL_DATA_PTR; 338 int ret; 339 340 if (quirks == RENESAS_GEN2_QUIRKS) { 341 ret = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), 342 "reg", 0, ®_res); 343 if (ret < 0) { 344 dev_err(dev, "\"reg\" resource not found, ret=%i\n", 345 ret); 346 return ret; 347 } 348 349 if (fdt_resource_size(®_res) == 0x100) 350 quirks |= TMIO_SD_CAP_16BIT; 351 } 352 353 ret = clk_get_by_index(dev, 0, &clk); 354 if (ret < 0) { 355 dev_err(dev, "failed to get host clock\n"); 356 return ret; 357 } 358 359 /* set to max rate */ 360 priv->mclk = clk_set_rate(&clk, ULONG_MAX); 361 if (IS_ERR_VALUE(priv->mclk)) { 362 dev_err(dev, "failed to set rate for host clock\n"); 363 clk_free(&clk); 364 return priv->mclk; 365 } 366 367 ret = clk_enable(&clk); 368 clk_free(&clk); 369 if (ret) { 370 dev_err(dev, "failed to enable host clock\n"); 371 return ret; 372 } 373 374 ret = tmio_sd_probe(dev, quirks); 375 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) 376 if (!ret) 377 renesas_sdhi_reset_tuning(dev_get_priv(dev)); 378 #endif 379 return ret; 380 } 381 382 U_BOOT_DRIVER(renesas_sdhi) = { 383 .name = "renesas-sdhi", 384 .id = UCLASS_MMC, 385 .of_match = renesas_sdhi_match, 386 .bind = tmio_sd_bind, 387 .probe = renesas_sdhi_probe, 388 .priv_auto_alloc_size = sizeof(struct tmio_sd_priv), 389 .platdata_auto_alloc_size = sizeof(struct tmio_sd_plat), 390 .ops = &renesas_sdhi_ops, 391 }; 392