1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2012 Red Hat Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * The above copyright notice and this permission notice (including the 22 * next paragraph) shall be included in all copies or substantial portions 23 * of the Software. 24 */ 25 /* 26 * Authors: Dave Airlie <airlied@redhat.com> 27 */ 28 29 #include <linux/delay.h> 30 #include <linux/pci.h> 31 #include <linux/sizes.h> 32 33 #include <drm/drm_drv.h> 34 #include <drm/drm_managed.h> 35 #include <drm/drm_print.h> 36 37 #include "ast_drv.h" 38 #include "ast_post.h" 39 40 /* 41 * POST 42 */ 43 44 void ast_2300_set_def_ext_reg(struct ast_device *ast) 45 { 46 static const u8 extreginfo[] = { 0x0f, 0x04, 0x1f, 0xff }; 47 u8 i, index, reg; 48 const u8 *ext_reg_info; 49 50 /* reset scratch */ 51 for (i = 0x81; i <= 0x9f; i++) 52 ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00); 53 54 ext_reg_info = extreginfo; 55 index = 0xa0; 56 while (*ext_reg_info != 0xff) { 57 ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info); 58 index++; 59 ext_reg_info++; 60 } 61 62 /* disable standard IO/MEM decode if secondary */ 63 /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */ 64 65 /* Set Ext. Default */ 66 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01); 67 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00); 68 69 /* Enable RAMDAC for A1 */ 70 reg = 0x04; 71 reg |= 0x20; 72 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg); 73 } 74 75 /* AST 2300 DRAM settings */ 76 #define AST_DDR3 0 77 #define AST_DDR2 1 78 79 struct ast2300_dram_param { 80 u32 dram_type; 81 u32 dram_chipid; 82 u32 dram_freq; 83 u32 vram_size; 84 u32 odt; 85 u32 wodt; 86 u32 rodt; 87 u32 dram_config; 88 u32 reg_PERIOD; 89 u32 reg_MADJ; 90 u32 reg_SADJ; 91 u32 reg_MRS; 92 u32 reg_EMRS; 93 u32 reg_AC1; 94 u32 reg_AC2; 95 u32 reg_DQSIC; 96 u32 reg_DRV; 97 u32 reg_IOZ; 98 u32 reg_DQIDLY; 99 u32 reg_FREQ; 100 u32 madj_max; 101 u32 dll2_finetune_step; 102 }; 103 104 /* 105 * DQSI DLL CBR Setting 106 */ 107 #define CBR_SIZE0 ((1 << 10) - 1) 108 #define CBR_SIZE1 ((4 << 10) - 1) 109 #define CBR_SIZE2 ((64 << 10) - 1) 110 #define CBR_PASSNUM 5 111 #define CBR_PASSNUM2 5 112 #define CBR_THRESHOLD 10 113 #define CBR_THRESHOLD2 10 114 #define TIMEOUT 5000000 115 #define CBR_PATNUM 8 116 117 static const u32 pattern[8] = { 118 0xFF00FF00, 119 0xCC33CC33, 120 0xAA55AA55, 121 0x88778877, 122 0x92CC4D6E, 123 0x543D3CDE, 124 0xF1E843C7, 125 0x7C61D253 126 }; 127 128 static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl) 129 { 130 u32 data, timeout; 131 132 ast_moutdwm(ast, 0x1e6e0070, 0x00000000); 133 ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl); 134 timeout = 0; 135 do { 136 data = ast_mindwm(ast, 0x1e6e0070) & 0x1000; 137 if (++timeout > TIMEOUT) { 138 ast_moutdwm(ast, 0x1e6e0070, 0x0); 139 return 0xffffffff; 140 } 141 } while (!data); 142 data = ast_mindwm(ast, 0x1e6e0078); 143 data = (data | (data >> 16)) & 0xffff; 144 ast_moutdwm(ast, 0x1e6e0070, 0x00000000); 145 return data; 146 } 147 148 static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen) 149 { 150 return mmc_test2(ast, datagen, 0x41); 151 } 152 153 static bool mmc_test_single(struct ast_device *ast, u32 datagen) 154 { 155 return mmc_test(ast, datagen, 0xc5); 156 } 157 158 static u32 mmc_test_single2(struct ast_device *ast, u32 datagen) 159 { 160 return mmc_test2(ast, datagen, 0x05); 161 } 162 163 static int cbr_test(struct ast_device *ast) 164 { 165 u32 data; 166 int i; 167 168 data = mmc_test_single2(ast, 0); 169 if ((data & 0xff) && (data & 0xff00)) 170 return 0; 171 for (i = 0; i < 8; i++) { 172 data = mmc_test_burst2(ast, i); 173 if ((data & 0xff) && (data & 0xff00)) 174 return 0; 175 } 176 if (!data) 177 return 3; 178 else if (data & 0xff) 179 return 2; 180 return 1; 181 } 182 183 static int cbr_scan(struct ast_device *ast) 184 { 185 u32 data, data2, patcnt, loop; 186 187 data2 = 3; 188 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { 189 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); 190 for (loop = 0; loop < CBR_PASSNUM2; loop++) { 191 data = cbr_test(ast); 192 if (data != 0) { 193 data2 &= data; 194 if (!data2) 195 return 0; 196 break; 197 } 198 } 199 if (loop == CBR_PASSNUM2) 200 return 0; 201 } 202 return data2; 203 } 204 205 static u32 cbr_test2(struct ast_device *ast) 206 { 207 u32 data; 208 209 data = mmc_test_burst2(ast, 0); 210 if (data == 0xffff) 211 return 0; 212 data |= mmc_test_single2(ast, 0); 213 if (data == 0xffff) 214 return 0; 215 216 return ~data & 0xffff; 217 } 218 219 static u32 cbr_scan2(struct ast_device *ast) 220 { 221 u32 data, data2, patcnt, loop; 222 223 data2 = 0xffff; 224 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { 225 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); 226 for (loop = 0; loop < CBR_PASSNUM2; loop++) { 227 data = cbr_test2(ast); 228 if (data != 0) { 229 data2 &= data; 230 if (!data2) 231 return 0; 232 break; 233 } 234 } 235 if (loop == CBR_PASSNUM2) 236 return 0; 237 } 238 return data2; 239 } 240 241 static bool cbr_test3(struct ast_device *ast) 242 { 243 if (!mmc_test_burst(ast, 0)) 244 return false; 245 if (!mmc_test_single(ast, 0)) 246 return false; 247 return true; 248 } 249 250 static bool cbr_scan3(struct ast_device *ast) 251 { 252 u32 patcnt, loop; 253 254 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { 255 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); 256 for (loop = 0; loop < 2; loop++) { 257 if (cbr_test3(ast)) 258 break; 259 } 260 if (loop == 2) 261 return false; 262 } 263 return true; 264 } 265 266 static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param) 267 { 268 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0; 269 bool status = false; 270 FINETUNE_START: 271 for (cnt = 0; cnt < 16; cnt++) { 272 dllmin[cnt] = 0xff; 273 dllmax[cnt] = 0x0; 274 } 275 passcnt = 0; 276 for (dlli = 0; dlli < 76; dlli++) { 277 ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24)); 278 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1); 279 data = cbr_scan2(ast); 280 if (data != 0) { 281 mask = 0x00010001; 282 for (cnt = 0; cnt < 16; cnt++) { 283 if (data & mask) { 284 if (dllmin[cnt] > dlli) 285 dllmin[cnt] = dlli; 286 if (dllmax[cnt] < dlli) 287 dllmax[cnt] = dlli; 288 } 289 mask <<= 1; 290 } 291 passcnt++; 292 } else if (passcnt >= CBR_THRESHOLD2) { 293 break; 294 } 295 } 296 gold_sadj[0] = 0x0; 297 passcnt = 0; 298 for (cnt = 0; cnt < 16; cnt++) { 299 if ((dllmax[cnt] > dllmin[cnt]) && 300 ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { 301 gold_sadj[0] += dllmin[cnt]; 302 passcnt++; 303 } 304 } 305 if (retry++ > 10) 306 goto FINETUNE_DONE; 307 if (passcnt != 16) 308 goto FINETUNE_START; 309 status = true; 310 FINETUNE_DONE: 311 gold_sadj[0] = gold_sadj[0] >> 4; 312 gold_sadj[1] = gold_sadj[0]; 313 314 data = 0; 315 for (cnt = 0; cnt < 8; cnt++) { 316 data >>= 3; 317 if ((dllmax[cnt] > dllmin[cnt]) && 318 ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { 319 dlli = dllmin[cnt]; 320 if (gold_sadj[0] >= dlli) { 321 dlli = ((gold_sadj[0] - dlli) * 19) >> 5; 322 if (dlli > 3) 323 dlli = 3; 324 } else { 325 dlli = ((dlli - gold_sadj[0]) * 19) >> 5; 326 if (dlli > 4) 327 dlli = 4; 328 dlli = (8 - dlli) & 0x7; 329 } 330 data |= dlli << 21; 331 } 332 } 333 ast_moutdwm(ast, 0x1E6E0080, data); 334 335 data = 0; 336 for (cnt = 8; cnt < 16; cnt++) { 337 data >>= 3; 338 if ((dllmax[cnt] > dllmin[cnt]) && 339 ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { 340 dlli = dllmin[cnt]; 341 if (gold_sadj[1] >= dlli) { 342 dlli = ((gold_sadj[1] - dlli) * 19) >> 5; 343 if (dlli > 3) 344 dlli = 3; 345 else 346 dlli = (dlli - 1) & 0x7; 347 } else { 348 dlli = ((dlli - gold_sadj[1]) * 19) >> 5; 349 dlli += 1; 350 if (dlli > 4) 351 dlli = 4; 352 dlli = (8 - dlli) & 0x7; 353 } 354 data |= dlli << 21; 355 } 356 } 357 ast_moutdwm(ast, 0x1E6E0084, data); 358 return status; 359 } /* finetuneDQI_L */ 360 361 static void finetuneDQSI(struct ast_device *ast) 362 { 363 u32 dlli, dqsip, dqidly; 364 u32 reg_mcr18, reg_mcr0c, passcnt[2], diff; 365 u32 g_dqidly, g_dqsip, g_margin, g_side; 366 u16 pass[32][2][2]; 367 char tag[2][76]; 368 369 /* Disable DQI CBR */ 370 reg_mcr0c = ast_mindwm(ast, 0x1E6E000C); 371 reg_mcr18 = ast_mindwm(ast, 0x1E6E0018); 372 reg_mcr18 &= 0x0000ffff; 373 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); 374 375 for (dlli = 0; dlli < 76; dlli++) { 376 tag[0][dlli] = 0x0; 377 tag[1][dlli] = 0x0; 378 } 379 for (dqidly = 0; dqidly < 32; dqidly++) { 380 pass[dqidly][0][0] = 0xff; 381 pass[dqidly][0][1] = 0x0; 382 pass[dqidly][1][0] = 0xff; 383 pass[dqidly][1][1] = 0x0; 384 } 385 for (dqidly = 0; dqidly < 32; dqidly++) { 386 passcnt[0] = 0; 387 passcnt[1] = 0; 388 for (dqsip = 0; dqsip < 2; dqsip++) { 389 ast_moutdwm(ast, 0x1E6E000C, 0); 390 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23)); 391 ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c); 392 for (dlli = 0; dlli < 76; dlli++) { 393 ast_moutdwm(ast, 0x1E6E0068, 394 0x00001300 | (dlli << 16) | (dlli << 24)); 395 ast_moutdwm(ast, 0x1E6E0070, 0); 396 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0); 397 if (cbr_scan3(ast)) { 398 if (dlli == 0) 399 break; 400 passcnt[dqsip]++; 401 tag[dqsip][dlli] = 'P'; 402 if (dlli < pass[dqidly][dqsip][0]) 403 pass[dqidly][dqsip][0] = (u16)dlli; 404 if (dlli > pass[dqidly][dqsip][1]) 405 pass[dqidly][dqsip][1] = (u16)dlli; 406 } else if (passcnt[dqsip] >= 5) { 407 break; 408 } else { 409 pass[dqidly][dqsip][0] = 0xff; 410 pass[dqidly][dqsip][1] = 0x0; 411 } 412 } 413 } 414 if (passcnt[0] == 0 && passcnt[1] == 0) 415 dqidly++; 416 } 417 /* Search margin */ 418 g_dqidly = 0; 419 g_dqsip = 0; 420 g_margin = 0; 421 g_side = 0; 422 423 for (dqidly = 0; dqidly < 32; dqidly++) { 424 for (dqsip = 0; dqsip < 2; dqsip++) { 425 if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1]) 426 continue; 427 diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0]; 428 if ((diff + 2) < g_margin) 429 continue; 430 passcnt[0] = 0; 431 passcnt[1] = 0; 432 for (dlli = pass[dqidly][dqsip][0]; 433 dlli > 0 && tag[dqsip][dlli] != 0; 434 dlli--, passcnt[0]++) { 435 } 436 for (dlli = pass[dqidly][dqsip][1]; 437 dlli < 76 && tag[dqsip][dlli] != 0; 438 dlli++, passcnt[1]++) { 439 } 440 if (passcnt[0] > passcnt[1]) 441 passcnt[0] = passcnt[1]; 442 passcnt[1] = 0; 443 if (passcnt[0] > g_side) 444 passcnt[1] = passcnt[0] - g_side; 445 if (diff > (g_margin + 1) && (passcnt[1] > 0 || passcnt[0] > 8)) { 446 g_margin = diff; 447 g_dqidly = dqidly; 448 g_dqsip = dqsip; 449 g_side = passcnt[0]; 450 } else if (passcnt[1] > 1 && g_side < 8) { 451 if (diff > g_margin) 452 g_margin = diff; 453 g_dqidly = dqidly; 454 g_dqsip = dqsip; 455 g_side = passcnt[0]; 456 } 457 } 458 } 459 reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23); 460 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); 461 } 462 463 static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param) 464 { 465 u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0; 466 bool status = false; 467 468 finetuneDQSI(ast); 469 if (finetuneDQI_L(ast, param) == false) 470 return status; 471 472 CBR_START2: 473 dllmin[0] = 0xff; 474 dllmin[1] = 0xff; 475 dllmax[0] = 0x0; 476 dllmax[1] = 0x0; 477 passcnt = 0; 478 for (dlli = 0; dlli < 76; dlli++) { 479 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); 480 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2); 481 data = cbr_scan(ast); 482 if (data != 0) { 483 if (data & 0x1) { 484 if (dllmin[0] > dlli) 485 dllmin[0] = dlli; 486 if (dllmax[0] < dlli) 487 dllmax[0] = dlli; 488 } 489 if (data & 0x2) { 490 if (dllmin[1] > dlli) 491 dllmin[1] = dlli; 492 if (dllmax[1] < dlli) 493 dllmax[1] = dlli; 494 } 495 passcnt++; 496 } else if (passcnt >= CBR_THRESHOLD) { 497 break; 498 } 499 } 500 if (retry++ > 10) 501 goto CBR_DONE2; 502 if (dllmax[0] == 0 || (dllmax[0] - dllmin[0]) < CBR_THRESHOLD) 503 goto CBR_START2; 504 if (dllmax[1] == 0 || (dllmax[1] - dllmin[1]) < CBR_THRESHOLD) 505 goto CBR_START2; 506 status = true; 507 CBR_DONE2: 508 dlli = (dllmin[1] + dllmax[1]) >> 1; 509 dlli <<= 8; 510 dlli += (dllmin[0] + dllmax[0]) >> 1; 511 ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16)); 512 return status; 513 } /* CBRDLL2 */ 514 515 static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param) 516 { 517 u32 trap, trap_AC2, trap_MRS; 518 519 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); 520 521 /* Ger trap info */ 522 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; 523 trap_AC2 = 0x00020000 + (trap << 16); 524 trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19); 525 trap_MRS = 0x00000010 + (trap << 4); 526 trap_MRS |= ((trap & 0x2) << 18); 527 528 param->reg_MADJ = 0x00034C4C; 529 param->reg_SADJ = 0x00001800; 530 param->reg_DRV = 0x000000F0; 531 param->reg_PERIOD = param->dram_freq; 532 param->rodt = 0; 533 534 switch (param->dram_freq) { 535 case 336: 536 ast_moutdwm(ast, 0x1E6E2020, 0x0190); 537 param->wodt = 0; 538 param->reg_AC1 = 0x22202725; 539 param->reg_AC2 = 0xAA007613 | trap_AC2; 540 param->reg_DQSIC = 0x000000BA; 541 param->reg_MRS = 0x04001400 | trap_MRS; 542 param->reg_EMRS = 0x00000000; 543 param->reg_IOZ = 0x00000023; 544 param->reg_DQIDLY = 0x00000074; 545 param->reg_FREQ = 0x00004DC0; 546 param->madj_max = 96; 547 param->dll2_finetune_step = 3; 548 switch (param->dram_chipid) { 549 default: 550 case AST_DRAM_512Mx16: 551 case AST_DRAM_1Gx16: 552 param->reg_AC2 = 0xAA007613 | trap_AC2; 553 break; 554 case AST_DRAM_2Gx16: 555 param->reg_AC2 = 0xAA00761C | trap_AC2; 556 break; 557 case AST_DRAM_4Gx16: 558 param->reg_AC2 = 0xAA007636 | trap_AC2; 559 break; 560 } 561 break; 562 default: 563 case 396: 564 ast_moutdwm(ast, 0x1E6E2020, 0x03F1); 565 param->wodt = 1; 566 param->reg_AC1 = 0x33302825; 567 param->reg_AC2 = 0xCC009617 | trap_AC2; 568 param->reg_DQSIC = 0x000000E2; 569 param->reg_MRS = 0x04001600 | trap_MRS; 570 param->reg_EMRS = 0x00000000; 571 param->reg_IOZ = 0x00000034; 572 param->reg_DRV = 0x000000FA; 573 param->reg_DQIDLY = 0x00000089; 574 param->reg_FREQ = 0x00005040; 575 param->madj_max = 96; 576 param->dll2_finetune_step = 4; 577 578 switch (param->dram_chipid) { 579 default: 580 case AST_DRAM_512Mx16: 581 case AST_DRAM_1Gx16: 582 param->reg_AC2 = 0xCC009617 | trap_AC2; 583 break; 584 case AST_DRAM_2Gx16: 585 param->reg_AC2 = 0xCC009622 | trap_AC2; 586 break; 587 case AST_DRAM_4Gx16: 588 param->reg_AC2 = 0xCC00963F | trap_AC2; 589 break; 590 } 591 break; 592 593 case 408: 594 ast_moutdwm(ast, 0x1E6E2020, 0x01F0); 595 param->wodt = 1; 596 param->reg_AC1 = 0x33302825; 597 param->reg_AC2 = 0xCC009617 | trap_AC2; 598 param->reg_DQSIC = 0x000000E2; 599 param->reg_MRS = 0x04001600 | trap_MRS; 600 param->reg_EMRS = 0x00000000; 601 param->reg_IOZ = 0x00000023; 602 param->reg_DRV = 0x000000FA; 603 param->reg_DQIDLY = 0x00000089; 604 param->reg_FREQ = 0x000050C0; 605 param->madj_max = 96; 606 param->dll2_finetune_step = 4; 607 608 switch (param->dram_chipid) { 609 default: 610 case AST_DRAM_512Mx16: 611 case AST_DRAM_1Gx16: 612 param->reg_AC2 = 0xCC009617 | trap_AC2; 613 break; 614 case AST_DRAM_2Gx16: 615 param->reg_AC2 = 0xCC009622 | trap_AC2; 616 break; 617 case AST_DRAM_4Gx16: 618 param->reg_AC2 = 0xCC00963F | trap_AC2; 619 break; 620 } 621 622 break; 623 case 456: 624 ast_moutdwm(ast, 0x1E6E2020, 0x0230); 625 param->wodt = 0; 626 param->reg_AC1 = 0x33302926; 627 param->reg_AC2 = 0xCD44961A; 628 param->reg_DQSIC = 0x000000FC; 629 param->reg_MRS = 0x00081830; 630 param->reg_EMRS = 0x00000000; 631 param->reg_IOZ = 0x00000045; 632 param->reg_DQIDLY = 0x00000097; 633 param->reg_FREQ = 0x000052C0; 634 param->madj_max = 88; 635 param->dll2_finetune_step = 4; 636 break; 637 case 504: 638 ast_moutdwm(ast, 0x1E6E2020, 0x0270); 639 param->wodt = 1; 640 param->reg_AC1 = 0x33302926; 641 param->reg_AC2 = 0xDE44A61D; 642 param->reg_DQSIC = 0x00000117; 643 param->reg_MRS = 0x00081A30; 644 param->reg_EMRS = 0x00000000; 645 param->reg_IOZ = 0x070000BB; 646 param->reg_DQIDLY = 0x000000A0; 647 param->reg_FREQ = 0x000054C0; 648 param->madj_max = 79; 649 param->dll2_finetune_step = 4; 650 break; 651 case 528: 652 ast_moutdwm(ast, 0x1E6E2020, 0x0290); 653 param->wodt = 1; 654 param->rodt = 1; 655 param->reg_AC1 = 0x33302926; 656 param->reg_AC2 = 0xEF44B61E; 657 param->reg_DQSIC = 0x00000125; 658 param->reg_MRS = 0x00081A30; 659 param->reg_EMRS = 0x00000040; 660 param->reg_DRV = 0x000000F5; 661 param->reg_IOZ = 0x00000023; 662 param->reg_DQIDLY = 0x00000088; 663 param->reg_FREQ = 0x000055C0; 664 param->madj_max = 76; 665 param->dll2_finetune_step = 3; 666 break; 667 case 576: 668 ast_moutdwm(ast, 0x1E6E2020, 0x0140); 669 param->reg_MADJ = 0x00136868; 670 param->reg_SADJ = 0x00004534; 671 param->wodt = 1; 672 param->rodt = 1; 673 param->reg_AC1 = 0x33302A37; 674 param->reg_AC2 = 0xEF56B61E; 675 param->reg_DQSIC = 0x0000013F; 676 param->reg_MRS = 0x00101A50; 677 param->reg_EMRS = 0x00000040; 678 param->reg_DRV = 0x000000FA; 679 param->reg_IOZ = 0x00000023; 680 param->reg_DQIDLY = 0x00000078; 681 param->reg_FREQ = 0x000057C0; 682 param->madj_max = 136; 683 param->dll2_finetune_step = 3; 684 break; 685 case 600: 686 ast_moutdwm(ast, 0x1E6E2020, 0x02E1); 687 param->reg_MADJ = 0x00136868; 688 param->reg_SADJ = 0x00004534; 689 param->wodt = 1; 690 param->rodt = 1; 691 param->reg_AC1 = 0x32302A37; 692 param->reg_AC2 = 0xDF56B61F; 693 param->reg_DQSIC = 0x0000014D; 694 param->reg_MRS = 0x00101A50; 695 param->reg_EMRS = 0x00000004; 696 param->reg_DRV = 0x000000F5; 697 param->reg_IOZ = 0x00000023; 698 param->reg_DQIDLY = 0x00000078; 699 param->reg_FREQ = 0x000058C0; 700 param->madj_max = 132; 701 param->dll2_finetune_step = 3; 702 break; 703 case 624: 704 ast_moutdwm(ast, 0x1E6E2020, 0x0160); 705 param->reg_MADJ = 0x00136868; 706 param->reg_SADJ = 0x00004534; 707 param->wodt = 1; 708 param->rodt = 1; 709 param->reg_AC1 = 0x32302A37; 710 param->reg_AC2 = 0xEF56B621; 711 param->reg_DQSIC = 0x0000015A; 712 param->reg_MRS = 0x02101A50; 713 param->reg_EMRS = 0x00000004; 714 param->reg_DRV = 0x000000F5; 715 param->reg_IOZ = 0x00000034; 716 param->reg_DQIDLY = 0x00000078; 717 param->reg_FREQ = 0x000059C0; 718 param->madj_max = 128; 719 param->dll2_finetune_step = 3; 720 break; 721 } /* switch freq */ 722 723 switch (param->dram_chipid) { 724 case AST_DRAM_512Mx16: 725 param->dram_config = 0x130; 726 break; 727 default: 728 case AST_DRAM_1Gx16: 729 param->dram_config = 0x131; 730 break; 731 case AST_DRAM_2Gx16: 732 param->dram_config = 0x132; 733 break; 734 case AST_DRAM_4Gx16: 735 param->dram_config = 0x133; 736 break; 737 } /* switch size */ 738 739 switch (param->vram_size) { 740 default: 741 case SZ_8M: 742 param->dram_config |= 0x00; 743 break; 744 case SZ_16M: 745 param->dram_config |= 0x04; 746 break; 747 case SZ_32M: 748 param->dram_config |= 0x08; 749 break; 750 case SZ_64M: 751 param->dram_config |= 0x0c; 752 break; 753 } 754 } 755 756 static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param) 757 { 758 u32 data, data2, retry = 0; 759 760 ddr3_init_start: 761 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); 762 ast_moutdwm(ast, 0x1E6E0018, 0x00000100); 763 ast_moutdwm(ast, 0x1E6E0024, 0x00000000); 764 ast_moutdwm(ast, 0x1E6E0034, 0x00000000); 765 udelay(10); 766 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); 767 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); 768 udelay(10); 769 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); 770 udelay(10); 771 772 ast_moutdwm(ast, 0x1E6E0004, param->dram_config); 773 ast_moutdwm(ast, 0x1E6E0008, 0x90040f); 774 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); 775 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); 776 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); 777 ast_moutdwm(ast, 0x1E6E0080, 0x00000000); 778 ast_moutdwm(ast, 0x1E6E0084, 0x00000000); 779 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); 780 ast_moutdwm(ast, 0x1E6E0018, 0x4000A170); 781 ast_moutdwm(ast, 0x1E6E0018, 0x00002370); 782 ast_moutdwm(ast, 0x1E6E0038, 0x00000000); 783 ast_moutdwm(ast, 0x1E6E0040, 0xFF444444); 784 ast_moutdwm(ast, 0x1E6E0044, 0x22222222); 785 ast_moutdwm(ast, 0x1E6E0048, 0x22222222); 786 ast_moutdwm(ast, 0x1E6E004C, 0x00000002); 787 ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 788 ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 789 ast_moutdwm(ast, 0x1E6E0054, 0); 790 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); 791 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); 792 ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 793 ast_moutdwm(ast, 0x1E6E0074, 0x00000000); 794 ast_moutdwm(ast, 0x1E6E0078, 0x00000000); 795 ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 796 /* Wait MCLK2X lock to MCLK */ 797 do { 798 data = ast_mindwm(ast, 0x1E6E001C); 799 } while (!(data & 0x08000000)); 800 data = ast_mindwm(ast, 0x1E6E001C); 801 data = (data >> 8) & 0xff; 802 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { 803 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; 804 if ((data2 & 0xff) > param->madj_max) 805 break; 806 ast_moutdwm(ast, 0x1E6E0064, data2); 807 if (data2 & 0x00100000) 808 data2 = ((data2 & 0xff) >> 3) + 3; 809 else 810 data2 = ((data2 & 0xff) >> 2) + 5; 811 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; 812 data2 += data & 0xff; 813 data = data | (data2 << 8); 814 ast_moutdwm(ast, 0x1E6E0068, data); 815 udelay(10); 816 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); 817 udelay(10); 818 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; 819 ast_moutdwm(ast, 0x1E6E0018, data); 820 data = data | 0x200; 821 ast_moutdwm(ast, 0x1E6E0018, data); 822 do { 823 data = ast_mindwm(ast, 0x1E6E001C); 824 } while (!(data & 0x08000000)); 825 826 data = ast_mindwm(ast, 0x1E6E001C); 827 data = (data >> 8) & 0xff; 828 } 829 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff); 830 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; 831 ast_moutdwm(ast, 0x1E6E0018, data); 832 833 ast_moutdwm(ast, 0x1E6E0034, 0x00000001); 834 ast_moutdwm(ast, 0x1E6E000C, 0x00000040); 835 udelay(50); 836 /* Mode Register Setting */ 837 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); 838 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); 839 ast_moutdwm(ast, 0x1E6E0028, 0x00000005); 840 ast_moutdwm(ast, 0x1E6E0028, 0x00000007); 841 ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 842 ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 843 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); 844 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); 845 ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 846 847 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01); 848 data = 0; 849 if (param->wodt) 850 data = 0x300; 851 if (param->rodt) 852 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); 853 ast_moutdwm(ast, 0x1E6E0034, data | 0x3); 854 855 /* Calibrate the DQSI delay */ 856 if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) 857 goto ddr3_init_start; 858 859 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); 860 /* ECC Memory Initialization */ 861 #ifdef ECC 862 ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 863 ast_moutdwm(ast, 0x1E6E0070, 0x221); 864 do { 865 data = ast_mindwm(ast, 0x1E6E0070); 866 } while (!(data & 0x00001000)); 867 ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 868 ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 869 ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 870 #endif 871 } 872 873 static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param) 874 { 875 u32 trap, trap_AC2, trap_MRS; 876 877 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); 878 879 /* Ger trap info */ 880 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; 881 trap_AC2 = (trap << 20) | (trap << 16); 882 trap_AC2 += 0x00110000; 883 trap_MRS = 0x00000040 | (trap << 4); 884 885 param->reg_MADJ = 0x00034C4C; 886 param->reg_SADJ = 0x00001800; 887 param->reg_DRV = 0x000000F0; 888 param->reg_PERIOD = param->dram_freq; 889 param->rodt = 0; 890 891 switch (param->dram_freq) { 892 case 264: 893 ast_moutdwm(ast, 0x1E6E2020, 0x0130); 894 param->wodt = 0; 895 param->reg_AC1 = 0x11101513; 896 param->reg_AC2 = 0x78117011; 897 param->reg_DQSIC = 0x00000092; 898 param->reg_MRS = 0x00000842; 899 param->reg_EMRS = 0x00000000; 900 param->reg_DRV = 0x000000F0; 901 param->reg_IOZ = 0x00000034; 902 param->reg_DQIDLY = 0x0000005A; 903 param->reg_FREQ = 0x00004AC0; 904 param->madj_max = 138; 905 param->dll2_finetune_step = 3; 906 break; 907 case 336: 908 ast_moutdwm(ast, 0x1E6E2020, 0x0190); 909 param->wodt = 1; 910 param->reg_AC1 = 0x22202613; 911 param->reg_AC2 = 0xAA009016 | trap_AC2; 912 param->reg_DQSIC = 0x000000BA; 913 param->reg_MRS = 0x00000A02 | trap_MRS; 914 param->reg_EMRS = 0x00000040; 915 param->reg_DRV = 0x000000FA; 916 param->reg_IOZ = 0x00000034; 917 param->reg_DQIDLY = 0x00000074; 918 param->reg_FREQ = 0x00004DC0; 919 param->madj_max = 96; 920 param->dll2_finetune_step = 3; 921 switch (param->dram_chipid) { 922 default: 923 case AST_DRAM_512Mx16: 924 param->reg_AC2 = 0xAA009012 | trap_AC2; 925 break; 926 case AST_DRAM_1Gx16: 927 param->reg_AC2 = 0xAA009016 | trap_AC2; 928 break; 929 case AST_DRAM_2Gx16: 930 param->reg_AC2 = 0xAA009023 | trap_AC2; 931 break; 932 case AST_DRAM_4Gx16: 933 param->reg_AC2 = 0xAA00903B | trap_AC2; 934 break; 935 } 936 break; 937 default: 938 case 396: 939 ast_moutdwm(ast, 0x1E6E2020, 0x03F1); 940 param->wodt = 1; 941 param->rodt = 0; 942 param->reg_AC1 = 0x33302714; 943 param->reg_AC2 = 0xCC00B01B | trap_AC2; 944 param->reg_DQSIC = 0x000000E2; 945 param->reg_MRS = 0x00000C02 | trap_MRS; 946 param->reg_EMRS = 0x00000040; 947 param->reg_DRV = 0x000000FA; 948 param->reg_IOZ = 0x00000034; 949 param->reg_DQIDLY = 0x00000089; 950 param->reg_FREQ = 0x00005040; 951 param->madj_max = 96; 952 param->dll2_finetune_step = 4; 953 954 switch (param->dram_chipid) { 955 case AST_DRAM_512Mx16: 956 param->reg_AC2 = 0xCC00B016 | trap_AC2; 957 break; 958 default: 959 case AST_DRAM_1Gx16: 960 param->reg_AC2 = 0xCC00B01B | trap_AC2; 961 break; 962 case AST_DRAM_2Gx16: 963 param->reg_AC2 = 0xCC00B02B | trap_AC2; 964 break; 965 case AST_DRAM_4Gx16: 966 param->reg_AC2 = 0xCC00B03F | trap_AC2; 967 break; 968 } 969 970 break; 971 972 case 408: 973 ast_moutdwm(ast, 0x1E6E2020, 0x01F0); 974 param->wodt = 1; 975 param->rodt = 0; 976 param->reg_AC1 = 0x33302714; 977 param->reg_AC2 = 0xCC00B01B | trap_AC2; 978 param->reg_DQSIC = 0x000000E2; 979 param->reg_MRS = 0x00000C02 | trap_MRS; 980 param->reg_EMRS = 0x00000040; 981 param->reg_DRV = 0x000000FA; 982 param->reg_IOZ = 0x00000034; 983 param->reg_DQIDLY = 0x00000089; 984 param->reg_FREQ = 0x000050C0; 985 param->madj_max = 96; 986 param->dll2_finetune_step = 4; 987 988 switch (param->dram_chipid) { 989 case AST_DRAM_512Mx16: 990 param->reg_AC2 = 0xCC00B016 | trap_AC2; 991 break; 992 default: 993 case AST_DRAM_1Gx16: 994 param->reg_AC2 = 0xCC00B01B | trap_AC2; 995 break; 996 case AST_DRAM_2Gx16: 997 param->reg_AC2 = 0xCC00B02B | trap_AC2; 998 break; 999 case AST_DRAM_4Gx16: 1000 param->reg_AC2 = 0xCC00B03F | trap_AC2; 1001 break; 1002 } 1003 1004 break; 1005 case 456: 1006 ast_moutdwm(ast, 0x1E6E2020, 0x0230); 1007 param->wodt = 0; 1008 param->reg_AC1 = 0x33302815; 1009 param->reg_AC2 = 0xCD44B01E; 1010 param->reg_DQSIC = 0x000000FC; 1011 param->reg_MRS = 0x00000E72; 1012 param->reg_EMRS = 0x00000000; 1013 param->reg_DRV = 0x00000000; 1014 param->reg_IOZ = 0x00000034; 1015 param->reg_DQIDLY = 0x00000097; 1016 param->reg_FREQ = 0x000052C0; 1017 param->madj_max = 88; 1018 param->dll2_finetune_step = 3; 1019 break; 1020 case 504: 1021 ast_moutdwm(ast, 0x1E6E2020, 0x0261); 1022 param->wodt = 1; 1023 param->rodt = 1; 1024 param->reg_AC1 = 0x33302815; 1025 param->reg_AC2 = 0xDE44C022; 1026 param->reg_DQSIC = 0x00000117; 1027 param->reg_MRS = 0x00000E72; 1028 param->reg_EMRS = 0x00000040; 1029 param->reg_DRV = 0x0000000A; 1030 param->reg_IOZ = 0x00000045; 1031 param->reg_DQIDLY = 0x000000A0; 1032 param->reg_FREQ = 0x000054C0; 1033 param->madj_max = 79; 1034 param->dll2_finetune_step = 3; 1035 break; 1036 case 528: 1037 ast_moutdwm(ast, 0x1E6E2020, 0x0120); 1038 param->wodt = 1; 1039 param->rodt = 1; 1040 param->reg_AC1 = 0x33302815; 1041 param->reg_AC2 = 0xEF44D024; 1042 param->reg_DQSIC = 0x00000125; 1043 param->reg_MRS = 0x00000E72; 1044 param->reg_EMRS = 0x00000004; 1045 param->reg_DRV = 0x000000F9; 1046 param->reg_IOZ = 0x00000045; 1047 param->reg_DQIDLY = 0x000000A7; 1048 param->reg_FREQ = 0x000055C0; 1049 param->madj_max = 76; 1050 param->dll2_finetune_step = 3; 1051 break; 1052 case 552: 1053 ast_moutdwm(ast, 0x1E6E2020, 0x02A1); 1054 param->wodt = 1; 1055 param->rodt = 1; 1056 param->reg_AC1 = 0x43402915; 1057 param->reg_AC2 = 0xFF44E025; 1058 param->reg_DQSIC = 0x00000132; 1059 param->reg_MRS = 0x00000E72; 1060 param->reg_EMRS = 0x00000040; 1061 param->reg_DRV = 0x0000000A; 1062 param->reg_IOZ = 0x00000045; 1063 param->reg_DQIDLY = 0x000000AD; 1064 param->reg_FREQ = 0x000056C0; 1065 param->madj_max = 76; 1066 param->dll2_finetune_step = 3; 1067 break; 1068 case 576: 1069 ast_moutdwm(ast, 0x1E6E2020, 0x0140); 1070 param->wodt = 1; 1071 param->rodt = 1; 1072 param->reg_AC1 = 0x43402915; 1073 param->reg_AC2 = 0xFF44E027; 1074 param->reg_DQSIC = 0x0000013F; 1075 param->reg_MRS = 0x00000E72; 1076 param->reg_EMRS = 0x00000004; 1077 param->reg_DRV = 0x000000F5; 1078 param->reg_IOZ = 0x00000045; 1079 param->reg_DQIDLY = 0x000000B3; 1080 param->reg_FREQ = 0x000057C0; 1081 param->madj_max = 76; 1082 param->dll2_finetune_step = 3; 1083 break; 1084 } 1085 1086 switch (param->dram_chipid) { 1087 case AST_DRAM_512Mx16: 1088 param->dram_config = 0x100; 1089 break; 1090 default: 1091 case AST_DRAM_1Gx16: 1092 param->dram_config = 0x121; 1093 break; 1094 case AST_DRAM_2Gx16: 1095 param->dram_config = 0x122; 1096 break; 1097 case AST_DRAM_4Gx16: 1098 param->dram_config = 0x123; 1099 break; 1100 } /* switch size */ 1101 1102 switch (param->vram_size) { 1103 default: 1104 case SZ_8M: 1105 param->dram_config |= 0x00; 1106 break; 1107 case SZ_16M: 1108 param->dram_config |= 0x04; 1109 break; 1110 case SZ_32M: 1111 param->dram_config |= 0x08; 1112 break; 1113 case SZ_64M: 1114 param->dram_config |= 0x0c; 1115 break; 1116 } 1117 } 1118 1119 static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param) 1120 { 1121 u32 data, data2, retry = 0; 1122 1123 ddr2_init_start: 1124 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); 1125 ast_moutdwm(ast, 0x1E6E0018, 0x00000100); 1126 ast_moutdwm(ast, 0x1E6E0024, 0x00000000); 1127 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); 1128 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); 1129 udelay(10); 1130 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); 1131 udelay(10); 1132 1133 ast_moutdwm(ast, 0x1E6E0004, param->dram_config); 1134 ast_moutdwm(ast, 0x1E6E0008, 0x90040f); 1135 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); 1136 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); 1137 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); 1138 ast_moutdwm(ast, 0x1E6E0080, 0x00000000); 1139 ast_moutdwm(ast, 0x1E6E0084, 0x00000000); 1140 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); 1141 ast_moutdwm(ast, 0x1E6E0018, 0x4000A130); 1142 ast_moutdwm(ast, 0x1E6E0018, 0x00002330); 1143 ast_moutdwm(ast, 0x1E6E0038, 0x00000000); 1144 ast_moutdwm(ast, 0x1E6E0040, 0xFF808000); 1145 ast_moutdwm(ast, 0x1E6E0044, 0x88848466); 1146 ast_moutdwm(ast, 0x1E6E0048, 0x44440008); 1147 ast_moutdwm(ast, 0x1E6E004C, 0x00000000); 1148 ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 1149 ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 1150 ast_moutdwm(ast, 0x1E6E0054, 0); 1151 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); 1152 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); 1153 ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 1154 ast_moutdwm(ast, 0x1E6E0074, 0x00000000); 1155 ast_moutdwm(ast, 0x1E6E0078, 0x00000000); 1156 ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 1157 1158 /* Wait MCLK2X lock to MCLK */ 1159 do { 1160 data = ast_mindwm(ast, 0x1E6E001C); 1161 } while (!(data & 0x08000000)); 1162 data = ast_mindwm(ast, 0x1E6E001C); 1163 data = (data >> 8) & 0xff; 1164 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { 1165 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; 1166 if ((data2 & 0xff) > param->madj_max) 1167 break; 1168 ast_moutdwm(ast, 0x1E6E0064, data2); 1169 if (data2 & 0x00100000) 1170 data2 = ((data2 & 0xff) >> 3) + 3; 1171 else 1172 data2 = ((data2 & 0xff) >> 2) + 5; 1173 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; 1174 data2 += data & 0xff; 1175 data = data | (data2 << 8); 1176 ast_moutdwm(ast, 0x1E6E0068, data); 1177 udelay(10); 1178 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); 1179 udelay(10); 1180 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; 1181 ast_moutdwm(ast, 0x1E6E0018, data); 1182 data = data | 0x200; 1183 ast_moutdwm(ast, 0x1E6E0018, data); 1184 do { 1185 data = ast_mindwm(ast, 0x1E6E001C); 1186 } while (!(data & 0x08000000)); 1187 1188 data = ast_mindwm(ast, 0x1E6E001C); 1189 data = (data >> 8) & 0xff; 1190 } 1191 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff); 1192 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; 1193 ast_moutdwm(ast, 0x1E6E0018, data); 1194 1195 ast_moutdwm(ast, 0x1E6E0034, 0x00000001); 1196 ast_moutdwm(ast, 0x1E6E000C, 0x00000000); 1197 udelay(50); 1198 /* Mode Register Setting */ 1199 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); 1200 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); 1201 ast_moutdwm(ast, 0x1E6E0028, 0x00000005); 1202 ast_moutdwm(ast, 0x1E6E0028, 0x00000007); 1203 ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 1204 ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 1205 1206 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); 1207 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); 1208 ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 1209 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380); 1210 ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 1211 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); 1212 ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 1213 1214 ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01); 1215 data = 0; 1216 if (param->wodt) 1217 data = 0x500; 1218 if (param->rodt) 1219 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); 1220 ast_moutdwm(ast, 0x1E6E0034, data | 0x3); 1221 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); 1222 1223 /* Calibrate the DQSI delay */ 1224 if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) 1225 goto ddr2_init_start; 1226 1227 /* ECC Memory Initialization */ 1228 #ifdef ECC 1229 ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 1230 ast_moutdwm(ast, 0x1E6E0070, 0x221); 1231 do { 1232 data = ast_mindwm(ast, 0x1E6E0070); 1233 } while (!(data & 0x00001000)); 1234 ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 1235 ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 1236 ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 1237 #endif 1238 } 1239 1240 static void ast_post_chip_2300(struct ast_device *ast) 1241 { 1242 struct ast2300_dram_param param; 1243 u32 temp; 1244 u8 reg; 1245 1246 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 1247 if ((reg & 0x80) == 0) {/* vga only */ 1248 ast_write32(ast, 0xf004, 0x1e6e0000); 1249 ast_write32(ast, 0xf000, 0x1); 1250 ast_write32(ast, 0x12000, 0x1688a8a8); 1251 do { 1252 ; 1253 } while (ast_read32(ast, 0x12000) != 0x1); 1254 1255 ast_write32(ast, 0x10000, 0xfc600309); 1256 do { 1257 ; 1258 } while (ast_read32(ast, 0x10000) != 0x1); 1259 1260 /* Slow down CPU/AHB CLK in VGA only mode */ 1261 temp = ast_read32(ast, 0x12008); 1262 temp |= 0x73; 1263 ast_write32(ast, 0x12008, temp); 1264 1265 param.dram_freq = 396; 1266 param.dram_type = AST_DDR3; 1267 temp = ast_mindwm(ast, 0x1e6e2070); 1268 if (temp & 0x01000000) 1269 param.dram_type = AST_DDR2; 1270 switch (temp & 0x18000000) { 1271 case 0: 1272 param.dram_chipid = AST_DRAM_512Mx16; 1273 break; 1274 default: 1275 case 0x08000000: 1276 param.dram_chipid = AST_DRAM_1Gx16; 1277 break; 1278 case 0x10000000: 1279 param.dram_chipid = AST_DRAM_2Gx16; 1280 break; 1281 case 0x18000000: 1282 param.dram_chipid = AST_DRAM_4Gx16; 1283 break; 1284 } 1285 switch (temp & 0x0c) { 1286 default: 1287 case 0x00: 1288 param.vram_size = SZ_8M; 1289 break; 1290 case 0x04: 1291 param.vram_size = SZ_16M; 1292 break; 1293 case 0x08: 1294 param.vram_size = SZ_32M; 1295 break; 1296 case 0x0c: 1297 param.vram_size = SZ_64M; 1298 break; 1299 } 1300 1301 if (param.dram_type == AST_DDR3) { 1302 get_ddr3_info(ast, ¶m); 1303 ddr3_init(ast, ¶m); 1304 } else { 1305 get_ddr2_info(ast, ¶m); 1306 ddr2_init(ast, ¶m); 1307 } 1308 1309 temp = ast_mindwm(ast, 0x1e6e2040); 1310 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); 1311 } 1312 1313 /* wait ready */ 1314 do { 1315 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 1316 } while ((reg & 0x40) == 0); 1317 } 1318 1319 int ast_2300_post(struct ast_device *ast) 1320 { 1321 ast_2300_set_def_ext_reg(ast); 1322 1323 if (ast->config_mode == ast_use_p2a) { 1324 ast_post_chip_2300(ast); 1325 ast_init_3rdtx(ast); 1326 } else { 1327 if (ast->tx_chip == AST_TX_SIL164) { 1328 /* Enable DVO */ 1329 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); 1330 } 1331 } 1332 1333 return 0; 1334 } 1335 1336 /* 1337 * Device initialization 1338 */ 1339 1340 void ast_2300_detect_tx_chip(struct ast_device *ast) 1341 { 1342 enum ast_tx_chip tx_chip = AST_TX_NONE; 1343 struct drm_device *dev = &ast->base; 1344 u8 vgacrd1; 1345 1346 /* 1347 * On AST GEN4+, look at the configuration set by the SoC in 1348 * the SOC scratch register #1 bits 11:8 (interestingly marked 1349 * as "reserved" in the spec) 1350 */ 1351 vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 1352 AST_IO_VGACRD1_TX_TYPE_MASK); 1353 switch (vgacrd1) { 1354 /* 1355 * GEN4 to GEN6 1356 */ 1357 case AST_IO_VGACRD1_TX_SIL164_VBIOS: 1358 tx_chip = AST_TX_SIL164; 1359 break; 1360 case AST_IO_VGACRD1_TX_DP501_VBIOS: 1361 ast->dp501_fw_addr = drmm_kzalloc(dev, SZ_32K, GFP_KERNEL); 1362 if (ast->dp501_fw_addr) { 1363 /* backup firmware */ 1364 if (ast_backup_fw(ast, ast->dp501_fw_addr, SZ_32K)) { 1365 drmm_kfree(dev, ast->dp501_fw_addr); 1366 ast->dp501_fw_addr = NULL; 1367 } 1368 } 1369 fallthrough; 1370 case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW: 1371 tx_chip = AST_TX_DP501; 1372 break; 1373 /* 1374 * GEN7+ 1375 */ 1376 case AST_IO_VGACRD1_TX_ASTDP: 1377 tx_chip = AST_TX_ASTDP; 1378 break; 1379 /* 1380 * Several of the listed TX chips are not explicitly supported 1381 * by the ast driver. If these exist in real-world devices, they 1382 * are most likely reported as VGA or SIL164 outputs. We warn here 1383 * to get bug reports for these devices. If none come in for some 1384 * time, we can begin to fail device probing on these values. 1385 */ 1386 case AST_IO_VGACRD1_TX_ITE66121_VBIOS: 1387 drm_warn(dev, "ITE IT66121 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); 1388 break; 1389 case AST_IO_VGACRD1_TX_CH7003_VBIOS: 1390 drm_warn(dev, "Chrontel CH7003 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); 1391 break; 1392 case AST_IO_VGACRD1_TX_ANX9807_VBIOS: 1393 drm_warn(dev, "Analogix ANX9807 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); 1394 break; 1395 } 1396 1397 __ast_device_set_tx_chip(ast, tx_chip); 1398 } 1399 1400 static void ast_2300_detect_widescreen(struct ast_device *ast) 1401 { 1402 if (__ast_2100_detect_wsxga_p(ast) || ast->chip == AST1300) { 1403 ast->support_wsxga_p = true; 1404 ast->support_fullhd = true; 1405 } 1406 if (__ast_2100_detect_wuxga(ast)) 1407 ast->support_wuxga = true; 1408 } 1409 1410 static const struct ast_device_quirks ast_2300_device_quirks = { 1411 .crtc_mem_req_threshold_low = 96, 1412 .crtc_mem_req_threshold_high = 120, 1413 }; 1414 1415 struct drm_device *ast_2300_device_create(struct pci_dev *pdev, 1416 const struct drm_driver *drv, 1417 enum ast_chip chip, 1418 enum ast_config_mode config_mode, 1419 void __iomem *regs, 1420 void __iomem *ioregs, 1421 bool need_post) 1422 { 1423 struct drm_device *dev; 1424 struct ast_device *ast; 1425 int ret; 1426 1427 ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base); 1428 if (IS_ERR(ast)) 1429 return ERR_CAST(ast); 1430 dev = &ast->base; 1431 1432 ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2300_device_quirks); 1433 1434 ast->dclk_table = ast_2000_dclk_table; 1435 1436 ast_2300_detect_tx_chip(ast); 1437 1438 if (need_post) { 1439 ret = ast_post_gpu(ast); 1440 if (ret) 1441 return ERR_PTR(ret); 1442 } 1443 1444 ret = ast_mm_init(ast); 1445 if (ret) 1446 return ERR_PTR(ret); 1447 1448 /* map reserved buffer */ 1449 ast->dp501_fw_buf = NULL; 1450 if (ast->vram_size < pci_resource_len(pdev, 0)) { 1451 ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0); 1452 if (!ast->dp501_fw_buf) 1453 drm_info(dev, "failed to map reserved buffer!\n"); 1454 } 1455 1456 ast_2300_detect_widescreen(ast); 1457 1458 ret = ast_mode_config_init(ast); 1459 if (ret) 1460 return ERR_PTR(ret); 1461 1462 return dev; 1463 } 1464