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