1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) ASPEED Technology Inc. 4 */ 5#include <common.h> 6#include <clk.h> 7#include <dm.h> 8#include <errno.h> 9#include <ram.h> 10#include <regmap.h> 11#include <reset.h> 12#include <asm/io.h> 13#include <asm/arch/scu_ast2600.h> 14#include <asm/arch/sdram_ast2600.h> 15#include <asm/global_data.h> 16#include <linux/err.h> 17#include <linux/kernel.h> 18#include <linux/bitfield.h> 19#include <dt-bindings/clock/ast2600-clock.h> 20 21#define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea 22#define DDR_PHY_TBL_END 0xaeededed 23 24/** 25 * phyr030[18:16] - Ron PU (PHY side) 26 * phyr030[14:12] - Ron PD (PHY side) 27 * b'000 : disable 28 * b'001 : 240 ohm 29 * b'010 : 120 ohm 30 * b'011 : 80 ohm 31 * b'100 : 60 ohm 32 * b'101 : 48 ohm 33 * b'110 : 40 ohm 34 * b'111 : 34 ohm (default) 35 */ 36#define PHY_RON ((0x7 << 16) | (0x7 << 12)) 37 38/** 39 * phyr030[10:8] - ODT configuration (PHY side) 40 * b'000 : ODT disabled 41 * b'001 : 240 ohm 42 * b'010 : 120 ohm 43 * b'011 : 80 ohm (default) 44 * b'100 : 60 ohm 45 * b'101 : 48 ohm 46 * b'110 : 40 ohm 47 * b'111 : 34 ohm 48 */ 49#define PHY_ODT (0x3 << 8) 50 51/** 52 * MR1[2:1] output driver impedance 53 * b'00 : 34 ohm (default) 54 * b'01 : 48 ohm 55 */ 56#define DRAM_RON (0x0 << 1) 57 58/** 59 * DRAM ODT - synchronous ODT mode 60 * RTT_WR: disable 61 * RTT_NOM = RTT_PARK 62 * 63 * MR1[10:8] RTT_NOM 64 * b'000 : RTT_NOM disable 65 * b'001 : 60 ohm 66 * b'010 : 120 ohm 67 * b'011 : 40 ohm 68 * b'100 : 240 ohm 69 * b'101 : 48 ohm (default) 70 * b'110 : 80 ohm 71 * b'111 : 34 ohm 72 * 73 * MR5[8:6] RTT_PARK 74 * b'000 : RTT_PARK disable 75 * b'001 : 60 ohm 76 * b'010 : 120 ohm 77 * b'011 : 40 ohm 78 * b'100 : 240 ohm 79 * b'101 : 48 ohm (default) 80 * b'110 : 80 ohm 81 * b'111 : 34 ohm 82 * 83 * MR2[11:9] RTT_WR 84 * b'000 : Dynamic ODT off (default) 85 * b'001 : 120 ohm 86 * b'010 : 240 ohm 87 * b'011 : Hi-Z 88 * b'100 : 80 ohm 89 */ 90#define RTT_WR (0x0 << 9) 91#define RTT_NOM (0x5 << 8) 92#define RTT_PARK (0x5 << 6) 93 94/** 95 * MR6[6] VrefDQ training range 96 * b'0 : range 1 97 * b'1 : range 2 (default) 98 */ 99#define VREFDQ_RANGE_2 BIT(6) 100 101/** 102 * Latency setting: 103 * AL = PL = 0 (hardware fixed setting) 104 * -> WL = AL + CWL + PL = CWL 105 * -> RL = AL + CL + PL = CL 106 */ 107#define CFG_WL 9 108#define CFG_RL 12 109#define T_RDDATA_EN ((CFG_RL - 2) << 8) 110#define T_PHY_WRLAT (CFG_WL - 2) 111 112/* MR0 */ 113#define MR0_CL_12 (BIT(4) | BIT(2)) 114#define MR0_WR12_RTP6 BIT(9) 115#define MR0_DLL_RESET BIT(8) 116#define MR0_VAL (MR0_CL_12 | MR0_WR12_RTP6 | MR0_DLL_RESET) 117 118/* MR1 */ 119#define MR1_VAL (0x0001 | RTT_NOM | DRAM_RON) 120 121/* MR2 */ 122#define MR2_CWL_9 0 123#define MR2_VAL (0x0000 | RTT_WR | MR2_CWL_9) 124 125/* MR3 ~ MR6 */ 126#define MR3_VAL 0x0000 127#define MR4_VAL 0x0000 128#define MR5_VAL (0x0400 | RTT_PARK) 129#define MR6_VAL 0x0400 130 131/** 132 * The offset value applied to the DDR PHY write data eye training result 133 * to fine-tune the write DQ/DQS alignment 134 */ 135#define WR_DATA_EYE_OFFSET (0x10 << 8) 136 137#if defined(CONFIG_ASPEED_DDR4_800) 138u32 ast2600_sdramphy_config[165] = { 139 0x1e6e0100, // start address 140 0x00000000, // phyr000 141 0x0c002062, // phyr004 142 0x1a7a0063, // phyr008 143 0x5a7a0063, // phyr00c 144 0x1a7a0063, // phyr010 145 0x1a7a0063, // phyr014 146 0x20000000, // phyr018 147 0x20000000, // phyr01c 148 0x20000000, // phyr020 149 0x20000000, // phyr024 150 0x00000008, // phyr028 151 0x00000000, // phyr02c 152 (PHY_RON | PHY_ODT), /* phyr030 */ 153 0x00000000, // phyr034 154 0x00000000, // phyr038 155 0x20000000, // phyr03c 156 0x50506000, // phyr040 157 0x50505050, // phyr044 158 0x00002f07, // phyr048 159 0x00003080, // phyr04c 160 0x04000000, // phyr050 161 ((MR3_VAL << 16) | MR2_VAL), /* phyr054 */ 162 ((MR0_VAL << 16) | MR1_VAL), /* phyr058 */ 163 ((MR5_VAL << 16) | MR4_VAL), /* phyr05c */ 164 ((0x0800 << 16) | MR6_VAL | VREFDQ_RANGE_2 | 0xe), /* phyr060 */ 165 0x00000000, // phyr064 166 0x00180008, // phyr068 167 0x00e00400, // phyr06c 168 0x00140206, // phyr070 169 0x1d4c0000, // phyr074 170 (0x493e0100 | T_PHY_WRLAT), /* phyr078 */ 171 0x08060404, // phyr07c 172 (0x90000000 | T_RDDATA_EN), /* phyr080 */ 173 0x06420618, // phyr084 174 0x00001002, // phyr088 175 0x05701016, // phyr08c 176 0x10000000, // phyr090 177 0xaeeddeea, // change address 178 0x1e6e019c, // new address 179 0x20202020, // phyr09c 180 0x20202020, // phyr0a0 181 0x00002020, // phyr0a4 182 0x00002020, // phyr0a8 183 0x00000001, // phyr0ac 184 0xaeeddeea, // change address 185 0x1e6e01cc, // new address 186 0x01010101, // phyr0cc 187 0x01010101, // phyr0d0 188 0x80808080, // phyr0d4 189 0x80808080, // phyr0d8 190 0xaeeddeea, // change address 191 0x1e6e0288, // new address 192 0x80808080, // phyr188 193 0x80808080, // phyr18c 194 0x80808080, // phyr190 195 0x80808080, // phyr194 196 0xaeeddeea, // change address 197 0x1e6e02f8, // new address 198 0x90909090, // phyr1f8 199 0x88888888, // phyr1fc 200 0xaeeddeea, // change address 201 0x1e6e0300, // new address 202 0x00000000, // phyr200 203 0xaeeddeea, // change address 204 0x1e6e0194, // new address 205 0x80118260, // phyr094 206 0xaeeddeea, // change address 207 0x1e6e019c, // new address 208 0x20202020, // phyr09c 209 0x20202020, // phyr0a0 210 0x00002020, // phyr0a4 211 0x00000000, /* phyr0a8 */ 212 0x00000001, // phyr0ac 213 0xaeeddeea, // change address 214 0x1e6e0318, // new address 215 0x09222719, // phyr218 216 0x00aa4403, // phyr21c 217 0xaeeddeea, // change address 218 0x1e6e0198, // new address 219 0x08060000, // phyr098 220 0xaeeddeea, // change address 221 0x1e6e01b0, // new address 222 0x00000000, // phyr0b0 223 0x00000000, // phyr0b4 224 0x00000000, // phyr0b8 225 0x00000000, // phyr0bc 226 0x00000000, // phyr0c0 227 0x00000000, // phyr0c4 228 0x000aff2c, // phyr0c8 229 0xaeeddeea, // change address 230 0x1e6e01dc, // new address 231 0x00080000, // phyr0dc 232 0x00000000, // phyr0e0 233 0xaa55aa55, // phyr0e4 234 0x55aa55aa, // phyr0e8 235 0xaaaa5555, // phyr0ec 236 0x5555aaaa, // phyr0f0 237 0xaa55aa55, // phyr0f4 238 0x55aa55aa, // phyr0f8 239 0xaaaa5555, // phyr0fc 240 0x5555aaaa, // phyr100 241 0xaa55aa55, // phyr104 242 0x55aa55aa, // phyr108 243 0xaaaa5555, // phyr10c 244 0x5555aaaa, // phyr110 245 0xaa55aa55, // phyr114 246 0x55aa55aa, // phyr118 247 0xaaaa5555, // phyr11c 248 0x5555aaaa, // phyr120 249 0x20202020, // phyr124 250 0x20202020, // phyr128 251 0x20202020, // phyr12c 252 0x20202020, // phyr130 253 0x20202020, // phyr134 254 0x20202020, // phyr138 255 0x20202020, // phyr13c 256 0x20202020, // phyr140 257 0x20202020, // phyr144 258 0x20202020, // phyr148 259 0x20202020, // phyr14c 260 0x20202020, // phyr150 261 0x20202020, // phyr154 262 0x20202020, // phyr158 263 0x20202020, // phyr15c 264 0x20202020, // phyr160 265 0x20202020, // phyr164 266 0x20202020, // phyr168 267 0x20202020, // phyr16c 268 0x20202020, // phyr170 269 0xaeeddeea, // change address 270 0x1e6e0298, // new address 271 0x20200000, /* phyr198 */ 272 0x20202020, // phyr19c 273 0x20202020, // phyr1a0 274 0x20202020, // phyr1a4 275 0x20202020, // phyr1a8 276 0x20202020, // phyr1ac 277 0x20202020, // phyr1b0 278 0x20202020, // phyr1b4 279 0x20202020, // phyr1b8 280 0x20202020, // phyr1bc 281 0x20202020, // phyr1c0 282 0x20202020, // phyr1c4 283 0x20202020, // phyr1c8 284 0x20202020, // phyr1cc 285 0x20202020, // phyr1d0 286 0x20202020, // phyr1d4 287 0x20202020, // phyr1d8 288 0x20202020, // phyr1dc 289 0x20202020, // phyr1e0 290 0x20202020, // phyr1e4 291 0x00002020, // phyr1e8 292 0xaeeddeea, // change address 293 0x1e6e0304, // new address 294 (0x00000001 | WR_DATA_EYE_OFFSET), /* phyr204 */ 295 0xaeeddeea, // change address 296 0x1e6e027c, // new address 297 0x4e400000, // phyr17c 298 0x59595959, // phyr180 299 0x40404040, // phyr184 300 0xaeeddeea, // change address 301 0x1e6e02f4, // new address 302 0x00000059, // phyr1f4 303 0xaeededed, // end 304}; 305#else 306u32 ast2600_sdramphy_config[165] = { 307 0x1e6e0100, // start address 308 0x00000000, // phyr000 309 0x0c002062, // phyr004 310 0x1a7a0063, // phyr008 311 0x5a7a0063, // phyr00c 312 0x1a7a0063, // phyr010 313 0x1a7a0063, // phyr014 314 0x20000000, // phyr018 315 0x20000000, // phyr01c 316 0x20000000, // phyr020 317 0x20000000, // phyr024 318 0x00000008, // phyr028 319 0x00000000, // phyr02c 320 (PHY_RON | PHY_ODT), /* phyr030 */ 321 0x00000000, // phyr034 322 0x00000000, // phyr038 323 0x20000000, // phyr03c 324 0x50506000, // phyr040 325 0x50505050, // phyr044 326 0x00002f07, // phyr048 327 0x00003080, // phyr04c 328 0x04000000, // phyr050 329 ((MR3_VAL << 16) | MR2_VAL), /* phyr054 */ 330 ((MR0_VAL << 16) | MR1_VAL), /* phyr058 */ 331 ((MR5_VAL << 16) | MR4_VAL), /* phyr05c */ 332 ((0x0800 << 16) | MR6_VAL | VREFDQ_RANGE_2 | 0xe), /* phyr060 */ 333 0x00000000, // phyr064 334 0x00180008, // phyr068 335 0x00e00400, // phyr06c 336 0x00140206, // phyr070 337 0x1d4c0000, // phyr074 338 (0x493e0100 | T_PHY_WRLAT), /* phyr078 */ 339 0x08060404, // phyr07c 340 (0x90000000 | T_RDDATA_EN), /* phyr080 */ 341 0x06420c30, // phyr084 342 0x00001002, // phyr088 343 0x05701016, // phyr08c 344 0x10000000, // phyr090 345 0xaeeddeea, // change address 346 0x1e6e019c, // new address 347 0x20202020, // phyr09c 348 0x20202020, // phyr0a0 349 0x00002020, // phyr0a4 350 0x00002020, // phyr0a8 351 0x00000001, // phyr0ac 352 0xaeeddeea, // change address 353 0x1e6e01cc, // new address 354 0x01010101, // phyr0cc 355 0x01010101, // phyr0d0 356 0x80808080, // phyr0d4 357 0x80808080, // phyr0d8 358 0xaeeddeea, // change address 359 0x1e6e0288, // new address 360 0x80808080, // phyr188 361 0x80808080, // phyr18c 362 0x80808080, // phyr190 363 0x80808080, // phyr194 364 0xaeeddeea, // change address 365 0x1e6e02f8, // new address 366 0x90909090, // phyr1f8 367 0x88888888, // phyr1fc 368 0xaeeddeea, // change address 369 0x1e6e0300, // new address 370 0x00000000, // phyr200 371 0xaeeddeea, // change address 372 0x1e6e0194, // new address 373 0x801112e0, // phyr094 374 0xaeeddeea, // change address 375 0x1e6e019c, // new address 376 0x20202020, // phyr09c 377 0x20202020, // phyr0a0 378 0x00002020, // phyr0a4 379 0x00000000, /* phyr0a8 */ 380 0x00000001, // phyr0ac 381 0xaeeddeea, // change address 382 0x1e6e0318, // new address 383 0x09222719, // phyr218 384 0x00aa4403, // phyr21c 385 0xaeeddeea, // change address 386 0x1e6e0198, // new address 387 0x08060000, // phyr098 388 0xaeeddeea, // change address 389 0x1e6e01b0, // new address 390 0x00000000, // phyr0b0 391 0x00000000, // phyr0b4 392 0x00000000, // phyr0b8 393 0x00000000, // phyr0bc 394 0x00000000, // phyr0c0 - ori 395 0x00000000, // phyr0c4 396 0x000aff2c, // phyr0c8 397 0xaeeddeea, // change address 398 0x1e6e01dc, // new address 399 0x00080000, // phyr0dc 400 0x00000000, // phyr0e0 401 0xaa55aa55, // phyr0e4 402 0x55aa55aa, // phyr0e8 403 0xaaaa5555, // phyr0ec 404 0x5555aaaa, // phyr0f0 405 0xaa55aa55, // phyr0f4 406 0x55aa55aa, // phyr0f8 407 0xaaaa5555, // phyr0fc 408 0x5555aaaa, // phyr100 409 0xaa55aa55, // phyr104 410 0x55aa55aa, // phyr108 411 0xaaaa5555, // phyr10c 412 0x5555aaaa, // phyr110 413 0xaa55aa55, // phyr114 414 0x55aa55aa, // phyr118 415 0xaaaa5555, // phyr11c 416 0x5555aaaa, // phyr120 417 0x20202020, // phyr124 418 0x20202020, // phyr128 419 0x20202020, // phyr12c 420 0x20202020, // phyr130 421 0x20202020, // phyr134 422 0x20202020, // phyr138 423 0x20202020, // phyr13c 424 0x20202020, // phyr140 425 0x20202020, // phyr144 426 0x20202020, // phyr148 427 0x20202020, // phyr14c 428 0x20202020, // phyr150 429 0x20202020, // phyr154 430 0x20202020, // phyr158 431 0x20202020, // phyr15c 432 0x20202020, // phyr160 433 0x20202020, // phyr164 434 0x20202020, // phyr168 435 0x20202020, // phyr16c 436 0x20202020, // phyr170 437 0xaeeddeea, // change address 438 0x1e6e0298, // new address 439 0x20200000, /* phyr198 */ 440 0x20202020, // phyr19c 441 0x20202020, // phyr1a0 442 0x20202020, // phyr1a4 443 0x20202020, // phyr1a8 444 0x20202020, // phyr1ac 445 0x20202020, // phyr1b0 446 0x20202020, // phyr1b4 447 0x20202020, // phyr1b8 448 0x20202020, // phyr1bc 449 0x20202020, // phyr1c0 450 0x20202020, // phyr1c4 451 0x20202020, // phyr1c8 452 0x20202020, // phyr1cc 453 0x20202020, // phyr1d0 454 0x20202020, // phyr1d4 455 0x20202020, // phyr1d8 456 0x20202020, // phyr1dc 457 0x20202020, // phyr1e0 458 0x20202020, // phyr1e4 459 0x00002020, // phyr1e8 460 0xaeeddeea, // change address 461 0x1e6e0304, // new address 462 (0x00000001 | WR_DATA_EYE_OFFSET), /* phyr204 */ 463 0xaeeddeea, // change address 464 0x1e6e027c, // new address 465 0x4e400000, // phyr17c 466 0x59595959, // phyr180 467 0x40404040, // phyr184 468 0xaeeddeea, // change address 469 0x1e6e02f4, // new address 470 0x00000059, // phyr1f4 471 0xaeededed, // end 472}; 473#endif 474 475/* MPLL configuration */ 476#define SCU_MPLL_FREQ_400M 0x0008405F 477#define SCU_MPLL_EXT_400M 0x0000002F 478#define SCU_MPLL_FREQ_333M 0x00488299 479#define SCU_MPLL_EXT_333M 0x0000014C 480#define SCU_MPLL_FREQ_200M 0x0078007F 481#define SCU_MPLL_EXT_200M 0x0000003F 482#define SCU_MPLL_FREQ_100M 0x0078003F 483#define SCU_MPLL_EXT_100M 0x0000001F 484 485#if defined(CONFIG_ASPEED_DDR4_1600) 486#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_400M 487#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_400M 488#elif defined(CONFIG_ASPEED_DDR4_1333) 489#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_333M 490#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_333M 491#elif defined(CONFIG_ASPEED_DDR4_800) 492#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_200M 493#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_200M 494#elif defined(CONFIG_ASPEED_DDR4_400) 495#define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_100M 496#define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_100M 497#else 498#error "undefined DDR4 target rate\n" 499#endif 500 501/* 502 * AC timing and SDRAM mode register setting 503 * for real chip are derived from the model GDDR4-1600 504 */ 505#define DDR4_MR01_MODE ((MR1_VAL << 16) | MR0_VAL) 506#define DDR4_MR23_MODE ((MR3_VAL << 16) | MR2_VAL) 507#define DDR4_MR45_MODE ((MR5_VAL << 16) | MR4_VAL) 508#define DDR4_MR6_MODE MR6_VAL 509#define DDR4_TRFC_1600 0x467299f1 510#define DDR4_TRFC_1333 0x3a5f80c9 511#define DDR4_TRFC_800 0x23394c78 512#define DDR4_TRFC_400 0x111c263c 513 514#if defined(CONFIG_ASPEED_DDR4_1600) 515#define DDR4_TRFC DDR4_TRFC_1600 516#define DDR4_PHY_TRAIN_TRFC 0xc30 517#elif defined(CONFIG_ASPEED_DDR4_1333) 518#define DDR4_TRFC DDR4_TRFC_1333 519#define DDR4_PHY_TRAIN_TRFC 0xa25 520#elif defined(CONFIG_ASPEED_DDR4_800) 521#define DDR4_TRFC DDR4_TRFC_800 522#define DDR4_PHY_TRAIN_TRFC 0x618 523#elif defined(CONFIG_ASPEED_DDR4_400) 524#define DDR4_TRFC DDR4_TRFC_400 525#define DDR4_PHY_TRAIN_TRFC 0x30c 526#else 527#error "undefined tRFC setting" 528#endif 529 530/* supported SDRAM size */ 531#define SDRAM_SIZE_1KB (1024U) 532#define SDRAM_SIZE_1MB (SDRAM_SIZE_1KB * SDRAM_SIZE_1KB) 533#define SDRAM_MIN_SIZE (256 * SDRAM_SIZE_1MB) 534#define SDRAM_MAX_SIZE (2048 * SDRAM_SIZE_1MB) 535 536DECLARE_GLOBAL_DATA_PTR; 537 538static const u32 ddr4_ac_timing[4] = { 539 0x040e0307, 0x0f4711f1, 0x0e060304, 0x00001240 }; 540static const u32 ddr_max_grant_params[4] = { 541 0x44444444, 0x44444444, 0x44444444, 0x44444444 }; 542 543struct dram_info { 544 struct ram_info info; 545 struct clk ddr_clk; 546 struct ast2600_sdrammc_regs *regs; 547 struct ast2600_scu *scu; 548 struct ast2600_ddr_phy *phy; 549 void __iomem *phy_setting; 550 void __iomem *phy_status; 551 ulong clock_rate; 552}; 553 554static void ast2600_sdramphy_kick_training(struct dram_info *info) 555{ 556 u32 data; 557 struct ast2600_sdrammc_regs *regs = info->regs; 558 559 writel(SDRAM_PHYCTRL0_NRST, ®s->phy_ctrl[0]); 560 udelay(5); 561 writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, ®s->phy_ctrl[0]); 562 udelay(1000); 563 564 while (1) { 565 data = readl(®s->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT; 566 if (data == 0) 567 break; 568 } 569} 570 571/** 572 * @brief load DDR-PHY configurations table to the PHY registers 573 * @param[in] p_tbl - pointer to the configuration table 574 * @param[in] info - pointer to the DRAM info struct 575 * 576 * There are two sets of MRS (Mode Registers) configuration in ast2600 memory 577 * system: one is in the SDRAM MC (memory controller) which is used in run 578 * time, and the other is in the DDR-PHY IP which is used during DDR-PHY 579 * training. 580 */ 581static void ast2600_sdramphy_init(u32 *p_tbl, struct dram_info *info) 582{ 583 u32 reg_base = (u32)info->phy_setting; 584 u32 addr = p_tbl[0]; 585 u32 data; 586 int i = 1; 587 588 writel(0, &info->regs->phy_ctrl[0]); 589 udelay(10); 590 591 while (1) { 592 if (addr < reg_base) { 593 debug("invalid DDR-PHY addr: 0x%08x\n", addr); 594 break; 595 } 596 data = p_tbl[i++]; 597 598 if (data == DDR_PHY_TBL_END) { 599 break; 600 } else if (data == DDR_PHY_TBL_CHG_ADDR) { 601 addr = p_tbl[i++]; 602 } else { 603 writel(data, addr); 604 addr += 4; 605 } 606 } 607 608 data = readl(info->phy_setting + 0x84) & ~GENMASK(16, 0); 609 data |= DDR4_PHY_TRAIN_TRFC; 610 writel(data, info->phy_setting + 0x84); 611} 612 613static int ast2600_sdramphy_check_status(struct dram_info *info) 614{ 615 u32 value, tmp; 616 u32 reg_base = (u32)info->phy_status; 617 int need_retrain = 0; 618 619 debug("\nSDRAM PHY training report:\n"); 620 621 /* training status */ 622 value = readl(reg_base + 0x00); 623 debug("rO_DDRPHY_reg offset 0x00 = 0x%08x\n", value); 624 625 if (value & BIT(3)) 626 debug("\tinitial PVT calibration fail\n"); 627 628 if (value & BIT(5)) 629 debug("\truntime calibration fail\n"); 630 631 /* PU & PD */ 632 value = readl(reg_base + 0x30); 633 debug("rO_DDRPHY_reg offset 0x30 = 0x%08x\n", value); 634 debug(" PU = 0x%02x\n", value & 0xff); 635 debug(" PD = 0x%02x\n", (value >> 16) & 0xff); 636 637 /* read eye window */ 638 value = readl(reg_base + 0x68); 639 if (0 == (value & GENMASK(7, 0))) 640 need_retrain = 1; 641 642 debug("rO_DDRPHY_reg offset 0x68 = 0x%08x\n", value); 643 debug(" rising edge of read data eye training pass window\n"); 644 tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255; 645 debug(" B0:%d%%\n", tmp); 646 tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255; 647 debug(" B1:%d%%\n", tmp); 648 649 value = readl(reg_base + 0xC8); 650 debug("rO_DDRPHY_reg offset 0xC8 = 0x%08x\n", value); 651 debug(" falling edge of read data eye training pass window\n"); 652 tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255; 653 debug(" B0:%d%%\n", tmp); 654 tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255; 655 debug(" B1:%d%%\n", tmp); 656 657 /* write eye window */ 658 value = readl(reg_base + 0x7c); 659 if (0 == (value & GENMASK(7, 0))) 660 need_retrain = 1; 661 662 debug("rO_DDRPHY_reg offset 0x7C = 0x%08x\n", value); 663 debug(" rising edge of write data eye training pass window\n"); 664 tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255; 665 debug(" B0:%d%%\n", tmp); 666 tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255; 667 debug(" B1:%d%%\n", tmp); 668 669 /* read Vref training result */ 670 value = readl(reg_base + 0x88); 671 debug("rO_DDRPHY_reg offset 0x88 = 0x%08x\n", value); 672 debug(" read Vref training result\n"); 673 tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 127; 674 debug(" B0:%d%%\n", tmp); 675 tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 127; 676 debug(" B1:%d%%\n", tmp); 677 678 /* write Vref training result */ 679 value = readl(reg_base + 0x90); 680 debug("rO_DDRPHY_reg offset 0x90 = 0x%08x\n", value); 681 682 /* gate train */ 683 value = readl(reg_base + 0x50); 684 if ((0 == (value & GENMASK(15, 0))) || 685 (0 == (value & GENMASK(31, 16)))) { 686 need_retrain = 1; 687 } 688 689 debug("rO_DDRPHY_reg offset 0x50 = 0x%08x\n", value); 690 691 return need_retrain; 692} 693 694#ifndef CONFIG_ASPEED_BYPASS_SELFTEST 695#define MC_TEST_PATTERN_N 8 696static u32 as2600_sdrammc_test_pattern[MC_TEST_PATTERN_N] = { 697 0xcc33cc33, 0xff00ff00, 0xaa55aa55, 0x88778877, 698 0x92cc4d6e, 0x543d3cde, 0xf1e843c7, 0x7c61d253 }; 699 700#define TIMEOUT_DRAM 5000000 701int ast2600_sdrammc_dg_test(struct dram_info *info, unsigned int datagen, u32 mode) 702{ 703 unsigned int data; 704 unsigned int timeout = 0; 705 struct ast2600_sdrammc_regs *regs = info->regs; 706 707 writel(0, ®s->ecc_test_ctrl); 708 709 if (mode == 0) 710 writel(0x00000085 | (datagen << 3), ®s->ecc_test_ctrl); 711 else 712 writel(0x000000C1 | (datagen << 3), ®s->ecc_test_ctrl); 713 714 do { 715 data = readl(®s->ecc_test_ctrl) & GENMASK(13, 12); 716 717 if (data & BIT(13)) 718 return 0; 719 720 if (++timeout > TIMEOUT_DRAM) { 721 debug("Timeout!!\n"); 722 writel(0, ®s->ecc_test_ctrl); 723 return -1; 724 } 725 } while (!data); 726 727 writel(0, ®s->ecc_test_ctrl); 728 729 return 0; 730} 731 732int ast2600_sdrammc_cbr_test(struct dram_info *info) 733{ 734 u32 i; 735 struct ast2600_sdrammc_regs *regs = info->regs; 736 737 clrsetbits_le32(®s->test_addr, GENMASK(30, 4), 0x7ffff0); 738 739 /* single */ 740 for (i = 0; i < 8; i++) 741 if (ast2600_sdrammc_dg_test(info, i, 0)) 742 return -1; 743 744 /* burst */ 745 for (i = 0; i < 8; i++) 746 if (ast2600_sdrammc_dg_test(info, i, i)) 747 return -1; 748 749 return 0; 750} 751 752static int ast2600_sdrammc_test(struct dram_info *info) 753{ 754 struct ast2600_sdrammc_regs *regs = info->regs; 755 756 u32 pass_cnt = 0; 757 u32 fail_cnt = 0; 758 u32 target_cnt = 2; 759 u32 test_cnt = 0; 760 u32 pattern; 761 u32 i = 0; 762 bool finish = false; 763 764 debug("sdram mc test:\n"); 765 while (!finish) { 766 pattern = as2600_sdrammc_test_pattern[i++]; 767 i = i % MC_TEST_PATTERN_N; 768 debug(" pattern = %08X : ", pattern); 769 writel(pattern, ®s->test_init_val); 770 771 if (ast2600_sdrammc_cbr_test(info)) { 772 debug("fail\n"); 773 fail_cnt++; 774 } else { 775 debug("pass\n"); 776 pass_cnt++; 777 } 778 779 if (++test_cnt == target_cnt) 780 finish = true; 781 } 782 debug("statistics: pass/fail/total:%d/%d/%d\n", pass_cnt, fail_cnt, 783 target_cnt); 784 785 return fail_cnt; 786} 787#endif 788 789/* 790 * scu500[14:13] 791 * 2b'00: VGA memory size = 16MB 792 * 2b'01: VGA memory size = 16MB 793 * 2b'10: VGA memory size = 32MB 794 * 2b'11: VGA memory size = 64MB 795 * 796 * mcr04[3:2] 797 * 2b'00: VGA memory size = 8MB 798 * 2b'01: VGA memory size = 16MB 799 * 2b'10: VGA memory size = 32MB 800 * 2b'11: VGA memory size = 64MB 801 */ 802static size_t ast2600_sdrammc_get_vga_mem_size(struct dram_info *info) 803{ 804 u32 vga_hwconf; 805 size_t vga_mem_size_base = 8 * 1024 * 1024; 806 807 vga_hwconf = 808 (readl(&info->scu->hwstrap1) & SCU_HWSTRAP1_VGA_MEM_MASK) >> 809 SCU_HWSTRAP1_VGA_MEM_SHIFT; 810 811 if (vga_hwconf == 0) { 812 vga_hwconf = 1; 813 writel(vga_hwconf << SCU_HWSTRAP1_VGA_MEM_SHIFT, 814 &info->scu->hwstrap1); 815 } 816 817 clrsetbits_le32(&info->regs->config, SDRAM_CONF_VGA_SIZE_MASK, 818 ((vga_hwconf << SDRAM_CONF_VGA_SIZE_SHIFT) & 819 SDRAM_CONF_VGA_SIZE_MASK)); 820 821 /* no need to reserve VGA memory if efuse[VGA disable] is set */ 822 if (readl(&info->scu->efuse) & SCU_EFUSE_DIS_VGA) 823 return 0; 824 825 return vga_mem_size_base << vga_hwconf; 826} 827 828/* 829 * Find out RAM size and save it in dram_info 830 * 831 * The procedure is taken from Aspeed SDK 832 */ 833static void ast2600_sdrammc_calc_size(struct dram_info *info) 834{ 835 /* The controller supports 256/512/1024/2048 MB ram */ 836 size_t ram_size = SDRAM_MIN_SIZE; 837 const int write_test_offset = 0x100000; 838 u32 test_pattern = 0xdeadbeef; 839 u32 cap_param = SDRAM_CONF_CAP_2048M; 840 u32 refresh_timing_param = DDR4_TRFC; 841 const u32 write_addr_base = CFG_SYS_SDRAM_BASE + write_test_offset; 842 843 for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE; 844 ram_size >>= 1) { 845 writel(test_pattern, write_addr_base + (ram_size >> 1)); 846 test_pattern = (test_pattern >> 4) | (test_pattern << 28); 847 } 848 849 /* One last write to overwrite all wrapped values */ 850 writel(test_pattern, write_addr_base); 851 852 /* Reset the pattern and see which value was really written */ 853 test_pattern = 0xdeadbeef; 854 for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE; 855 ram_size >>= 1) { 856 if (readl(write_addr_base + (ram_size >> 1)) == test_pattern) 857 break; 858 859 --cap_param; 860 refresh_timing_param >>= 8; 861 test_pattern = (test_pattern >> 4) | (test_pattern << 28); 862 } 863 864 clrsetbits_le32(&info->regs->ac_timing[1], 865 (SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT), 866 ((refresh_timing_param & SDRAM_AC_TRFC_MASK) 867 << SDRAM_AC_TRFC_SHIFT)); 868 869 info->info.base = CFG_SYS_SDRAM_BASE; 870 info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info); 871 872 clrsetbits_le32(&info->regs->config, SDRAM_CONF_CAP_MASK, 873 ((cap_param << SDRAM_CONF_CAP_SHIFT) & SDRAM_CONF_CAP_MASK)); 874} 875 876static int ast2600_sdrammc_init_ddr4(struct dram_info *info) 877{ 878 const u32 power_ctrl = MCR34_CKE_EN | MCR34_AUTOPWRDN_EN | 879 MCR34_MREQ_BYPASS_DIS | MCR34_RESETN_DIS | 880 MCR34_ODT_EN | MCR34_ODT_AUTO_ON | 881 (0x1 << MCR34_ODT_EXT_SHIFT); 882 883 /* init SDRAM-PHY only on real chip */ 884 ast2600_sdramphy_init(ast2600_sdramphy_config, info); 885 writel((MCR34_CKE_EN | MCR34_MREQI_DIS | MCR34_RESETN_DIS), 886 &info->regs->power_ctrl); 887 udelay(5); 888 ast2600_sdramphy_kick_training(info); 889 udelay(500); 890 writel(SDRAM_RESET_DLL_ZQCL_EN, &info->regs->refresh_timing); 891 892 writel(MCR30_SET_MR(3), &info->regs->mode_setting_control); 893 writel(MCR30_SET_MR(6), &info->regs->mode_setting_control); 894 writel(MCR30_SET_MR(5), &info->regs->mode_setting_control); 895 writel(MCR30_SET_MR(4), &info->regs->mode_setting_control); 896 writel(MCR30_SET_MR(2), &info->regs->mode_setting_control); 897 writel(MCR30_SET_MR(1), &info->regs->mode_setting_control); 898 writel(MCR30_SET_MR(0) | MCR30_RESET_DLL_DELAY_EN, 899 &info->regs->mode_setting_control); 900 901 writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN | 902 (0x5f << SDRAM_REFRESH_PERIOD_SHIFT), 903 &info->regs->refresh_timing); 904 905 /* wait self-refresh idle */ 906 while (readl(&info->regs->power_ctrl) & 907 MCR34_SELF_REFRESH_STATUS_MASK) 908 ; 909 910 writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN | 911 SDRAM_REFRESH_ZQCS_EN | 912 (0x5f << SDRAM_REFRESH_PERIOD_SHIFT) | 913 (0x42aa << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT), 914 &info->regs->refresh_timing); 915 916 writel(power_ctrl, &info->regs->power_ctrl); 917 udelay(500); 918 919 return 0; 920} 921 922static void ast2600_sdrammc_unlock(struct dram_info *info) 923{ 924 writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key); 925 while (!readl(&info->regs->protection_key)) 926 ; 927} 928 929static void ast2600_sdrammc_lock(struct dram_info *info) 930{ 931 writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key); 932 while (readl(&info->regs->protection_key)) 933 ; 934} 935 936static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs) 937{ 938 int i; 939 u32 reg; 940 941 writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, ®s->power_ctrl); 942 writel(SDRAM_VIDEO_UNLOCK_KEY, ®s->gm_protection_key); 943 writel(0x10 << MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT, 944 ®s->arbitration_ctrl); 945 writel(0xFFBBFFF4, ®s->req_limit_mask); 946 947 for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i) 948 writel(ddr_max_grant_params[i], ®s->max_grant_len[i]); 949 950 writel(MCR50_RESET_ALL_INTR, ®s->intr_ctrl); 951 952 writel(0x07FFFFFF, ®s->ecc_range_ctrl); 953 954 writel(0, ®s->ecc_test_ctrl); 955 writel(0x80000001, ®s->test_addr); 956 writel(0, ®s->test_fail_dq_bit); 957 writel(0, ®s->test_init_val); 958 959 writel(0xFFFFFFFF, ®s->req_input_ctrl); 960 writel(0, ®s->req_high_pri_ctrl); 961 962 udelay(600); 963 964#ifdef CONFIG_ASPEED_DDR4_DUALX8 965 writel(0x37, ®s->config); 966#else 967 writel(0x17, ®s->config); 968#endif 969 970 /* load controller setting */ 971 for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i) 972 writel(ddr4_ac_timing[i], ®s->ac_timing[i]); 973 974 /* update CL and WL */ 975 reg = readl(®s->ac_timing[1]); 976 reg &= ~(SDRAM_WL_SETTING | SDRAM_CL_SETTING); 977 reg |= FIELD_PREP(SDRAM_WL_SETTING, CFG_WL - 5) | 978 FIELD_PREP(SDRAM_CL_SETTING, CFG_RL - 5); 979 writel(reg, ®s->ac_timing[1]); 980 981 writel(DDR4_MR01_MODE, ®s->mr01_mode_setting); 982 writel(DDR4_MR23_MODE, ®s->mr23_mode_setting); 983 writel(DDR4_MR45_MODE, ®s->mr45_mode_setting); 984 writel(DDR4_MR6_MODE, ®s->mr6_mode_setting); 985} 986 987/* 988 * Update size info according to the ECC HW setting 989 * 990 * Assume SDRAM has been initialized by SPL or the host. To get the RAM size, we 991 * don't need to calculate the ECC size again but read from MCR04 and derive the 992 * size from its value. 993 */ 994static void ast2600_sdrammc_update_size(struct dram_info *info) 995{ 996 struct ast2600_sdrammc_regs *regs = info->regs; 997 u32 conf = readl(®s->config); 998 u32 cap_param; 999 size_t ram_size = SDRAM_MAX_SIZE; 1000 size_t hw_size; 1001 1002 cap_param = (conf & SDRAM_CONF_CAP_MASK) >> SDRAM_CONF_CAP_SHIFT; 1003 switch (cap_param) { 1004 case SDRAM_CONF_CAP_2048M: 1005 ram_size = 2048 * SDRAM_SIZE_1MB; 1006 break; 1007 case SDRAM_CONF_CAP_1024M: 1008 ram_size = 1024 * SDRAM_SIZE_1MB; 1009 break; 1010 case SDRAM_CONF_CAP_512M: 1011 ram_size = 512 * SDRAM_SIZE_1MB; 1012 break; 1013 case SDRAM_CONF_CAP_256M: 1014 ram_size = 256 * SDRAM_SIZE_1MB; 1015 break; 1016 } 1017 1018 info->info.base = CFG_SYS_SDRAM_BASE; 1019 info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info); 1020 1021 if (0 == (conf & SDRAM_CONF_ECC_SETUP)) 1022 return; 1023 1024 hw_size = readl(®s->ecc_range_ctrl) & SDRAM_ECC_RANGE_ADDR_MASK; 1025 hw_size += (1 << SDRAM_ECC_RANGE_ADDR_SHIFT); 1026 1027 info->info.size = hw_size; 1028} 1029 1030#ifdef CONFIG_ASPEED_ECC 1031static void ast2600_sdrammc_ecc_enable(struct dram_info *info) 1032{ 1033 struct ast2600_sdrammc_regs *regs = info->regs; 1034 size_t conf_size; 1035 u32 reg; 1036 1037 conf_size = CONFIG_ASPEED_ECC_SIZE * SDRAM_SIZE_1MB; 1038 if (conf_size > info->info.size) { 1039 printf("warning: ECC configured %dMB but actual size is %dMB\n", 1040 CONFIG_ASPEED_ECC_SIZE, 1041 info->info.size / SDRAM_SIZE_1MB); 1042 conf_size = info->info.size; 1043 } else if (conf_size == 0) { 1044 conf_size = info->info.size; 1045 } 1046 1047 info->info.size = (((conf_size / 9) * 8) >> 20) << 20; 1048 writel(((info->info.size >> 20) - 1) << 20, ®s->ecc_range_ctrl); 1049 reg = readl(®s->config) | SDRAM_CONF_ECC_SETUP; 1050 writel(reg, ®s->config); 1051 1052 writel(0, ®s->test_init_val); 1053 writel(0x80000001, ®s->test_addr); 1054 writel(0x221, ®s->ecc_test_ctrl); 1055 while (0 == (readl(®s->ecc_test_ctrl) & BIT(12))) 1056 ; 1057 writel(0, ®s->ecc_test_ctrl); 1058 writel(BIT(31), ®s->intr_ctrl); 1059 writel(0, ®s->intr_ctrl); 1060} 1061#endif 1062 1063static int ast2600_sdrammc_probe(struct udevice *dev) 1064{ 1065 int ret; 1066 u32 reg; 1067 struct dram_info *priv = (struct dram_info *)dev_get_priv(dev); 1068 struct ast2600_sdrammc_regs *regs = priv->regs; 1069 struct udevice *clk_dev; 1070 1071 /* find SCU base address from clock device */ 1072 ret = uclass_get_device_by_driver(UCLASS_CLK, 1073 DM_DRIVER_GET(aspeed_ast2600_scu), &clk_dev); 1074 if (ret) { 1075 debug("clock device not defined\n"); 1076 return ret; 1077 } 1078 1079 priv->scu = devfdt_get_addr_ptr(clk_dev); 1080 if (IS_ERR(priv->scu)) { 1081 debug("%s(): can't get SCU\n", __func__); 1082 return PTR_ERR(priv->scu); 1083 } 1084 1085 if (readl(&priv->scu->dram_hdshk) & SCU_DRAM_HDSHK_RDY) { 1086 printf("already initialized, "); 1087 ast2600_sdrammc_update_size(priv); 1088 return 0; 1089 } 1090 1091 reg = readl(&priv->scu->mpll); 1092 reg &= ~(SCU_PLL_BYPASS | SCU_PLL_OFF | SCU_PLL_DIV_MASK | 1093 SCU_PLL_DENUM_MASK | SCU_PLL_NUM_MASK); 1094 reg |= (SCU_PLL_RST | SCU_MPLL_FREQ_CFG); 1095 writel(reg, &priv->scu->mpll); 1096 writel(SCU_MPLL_EXT_CFG, &priv->scu->mpll_ext); 1097 udelay(100); 1098 reg &= ~SCU_PLL_RST; 1099 writel(reg, &priv->scu->mpll); 1100 1101 while ((readl(&priv->scu->mpll_ext) & BIT(31)) == 0) 1102 ; 1103 1104 ast2600_sdrammc_unlock(priv); 1105 ast2600_sdrammc_common_init(regs); 1106L_ast2600_sdramphy_train: 1107 ast2600_sdrammc_init_ddr4(priv); 1108 1109 if (ast2600_sdramphy_check_status(priv) != 0) { 1110 printf("DDR4 PHY training fail, retrain\n"); 1111 goto L_ast2600_sdramphy_train; 1112 } 1113 1114 ast2600_sdrammc_calc_size(priv); 1115 1116#ifndef CONFIG_ASPEED_BYPASS_SELFTEST 1117 if (ast2600_sdrammc_test(priv) != 0) { 1118 printf("%s: DDR4 init fail\n", __func__); 1119 return -EINVAL; 1120 } 1121#endif 1122 1123#ifdef CONFIG_ASPEED_ECC 1124 ast2600_sdrammc_ecc_enable(priv); 1125#endif 1126 1127 writel(readl(&priv->scu->dram_hdshk) | SCU_DRAM_HDSHK_RDY, 1128 &priv->scu->dram_hdshk); 1129 1130 clrbits_le32(®s->intr_ctrl, MCR50_RESET_ALL_INTR); 1131 ast2600_sdrammc_lock(priv); 1132 return 0; 1133} 1134 1135static int ast2600_sdrammc_of_to_plat(struct udevice *dev) 1136{ 1137 struct dram_info *priv = dev_get_priv(dev); 1138 1139 priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0); 1140 priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1); 1141 priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2); 1142 1143 priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 1144 "clock-frequency", 0); 1145 if (!priv->clock_rate) { 1146 debug("DDR Clock Rate not defined\n"); 1147 return -EINVAL; 1148 } 1149 1150 return 0; 1151} 1152 1153static int ast2600_sdrammc_get_info(struct udevice *dev, struct ram_info *info) 1154{ 1155 struct dram_info *priv = dev_get_priv(dev); 1156 1157 *info = priv->info; 1158 1159 return 0; 1160} 1161 1162static struct ram_ops ast2600_sdrammc_ops = { 1163 .get_info = ast2600_sdrammc_get_info, 1164}; 1165 1166static const struct udevice_id ast2600_sdrammc_ids[] = { 1167 { .compatible = "aspeed,ast2600-sdrammc" }, 1168 { } 1169}; 1170 1171U_BOOT_DRIVER(sdrammc_ast2600) = { 1172 .name = "aspeed_ast2600_sdrammc", 1173 .id = UCLASS_RAM, 1174 .of_match = ast2600_sdrammc_ids, 1175 .ops = &ast2600_sdrammc_ops, 1176 .of_to_plat = ast2600_sdrammc_of_to_plat, 1177 .probe = ast2600_sdrammc_probe, 1178 .priv_auto = sizeof(struct dram_info), 1179}; 1180