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