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