1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2021 Rockchip Electronics Co., Ltd. 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <syscon.h> 9 #include <asm/io.h> 10 #include <dm/of_access.h> 11 #include <asm/arch/clock.h> 12 #include <asm/arch/rockchip_smccc.h> 13 #include <asm/arch/sdram.h> 14 #include <asm/arch/sdram_common.h> 15 16 #define DDR2_PARAMS_PHANDLE_NAME "ddr2_params" 17 #define DDR3_PARAMS_PHANDLE_NAME "ddr3_params" 18 #define DDR4_PARAMS_PHANDLE_NAME "ddr4_params" 19 #define LPDDR2_PARAMS_PHANDLE_NAME "lpddr2_params" 20 #define LPDDR3_PARAMS_PHANDLE_NAME "lpddr3_params" 21 #define LPDDR4_PARAMS_PHANDLE_NAME "lpddr4_params" 22 #define LPDDR4X_PARAMS_PHANDLE_NAME "lpddr4x_params" 23 #define LPDDR5_PARAMS_PHANDLE_NAME "lpddr5_params" 24 25 #define DTS_PAR_OFFSET (4096) 26 #define PARAMS_INVALID_VAL (0xff00aa99) 27 #define PARAMS_IGNORE_THIS (0) 28 29 #define PMUGRF_OS_REG(n) (0x200 + (n) * 4) 30 31 struct rk3326_ddr_de_skew_setting { 32 unsigned int ca_de_skew[30]; 33 unsigned int cs0_de_skew[84]; 34 unsigned int cs1_de_skew[84]; 35 }; 36 37 /* there is a matching relationship, modify it with caution */ 38 static char *dmc_fsp_params[] = { 39 "debug_print_level", 40 "phy_de_skew_en", 41 /* if need, add parameter after */ 42 }; 43 44 /* there is a matching relationship, modify it with caution */ 45 static char *ddr_params_v1[] = { 46 /* version information V1.00 */ 47 "version", 48 "expanded_version", 49 "reserved", 50 /* freq info, freq_0 is final frequency, unit: MHz */ 51 "freq_0", 52 "freq_1", 53 "freq_2", 54 "freq_3", 55 "freq_4", 56 "freq_5", 57 /* power save setting */ 58 "pd_idle", 59 "sr_idle", 60 "sr_mc_gate_idle", 61 "srpd_lite_idle", 62 "standby_idle", 63 "pd_dis_freq", 64 "sr_dis_freq", 65 "dram_dll_dis_freq", 66 "phy_dll_dis_freq", 67 /* drv when odt on */ 68 "phy_dq_drv_odten", 69 "phy_ca_drv_odten", 70 "phy_clk_drv_odten", 71 "dram_dq_drv_odten", 72 /* drv when odt off */ 73 "phy_dq_drv_odtoff", 74 "phy_ca_drv_odtoff", 75 "phy_clk_drv_odtoff", 76 "dram_dq_drv_odtoff", 77 /* odt info */ 78 "dram_odt", 79 "phy_odt", 80 "phy_odt_puup_en", 81 "phy_odt_pudn_en", 82 /* odt enable freq */ 83 "dram_dq_odt_en_freq", 84 "phy_odt_en_freq", 85 /* slew rate when odt enable */ 86 "phy_dq_sr_odten", 87 "phy_ca_sr_odten", 88 "phy_clk_sr_odten", 89 /* slew rate when odt disable */ 90 "phy_dq_sr_odtoff", 91 "phy_ca_sr_odtoff", 92 "phy_clk_sr_odtoff", 93 /* ssmod setting*/ 94 "ssmod_downspread", 95 "ssmod_div", 96 "ssmod_spread", 97 /* 2T mode */ 98 "mode_2t", 99 /* speed bin */ 100 "speed_bin", 101 /* dram extended temperature support */ 102 "dram_ext_temp", 103 /* byte map */ 104 "byte_map", 105 /* dq map */ 106 "dq_map_cs0_dq_l", 107 "dq_map_cs0_dq_h", 108 "dq_map_cs1_dq_l", 109 "dq_map_cs1_dq_h", 110 /* for LPDDR4 and LPDDR4X */ 111 /* odt info */ 112 "lp4_ca_odt", 113 "lp4_drv_pu_cal_odten", 114 "lp4_drv_pu_cal_odtoff", 115 "phy_lp4_drv_pulldown_en_odten", 116 "phy_lp4_drv_pulldown_en_odtoff", 117 /* odt enable freq */ 118 "lp4_ca_odt_en_freq", 119 /* lp4 cs drv info and ca odt info */ 120 "phy_lp4_cs_drv_odten", 121 "phy_lp4_cs_drv_odtoff", 122 "lp4_odte_ck_en", 123 "lp4_odte_cs_en", 124 "lp4_odtd_ca_en", 125 /* lp4 vref info when odt enable */ 126 "phy_lp4_dq_vref_odten", 127 "lp4_dq_vref_odten", 128 "lp4_ca_vref_odten", 129 /* lp4 vref info when odt disable */ 130 "phy_lp4_dq_vref_odtoff", 131 "lp4_dq_vref_odtoff", 132 "lp4_ca_vref_odtoff", 133 /* if need, add parameter after and change the minor version. */ 134 }; 135 136 /* the expanded version V1.00 add skew info */ 137 static char *ddr_params_exp_v1[] = { 138 "ddr3a1_ddr4a9_de-skew", 139 "ddr3a0_ddr4a10_de-skew", 140 "ddr3a3_ddr4a6_de-skew", 141 "ddr3a2_ddr4a4_de-skew", 142 "ddr3a5_ddr4a8_de-skew", 143 "ddr3a4_ddr4a5_de-skew", 144 "ddr3a7_ddr4a11_de-skew", 145 "ddr3a6_ddr4a7_de-skew", 146 "ddr3a9_ddr4a0_de-skew", 147 "ddr3a8_ddr4a13_de-skew", 148 "ddr3a11_ddr4a3_de-skew", 149 "ddr3a10_ddr4cs0_de-skew", 150 "ddr3a13_ddr4a2_de-skew", 151 "ddr3a12_ddr4ba1_de-skew", 152 "ddr3a15_ddr4odt0_de-skew", 153 "ddr3a14_ddr4a1_de-skew", 154 "ddr3ba1_ddr4a15_de-skew", 155 "ddr3ba0_ddr4bg0_de-skew", 156 "ddr3ras_ddr4cke_de-skew", 157 "ddr3ba2_ddr4ba0_de-skew", 158 "ddr3we_ddr4bg1_de-skew", 159 "ddr3cas_ddr4a12_de-skew", 160 "ddr3ckn_ddr4ckn_de-skew", 161 "ddr3ckp_ddr4ckp_de-skew", 162 "ddr3cke_ddr4a16_de-skew", 163 "ddr3odt0_ddr4a14_de-skew", 164 "ddr3cs0_ddr4act_de-skew", 165 "ddr3reset_ddr4reset_de-skew", 166 "ddr3cs1_ddr4cs1_de-skew", 167 "ddr3odt1_ddr4odt1_de-skew", 168 169 "cs0_dm0_rx_de-skew", 170 "cs0_dm0_tx_de-skew", 171 "cs0_dq0_rx_de-skew", 172 "cs0_dq0_tx_de-skew", 173 "cs0_dq1_rx_de-skew", 174 "cs0_dq1_tx_de-skew", 175 "cs0_dq2_rx_de-skew", 176 "cs0_dq2_tx_de-skew", 177 "cs0_dq3_rx_de-skew", 178 "cs0_dq3_tx_de-skew", 179 "cs0_dq4_rx_de-skew", 180 "cs0_dq4_tx_de-skew", 181 "cs0_dq5_rx_de-skew", 182 "cs0_dq5_tx_de-skew", 183 "cs0_dq6_rx_de-skew", 184 "cs0_dq6_tx_de-skew", 185 "cs0_dq7_rx_de-skew", 186 "cs0_dq7_tx_de-skew", 187 "cs0_dqs0_rx_de-skew", 188 "cs0_dqs0p_tx_de-skew", 189 "cs0_dqs0n_tx_de-skew", 190 191 "cs0_dm1_rx_de-skew", 192 "cs0_dm1_tx_de-skew", 193 "cs0_dq8_rx_de-skew", 194 "cs0_dq8_tx_de-skew", 195 "cs0_dq9_rx_de-skew", 196 "cs0_dq9_tx_de-skew", 197 "cs0_dq10_rx_de-skew", 198 "cs0_dq10_tx_de-skew", 199 "cs0_dq11_rx_de-skew", 200 "cs0_dq11_tx_de-skew", 201 "cs0_dq12_rx_de-skew", 202 "cs0_dq12_tx_de-skew", 203 "cs0_dq13_rx_de-skew", 204 "cs0_dq13_tx_de-skew", 205 "cs0_dq14_rx_de-skew", 206 "cs0_dq14_tx_de-skew", 207 "cs0_dq15_rx_de-skew", 208 "cs0_dq15_tx_de-skew", 209 "cs0_dqs1_rx_de-skew", 210 "cs0_dqs1p_tx_de-skew", 211 "cs0_dqs1n_tx_de-skew", 212 213 "cs0_dm2_rx_de-skew", 214 "cs0_dm2_tx_de-skew", 215 "cs0_dq16_rx_de-skew", 216 "cs0_dq16_tx_de-skew", 217 "cs0_dq17_rx_de-skew", 218 "cs0_dq17_tx_de-skew", 219 "cs0_dq18_rx_de-skew", 220 "cs0_dq18_tx_de-skew", 221 "cs0_dq19_rx_de-skew", 222 "cs0_dq19_tx_de-skew", 223 "cs0_dq20_rx_de-skew", 224 "cs0_dq20_tx_de-skew", 225 "cs0_dq21_rx_de-skew", 226 "cs0_dq21_tx_de-skew", 227 "cs0_dq22_rx_de-skew", 228 "cs0_dq22_tx_de-skew", 229 "cs0_dq23_rx_de-skew", 230 "cs0_dq23_tx_de-skew", 231 "cs0_dqs2_rx_de-skew", 232 "cs0_dqs2p_tx_de-skew", 233 "cs0_dqs2n_tx_de-skew", 234 235 "cs0_dm3_rx_de-skew", 236 "cs0_dm3_tx_de-skew", 237 "cs0_dq24_rx_de-skew", 238 "cs0_dq24_tx_de-skew", 239 "cs0_dq25_rx_de-skew", 240 "cs0_dq25_tx_de-skew", 241 "cs0_dq26_rx_de-skew", 242 "cs0_dq26_tx_de-skew", 243 "cs0_dq27_rx_de-skew", 244 "cs0_dq27_tx_de-skew", 245 "cs0_dq28_rx_de-skew", 246 "cs0_dq28_tx_de-skew", 247 "cs0_dq29_rx_de-skew", 248 "cs0_dq29_tx_de-skew", 249 "cs0_dq30_rx_de-skew", 250 "cs0_dq30_tx_de-skew", 251 "cs0_dq31_rx_de-skew", 252 "cs0_dq31_tx_de-skew", 253 "cs0_dqs3_rx_de-skew", 254 "cs0_dqs3p_tx_de-skew", 255 "cs0_dqs3n_tx_de-skew", 256 257 "cs1_dm0_rx_de-skew", 258 "cs1_dm0_tx_de-skew", 259 "cs1_dq0_rx_de-skew", 260 "cs1_dq0_tx_de-skew", 261 "cs1_dq1_rx_de-skew", 262 "cs1_dq1_tx_de-skew", 263 "cs1_dq2_rx_de-skew", 264 "cs1_dq2_tx_de-skew", 265 "cs1_dq3_rx_de-skew", 266 "cs1_dq3_tx_de-skew", 267 "cs1_dq4_rx_de-skew", 268 "cs1_dq4_tx_de-skew", 269 "cs1_dq5_rx_de-skew", 270 "cs1_dq5_tx_de-skew", 271 "cs1_dq6_rx_de-skew", 272 "cs1_dq6_tx_de-skew", 273 "cs1_dq7_rx_de-skew", 274 "cs1_dq7_tx_de-skew", 275 "cs1_dqs0_rx_de-skew", 276 "cs1_dqs0p_tx_de-skew", 277 "cs1_dqs0n_tx_de-skew", 278 279 "cs1_dm1_rx_de-skew", 280 "cs1_dm1_tx_de-skew", 281 "cs1_dq8_rx_de-skew", 282 "cs1_dq8_tx_de-skew", 283 "cs1_dq9_rx_de-skew", 284 "cs1_dq9_tx_de-skew", 285 "cs1_dq10_rx_de-skew", 286 "cs1_dq10_tx_de-skew", 287 "cs1_dq11_rx_de-skew", 288 "cs1_dq11_tx_de-skew", 289 "cs1_dq12_rx_de-skew", 290 "cs1_dq12_tx_de-skew", 291 "cs1_dq13_rx_de-skew", 292 "cs1_dq13_tx_de-skew", 293 "cs1_dq14_rx_de-skew", 294 "cs1_dq14_tx_de-skew", 295 "cs1_dq15_rx_de-skew", 296 "cs1_dq15_tx_de-skew", 297 "cs1_dqs1_rx_de-skew", 298 "cs1_dqs1p_tx_de-skew", 299 "cs1_dqs1n_tx_de-skew", 300 301 "cs1_dm2_rx_de-skew", 302 "cs1_dm2_tx_de-skew", 303 "cs1_dq16_rx_de-skew", 304 "cs1_dq16_tx_de-skew", 305 "cs1_dq17_rx_de-skew", 306 "cs1_dq17_tx_de-skew", 307 "cs1_dq18_rx_de-skew", 308 "cs1_dq18_tx_de-skew", 309 "cs1_dq19_rx_de-skew", 310 "cs1_dq19_tx_de-skew", 311 "cs1_dq20_rx_de-skew", 312 "cs1_dq20_tx_de-skew", 313 "cs1_dq21_rx_de-skew", 314 "cs1_dq21_tx_de-skew", 315 "cs1_dq22_rx_de-skew", 316 "cs1_dq22_tx_de-skew", 317 "cs1_dq23_rx_de-skew", 318 "cs1_dq23_tx_de-skew", 319 "cs1_dqs2_rx_de-skew", 320 "cs1_dqs2p_tx_de-skew", 321 "cs1_dqs2n_tx_de-skew", 322 323 "cs1_dm3_rx_de-skew", 324 "cs1_dm3_tx_de-skew", 325 "cs1_dq24_rx_de-skew", 326 "cs1_dq24_tx_de-skew", 327 "cs1_dq25_rx_de-skew", 328 "cs1_dq25_tx_de-skew", 329 "cs1_dq26_rx_de-skew", 330 "cs1_dq26_tx_de-skew", 331 "cs1_dq27_rx_de-skew", 332 "cs1_dq27_tx_de-skew", 333 "cs1_dq28_rx_de-skew", 334 "cs1_dq28_tx_de-skew", 335 "cs1_dq29_rx_de-skew", 336 "cs1_dq29_tx_de-skew", 337 "cs1_dq30_rx_de-skew", 338 "cs1_dq30_tx_de-skew", 339 "cs1_dq31_rx_de-skew", 340 "cs1_dq31_tx_de-skew", 341 "cs1_dqs3_rx_de-skew", 342 "cs1_dqs3p_tx_de-skew", 343 "cs1_dqs3n_tx_de-skew", 344 }; 345 346 static int get_atf_version(void) 347 { 348 struct arm_smccc_res res; 349 350 res = sip_smc_dram(0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION); 351 352 if (res.a0) 353 return -ENOMEM; 354 else 355 return res.a1; 356 } 357 358 static int dmc_fsp_probe(struct udevice *dev) 359 { 360 struct device_node *np_params, *np_tim; 361 struct arm_smccc_res res; 362 void *pmugrf_base; 363 int *p = NULL; 364 char *phandle_name = NULL; 365 char **ddr_params; 366 char **ddr_params_exp; 367 int ddr_params_version; 368 int expanded_version; 369 u32 dram_type, os_reg2_val, os_reg3_val; 370 u32 phy_de_skew_en; 371 u32 i = 0, count = 0, size = 0, count_exp = 0; 372 ulong atf_version_limit; 373 374 atf_version_limit = dev_get_driver_data(dev); 375 if (get_atf_version() < atf_version_limit) { 376 printf("%s: trusted firmware need to update or is invalid!\n", __func__); 377 printf("%s: current ATF version 0x%x, required version 0x%lx\n", 378 __func__, get_atf_version(), atf_version_limit); 379 return 0; 380 } 381 382 pmugrf_base = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); 383 os_reg2_val = readl(pmugrf_base + PMUGRF_OS_REG(2)); 384 os_reg3_val = readl(pmugrf_base + PMUGRF_OS_REG(3)); 385 dram_type = SYS_REG_DEC_DDRTYPE_V3(os_reg2_val, os_reg3_val); 386 387 if (dram_type == DDR2) 388 phandle_name = DDR2_PARAMS_PHANDLE_NAME; 389 else if (dram_type == DDR3) 390 phandle_name = DDR3_PARAMS_PHANDLE_NAME; 391 else if (dram_type == DDR4) 392 phandle_name = DDR4_PARAMS_PHANDLE_NAME; 393 else if (dram_type == LPDDR2) 394 phandle_name = LPDDR2_PARAMS_PHANDLE_NAME; 395 else if (dram_type == LPDDR3) 396 phandle_name = LPDDR3_PARAMS_PHANDLE_NAME; 397 else if (dram_type == LPDDR4) 398 phandle_name = LPDDR4_PARAMS_PHANDLE_NAME; 399 else if (dram_type == LPDDR4X) 400 phandle_name = LPDDR4X_PARAMS_PHANDLE_NAME; 401 else if (dram_type == LPDDR5) 402 phandle_name = LPDDR5_PARAMS_PHANDLE_NAME; 403 else 404 printf("%s: dram_type unsupported\n", __func__); 405 406 np_params = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0); 407 if (!np_params) { 408 printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name); 409 return -EINVAL; 410 } 411 412 ddr_params_version = ofnode_read_u32_default(np_to_ofnode(np_params), "version", -1); 413 if (ddr_params_version < 0) { 414 printf("%s: get ddr_params_version error\n", __func__); 415 return -EINVAL; 416 } 417 418 if ((ddr_params_version & 0xff00) == 0x100 && 419 (ddr_params_version & 0xffff) <= 0x101) { 420 count = ARRAY_SIZE(ddr_params_v1); 421 ddr_params = ddr_params_v1; 422 } else { 423 printf("%s: ddr_params_version=0x%x unsupported\n", __func__, ddr_params_version); 424 return -EINVAL; 425 } 426 427 expanded_version = ofnode_read_u32_default(np_to_ofnode(np_params), 428 "expanded_version", 0); 429 if (expanded_version != PARAMS_IGNORE_THIS) { 430 if ((expanded_version & 0xff00) == 0x100 && 431 (expanded_version & 0xffff) <= 0x100) { 432 count_exp = ARRAY_SIZE(ddr_params_exp_v1); 433 ddr_params_exp = ddr_params_exp_v1; 434 } else { 435 printf("expanded_version=0x%x unsupported\n", 436 expanded_version); 437 return -1; 438 } 439 } else if ((ddr_params_version & 0xffff) == 0x101) { 440 count_exp = ARRAY_SIZE(ddr_params_exp_v1); 441 } 442 /* 443 * page 0 is used for share param 444 * page 1~N is used for dmc_fsp and ddr_params_exp param 445 */ 446 size = ((count + count_exp) * 4 + 4096); 447 res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1, SHARE_PAGE_TYPE_DDRFSP); 448 if (res.a0 != 0) { 449 printf("%s:no share memory for init\n", __func__); 450 return -ENOMEM; 451 } 452 453 /* fill share memory and pass to the atf */ 454 p = (int *)(res.a1); 455 for (i = 0; i < ARRAY_SIZE(dmc_fsp_params); i++) 456 p[i] = dev_read_u32_default(dev, dmc_fsp_params[i], PARAMS_INVALID_VAL); 457 458 phy_de_skew_en = p[1]; 459 460 p = (int *)(res.a1 + DTS_PAR_OFFSET / 4); 461 for (i = 0; i < ARRAY_SIZE(ddr_params_v1); i++) { 462 p[i] = ofnode_read_u32_default(np_to_ofnode(np_params), ddr_params[i], 463 PARAMS_INVALID_VAL); 464 } 465 466 if (expanded_version != PARAMS_IGNORE_THIS) { 467 if ((expanded_version & 0xff00) == 0x100 && 468 (expanded_version & 0xffff) <= 0x100) { 469 phandle_name = "ddr_timing"; 470 np_tim = 471 of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), 472 phandle_name, 0); 473 if (!np_tim) { 474 printf("%s: of_parse_phandle %s error!\n", 475 __func__, phandle_name); 476 return -EINVAL; 477 } 478 for (i = count; i < (count + count_exp); i++) { 479 p[i] = 480 ofnode_read_u32_default(np_to_ofnode(np_tim), 481 ddr_params_exp[i - 482 count], 483 PARAMS_INVALID_VAL); 484 } 485 /* expanded_version and start point */ 486 p[1] = (p[1] & 0xffff) | (count << 16); 487 } 488 } else if (phy_de_skew_en && (phy_de_skew_en != PARAMS_INVALID_VAL)) { 489 phandle_name = "ddr_timing"; 490 np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0); 491 if (!np_tim) { 492 printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name); 493 return -EINVAL; 494 } 495 for (i = count; 496 i < (count + ARRAY_SIZE(ddr_params_exp_v1)); i++) { 497 p[i] = 498 ofnode_read_u32_default(np_to_ofnode(np_tim), 499 ddr_params_exp_v1[i - count], 500 PARAMS_INVALID_VAL); 501 } 502 } 503 504 flush_cache((unsigned long)(res.a1), (DIV_ROUND_UP(size, 4096) + 1) * 0x1000); 505 res = sip_smc_dram(SHARE_PAGE_TYPE_DDRFSP, 0, ROCKCHIP_SIP_CONFIG_DRAM_FSP_INIT); 506 if (res.a0) { 507 printf("%s: rockchip_sip_config_dram_fsp_init error:%lx\n", __func__, res.a0); 508 return -ENOMEM; 509 } 510 511 return 0; 512 } 513 514 static const struct udevice_id rockchip_dmc_fsp_ids[] = { 515 { .compatible = "rockchip,rk3568-dmc-fsp", .data = 0x102}, 516 { .compatible = "rockchip,px30s-dmc-fsp", .data = 0x106}, 517 { } 518 }; 519 520 U_BOOT_DRIVER(dmc_fsp) = { 521 .name = "rockchip_dmc_fsp", 522 .id = UCLASS_DMC, 523 .probe = dmc_fsp_probe, 524 .of_match = rockchip_dmc_fsp_ids, 525 }; 526