soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / drivers / aspeed / common / ast_post.c
blob856e4e5ac693a59adcf1161baaefd95a44f6f0b8
1 /* SPDX-License-Identifier: MIT */
3 #define COREBOOT_AST_FAILOVER_TIMEOUT 10000000
5 #include <console/console.h>
6 #include <delay.h>
8 #include "ast_drv.h"
9 #include "ast_dram_tables.h"
11 static void ast_post_chip_2300(struct drm_device *dev);
12 static void ast_post_chip_2500(struct drm_device *dev);
14 void ast_enable_vga(struct drm_device *dev)
16 struct ast_private *ast = dev->dev_private;
18 ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01);
19 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01);
22 void ast_enable_mmio(struct drm_device *dev)
24 struct ast_private *ast = dev->dev_private;
26 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04);
29 bool ast_is_vga_enabled(struct drm_device *dev)
31 struct ast_private *ast = dev->dev_private;
32 u8 ch;
34 if (ast->chip == AST1180) {
35 /* TODO 1180 */
36 } else {
37 ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
38 return !!(ch & 0x01);
40 return false;
43 static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
44 static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
45 static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
47 static void
48 ast_set_def_ext_reg(struct drm_device *dev)
50 struct ast_private *ast = dev->dev_private;
51 u8 i, index, reg;
52 uint32_t data;
53 const u8 *ext_reg_info;
55 pci_read_config_dword(ast->dev->pdev, 0x08, &data);
56 uint8_t revision = data & 0xff;
58 /* reset scratch */
59 for (i = 0x81; i <= 0x9f; i++)
60 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
62 if (ast->chip == AST2300 || ast->chip == AST2400 ||
63 ast->chip == AST2500) {
64 if (revision >= 0x20)
65 ext_reg_info = extreginfo_ast2300;
66 else
67 ext_reg_info = extreginfo_ast2300a0;
68 } else
69 ext_reg_info = extreginfo;
71 index = 0xa0;
72 while (*ext_reg_info != 0xff) {
73 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
74 index++;
75 ext_reg_info++;
78 /* disable standard IO/MEM decode if secondary */
79 /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
81 /* Set Ext. Default */
82 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
83 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
85 /* Enable RAMDAC for A1 */
86 reg = 0x04;
87 if (ast->chip == AST2300 || ast->chip == AST2400 ||
88 ast->chip == AST2500)
89 reg |= 0x20;
90 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
93 u32 ast_mindwm(struct ast_private *ast, u32 r)
95 uint32_t timeout;
96 uint32_t data;
98 ast_write32(ast, 0xf004, r & 0xffff0000);
99 ast_write32(ast, 0xf000, 0x1);
101 timeout = 0;
102 do {
103 data = ast_read32(ast, 0xf004) & 0xffff0000;
104 timeout++;
105 } while ((data != (r & 0xffff0000)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
106 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
107 dev_err(dev->pdev, "Timeout while waiting for register\n");
108 return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
111 void ast_moutdwm(struct ast_private *ast, u32 r, u32 v)
113 uint32_t timeout;
114 uint32_t data;
116 ast_write32(ast, 0xf004, r & 0xffff0000);
117 ast_write32(ast, 0xf000, 0x1);
118 timeout = 0;
119 do {
120 data = ast_read32(ast, 0xf004) & 0xffff0000;
121 timeout++;
122 } while ((data != (r & 0xffff0000)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
123 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
124 dev_err(dev->pdev, "Timeout while waiting for register\n");
125 ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
129 * AST2100/2150 DLL CBR Setting
131 #define CBR_SIZE_AST2150 ((16 << 10) - 1)
132 #define CBR_PASSNUM_AST2150 5
133 #define CBR_THRESHOLD_AST2150 10
134 #define CBR_THRESHOLD2_AST2150 10
135 #define TIMEOUT_AST2150 5000000
137 #define CBR_PATNUM_AST2150 8
139 static const u32 pattern_AST2150[14] = {
140 0xFF00FF00,
141 0xCC33CC33,
142 0xAA55AA55,
143 0xFFFE0001,
144 0x683501FE,
145 0x0F1929B0,
146 0x2D0B4346,
147 0x60767F02,
148 0x6FBE36A6,
149 0x3A253035,
150 0x3019686D,
151 0x41C6167E,
152 0x620152BF,
153 0x20F050E0
156 static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
158 u32 data, timeout;
160 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
161 ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
162 timeout = 0;
163 do {
164 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
165 if (++timeout > TIMEOUT_AST2150) {
166 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
167 return 0xffffffff;
169 } while (!data);
170 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
171 ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (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;
179 } while (!data);
180 data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
181 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
182 return data;
185 static int cbrtest_ast2150(struct ast_private *ast)
187 int i;
189 for (i = 0; i < 8; i++)
190 if (mmctestburst2_ast2150(ast, i))
191 return 0;
192 return 1;
195 static int cbrscan_ast2150(struct ast_private *ast, int busw)
197 u32 patcnt, loop;
199 for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
200 ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
201 for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
202 if (cbrtest_ast2150(ast))
203 break;
205 if (loop == CBR_PASSNUM_AST2150)
206 return 0;
208 return 1;
211 static void cbrdlli_ast2150(struct ast_private *ast, int busw)
213 u32 dll_min[4], dll_max[4], dlli, data, passcnt;
215 cbr_start:
216 dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
217 dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
218 passcnt = 0;
220 for (dlli = 0; dlli < 100; dlli++) {
221 ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
222 data = cbrscan_ast2150(ast, busw);
223 if (data != 0) {
224 if (data & 0x1) {
225 if (dll_min[0] > dlli)
226 dll_min[0] = dlli;
227 if (dll_max[0] < dlli)
228 dll_max[0] = dlli;
230 passcnt++;
231 } else if (passcnt >= CBR_THRESHOLD_AST2150)
232 goto cbr_start;
234 if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
235 goto cbr_start;
237 dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
238 ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
241 static void ast_init_dram_reg(struct drm_device *dev)
243 struct ast_private *ast = dev->dev_private;
244 u8 j;
245 u32 data, temp, i;
246 uint32_t timeout;
247 const struct ast_dramstruct *dram_reg_info;
249 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
251 if ((j & 0x80) == 0) { /* VGA only */
252 if (ast->chip == AST2000) {
253 dram_reg_info = ast2000_dram_table_data;
254 ast_write32(ast, 0xf004, 0x1e6e0000);
255 ast_write32(ast, 0xf000, 0x1);
256 ast_write32(ast, 0x10100, 0xa8);
258 timeout = 0;
259 do {
260 timeout++;
261 } while ((ast_read32(ast, 0x10100) != 0xa8) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
262 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
263 dev_err(dev->pdev, "Timeout while waiting for register\n");
264 } else {/* AST2100/1100 */
265 if (ast->chip == AST2100 || ast->chip == 2200)
266 dram_reg_info = ast2100_dram_table_data;
267 else
268 dram_reg_info = ast1100_dram_table_data;
270 ast_write32(ast, 0xf004, 0x1e6e0000);
271 ast_write32(ast, 0xf000, 0x1);
272 ast_write32(ast, 0x12000, 0x1688A8A8);
274 /* Wait up to 2.5 seconds for device initialization / register unlock */
275 for (i = 0; i < 250; i++) {
276 if (ast_read32(ast, 0x12000) == 0x01)
277 break;
278 mdelay(10);
280 if (ast_read32(ast, 0x12000) != 0x01)
281 dev_err(dev->pdev, "Unable to unlock SCU registers\n");
283 ast_write32(ast, 0x10000, 0xfc600309);
285 /* Wait up to 2.5 seconds for device initialization / register unlock */
286 for (i = 0; i < 250; i++) {
287 if (ast_read32(ast, 0x10000) == 0x01)
288 break;
289 mdelay(10);
291 if (ast_read32(ast, 0x10000) != 0x01)
292 dev_err(dev->pdev, "Unable to unlock SDRAM control registers\n");
295 while (dram_reg_info->index != 0xffff) {
296 if (dram_reg_info->index == 0xff00) {/* delay fn */
297 for (i = 0; i < 15; i++)
298 udelay(dram_reg_info->data);
299 } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
300 data = dram_reg_info->data;
301 if (ast->dram_type == AST_DRAM_1Gx16)
302 data = 0x00000d89;
303 else if (ast->dram_type == AST_DRAM_1Gx32)
304 data = 0x00000c8d;
306 temp = ast_read32(ast, 0x12070);
307 temp &= 0xc;
308 temp <<= 2;
309 ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
310 } else
311 ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
312 dram_reg_info++;
315 /* AST 2100/2150 DRAM calibration */
316 data = ast_read32(ast, 0x10120);
317 if (data == 0x5061) { /* 266Mhz */
318 data = ast_read32(ast, 0x10004);
319 if (data & 0x40)
320 cbrdlli_ast2150(ast, 16); /* 16 bits */
321 else
322 cbrdlli_ast2150(ast, 32); /* 32 bits */
325 switch (ast->chip) {
326 case AST2000:
327 temp = ast_read32(ast, 0x10140);
328 ast_write32(ast, 0x10140, temp | 0x40);
329 break;
330 case AST1100:
331 case AST2100:
332 case AST2200:
333 case AST2150:
334 temp = ast_read32(ast, 0x1200c);
335 ast_write32(ast, 0x1200c, temp & 0xfffffffd);
336 temp = ast_read32(ast, 0x12040);
337 ast_write32(ast, 0x12040, temp | 0x40);
338 break;
339 default:
340 break;
344 /* wait ready */
345 /* Wait up to 2.5 seconds for device to become ready */
346 for (i = 0; i < 250; i++) {
347 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
348 mdelay(10);
349 if ((j & 0x40) != 0)
350 break;
352 if ((j & 0x40) == 0)
353 dev_err(dev->pdev, "Timeout while waiting for device to signal ready\n");
356 void ast_post_gpu(struct drm_device *dev)
358 u32 reg;
359 struct ast_private *ast = dev->dev_private;
361 pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
362 reg |= 0x3;
363 pci_write_config_dword(ast->dev->pdev, 0x04, reg);
365 ast_enable_vga(dev);
366 ast_open_key(ast);
367 ast_enable_mmio(dev);
368 ast_set_def_ext_reg(dev);
370 if (ast->config_mode == ast_use_p2a) {
371 if (ast->chip == AST2500)
372 ast_post_chip_2500(dev);
373 else if (ast->chip == AST2300 || ast->chip == AST2400)
374 ast_post_chip_2300(dev);
375 else
376 ast_init_dram_reg(dev);
378 ast_init_3rdtx(dev);
379 } else {
380 if (ast->tx_chip_type != AST_TX_NONE)
381 /* Enable DVO */
382 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);
386 /* AST 2300 DRAM settings */
387 #define AST_DDR3 0
388 #define AST_DDR2 1
390 struct ast2300_dram_param {
391 u32 dram_type;
392 u32 dram_chipid;
393 u32 dram_freq;
394 u32 vram_size;
395 u32 odt;
396 u32 wodt;
397 u32 rodt;
398 u32 dram_config;
399 u32 reg_PERIOD;
400 u32 reg_MADJ;
401 u32 reg_SADJ;
402 u32 reg_MRS;
403 u32 reg_EMRS;
404 u32 reg_AC1;
405 u32 reg_AC2;
406 u32 reg_DQSIC;
407 u32 reg_DRV;
408 u32 reg_IOZ;
409 u32 reg_DQIDLY;
410 u32 reg_FREQ;
411 u32 madj_max;
412 u32 dll2_finetune_step;
416 * DQSI DLL CBR Setting
418 #define CBR_SIZE0 ((1 << 10) - 1)
419 #define CBR_SIZE1 ((4 << 10) - 1)
420 #define CBR_SIZE2 ((64 << 10) - 1)
421 #define CBR_PASSNUM 5
422 #define CBR_PASSNUM2 5
423 #define CBR_THRESHOLD 10
424 #define CBR_THRESHOLD2 10
425 #define TIMEOUT 5000000
426 #define CBR_PATNUM 8
428 static const u32 pattern[8] = {
429 0xFF00FF00,
430 0xCC33CC33,
431 0xAA55AA55,
432 0x88778877,
433 0x92CC4D6E,
434 0x543D3CDE,
435 0xF1E843C7,
436 0x7C61D253
439 static bool mmc_test(struct ast_private *ast, u32 datagen, u8 test_ctl)
441 u32 data, timeout;
443 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
444 ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
445 timeout = 0;
446 do {
447 data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
448 if (data & 0x2000)
449 return false;
450 if (++timeout > TIMEOUT) {
451 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
452 return false;
454 } while (!data);
455 ast_moutdwm(ast, 0x1e6e0070, 0x0);
456 return true;
459 static u32 mmc_test2(struct ast_private *ast, u32 datagen, u8 test_ctl)
461 u32 data, timeout;
463 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
464 ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
465 timeout = 0;
466 do {
467 data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
468 if (++timeout > TIMEOUT) {
469 ast_moutdwm(ast, 0x1e6e0070, 0x0);
470 return 0xffffffff;
472 } while (!data);
473 data = ast_mindwm(ast, 0x1e6e0078);
474 data = (data | (data >> 16)) & 0xffff;
475 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
476 return data;
479 static bool mmc_test_burst(struct ast_private *ast, u32 datagen)
481 return mmc_test(ast, datagen, 0xc1);
484 static u32 mmc_test_burst2(struct ast_private *ast, u32 datagen)
486 return mmc_test2(ast, datagen, 0x41);
489 static bool mmc_test_single(struct ast_private *ast, u32 datagen)
491 return mmc_test(ast, datagen, 0xc5);
494 static u32 mmc_test_single2(struct ast_private *ast, u32 datagen)
496 return mmc_test2(ast, datagen, 0x05);
499 static bool mmc_test_single_2500(struct ast_private *ast, u32 datagen)
501 return mmc_test(ast, datagen, 0x85);
504 static int cbr_test(struct ast_private *ast)
506 u32 data;
507 int i;
508 data = mmc_test_single2(ast, 0);
509 if ((data & 0xff) && (data & 0xff00))
510 return 0;
511 for (i = 0; i < 8; i++) {
512 data = mmc_test_burst2(ast, i);
513 if ((data & 0xff) && (data & 0xff00))
514 return 0;
516 if (!data)
517 return 3;
518 else if (data & 0xff)
519 return 2;
520 return 1;
523 static int cbr_scan(struct ast_private *ast)
525 u32 data, data2, patcnt, loop;
527 data2 = 3;
528 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
529 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
530 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
531 if ((data = cbr_test(ast)) != 0) {
532 data2 &= data;
533 if (!data2)
534 return 0;
535 break;
538 if (loop == CBR_PASSNUM2)
539 return 0;
541 return data2;
544 static u32 cbr_test2(struct ast_private *ast)
546 u32 data;
548 data = mmc_test_burst2(ast, 0);
549 if (data == 0xffff)
550 return 0;
551 data |= mmc_test_single2(ast, 0);
552 if (data == 0xffff)
553 return 0;
555 return ~data & 0xffff;
558 static u32 cbr_scan2(struct ast_private *ast)
560 u32 data, data2, patcnt, loop;
562 data2 = 0xffff;
563 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
564 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
565 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
566 if ((data = cbr_test2(ast)) != 0) {
567 data2 &= data;
568 if (!data2)
569 return 0;
570 break;
573 if (loop == CBR_PASSNUM2)
574 return 0;
576 return data2;
579 static bool cbr_test3(struct ast_private *ast)
581 if (!mmc_test_burst(ast, 0))
582 return false;
583 if (!mmc_test_single(ast, 0))
584 return false;
585 return true;
588 static bool cbr_scan3(struct ast_private *ast)
590 u32 patcnt, loop;
592 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
593 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
594 for (loop = 0; loop < 2; loop++) {
595 if (cbr_test3(ast))
596 break;
598 if (loop == 2)
599 return false;
601 return true;
604 static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
606 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
607 bool status = false;
608 FINETUNE_START:
609 for (cnt = 0; cnt < 16; cnt++) {
610 dllmin[cnt] = 0xff;
611 dllmax[cnt] = 0x0;
613 passcnt = 0;
614 for (dlli = 0; dlli < 76; dlli++) {
615 ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
616 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
617 data = cbr_scan2(ast);
618 if (data != 0) {
619 mask = 0x00010001;
620 for (cnt = 0; cnt < 16; cnt++) {
621 if (data & mask) {
622 if (dllmin[cnt] > dlli) {
623 dllmin[cnt] = dlli;
625 if (dllmax[cnt] < dlli) {
626 dllmax[cnt] = dlli;
629 mask <<= 1;
631 passcnt++;
632 } else if (passcnt >= CBR_THRESHOLD2) {
633 break;
636 gold_sadj[0] = 0x0;
637 passcnt = 0;
638 for (cnt = 0; cnt < 16; cnt++) {
639 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
640 gold_sadj[0] += dllmin[cnt];
641 passcnt++;
644 if (retry++ > 10)
645 goto FINETUNE_DONE;
646 if (passcnt != 16) {
647 goto FINETUNE_START;
649 status = true;
650 FINETUNE_DONE:
651 gold_sadj[0] = gold_sadj[0] >> 4;
652 gold_sadj[1] = gold_sadj[0];
654 data = 0;
655 for (cnt = 0; cnt < 8; cnt++) {
656 data >>= 3;
657 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
658 dlli = dllmin[cnt];
659 if (gold_sadj[0] >= dlli) {
660 dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
661 if (dlli > 3) {
662 dlli = 3;
664 } else {
665 dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
666 if (dlli > 4) {
667 dlli = 4;
669 dlli = (8 - dlli) & 0x7;
671 data |= dlli << 21;
674 ast_moutdwm(ast, 0x1E6E0080, data);
676 data = 0;
677 for (cnt = 8; cnt < 16; cnt++) {
678 data >>= 3;
679 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
680 dlli = dllmin[cnt];
681 if (gold_sadj[1] >= dlli) {
682 dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
683 if (dlli > 3) {
684 dlli = 3;
685 } else {
686 dlli = (dlli - 1) & 0x7;
688 } else {
689 dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
690 dlli += 1;
691 if (dlli > 4) {
692 dlli = 4;
694 dlli = (8 - dlli) & 0x7;
696 data |= dlli << 21;
699 ast_moutdwm(ast, 0x1E6E0084, data);
700 return status;
701 } /* finetuneDQI_L */
703 static void finetuneDQSI(struct ast_private *ast)
705 u32 dlli, dqsip, dqidly;
706 u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
707 u32 g_dqidly, g_dqsip, g_margin, g_side;
708 u16 pass[32][2][2];
709 char tag[2][76];
711 /* Disable DQI CBR */
712 reg_mcr0c = ast_mindwm(ast, 0x1E6E000C);
713 reg_mcr18 = ast_mindwm(ast, 0x1E6E0018);
714 reg_mcr18 &= 0x0000ffff;
715 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
717 for (dlli = 0; dlli < 76; dlli++) {
718 tag[0][dlli] = 0x0;
719 tag[1][dlli] = 0x0;
721 for (dqidly = 0; dqidly < 32; dqidly++) {
722 pass[dqidly][0][0] = 0xff;
723 pass[dqidly][0][1] = 0x0;
724 pass[dqidly][1][0] = 0xff;
725 pass[dqidly][1][1] = 0x0;
727 for (dqidly = 0; dqidly < 32; dqidly++) {
728 passcnt[0] = passcnt[1] = 0;
729 for (dqsip = 0; dqsip < 2; dqsip++) {
730 ast_moutdwm(ast, 0x1E6E000C, 0);
731 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
732 ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
733 for (dlli = 0; dlli < 76; dlli++) {
734 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
735 ast_moutdwm(ast, 0x1E6E0070, 0);
736 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
737 if (cbr_scan3(ast)) {
738 if (dlli == 0)
739 break;
740 passcnt[dqsip]++;
741 tag[dqsip][dlli] = 'P';
742 if (dlli < pass[dqidly][dqsip][0])
743 pass[dqidly][dqsip][0] = (u16)dlli;
744 if (dlli > pass[dqidly][dqsip][1])
745 pass[dqidly][dqsip][1] = (u16)dlli;
746 } else if (passcnt[dqsip] >= 5)
747 break;
748 else {
749 pass[dqidly][dqsip][0] = 0xff;
750 pass[dqidly][dqsip][1] = 0x0;
754 if (passcnt[0] == 0 && passcnt[1] == 0)
755 dqidly++;
757 /* Search margin */
758 g_dqidly = g_dqsip = g_margin = g_side = 0;
760 for (dqidly = 0; dqidly < 32; dqidly++) {
761 for (dqsip = 0; dqsip < 2; dqsip++) {
762 if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
763 continue;
764 diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
765 if ((diff+2) < g_margin)
766 continue;
767 passcnt[0] = passcnt[1] = 0;
768 for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++);
769 for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++);
770 if (passcnt[0] > passcnt[1])
771 passcnt[0] = passcnt[1];
772 passcnt[1] = 0;
773 if (passcnt[0] > g_side)
774 passcnt[1] = passcnt[0] - g_side;
775 if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
776 g_margin = diff;
777 g_dqidly = dqidly;
778 g_dqsip = dqsip;
779 g_side = passcnt[0];
780 } else if (passcnt[1] > 1 && g_side < 8) {
781 if (diff > g_margin)
782 g_margin = diff;
783 g_dqidly = dqidly;
784 g_dqsip = dqsip;
785 g_side = passcnt[0];
789 reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
790 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
793 static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
795 u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
796 bool status = false;
798 finetuneDQSI(ast);
799 if (finetuneDQI_L(ast, param) == false)
800 return status;
802 CBR_START2:
803 dllmin[0] = dllmin[1] = 0xff;
804 dllmax[0] = dllmax[1] = 0x0;
805 passcnt = 0;
806 for (dlli = 0; dlli < 76; dlli++) {
807 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
808 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
809 data = cbr_scan(ast);
810 if (data != 0) {
811 if (data & 0x1) {
812 if (dllmin[0] > dlli) {
813 dllmin[0] = dlli;
815 if (dllmax[0] < dlli) {
816 dllmax[0] = dlli;
819 if (data & 0x2) {
820 if (dllmin[1] > dlli) {
821 dllmin[1] = dlli;
823 if (dllmax[1] < dlli) {
824 dllmax[1] = dlli;
827 passcnt++;
828 } else if (passcnt >= CBR_THRESHOLD) {
829 break;
832 if (retry++ > 10)
833 goto CBR_DONE2;
834 if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
835 goto CBR_START2;
837 if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
838 goto CBR_START2;
840 status = true;
841 CBR_DONE2:
842 dlli = (dllmin[1] + dllmax[1]) >> 1;
843 dlli <<= 8;
844 dlli += (dllmin[0] + dllmax[0]) >> 1;
845 ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
846 return status;
847 } /* CBRDLL2 */
849 static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
851 u32 trap, trap_AC2, trap_MRS;
853 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
855 /* Ger trap info */
856 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
857 trap_AC2 = 0x00020000 + (trap << 16);
858 trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
859 trap_MRS = 0x00000010 + (trap << 4);
860 trap_MRS |= ((trap & 0x2) << 18);
862 param->reg_MADJ = 0x00034C4C;
863 param->reg_SADJ = 0x00001800;
864 param->reg_DRV = 0x000000F0;
865 param->reg_PERIOD = param->dram_freq;
866 param->rodt = 0;
868 switch (param->dram_freq) {
869 case 336:
870 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
871 param->wodt = 0;
872 param->reg_AC1 = 0x22202725;
873 param->reg_AC2 = 0xAA007613 | trap_AC2;
874 param->reg_DQSIC = 0x000000BA;
875 param->reg_MRS = 0x04001400 | trap_MRS;
876 param->reg_EMRS = 0x00000000;
877 param->reg_IOZ = 0x00000023;
878 param->reg_DQIDLY = 0x00000074;
879 param->reg_FREQ = 0x00004DC0;
880 param->madj_max = 96;
881 param->dll2_finetune_step = 3;
882 switch (param->dram_chipid) {
883 default:
884 case AST_DRAM_512Mx16:
885 case AST_DRAM_1Gx16:
886 param->reg_AC2 = 0xAA007613 | trap_AC2;
887 break;
888 case AST_DRAM_2Gx16:
889 param->reg_AC2 = 0xAA00761C | trap_AC2;
890 break;
891 case AST_DRAM_4Gx16:
892 param->reg_AC2 = 0xAA007636 | trap_AC2;
893 break;
895 break;
896 default:
897 case 396:
898 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
899 param->wodt = 1;
900 param->reg_AC1 = 0x33302825;
901 param->reg_AC2 = 0xCC009617 | trap_AC2;
902 param->reg_DQSIC = 0x000000E2;
903 param->reg_MRS = 0x04001600 | trap_MRS;
904 param->reg_EMRS = 0x00000000;
905 param->reg_IOZ = 0x00000034;
906 param->reg_DRV = 0x000000FA;
907 param->reg_DQIDLY = 0x00000089;
908 param->reg_FREQ = 0x00005040;
909 param->madj_max = 96;
910 param->dll2_finetune_step = 4;
912 switch (param->dram_chipid) {
913 default:
914 case AST_DRAM_512Mx16:
915 case AST_DRAM_1Gx16:
916 param->reg_AC2 = 0xCC009617 | trap_AC2;
917 break;
918 case AST_DRAM_2Gx16:
919 param->reg_AC2 = 0xCC009622 | trap_AC2;
920 break;
921 case AST_DRAM_4Gx16:
922 param->reg_AC2 = 0xCC00963F | trap_AC2;
923 break;
925 break;
927 case 408:
928 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
929 param->wodt = 1;
930 param->reg_AC1 = 0x33302825;
931 param->reg_AC2 = 0xCC009617 | trap_AC2;
932 param->reg_DQSIC = 0x000000E2;
933 param->reg_MRS = 0x04001600 | trap_MRS;
934 param->reg_EMRS = 0x00000000;
935 param->reg_IOZ = 0x00000023;
936 param->reg_DRV = 0x000000FA;
937 param->reg_DQIDLY = 0x00000089;
938 param->reg_FREQ = 0x000050C0;
939 param->madj_max = 96;
940 param->dll2_finetune_step = 4;
942 switch (param->dram_chipid) {
943 default:
944 case AST_DRAM_512Mx16:
945 case AST_DRAM_1Gx16:
946 param->reg_AC2 = 0xCC009617 | trap_AC2;
947 break;
948 case AST_DRAM_2Gx16:
949 param->reg_AC2 = 0xCC009622 | trap_AC2;
950 break;
951 case AST_DRAM_4Gx16:
952 param->reg_AC2 = 0xCC00963F | trap_AC2;
953 break;
956 break;
957 case 456:
958 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
959 param->wodt = 0;
960 param->reg_AC1 = 0x33302926;
961 param->reg_AC2 = 0xCD44961A;
962 param->reg_DQSIC = 0x000000FC;
963 param->reg_MRS = 0x00081830;
964 param->reg_EMRS = 0x00000000;
965 param->reg_IOZ = 0x00000045;
966 param->reg_DQIDLY = 0x00000097;
967 param->reg_FREQ = 0x000052C0;
968 param->madj_max = 88;
969 param->dll2_finetune_step = 4;
970 break;
971 case 504:
972 ast_moutdwm(ast, 0x1E6E2020, 0x0270);
973 param->wodt = 1;
974 param->reg_AC1 = 0x33302926;
975 param->reg_AC2 = 0xDE44A61D;
976 param->reg_DQSIC = 0x00000117;
977 param->reg_MRS = 0x00081A30;
978 param->reg_EMRS = 0x00000000;
979 param->reg_IOZ = 0x070000BB;
980 param->reg_DQIDLY = 0x000000A0;
981 param->reg_FREQ = 0x000054C0;
982 param->madj_max = 79;
983 param->dll2_finetune_step = 4;
984 break;
985 case 528:
986 ast_moutdwm(ast, 0x1E6E2020, 0x0290);
987 param->wodt = 1;
988 param->rodt = 1;
989 param->reg_AC1 = 0x33302926;
990 param->reg_AC2 = 0xEF44B61E;
991 param->reg_DQSIC = 0x00000125;
992 param->reg_MRS = 0x00081A30;
993 param->reg_EMRS = 0x00000040;
994 param->reg_DRV = 0x000000F5;
995 param->reg_IOZ = 0x00000023;
996 param->reg_DQIDLY = 0x00000088;
997 param->reg_FREQ = 0x000055C0;
998 param->madj_max = 76;
999 param->dll2_finetune_step = 3;
1000 break;
1001 case 576:
1002 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1003 param->reg_MADJ = 0x00136868;
1004 param->reg_SADJ = 0x00004534;
1005 param->wodt = 1;
1006 param->rodt = 1;
1007 param->reg_AC1 = 0x33302A37;
1008 param->reg_AC2 = 0xEF56B61E;
1009 param->reg_DQSIC = 0x0000013F;
1010 param->reg_MRS = 0x00101A50;
1011 param->reg_EMRS = 0x00000040;
1012 param->reg_DRV = 0x000000FA;
1013 param->reg_IOZ = 0x00000023;
1014 param->reg_DQIDLY = 0x00000078;
1015 param->reg_FREQ = 0x000057C0;
1016 param->madj_max = 136;
1017 param->dll2_finetune_step = 3;
1018 break;
1019 case 600:
1020 ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
1021 param->reg_MADJ = 0x00136868;
1022 param->reg_SADJ = 0x00004534;
1023 param->wodt = 1;
1024 param->rodt = 1;
1025 param->reg_AC1 = 0x32302A37;
1026 param->reg_AC2 = 0xDF56B61F;
1027 param->reg_DQSIC = 0x0000014D;
1028 param->reg_MRS = 0x00101A50;
1029 param->reg_EMRS = 0x00000004;
1030 param->reg_DRV = 0x000000F5;
1031 param->reg_IOZ = 0x00000023;
1032 param->reg_DQIDLY = 0x00000078;
1033 param->reg_FREQ = 0x000058C0;
1034 param->madj_max = 132;
1035 param->dll2_finetune_step = 3;
1036 break;
1037 case 624:
1038 ast_moutdwm(ast, 0x1E6E2020, 0x0160);
1039 param->reg_MADJ = 0x00136868;
1040 param->reg_SADJ = 0x00004534;
1041 param->wodt = 1;
1042 param->rodt = 1;
1043 param->reg_AC1 = 0x32302A37;
1044 param->reg_AC2 = 0xEF56B621;
1045 param->reg_DQSIC = 0x0000015A;
1046 param->reg_MRS = 0x02101A50;
1047 param->reg_EMRS = 0x00000004;
1048 param->reg_DRV = 0x000000F5;
1049 param->reg_IOZ = 0x00000034;
1050 param->reg_DQIDLY = 0x00000078;
1051 param->reg_FREQ = 0x000059C0;
1052 param->madj_max = 128;
1053 param->dll2_finetune_step = 3;
1054 break;
1055 } /* switch freq */
1057 switch (param->dram_chipid) {
1058 case AST_DRAM_512Mx16:
1059 param->dram_config = 0x130;
1060 break;
1061 default:
1062 case AST_DRAM_1Gx16:
1063 param->dram_config = 0x131;
1064 break;
1065 case AST_DRAM_2Gx16:
1066 param->dram_config = 0x132;
1067 break;
1068 case AST_DRAM_4Gx16:
1069 param->dram_config = 0x133;
1070 break;
1071 } /* switch size */
1073 switch (param->vram_size) {
1074 default:
1075 case AST_VIDMEM_SIZE_8M:
1076 param->dram_config |= 0x00;
1077 break;
1078 case AST_VIDMEM_SIZE_16M:
1079 param->dram_config |= 0x04;
1080 break;
1081 case AST_VIDMEM_SIZE_32M:
1082 param->dram_config |= 0x08;
1083 break;
1084 case AST_VIDMEM_SIZE_64M:
1085 param->dram_config |= 0x0c;
1086 break;
1090 static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1092 u32 data, data2, retry = 0;
1093 uint32_t timeout;
1094 uint32_t timeout2;
1096 ddr3_init_start:
1097 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1098 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1099 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1100 ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
1101 udelay(10);
1102 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1103 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1104 udelay(10);
1105 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1106 udelay(10);
1108 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1109 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1110 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1111 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1112 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1113 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1114 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1115 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1116 ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
1117 ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
1118 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1119 ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
1120 ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
1121 ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1122 ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
1123 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1124 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1125 ast_moutdwm(ast, 0x1E6E0054, 0);
1126 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1127 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1128 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1129 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1130 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1131 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1132 /* Wait MCLK2X lock to MCLK */
1133 timeout = 0;
1134 do {
1135 data = ast_mindwm(ast, 0x1E6E001C);
1136 timeout++;
1137 } while ((!(data & 0x08000000)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1138 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1139 dev_err(dev->pdev, "Timeout while waiting for register\n");
1140 data = ast_mindwm(ast, 0x1E6E001C);
1141 data = (data >> 8) & 0xff;
1142 timeout = 0;
1143 while (((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT)) {
1144 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1145 if ((data2 & 0xff) > param->madj_max) {
1146 break;
1148 ast_moutdwm(ast, 0x1E6E0064, data2);
1149 if (data2 & 0x00100000) {
1150 data2 = ((data2 & 0xff) >> 3) + 3;
1151 } else {
1152 data2 = ((data2 & 0xff) >> 2) + 5;
1154 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1155 data2 += data & 0xff;
1156 data = data | (data2 << 8);
1157 ast_moutdwm(ast, 0x1E6E0068, data);
1158 udelay(10);
1159 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1160 udelay(10);
1161 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1162 ast_moutdwm(ast, 0x1E6E0018, data);
1163 data = data | 0x200;
1164 ast_moutdwm(ast, 0x1E6E0018, data);
1165 timeout2 = 0;
1166 do {
1167 data = ast_mindwm(ast, 0x1E6E001C);
1168 timeout2++;
1169 } while ((!(data & 0x08000000)) && (timeout2 < COREBOOT_AST_FAILOVER_TIMEOUT));
1170 if (timeout2 >= COREBOOT_AST_FAILOVER_TIMEOUT)
1171 dev_err(dev->pdev, "Timeout while waiting for register\n");
1173 data = ast_mindwm(ast, 0x1E6E001C);
1174 data = (data >> 8) & 0xff;
1176 timeout++;
1178 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1179 dev_err(dev->pdev, "Timeout while waiting for register\n");
1180 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
1181 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1182 ast_moutdwm(ast, 0x1E6E0018, data);
1184 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1185 ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
1186 udelay(50);
1187 /* Mode Register Setting */
1188 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1189 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1190 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1191 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1192 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1193 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1194 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1195 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1196 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1198 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1199 data = 0;
1200 if (param->wodt) {
1201 data = 0x300;
1203 if (param->rodt) {
1204 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1206 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1208 /* Calibrate the DQSI delay */
1209 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1210 goto ddr3_init_start;
1212 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1213 /* ECC Memory Initialization */
1214 #ifdef ECC
1215 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1216 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1217 timeout = 0;
1218 do {
1219 data = ast_mindwm(ast, 0x1E6E0070);
1220 timeout++;
1221 } while ((!(data & 0x00001000)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1222 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1223 dev_err(dev->pdev, "Timeout while waiting for register\n");
1224 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1225 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1226 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1227 #endif
1230 static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1232 u32 trap, trap_AC2, trap_MRS;
1234 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1236 /* Ger trap info */
1237 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1238 trap_AC2 = (trap << 20) | (trap << 16);
1239 trap_AC2 += 0x00110000;
1240 trap_MRS = 0x00000040 | (trap << 4);
1242 param->reg_MADJ = 0x00034C4C;
1243 param->reg_SADJ = 0x00001800;
1244 param->reg_DRV = 0x000000F0;
1245 param->reg_PERIOD = param->dram_freq;
1246 param->rodt = 0;
1248 switch (param->dram_freq) {
1249 case 264:
1250 ast_moutdwm(ast, 0x1E6E2020, 0x0130);
1251 param->wodt = 0;
1252 param->reg_AC1 = 0x11101513;
1253 param->reg_AC2 = 0x78117011;
1254 param->reg_DQSIC = 0x00000092;
1255 param->reg_MRS = 0x00000842;
1256 param->reg_EMRS = 0x00000000;
1257 param->reg_DRV = 0x000000F0;
1258 param->reg_IOZ = 0x00000034;
1259 param->reg_DQIDLY = 0x0000005A;
1260 param->reg_FREQ = 0x00004AC0;
1261 param->madj_max = 138;
1262 param->dll2_finetune_step = 3;
1263 break;
1264 case 336:
1265 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
1266 param->wodt = 1;
1267 param->reg_AC1 = 0x22202613;
1268 param->reg_AC2 = 0xAA009016 | trap_AC2;
1269 param->reg_DQSIC = 0x000000BA;
1270 param->reg_MRS = 0x00000A02 | trap_MRS;
1271 param->reg_EMRS = 0x00000040;
1272 param->reg_DRV = 0x000000FA;
1273 param->reg_IOZ = 0x00000034;
1274 param->reg_DQIDLY = 0x00000074;
1275 param->reg_FREQ = 0x00004DC0;
1276 param->madj_max = 96;
1277 param->dll2_finetune_step = 3;
1278 switch (param->dram_chipid) {
1279 default:
1280 case AST_DRAM_512Mx16:
1281 param->reg_AC2 = 0xAA009012 | trap_AC2;
1282 break;
1283 case AST_DRAM_1Gx16:
1284 param->reg_AC2 = 0xAA009016 | trap_AC2;
1285 break;
1286 case AST_DRAM_2Gx16:
1287 param->reg_AC2 = 0xAA009023 | trap_AC2;
1288 break;
1289 case AST_DRAM_4Gx16:
1290 param->reg_AC2 = 0xAA00903B | trap_AC2;
1291 break;
1293 break;
1294 default:
1295 case 396:
1296 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
1297 param->wodt = 1;
1298 param->rodt = 0;
1299 param->reg_AC1 = 0x33302714;
1300 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1301 param->reg_DQSIC = 0x000000E2;
1302 param->reg_MRS = 0x00000C02 | trap_MRS;
1303 param->reg_EMRS = 0x00000040;
1304 param->reg_DRV = 0x000000FA;
1305 param->reg_IOZ = 0x00000034;
1306 param->reg_DQIDLY = 0x00000089;
1307 param->reg_FREQ = 0x00005040;
1308 param->madj_max = 96;
1309 param->dll2_finetune_step = 4;
1311 switch (param->dram_chipid) {
1312 case AST_DRAM_512Mx16:
1313 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1314 break;
1315 default:
1316 case AST_DRAM_1Gx16:
1317 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1318 break;
1319 case AST_DRAM_2Gx16:
1320 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1321 break;
1322 case AST_DRAM_4Gx16:
1323 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1324 break;
1327 break;
1329 case 408:
1330 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
1331 param->wodt = 1;
1332 param->rodt = 0;
1333 param->reg_AC1 = 0x33302714;
1334 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1335 param->reg_DQSIC = 0x000000E2;
1336 param->reg_MRS = 0x00000C02 | trap_MRS;
1337 param->reg_EMRS = 0x00000040;
1338 param->reg_DRV = 0x000000FA;
1339 param->reg_IOZ = 0x00000034;
1340 param->reg_DQIDLY = 0x00000089;
1341 param->reg_FREQ = 0x000050C0;
1342 param->madj_max = 96;
1343 param->dll2_finetune_step = 4;
1345 switch (param->dram_chipid) {
1346 case AST_DRAM_512Mx16:
1347 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1348 break;
1349 default:
1350 case AST_DRAM_1Gx16:
1351 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1352 break;
1353 case AST_DRAM_2Gx16:
1354 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1355 break;
1356 case AST_DRAM_4Gx16:
1357 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1358 break;
1361 break;
1362 case 456:
1363 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
1364 param->wodt = 0;
1365 param->reg_AC1 = 0x33302815;
1366 param->reg_AC2 = 0xCD44B01E;
1367 param->reg_DQSIC = 0x000000FC;
1368 param->reg_MRS = 0x00000E72;
1369 param->reg_EMRS = 0x00000000;
1370 param->reg_DRV = 0x00000000;
1371 param->reg_IOZ = 0x00000034;
1372 param->reg_DQIDLY = 0x00000097;
1373 param->reg_FREQ = 0x000052C0;
1374 param->madj_max = 88;
1375 param->dll2_finetune_step = 3;
1376 break;
1377 case 504:
1378 ast_moutdwm(ast, 0x1E6E2020, 0x0261);
1379 param->wodt = 1;
1380 param->rodt = 1;
1381 param->reg_AC1 = 0x33302815;
1382 param->reg_AC2 = 0xDE44C022;
1383 param->reg_DQSIC = 0x00000117;
1384 param->reg_MRS = 0x00000E72;
1385 param->reg_EMRS = 0x00000040;
1386 param->reg_DRV = 0x0000000A;
1387 param->reg_IOZ = 0x00000045;
1388 param->reg_DQIDLY = 0x000000A0;
1389 param->reg_FREQ = 0x000054C0;
1390 param->madj_max = 79;
1391 param->dll2_finetune_step = 3;
1392 break;
1393 case 528:
1394 ast_moutdwm(ast, 0x1E6E2020, 0x0120);
1395 param->wodt = 1;
1396 param->rodt = 1;
1397 param->reg_AC1 = 0x33302815;
1398 param->reg_AC2 = 0xEF44D024;
1399 param->reg_DQSIC = 0x00000125;
1400 param->reg_MRS = 0x00000E72;
1401 param->reg_EMRS = 0x00000004;
1402 param->reg_DRV = 0x000000F9;
1403 param->reg_IOZ = 0x00000045;
1404 param->reg_DQIDLY = 0x000000A7;
1405 param->reg_FREQ = 0x000055C0;
1406 param->madj_max = 76;
1407 param->dll2_finetune_step = 3;
1408 break;
1409 case 552:
1410 ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
1411 param->wodt = 1;
1412 param->rodt = 1;
1413 param->reg_AC1 = 0x43402915;
1414 param->reg_AC2 = 0xFF44E025;
1415 param->reg_DQSIC = 0x00000132;
1416 param->reg_MRS = 0x00000E72;
1417 param->reg_EMRS = 0x00000040;
1418 param->reg_DRV = 0x0000000A;
1419 param->reg_IOZ = 0x00000045;
1420 param->reg_DQIDLY = 0x000000AD;
1421 param->reg_FREQ = 0x000056C0;
1422 param->madj_max = 76;
1423 param->dll2_finetune_step = 3;
1424 break;
1425 case 576:
1426 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1427 param->wodt = 1;
1428 param->rodt = 1;
1429 param->reg_AC1 = 0x43402915;
1430 param->reg_AC2 = 0xFF44E027;
1431 param->reg_DQSIC = 0x0000013F;
1432 param->reg_MRS = 0x00000E72;
1433 param->reg_EMRS = 0x00000004;
1434 param->reg_DRV = 0x000000F5;
1435 param->reg_IOZ = 0x00000045;
1436 param->reg_DQIDLY = 0x000000B3;
1437 param->reg_FREQ = 0x000057C0;
1438 param->madj_max = 76;
1439 param->dll2_finetune_step = 3;
1440 break;
1443 switch (param->dram_chipid) {
1444 case AST_DRAM_512Mx16:
1445 param->dram_config = 0x100;
1446 break;
1447 default:
1448 case AST_DRAM_1Gx16:
1449 param->dram_config = 0x121;
1450 break;
1451 case AST_DRAM_2Gx16:
1452 param->dram_config = 0x122;
1453 break;
1454 case AST_DRAM_4Gx16:
1455 param->dram_config = 0x123;
1456 break;
1457 } /* switch size */
1459 switch (param->vram_size) {
1460 default:
1461 case AST_VIDMEM_SIZE_8M:
1462 param->dram_config |= 0x00;
1463 break;
1464 case AST_VIDMEM_SIZE_16M:
1465 param->dram_config |= 0x04;
1466 break;
1467 case AST_VIDMEM_SIZE_32M:
1468 param->dram_config |= 0x08;
1469 break;
1470 case AST_VIDMEM_SIZE_64M:
1471 param->dram_config |= 0x0c;
1472 break;
1476 static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1478 u32 data, data2, retry = 0;
1479 uint32_t timeout;
1480 uint32_t timeout2;
1482 ddr2_init_start:
1483 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1484 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1485 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1486 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1487 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1488 udelay(10);
1489 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1490 udelay(10);
1492 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1493 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1494 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1495 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1496 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1497 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1498 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1499 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1500 ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
1501 ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
1502 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1503 ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
1504 ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
1505 ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
1506 ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
1507 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1508 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1509 ast_moutdwm(ast, 0x1E6E0054, 0);
1510 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1511 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1512 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1513 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1514 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1515 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1517 /* Wait MCLK2X lock to MCLK */
1518 timeout = 0;
1519 do {
1520 data = ast_mindwm(ast, 0x1E6E001C);
1521 timeout++;
1522 } while ((!(data & 0x08000000)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1523 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1524 dev_err(dev->pdev, "Timeout while waiting for register\n");
1525 data = ast_mindwm(ast, 0x1E6E001C);
1526 data = (data >> 8) & 0xff;
1527 timeout = 0;
1528 while (((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT)) {
1529 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1530 if ((data2 & 0xff) > param->madj_max) {
1531 break;
1533 ast_moutdwm(ast, 0x1E6E0064, data2);
1534 if (data2 & 0x00100000) {
1535 data2 = ((data2 & 0xff) >> 3) + 3;
1536 } else {
1537 data2 = ((data2 & 0xff) >> 2) + 5;
1539 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1540 data2 += data & 0xff;
1541 data = data | (data2 << 8);
1542 ast_moutdwm(ast, 0x1E6E0068, data);
1543 udelay(10);
1544 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1545 udelay(10);
1546 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1547 ast_moutdwm(ast, 0x1E6E0018, data);
1548 data = data | 0x200;
1549 ast_moutdwm(ast, 0x1E6E0018, data);
1550 timeout2 = 0;
1551 do {
1552 data = ast_mindwm(ast, 0x1E6E001C);
1553 timeout2++;
1554 } while ((!(data & 0x08000000)) && (timeout2 < COREBOOT_AST_FAILOVER_TIMEOUT));
1555 if (timeout2 >= COREBOOT_AST_FAILOVER_TIMEOUT)
1556 dev_err(dev->pdev, "Timeout while waiting for register\n");
1558 data = ast_mindwm(ast, 0x1E6E001C);
1559 data = (data >> 8) & 0xff;
1561 timeout++;
1563 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1564 dev_err(dev->pdev, "Timeout while waiting for register\n");
1565 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
1566 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1567 ast_moutdwm(ast, 0x1E6E0018, data);
1569 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1570 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1571 udelay(50);
1572 /* Mode Register Setting */
1573 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1574 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1575 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1576 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1577 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1578 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1580 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1581 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1582 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1583 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1584 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1585 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1586 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1588 ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1589 data = 0;
1590 if (param->wodt) {
1591 data = 0x500;
1593 if (param->rodt) {
1594 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1596 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1597 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1599 /* Calibrate the DQSI delay */
1600 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1601 goto ddr2_init_start;
1603 /* ECC Memory Initialization */
1604 #ifdef ECC
1605 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1606 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1607 timeout = 0;
1608 do {
1609 data = ast_mindwm(ast, 0x1E6E0070);
1610 timeout++;
1611 } while ((!(data & 0x00001000)) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1612 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1613 dev_err(dev->pdev, "Timeout while waiting for register\n");
1614 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1615 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1616 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1617 #endif
1620 static void ast_post_chip_2300(struct drm_device *dev)
1622 struct ast_private *ast = dev->dev_private;
1623 struct ast2300_dram_param param;
1624 u32 temp;
1625 u8 reg;
1626 uint32_t timeout;
1628 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1629 if ((reg & 0x80) == 0) {/* vga only */
1630 ast_write32(ast, 0xf004, 0x1e6e0000);
1631 ast_write32(ast, 0xf000, 0x1);
1632 ast_write32(ast, 0x12000, 0x1688a8a8);
1633 timeout = 0;
1634 do {
1635 timeout++;
1636 } while ((ast_read32(ast, 0x12000) != 0x1) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1637 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1638 dev_err(dev->pdev, "Timeout while waiting for register\n");
1640 ast_write32(ast, 0x10000, 0xfc600309);
1641 timeout = 0;
1642 do {
1643 timeout++;
1644 } while ((ast_read32(ast, 0x10000) != 0x1) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1645 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1646 dev_err(dev->pdev, "Timeout while waiting for register\n");
1648 /* Slow down CPU/AHB CLK in VGA only mode */
1649 temp = ast_read32(ast, 0x12008);
1650 temp |= 0x73;
1651 ast_write32(ast, 0x12008, temp);
1653 param.dram_freq = 396;
1654 param.dram_type = AST_DDR3;
1655 temp = ast_mindwm(ast, 0x1e6e2070);
1656 if (temp & 0x01000000)
1657 param.dram_type = AST_DDR2;
1658 switch (temp & 0x18000000) {
1659 case 0:
1660 param.dram_chipid = AST_DRAM_512Mx16;
1661 break;
1662 default:
1663 case 0x08000000:
1664 param.dram_chipid = AST_DRAM_1Gx16;
1665 break;
1666 case 0x10000000:
1667 param.dram_chipid = AST_DRAM_2Gx16;
1668 break;
1669 case 0x18000000:
1670 param.dram_chipid = AST_DRAM_4Gx16;
1671 break;
1673 switch (temp & 0x0c) {
1674 default:
1675 case 0x00:
1676 param.vram_size = AST_VIDMEM_SIZE_8M;
1677 break;
1679 case 0x04:
1680 param.vram_size = AST_VIDMEM_SIZE_16M;
1681 break;
1683 case 0x08:
1684 param.vram_size = AST_VIDMEM_SIZE_32M;
1685 break;
1687 case 0x0c:
1688 param.vram_size = AST_VIDMEM_SIZE_64M;
1689 break;
1692 if (param.dram_type == AST_DDR3) {
1693 get_ddr3_info(ast, &param);
1694 ddr3_init(ast, &param);
1695 } else {
1696 get_ddr2_info(ast, &param);
1697 ddr2_init(ast, &param);
1700 temp = ast_mindwm(ast, 0x1e6e2040);
1701 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
1704 /* wait ready */
1705 timeout = 0;
1706 do {
1707 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1708 timeout++;
1709 } while (((reg & 0x40) == 0) && (timeout < COREBOOT_AST_FAILOVER_TIMEOUT));
1710 if (timeout >= COREBOOT_AST_FAILOVER_TIMEOUT)
1711 dev_err(dev->pdev, "Timeout while waiting for register\n");
1714 static bool cbr_test_2500(struct ast_private *ast)
1716 ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
1717 ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
1718 if (!mmc_test_burst(ast, 0))
1719 return false;
1720 if (!mmc_test_single_2500(ast, 0))
1721 return false;
1722 return true;
1725 static bool ddr_test_2500(struct ast_private *ast)
1727 ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
1728 ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
1729 if (!mmc_test_burst(ast, 0))
1730 return false;
1731 if (!mmc_test_burst(ast, 1))
1732 return false;
1733 if (!mmc_test_burst(ast, 2))
1734 return false;
1735 if (!mmc_test_burst(ast, 3))
1736 return false;
1737 if (!mmc_test_single_2500(ast, 0))
1738 return false;
1739 return true;
1742 static void ddr_init_common_2500(struct ast_private *ast)
1744 ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
1745 ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
1746 ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF);
1747 ast_moutdwm(ast, 0x1E6E0040, 0x88448844);
1748 ast_moutdwm(ast, 0x1E6E0044, 0x24422288);
1749 ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1750 ast_moutdwm(ast, 0x1E6E004C, 0x22222222);
1751 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1752 ast_moutdwm(ast, 0x1E6E0208, 0x00000000);
1753 ast_moutdwm(ast, 0x1E6E0218, 0x00000000);
1754 ast_moutdwm(ast, 0x1E6E0220, 0x00000000);
1755 ast_moutdwm(ast, 0x1E6E0228, 0x00000000);
1756 ast_moutdwm(ast, 0x1E6E0230, 0x00000000);
1757 ast_moutdwm(ast, 0x1E6E02A8, 0x00000000);
1758 ast_moutdwm(ast, 0x1E6E02B0, 0x00000000);
1759 ast_moutdwm(ast, 0x1E6E0240, 0x86000000);
1760 ast_moutdwm(ast, 0x1E6E0244, 0x00008600);
1761 ast_moutdwm(ast, 0x1E6E0248, 0x80000000);
1762 ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
1765 static void ddr_phy_init_2500(struct ast_private *ast)
1767 u32 data, pass, timecnt;
1769 pass = 0;
1770 ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
1771 while (!pass) {
1772 for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
1773 data = ast_mindwm(ast, 0x1E6E0060) & 0x1;
1774 if (!data)
1775 break;
1777 if (timecnt != TIMEOUT) {
1778 data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000;
1779 if (!data)
1780 pass = 1;
1782 if (!pass) {
1783 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1784 udelay(10); /* delay 10 us */
1785 ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
1789 ast_moutdwm(ast, 0x1E6E0060, 0x00000006);
1793 * Check DRAM Size
1794 * 1Gb : 0x80000000 ~ 0x87FFFFFF
1795 * 2Gb : 0x80000000 ~ 0x8FFFFFFF
1796 * 4Gb : 0x80000000 ~ 0x9FFFFFFF
1797 * 8Gb : 0x80000000 ~ 0xBFFFFFFF
1799 static void check_dram_size_2500(struct ast_private *ast, u32 tRFC)
1801 u32 reg_04, reg_14;
1803 reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc;
1804 reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00;
1806 ast_moutdwm(ast, 0xA0100000, 0x41424344);
1807 ast_moutdwm(ast, 0x90100000, 0x35363738);
1808 ast_moutdwm(ast, 0x88100000, 0x292A2B2C);
1809 ast_moutdwm(ast, 0x80100000, 0x1D1E1F10);
1811 /* Check 8Gbit */
1812 if (ast_mindwm(ast, 0xA0100000) == 0x41424344) {
1813 reg_04 |= 0x03;
1814 reg_14 |= (tRFC >> 24) & 0xFF;
1815 /* Check 4Gbit */
1816 } else if (ast_mindwm(ast, 0x90100000) == 0x35363738) {
1817 reg_04 |= 0x02;
1818 reg_14 |= (tRFC >> 16) & 0xFF;
1819 /* Check 2Gbit */
1820 } else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) {
1821 reg_04 |= 0x01;
1822 reg_14 |= (tRFC >> 8) & 0xFF;
1823 } else {
1824 reg_14 |= tRFC & 0xFF;
1826 ast_moutdwm(ast, 0x1E6E0004, reg_04);
1827 ast_moutdwm(ast, 0x1E6E0014, reg_14);
1830 static void enable_cache_2500(struct ast_private *ast)
1832 u32 reg_04, data;
1834 reg_04 = ast_mindwm(ast, 0x1E6E0004);
1835 ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000);
1838 data = ast_mindwm(ast, 0x1E6E0004);
1839 while (!(data & 0x80000));
1840 ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
1843 static void set_mpll_2500(struct ast_private *ast)
1845 u32 addr, data, param;
1847 /* Reset MMC */
1848 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1849 ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
1850 for (addr = 0x1e6e0004; addr < 0x1e6e0090;) {
1851 ast_moutdwm(ast, addr, 0x0);
1852 addr += 4;
1854 ast_moutdwm(ast, 0x1E6E0034, 0x00020000);
1856 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1857 data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000;
1858 if (data) {
1859 /* CLKIN = 25MHz */
1860 param = 0x930023E0;
1861 ast_moutdwm(ast, 0x1E6E2160, 0x00011320);
1862 } else {
1863 /* CLKIN = 24MHz */
1864 param = 0x93002400;
1866 ast_moutdwm(ast, 0x1E6E2020, param);
1867 udelay(100);
1870 static void reset_mmc_2500(struct ast_private *ast)
1872 ast_moutdwm(ast, 0x1E78505C, 0x00000004);
1873 ast_moutdwm(ast, 0x1E785044, 0x00000001);
1874 ast_moutdwm(ast, 0x1E785048, 0x00004755);
1875 ast_moutdwm(ast, 0x1E78504C, 0x00000013);
1876 mdelay(100);
1877 ast_moutdwm(ast, 0x1E785054, 0x00000077);
1878 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1881 static void ddr3_init_2500(struct ast_private *ast, const u32 *ddr_table)
1883 ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
1884 ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
1885 ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
1886 ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
1887 ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
1888 ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
1889 ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
1890 ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
1892 /* DDR PHY Setting */
1893 ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE);
1894 ast_moutdwm(ast, 0x1E6E0204, 0x00001001);
1895 ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
1896 ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
1897 ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
1898 ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
1899 ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
1900 ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
1901 ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
1902 ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
1903 ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
1904 ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
1905 ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
1906 ast_moutdwm(ast, 0x1E6E02C0, 0x00000006);
1908 /* Controller Setting */
1909 ast_moutdwm(ast, 0x1E6E0034, 0x00020091);
1911 /* Wait DDR PHY init done */
1912 ddr_phy_init_2500(ast);
1914 ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
1915 ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
1916 ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
1918 check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
1919 enable_cache_2500(ast);
1920 ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
1921 ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
1924 static void ddr4_init_2500(struct ast_private *ast, const u32 *ddr_table)
1926 u32 data, data2, pass, retrycnt;
1927 u32 ddr_vref, phy_vref;
1928 u32 min_ddr_vref = 0, min_phy_vref = 0;
1929 u32 max_ddr_vref = 0, max_phy_vref = 0;
1931 ast_moutdwm(ast, 0x1E6E0004, 0x00000313);
1932 ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
1933 ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
1934 ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
1935 ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
1936 ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
1937 ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
1938 ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
1940 /* DDR PHY Setting */
1941 ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE);
1942 ast_moutdwm(ast, 0x1E6E0204, 0x09002000);
1943 ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
1944 ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
1945 ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
1946 ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
1947 ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
1948 ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
1949 ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
1950 ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
1951 ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
1952 ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
1953 ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
1954 ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C);
1955 ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E);
1957 /* Controller Setting */
1958 ast_moutdwm(ast, 0x1E6E0034, 0x0001A991);
1960 /* Train PHY Vref first */
1961 pass = 0;
1963 for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
1964 max_phy_vref = 0x0;
1965 pass = 0;
1966 ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06);
1967 for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
1968 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1969 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1970 ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8));
1971 /* Fire DFI Init */
1972 ddr_phy_init_2500(ast);
1973 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1974 if (cbr_test_2500(ast)) {
1975 pass++;
1976 data = ast_mindwm(ast, 0x1E6E03D0);
1977 data2 = data >> 8;
1978 data = data & 0xff;
1979 if (data > data2)
1980 data = data2;
1981 if (max_phy_vref < data) {
1982 max_phy_vref = data;
1983 min_phy_vref = phy_vref;
1985 } else if (pass > 0)
1986 break;
1989 ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8));
1991 /* Train DDR Vref next */
1992 pass = 0;
1994 for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
1995 min_ddr_vref = 0xFF;
1996 max_ddr_vref = 0x0;
1997 pass = 0;
1998 for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
1999 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
2000 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
2001 ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
2002 /* Fire DFI Init */
2003 ddr_phy_init_2500(ast);
2004 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
2005 if (cbr_test_2500(ast)) {
2006 pass++;
2007 if (min_ddr_vref > ddr_vref)
2008 min_ddr_vref = ddr_vref;
2009 if (max_ddr_vref < ddr_vref)
2010 max_ddr_vref = ddr_vref;
2011 } else if (pass != 0)
2012 break;
2016 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
2017 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
2018 ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
2019 ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
2021 /* Wait DDR PHY init done */
2022 ddr_phy_init_2500(ast);
2024 ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
2025 ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
2026 ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
2028 check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
2029 enable_cache_2500(ast);
2030 ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
2031 ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
2034 static bool ast_dram_init_2500(struct ast_private *ast)
2036 u32 data;
2037 u32 max_tries = 5;
2039 do {
2040 if (max_tries-- == 0)
2041 return false;
2042 set_mpll_2500(ast);
2043 reset_mmc_2500(ast);
2044 ddr_init_common_2500(ast);
2046 data = ast_mindwm(ast, 0x1E6E2070);
2047 if (data & 0x01000000)
2048 ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
2049 else
2050 ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
2051 } while (!ddr_test_2500(ast));
2053 ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41);
2055 /* Patch code */
2056 data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF;
2057 ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000);
2059 return true;
2062 void ast_post_chip_2500(struct drm_device *dev)
2064 struct ast_private *ast = dev->dev_private;
2065 u32 temp;
2066 u8 reg;
2068 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
2069 if ((reg & 0x80) == 0) {/* vga only */
2070 /* Clear bus lock condition */
2071 ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
2072 ast_moutdwm(ast, 0x1e600084, 0x00010000);
2073 ast_moutdwm(ast, 0x1e600088, 0x00000000);
2074 ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
2075 ast_write32(ast, 0xf004, 0x1e6e0000);
2076 ast_write32(ast, 0xf000, 0x1);
2077 ast_write32(ast, 0x12000, 0x1688a8a8);
2078 while (ast_read32(ast, 0x12000) != 0x1)
2081 ast_write32(ast, 0x10000, 0xfc600309);
2082 while (ast_read32(ast, 0x10000) != 0x1)
2085 /* Slow down CPU/AHB CLK in VGA only mode */
2086 temp = ast_read32(ast, 0x12008);
2087 temp |= 0x73;
2088 ast_write32(ast, 0x12008, temp);
2090 /* Reset USB port to patch USB unknown device issue */
2091 ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
2092 temp = ast_mindwm(ast, 0x1e6e2094);
2093 temp |= 0x00004000;
2094 ast_moutdwm(ast, 0x1e6e2094, temp);
2095 temp = ast_mindwm(ast, 0x1e6e2070);
2096 if (temp & 0x00800000) {
2097 ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
2098 mdelay(100);
2099 ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
2102 if (!ast_dram_init_2500(ast))
2103 printk(BIOS_ERR, "AST: DRAM init failed !\n");
2105 temp = ast_mindwm(ast, 0x1e6e2040);
2106 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
2109 /* wait ready */
2110 do {
2111 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
2112 } while ((reg & 0x40) == 0);