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