bpf: Prevent memory disambiguation attack
[linux/fpc-iii.git] / drivers / gpu / drm / ast / ast_post.c
blobf7d421359d564756ff86d78c64293e37eea74c7e
1 /*
2 * Copyright 2012 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 * The above copyright notice and this permission notice (including the
21 * next paragraph) shall be included in all copies or substantial portions
22 * of the Software.
26 * Authors: Dave Airlie <airlied@redhat.com>
29 #include <drm/drmP.h>
30 #include "ast_drv.h"
32 #include "ast_dram_tables.h"
34 static void ast_post_chip_2300(struct drm_device *dev);
35 static void ast_post_chip_2500(struct drm_device *dev);
37 void ast_enable_vga(struct drm_device *dev)
39 struct ast_private *ast = dev->dev_private;
41 ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01);
42 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01);
45 void ast_enable_mmio(struct drm_device *dev)
47 struct ast_private *ast = dev->dev_private;
49 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04);
53 bool ast_is_vga_enabled(struct drm_device *dev)
55 struct ast_private *ast = dev->dev_private;
56 u8 ch;
58 if (ast->chip == AST1180) {
59 /* TODO 1180 */
60 } else {
61 ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
62 return !!(ch & 0x01);
64 return false;
67 static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
68 static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
69 static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
71 static void
72 ast_set_def_ext_reg(struct drm_device *dev)
74 struct ast_private *ast = dev->dev_private;
75 u8 i, index, reg;
76 const u8 *ext_reg_info;
78 /* reset scratch */
79 for (i = 0x81; i <= 0x9f; i++)
80 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
82 if (ast->chip == AST2300 || ast->chip == AST2400 ||
83 ast->chip == AST2500) {
84 if (dev->pdev->revision >= 0x20)
85 ext_reg_info = extreginfo_ast2300;
86 else
87 ext_reg_info = extreginfo_ast2300a0;
88 } else
89 ext_reg_info = extreginfo;
91 index = 0xa0;
92 while (*ext_reg_info != 0xff) {
93 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
94 index++;
95 ext_reg_info++;
98 /* disable standard IO/MEM decode if secondary */
99 /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
101 /* Set Ext. Default */
102 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
103 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
105 /* Enable RAMDAC for A1 */
106 reg = 0x04;
107 if (ast->chip == AST2300 || ast->chip == AST2400 ||
108 ast->chip == AST2500)
109 reg |= 0x20;
110 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
113 u32 ast_mindwm(struct ast_private *ast, u32 r)
115 uint32_t data;
117 ast_write32(ast, 0xf004, r & 0xffff0000);
118 ast_write32(ast, 0xf000, 0x1);
120 do {
121 data = ast_read32(ast, 0xf004) & 0xffff0000;
122 } while (data != (r & 0xffff0000));
123 return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
126 void ast_moutdwm(struct ast_private *ast, u32 r, u32 v)
128 uint32_t data;
129 ast_write32(ast, 0xf004, r & 0xffff0000);
130 ast_write32(ast, 0xf000, 0x1);
131 do {
132 data = ast_read32(ast, 0xf004) & 0xffff0000;
133 } while (data != (r & 0xffff0000));
134 ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
138 * AST2100/2150 DLL CBR Setting
140 #define CBR_SIZE_AST2150 ((16 << 10) - 1)
141 #define CBR_PASSNUM_AST2150 5
142 #define CBR_THRESHOLD_AST2150 10
143 #define CBR_THRESHOLD2_AST2150 10
144 #define TIMEOUT_AST2150 5000000
146 #define CBR_PATNUM_AST2150 8
148 static const u32 pattern_AST2150[14] = {
149 0xFF00FF00,
150 0xCC33CC33,
151 0xAA55AA55,
152 0xFFFE0001,
153 0x683501FE,
154 0x0F1929B0,
155 0x2D0B4346,
156 0x60767F02,
157 0x6FBE36A6,
158 0x3A253035,
159 0x3019686D,
160 0x41C6167E,
161 0x620152BF,
162 0x20F050E0
165 static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
167 u32 data, timeout;
169 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
170 ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
171 timeout = 0;
172 do {
173 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
174 if (++timeout > TIMEOUT_AST2150) {
175 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
176 return 0xffffffff;
178 } while (!data);
179 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
180 ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
181 timeout = 0;
182 do {
183 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
184 if (++timeout > TIMEOUT_AST2150) {
185 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
186 return 0xffffffff;
188 } while (!data);
189 data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
190 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
191 return data;
194 #if 0 /* unused in DDX driver - here for completeness */
195 static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
197 u32 data, timeout;
199 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
200 ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
201 timeout = 0;
202 do {
203 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
204 if (++timeout > TIMEOUT_AST2150) {
205 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
206 return 0xffffffff;
208 } while (!data);
209 data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
210 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
211 return data;
213 #endif
215 static int cbrtest_ast2150(struct ast_private *ast)
217 int i;
219 for (i = 0; i < 8; i++)
220 if (mmctestburst2_ast2150(ast, i))
221 return 0;
222 return 1;
225 static int cbrscan_ast2150(struct ast_private *ast, int busw)
227 u32 patcnt, loop;
229 for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
230 ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
231 for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
232 if (cbrtest_ast2150(ast))
233 break;
235 if (loop == CBR_PASSNUM_AST2150)
236 return 0;
238 return 1;
242 static void cbrdlli_ast2150(struct ast_private *ast, int busw)
244 u32 dll_min[4], dll_max[4], dlli, data, passcnt;
246 cbr_start:
247 dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
248 dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
249 passcnt = 0;
251 for (dlli = 0; dlli < 100; dlli++) {
252 ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
253 data = cbrscan_ast2150(ast, busw);
254 if (data != 0) {
255 if (data & 0x1) {
256 if (dll_min[0] > dlli)
257 dll_min[0] = dlli;
258 if (dll_max[0] < dlli)
259 dll_max[0] = dlli;
261 passcnt++;
262 } else if (passcnt >= CBR_THRESHOLD_AST2150)
263 goto cbr_start;
265 if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
266 goto cbr_start;
268 dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
269 ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
274 static void ast_init_dram_reg(struct drm_device *dev)
276 struct ast_private *ast = dev->dev_private;
277 u8 j;
278 u32 data, temp, i;
279 const struct ast_dramstruct *dram_reg_info;
281 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
283 if ((j & 0x80) == 0) { /* VGA only */
284 if (ast->chip == AST2000) {
285 dram_reg_info = ast2000_dram_table_data;
286 ast_write32(ast, 0xf004, 0x1e6e0000);
287 ast_write32(ast, 0xf000, 0x1);
288 ast_write32(ast, 0x10100, 0xa8);
290 do {
292 } while (ast_read32(ast, 0x10100) != 0xa8);
293 } else {/* AST2100/1100 */
294 if (ast->chip == AST2100 || ast->chip == 2200)
295 dram_reg_info = ast2100_dram_table_data;
296 else
297 dram_reg_info = ast1100_dram_table_data;
299 ast_write32(ast, 0xf004, 0x1e6e0000);
300 ast_write32(ast, 0xf000, 0x1);
301 ast_write32(ast, 0x12000, 0x1688A8A8);
302 do {
304 } while (ast_read32(ast, 0x12000) != 0x01);
306 ast_write32(ast, 0x10000, 0xfc600309);
307 do {
309 } while (ast_read32(ast, 0x10000) != 0x01);
312 while (dram_reg_info->index != 0xffff) {
313 if (dram_reg_info->index == 0xff00) {/* delay fn */
314 for (i = 0; i < 15; i++)
315 udelay(dram_reg_info->data);
316 } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
317 data = dram_reg_info->data;
318 if (ast->dram_type == AST_DRAM_1Gx16)
319 data = 0x00000d89;
320 else if (ast->dram_type == AST_DRAM_1Gx32)
321 data = 0x00000c8d;
323 temp = ast_read32(ast, 0x12070);
324 temp &= 0xc;
325 temp <<= 2;
326 ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
327 } else
328 ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
329 dram_reg_info++;
332 /* AST 2100/2150 DRAM calibration */
333 data = ast_read32(ast, 0x10120);
334 if (data == 0x5061) { /* 266Mhz */
335 data = ast_read32(ast, 0x10004);
336 if (data & 0x40)
337 cbrdlli_ast2150(ast, 16); /* 16 bits */
338 else
339 cbrdlli_ast2150(ast, 32); /* 32 bits */
342 switch (ast->chip) {
343 case AST2000:
344 temp = ast_read32(ast, 0x10140);
345 ast_write32(ast, 0x10140, temp | 0x40);
346 break;
347 case AST1100:
348 case AST2100:
349 case AST2200:
350 case AST2150:
351 temp = ast_read32(ast, 0x1200c);
352 ast_write32(ast, 0x1200c, temp & 0xfffffffd);
353 temp = ast_read32(ast, 0x12040);
354 ast_write32(ast, 0x12040, temp | 0x40);
355 break;
356 default:
357 break;
361 /* wait ready */
362 do {
363 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
364 } while ((j & 0x40) == 0);
367 void ast_post_gpu(struct drm_device *dev)
369 u32 reg;
370 struct ast_private *ast = dev->dev_private;
372 pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
373 reg |= 0x3;
374 pci_write_config_dword(ast->dev->pdev, 0x04, reg);
376 ast_enable_vga(dev);
377 ast_open_key(ast);
378 ast_enable_mmio(dev);
379 ast_set_def_ext_reg(dev);
381 if (ast->config_mode == ast_use_p2a) {
382 if (ast->chip == AST2500)
383 ast_post_chip_2500(dev);
384 else if (ast->chip == AST2300 || ast->chip == AST2400)
385 ast_post_chip_2300(dev);
386 else
387 ast_init_dram_reg(dev);
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 */
396 /* AST 2300 DRAM settings */
397 #define AST_DDR3 0
398 #define AST_DDR2 1
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;
426 * DQSI DLL CBR Setting
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
438 static const u32 pattern[8] = {
439 0xFF00FF00,
440 0xCC33CC33,
441 0xAA55AA55,
442 0x88778877,
443 0x92CC4D6E,
444 0x543D3CDE,
445 0xF1E843C7,
446 0x7C61D253
449 static bool mmc_test(struct ast_private *ast, u32 datagen, u8 test_ctl)
451 u32 data, timeout;
453 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
454 ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
455 timeout = 0;
456 do {
457 data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
458 if (data & 0x2000)
459 return false;
460 if (++timeout > TIMEOUT) {
461 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
462 return false;
464 } while (!data);
465 ast_moutdwm(ast, 0x1e6e0070, 0x0);
466 return true;
469 static u32 mmc_test2(struct ast_private *ast, u32 datagen, u8 test_ctl)
471 u32 data, timeout;
473 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
474 ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
475 timeout = 0;
476 do {
477 data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
478 if (++timeout > TIMEOUT) {
479 ast_moutdwm(ast, 0x1e6e0070, 0x0);
480 return 0xffffffff;
482 } while (!data);
483 data = ast_mindwm(ast, 0x1e6e0078);
484 data = (data | (data >> 16)) & 0xffff;
485 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
486 return data;
490 static bool mmc_test_burst(struct ast_private *ast, u32 datagen)
492 return mmc_test(ast, datagen, 0xc1);
495 static u32 mmc_test_burst2(struct ast_private *ast, u32 datagen)
497 return mmc_test2(ast, datagen, 0x41);
500 static bool mmc_test_single(struct ast_private *ast, u32 datagen)
502 return mmc_test(ast, datagen, 0xc5);
505 static u32 mmc_test_single2(struct ast_private *ast, u32 datagen)
507 return mmc_test2(ast, datagen, 0x05);
510 static bool mmc_test_single_2500(struct ast_private *ast, u32 datagen)
512 return mmc_test(ast, datagen, 0x85);
515 static int cbr_test(struct ast_private *ast)
517 u32 data;
518 int i;
519 data = mmc_test_single2(ast, 0);
520 if ((data & 0xff) && (data & 0xff00))
521 return 0;
522 for (i = 0; i < 8; i++) {
523 data = mmc_test_burst2(ast, i);
524 if ((data & 0xff) && (data & 0xff00))
525 return 0;
527 if (!data)
528 return 3;
529 else if (data & 0xff)
530 return 2;
531 return 1;
534 static int cbr_scan(struct ast_private *ast)
536 u32 data, data2, patcnt, loop;
538 data2 = 3;
539 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
540 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
541 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
542 if ((data = cbr_test(ast)) != 0) {
543 data2 &= data;
544 if (!data2)
545 return 0;
546 break;
549 if (loop == CBR_PASSNUM2)
550 return 0;
552 return data2;
555 static u32 cbr_test2(struct ast_private *ast)
557 u32 data;
559 data = mmc_test_burst2(ast, 0);
560 if (data == 0xffff)
561 return 0;
562 data |= mmc_test_single2(ast, 0);
563 if (data == 0xffff)
564 return 0;
566 return ~data & 0xffff;
569 static u32 cbr_scan2(struct ast_private *ast)
571 u32 data, data2, patcnt, loop;
573 data2 = 0xffff;
574 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
575 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
576 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
577 if ((data = cbr_test2(ast)) != 0) {
578 data2 &= data;
579 if (!data2)
580 return 0;
581 break;
584 if (loop == CBR_PASSNUM2)
585 return 0;
587 return data2;
590 static bool cbr_test3(struct ast_private *ast)
592 if (!mmc_test_burst(ast, 0))
593 return false;
594 if (!mmc_test_single(ast, 0))
595 return false;
596 return true;
599 static bool cbr_scan3(struct ast_private *ast)
601 u32 patcnt, loop;
603 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
604 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
605 for (loop = 0; loop < 2; loop++) {
606 if (cbr_test3(ast))
607 break;
609 if (loop == 2)
610 return false;
612 return true;
615 static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
617 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
618 bool status = false;
619 FINETUNE_START:
620 for (cnt = 0; cnt < 16; cnt++) {
621 dllmin[cnt] = 0xff;
622 dllmax[cnt] = 0x0;
624 passcnt = 0;
625 for (dlli = 0; dlli < 76; dlli++) {
626 ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
627 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
628 data = cbr_scan2(ast);
629 if (data != 0) {
630 mask = 0x00010001;
631 for (cnt = 0; cnt < 16; cnt++) {
632 if (data & mask) {
633 if (dllmin[cnt] > dlli) {
634 dllmin[cnt] = dlli;
636 if (dllmax[cnt] < dlli) {
637 dllmax[cnt] = dlli;
640 mask <<= 1;
642 passcnt++;
643 } else if (passcnt >= CBR_THRESHOLD2) {
644 break;
647 gold_sadj[0] = 0x0;
648 passcnt = 0;
649 for (cnt = 0; cnt < 16; cnt++) {
650 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
651 gold_sadj[0] += dllmin[cnt];
652 passcnt++;
655 if (retry++ > 10)
656 goto FINETUNE_DONE;
657 if (passcnt != 16) {
658 goto FINETUNE_START;
660 status = true;
661 FINETUNE_DONE:
662 gold_sadj[0] = gold_sadj[0] >> 4;
663 gold_sadj[1] = gold_sadj[0];
665 data = 0;
666 for (cnt = 0; cnt < 8; cnt++) {
667 data >>= 3;
668 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
669 dlli = dllmin[cnt];
670 if (gold_sadj[0] >= dlli) {
671 dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
672 if (dlli > 3) {
673 dlli = 3;
675 } else {
676 dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
677 if (dlli > 4) {
678 dlli = 4;
680 dlli = (8 - dlli) & 0x7;
682 data |= dlli << 21;
685 ast_moutdwm(ast, 0x1E6E0080, data);
687 data = 0;
688 for (cnt = 8; cnt < 16; cnt++) {
689 data >>= 3;
690 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
691 dlli = dllmin[cnt];
692 if (gold_sadj[1] >= dlli) {
693 dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
694 if (dlli > 3) {
695 dlli = 3;
696 } else {
697 dlli = (dlli - 1) & 0x7;
699 } else {
700 dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
701 dlli += 1;
702 if (dlli > 4) {
703 dlli = 4;
705 dlli = (8 - dlli) & 0x7;
707 data |= dlli << 21;
710 ast_moutdwm(ast, 0x1E6E0084, data);
711 return status;
712 } /* finetuneDQI_L */
714 static void finetuneDQSI(struct ast_private *ast)
716 u32 dlli, dqsip, dqidly;
717 u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
718 u32 g_dqidly, g_dqsip, g_margin, g_side;
719 u16 pass[32][2][2];
720 char tag[2][76];
722 /* Disable DQI CBR */
723 reg_mcr0c = ast_mindwm(ast, 0x1E6E000C);
724 reg_mcr18 = ast_mindwm(ast, 0x1E6E0018);
725 reg_mcr18 &= 0x0000ffff;
726 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
728 for (dlli = 0; dlli < 76; dlli++) {
729 tag[0][dlli] = 0x0;
730 tag[1][dlli] = 0x0;
732 for (dqidly = 0; dqidly < 32; dqidly++) {
733 pass[dqidly][0][0] = 0xff;
734 pass[dqidly][0][1] = 0x0;
735 pass[dqidly][1][0] = 0xff;
736 pass[dqidly][1][1] = 0x0;
738 for (dqidly = 0; dqidly < 32; dqidly++) {
739 passcnt[0] = passcnt[1] = 0;
740 for (dqsip = 0; dqsip < 2; dqsip++) {
741 ast_moutdwm(ast, 0x1E6E000C, 0);
742 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
743 ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
744 for (dlli = 0; dlli < 76; dlli++) {
745 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
746 ast_moutdwm(ast, 0x1E6E0070, 0);
747 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
748 if (cbr_scan3(ast)) {
749 if (dlli == 0)
750 break;
751 passcnt[dqsip]++;
752 tag[dqsip][dlli] = 'P';
753 if (dlli < pass[dqidly][dqsip][0])
754 pass[dqidly][dqsip][0] = (u16) dlli;
755 if (dlli > pass[dqidly][dqsip][1])
756 pass[dqidly][dqsip][1] = (u16) dlli;
757 } else if (passcnt[dqsip] >= 5)
758 break;
759 else {
760 pass[dqidly][dqsip][0] = 0xff;
761 pass[dqidly][dqsip][1] = 0x0;
765 if (passcnt[0] == 0 && passcnt[1] == 0)
766 dqidly++;
768 /* Search margin */
769 g_dqidly = g_dqsip = g_margin = g_side = 0;
771 for (dqidly = 0; dqidly < 32; dqidly++) {
772 for (dqsip = 0; dqsip < 2; dqsip++) {
773 if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
774 continue;
775 diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
776 if ((diff+2) < g_margin)
777 continue;
778 passcnt[0] = passcnt[1] = 0;
779 for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++);
780 for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++);
781 if (passcnt[0] > passcnt[1])
782 passcnt[0] = passcnt[1];
783 passcnt[1] = 0;
784 if (passcnt[0] > g_side)
785 passcnt[1] = passcnt[0] - g_side;
786 if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
787 g_margin = diff;
788 g_dqidly = dqidly;
789 g_dqsip = dqsip;
790 g_side = passcnt[0];
791 } else if (passcnt[1] > 1 && g_side < 8) {
792 if (diff > g_margin)
793 g_margin = diff;
794 g_dqidly = dqidly;
795 g_dqsip = dqsip;
796 g_side = passcnt[0];
800 reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
801 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
804 static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
806 u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
807 bool status = false;
809 finetuneDQSI(ast);
810 if (finetuneDQI_L(ast, param) == false)
811 return status;
813 CBR_START2:
814 dllmin[0] = dllmin[1] = 0xff;
815 dllmax[0] = dllmax[1] = 0x0;
816 passcnt = 0;
817 for (dlli = 0; dlli < 76; dlli++) {
818 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
819 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
820 data = cbr_scan(ast);
821 if (data != 0) {
822 if (data & 0x1) {
823 if (dllmin[0] > dlli) {
824 dllmin[0] = dlli;
826 if (dllmax[0] < dlli) {
827 dllmax[0] = dlli;
830 if (data & 0x2) {
831 if (dllmin[1] > dlli) {
832 dllmin[1] = dlli;
834 if (dllmax[1] < dlli) {
835 dllmax[1] = dlli;
838 passcnt++;
839 } else if (passcnt >= CBR_THRESHOLD) {
840 break;
843 if (retry++ > 10)
844 goto CBR_DONE2;
845 if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
846 goto CBR_START2;
848 if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
849 goto CBR_START2;
851 status = true;
852 CBR_DONE2:
853 dlli = (dllmin[1] + dllmax[1]) >> 1;
854 dlli <<= 8;
855 dlli += (dllmin[0] + dllmax[0]) >> 1;
856 ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
857 return status;
858 } /* CBRDLL2 */
860 static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
862 u32 trap, trap_AC2, trap_MRS;
864 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
866 /* Ger trap info */
867 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
868 trap_AC2 = 0x00020000 + (trap << 16);
869 trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
870 trap_MRS = 0x00000010 + (trap << 4);
871 trap_MRS |= ((trap & 0x2) << 18);
873 param->reg_MADJ = 0x00034C4C;
874 param->reg_SADJ = 0x00001800;
875 param->reg_DRV = 0x000000F0;
876 param->reg_PERIOD = param->dram_freq;
877 param->rodt = 0;
879 switch (param->dram_freq) {
880 case 336:
881 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
882 param->wodt = 0;
883 param->reg_AC1 = 0x22202725;
884 param->reg_AC2 = 0xAA007613 | trap_AC2;
885 param->reg_DQSIC = 0x000000BA;
886 param->reg_MRS = 0x04001400 | trap_MRS;
887 param->reg_EMRS = 0x00000000;
888 param->reg_IOZ = 0x00000023;
889 param->reg_DQIDLY = 0x00000074;
890 param->reg_FREQ = 0x00004DC0;
891 param->madj_max = 96;
892 param->dll2_finetune_step = 3;
893 switch (param->dram_chipid) {
894 default:
895 case AST_DRAM_512Mx16:
896 case AST_DRAM_1Gx16:
897 param->reg_AC2 = 0xAA007613 | trap_AC2;
898 break;
899 case AST_DRAM_2Gx16:
900 param->reg_AC2 = 0xAA00761C | trap_AC2;
901 break;
902 case AST_DRAM_4Gx16:
903 param->reg_AC2 = 0xAA007636 | trap_AC2;
904 break;
906 break;
907 default:
908 case 396:
909 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
910 param->wodt = 1;
911 param->reg_AC1 = 0x33302825;
912 param->reg_AC2 = 0xCC009617 | trap_AC2;
913 param->reg_DQSIC = 0x000000E2;
914 param->reg_MRS = 0x04001600 | trap_MRS;
915 param->reg_EMRS = 0x00000000;
916 param->reg_IOZ = 0x00000034;
917 param->reg_DRV = 0x000000FA;
918 param->reg_DQIDLY = 0x00000089;
919 param->reg_FREQ = 0x00005040;
920 param->madj_max = 96;
921 param->dll2_finetune_step = 4;
923 switch (param->dram_chipid) {
924 default:
925 case AST_DRAM_512Mx16:
926 case AST_DRAM_1Gx16:
927 param->reg_AC2 = 0xCC009617 | trap_AC2;
928 break;
929 case AST_DRAM_2Gx16:
930 param->reg_AC2 = 0xCC009622 | trap_AC2;
931 break;
932 case AST_DRAM_4Gx16:
933 param->reg_AC2 = 0xCC00963F | trap_AC2;
934 break;
936 break;
938 case 408:
939 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
940 param->wodt = 1;
941 param->reg_AC1 = 0x33302825;
942 param->reg_AC2 = 0xCC009617 | trap_AC2;
943 param->reg_DQSIC = 0x000000E2;
944 param->reg_MRS = 0x04001600 | trap_MRS;
945 param->reg_EMRS = 0x00000000;
946 param->reg_IOZ = 0x00000023;
947 param->reg_DRV = 0x000000FA;
948 param->reg_DQIDLY = 0x00000089;
949 param->reg_FREQ = 0x000050C0;
950 param->madj_max = 96;
951 param->dll2_finetune_step = 4;
953 switch (param->dram_chipid) {
954 default:
955 case AST_DRAM_512Mx16:
956 case AST_DRAM_1Gx16:
957 param->reg_AC2 = 0xCC009617 | trap_AC2;
958 break;
959 case AST_DRAM_2Gx16:
960 param->reg_AC2 = 0xCC009622 | trap_AC2;
961 break;
962 case AST_DRAM_4Gx16:
963 param->reg_AC2 = 0xCC00963F | trap_AC2;
964 break;
967 break;
968 case 456:
969 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
970 param->wodt = 0;
971 param->reg_AC1 = 0x33302926;
972 param->reg_AC2 = 0xCD44961A;
973 param->reg_DQSIC = 0x000000FC;
974 param->reg_MRS = 0x00081830;
975 param->reg_EMRS = 0x00000000;
976 param->reg_IOZ = 0x00000045;
977 param->reg_DQIDLY = 0x00000097;
978 param->reg_FREQ = 0x000052C0;
979 param->madj_max = 88;
980 param->dll2_finetune_step = 4;
981 break;
982 case 504:
983 ast_moutdwm(ast, 0x1E6E2020, 0x0270);
984 param->wodt = 1;
985 param->reg_AC1 = 0x33302926;
986 param->reg_AC2 = 0xDE44A61D;
987 param->reg_DQSIC = 0x00000117;
988 param->reg_MRS = 0x00081A30;
989 param->reg_EMRS = 0x00000000;
990 param->reg_IOZ = 0x070000BB;
991 param->reg_DQIDLY = 0x000000A0;
992 param->reg_FREQ = 0x000054C0;
993 param->madj_max = 79;
994 param->dll2_finetune_step = 4;
995 break;
996 case 528:
997 ast_moutdwm(ast, 0x1E6E2020, 0x0290);
998 param->wodt = 1;
999 param->rodt = 1;
1000 param->reg_AC1 = 0x33302926;
1001 param->reg_AC2 = 0xEF44B61E;
1002 param->reg_DQSIC = 0x00000125;
1003 param->reg_MRS = 0x00081A30;
1004 param->reg_EMRS = 0x00000040;
1005 param->reg_DRV = 0x000000F5;
1006 param->reg_IOZ = 0x00000023;
1007 param->reg_DQIDLY = 0x00000088;
1008 param->reg_FREQ = 0x000055C0;
1009 param->madj_max = 76;
1010 param->dll2_finetune_step = 3;
1011 break;
1012 case 576:
1013 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1014 param->reg_MADJ = 0x00136868;
1015 param->reg_SADJ = 0x00004534;
1016 param->wodt = 1;
1017 param->rodt = 1;
1018 param->reg_AC1 = 0x33302A37;
1019 param->reg_AC2 = 0xEF56B61E;
1020 param->reg_DQSIC = 0x0000013F;
1021 param->reg_MRS = 0x00101A50;
1022 param->reg_EMRS = 0x00000040;
1023 param->reg_DRV = 0x000000FA;
1024 param->reg_IOZ = 0x00000023;
1025 param->reg_DQIDLY = 0x00000078;
1026 param->reg_FREQ = 0x000057C0;
1027 param->madj_max = 136;
1028 param->dll2_finetune_step = 3;
1029 break;
1030 case 600:
1031 ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
1032 param->reg_MADJ = 0x00136868;
1033 param->reg_SADJ = 0x00004534;
1034 param->wodt = 1;
1035 param->rodt = 1;
1036 param->reg_AC1 = 0x32302A37;
1037 param->reg_AC2 = 0xDF56B61F;
1038 param->reg_DQSIC = 0x0000014D;
1039 param->reg_MRS = 0x00101A50;
1040 param->reg_EMRS = 0x00000004;
1041 param->reg_DRV = 0x000000F5;
1042 param->reg_IOZ = 0x00000023;
1043 param->reg_DQIDLY = 0x00000078;
1044 param->reg_FREQ = 0x000058C0;
1045 param->madj_max = 132;
1046 param->dll2_finetune_step = 3;
1047 break;
1048 case 624:
1049 ast_moutdwm(ast, 0x1E6E2020, 0x0160);
1050 param->reg_MADJ = 0x00136868;
1051 param->reg_SADJ = 0x00004534;
1052 param->wodt = 1;
1053 param->rodt = 1;
1054 param->reg_AC1 = 0x32302A37;
1055 param->reg_AC2 = 0xEF56B621;
1056 param->reg_DQSIC = 0x0000015A;
1057 param->reg_MRS = 0x02101A50;
1058 param->reg_EMRS = 0x00000004;
1059 param->reg_DRV = 0x000000F5;
1060 param->reg_IOZ = 0x00000034;
1061 param->reg_DQIDLY = 0x00000078;
1062 param->reg_FREQ = 0x000059C0;
1063 param->madj_max = 128;
1064 param->dll2_finetune_step = 3;
1065 break;
1066 } /* switch freq */
1068 switch (param->dram_chipid) {
1069 case AST_DRAM_512Mx16:
1070 param->dram_config = 0x130;
1071 break;
1072 default:
1073 case AST_DRAM_1Gx16:
1074 param->dram_config = 0x131;
1075 break;
1076 case AST_DRAM_2Gx16:
1077 param->dram_config = 0x132;
1078 break;
1079 case AST_DRAM_4Gx16:
1080 param->dram_config = 0x133;
1081 break;
1082 } /* switch size */
1084 switch (param->vram_size) {
1085 default:
1086 case AST_VIDMEM_SIZE_8M:
1087 param->dram_config |= 0x00;
1088 break;
1089 case AST_VIDMEM_SIZE_16M:
1090 param->dram_config |= 0x04;
1091 break;
1092 case AST_VIDMEM_SIZE_32M:
1093 param->dram_config |= 0x08;
1094 break;
1095 case AST_VIDMEM_SIZE_64M:
1096 param->dram_config |= 0x0c;
1097 break;
1102 static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1104 u32 data, data2, retry = 0;
1106 ddr3_init_start:
1107 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1108 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1109 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1110 ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
1111 udelay(10);
1112 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1113 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1114 udelay(10);
1115 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1116 udelay(10);
1118 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1119 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1120 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1121 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1122 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1123 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1124 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1125 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1126 ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
1127 ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
1128 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1129 ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
1130 ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
1131 ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1132 ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
1133 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1134 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1135 ast_moutdwm(ast, 0x1E6E0054, 0);
1136 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1137 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1138 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1139 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1140 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1141 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1142 /* Wait MCLK2X lock to MCLK */
1143 do {
1144 data = ast_mindwm(ast, 0x1E6E001C);
1145 } while (!(data & 0x08000000));
1146 data = ast_mindwm(ast, 0x1E6E001C);
1147 data = (data >> 8) & 0xff;
1148 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1149 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1150 if ((data2 & 0xff) > param->madj_max) {
1151 break;
1153 ast_moutdwm(ast, 0x1E6E0064, data2);
1154 if (data2 & 0x00100000) {
1155 data2 = ((data2 & 0xff) >> 3) + 3;
1156 } else {
1157 data2 = ((data2 & 0xff) >> 2) + 5;
1159 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1160 data2 += data & 0xff;
1161 data = data | (data2 << 8);
1162 ast_moutdwm(ast, 0x1E6E0068, data);
1163 udelay(10);
1164 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1165 udelay(10);
1166 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1167 ast_moutdwm(ast, 0x1E6E0018, data);
1168 data = data | 0x200;
1169 ast_moutdwm(ast, 0x1E6E0018, data);
1170 do {
1171 data = ast_mindwm(ast, 0x1E6E001C);
1172 } while (!(data & 0x08000000));
1174 data = ast_mindwm(ast, 0x1E6E001C);
1175 data = (data >> 8) & 0xff;
1177 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
1178 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1179 ast_moutdwm(ast, 0x1E6E0018, data);
1181 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1182 ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
1183 udelay(50);
1184 /* Mode Register Setting */
1185 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1186 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1187 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1188 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1189 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1190 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1191 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1192 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1193 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1195 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1196 data = 0;
1197 if (param->wodt) {
1198 data = 0x300;
1200 if (param->rodt) {
1201 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1203 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1205 /* Calibrate the DQSI delay */
1206 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1207 goto ddr3_init_start;
1209 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1210 /* ECC Memory Initialization */
1211 #ifdef ECC
1212 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1213 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1214 do {
1215 data = ast_mindwm(ast, 0x1E6E0070);
1216 } while (!(data & 0x00001000));
1217 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1218 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1219 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1220 #endif
1225 static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1227 u32 trap, trap_AC2, trap_MRS;
1229 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1231 /* Ger trap info */
1232 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1233 trap_AC2 = (trap << 20) | (trap << 16);
1234 trap_AC2 += 0x00110000;
1235 trap_MRS = 0x00000040 | (trap << 4);
1238 param->reg_MADJ = 0x00034C4C;
1239 param->reg_SADJ = 0x00001800;
1240 param->reg_DRV = 0x000000F0;
1241 param->reg_PERIOD = param->dram_freq;
1242 param->rodt = 0;
1244 switch (param->dram_freq) {
1245 case 264:
1246 ast_moutdwm(ast, 0x1E6E2020, 0x0130);
1247 param->wodt = 0;
1248 param->reg_AC1 = 0x11101513;
1249 param->reg_AC2 = 0x78117011;
1250 param->reg_DQSIC = 0x00000092;
1251 param->reg_MRS = 0x00000842;
1252 param->reg_EMRS = 0x00000000;
1253 param->reg_DRV = 0x000000F0;
1254 param->reg_IOZ = 0x00000034;
1255 param->reg_DQIDLY = 0x0000005A;
1256 param->reg_FREQ = 0x00004AC0;
1257 param->madj_max = 138;
1258 param->dll2_finetune_step = 3;
1259 break;
1260 case 336:
1261 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
1262 param->wodt = 1;
1263 param->reg_AC1 = 0x22202613;
1264 param->reg_AC2 = 0xAA009016 | trap_AC2;
1265 param->reg_DQSIC = 0x000000BA;
1266 param->reg_MRS = 0x00000A02 | trap_MRS;
1267 param->reg_EMRS = 0x00000040;
1268 param->reg_DRV = 0x000000FA;
1269 param->reg_IOZ = 0x00000034;
1270 param->reg_DQIDLY = 0x00000074;
1271 param->reg_FREQ = 0x00004DC0;
1272 param->madj_max = 96;
1273 param->dll2_finetune_step = 3;
1274 switch (param->dram_chipid) {
1275 default:
1276 case AST_DRAM_512Mx16:
1277 param->reg_AC2 = 0xAA009012 | trap_AC2;
1278 break;
1279 case AST_DRAM_1Gx16:
1280 param->reg_AC2 = 0xAA009016 | trap_AC2;
1281 break;
1282 case AST_DRAM_2Gx16:
1283 param->reg_AC2 = 0xAA009023 | trap_AC2;
1284 break;
1285 case AST_DRAM_4Gx16:
1286 param->reg_AC2 = 0xAA00903B | trap_AC2;
1287 break;
1289 break;
1290 default:
1291 case 396:
1292 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
1293 param->wodt = 1;
1294 param->rodt = 0;
1295 param->reg_AC1 = 0x33302714;
1296 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1297 param->reg_DQSIC = 0x000000E2;
1298 param->reg_MRS = 0x00000C02 | trap_MRS;
1299 param->reg_EMRS = 0x00000040;
1300 param->reg_DRV = 0x000000FA;
1301 param->reg_IOZ = 0x00000034;
1302 param->reg_DQIDLY = 0x00000089;
1303 param->reg_FREQ = 0x00005040;
1304 param->madj_max = 96;
1305 param->dll2_finetune_step = 4;
1307 switch (param->dram_chipid) {
1308 case AST_DRAM_512Mx16:
1309 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1310 break;
1311 default:
1312 case AST_DRAM_1Gx16:
1313 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1314 break;
1315 case AST_DRAM_2Gx16:
1316 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1317 break;
1318 case AST_DRAM_4Gx16:
1319 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1320 break;
1323 break;
1325 case 408:
1326 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
1327 param->wodt = 1;
1328 param->rodt = 0;
1329 param->reg_AC1 = 0x33302714;
1330 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1331 param->reg_DQSIC = 0x000000E2;
1332 param->reg_MRS = 0x00000C02 | trap_MRS;
1333 param->reg_EMRS = 0x00000040;
1334 param->reg_DRV = 0x000000FA;
1335 param->reg_IOZ = 0x00000034;
1336 param->reg_DQIDLY = 0x00000089;
1337 param->reg_FREQ = 0x000050C0;
1338 param->madj_max = 96;
1339 param->dll2_finetune_step = 4;
1341 switch (param->dram_chipid) {
1342 case AST_DRAM_512Mx16:
1343 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1344 break;
1345 default:
1346 case AST_DRAM_1Gx16:
1347 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1348 break;
1349 case AST_DRAM_2Gx16:
1350 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1351 break;
1352 case AST_DRAM_4Gx16:
1353 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1354 break;
1357 break;
1358 case 456:
1359 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
1360 param->wodt = 0;
1361 param->reg_AC1 = 0x33302815;
1362 param->reg_AC2 = 0xCD44B01E;
1363 param->reg_DQSIC = 0x000000FC;
1364 param->reg_MRS = 0x00000E72;
1365 param->reg_EMRS = 0x00000000;
1366 param->reg_DRV = 0x00000000;
1367 param->reg_IOZ = 0x00000034;
1368 param->reg_DQIDLY = 0x00000097;
1369 param->reg_FREQ = 0x000052C0;
1370 param->madj_max = 88;
1371 param->dll2_finetune_step = 3;
1372 break;
1373 case 504:
1374 ast_moutdwm(ast, 0x1E6E2020, 0x0261);
1375 param->wodt = 1;
1376 param->rodt = 1;
1377 param->reg_AC1 = 0x33302815;
1378 param->reg_AC2 = 0xDE44C022;
1379 param->reg_DQSIC = 0x00000117;
1380 param->reg_MRS = 0x00000E72;
1381 param->reg_EMRS = 0x00000040;
1382 param->reg_DRV = 0x0000000A;
1383 param->reg_IOZ = 0x00000045;
1384 param->reg_DQIDLY = 0x000000A0;
1385 param->reg_FREQ = 0x000054C0;
1386 param->madj_max = 79;
1387 param->dll2_finetune_step = 3;
1388 break;
1389 case 528:
1390 ast_moutdwm(ast, 0x1E6E2020, 0x0120);
1391 param->wodt = 1;
1392 param->rodt = 1;
1393 param->reg_AC1 = 0x33302815;
1394 param->reg_AC2 = 0xEF44D024;
1395 param->reg_DQSIC = 0x00000125;
1396 param->reg_MRS = 0x00000E72;
1397 param->reg_EMRS = 0x00000004;
1398 param->reg_DRV = 0x000000F9;
1399 param->reg_IOZ = 0x00000045;
1400 param->reg_DQIDLY = 0x000000A7;
1401 param->reg_FREQ = 0x000055C0;
1402 param->madj_max = 76;
1403 param->dll2_finetune_step = 3;
1404 break;
1405 case 552:
1406 ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
1407 param->wodt = 1;
1408 param->rodt = 1;
1409 param->reg_AC1 = 0x43402915;
1410 param->reg_AC2 = 0xFF44E025;
1411 param->reg_DQSIC = 0x00000132;
1412 param->reg_MRS = 0x00000E72;
1413 param->reg_EMRS = 0x00000040;
1414 param->reg_DRV = 0x0000000A;
1415 param->reg_IOZ = 0x00000045;
1416 param->reg_DQIDLY = 0x000000AD;
1417 param->reg_FREQ = 0x000056C0;
1418 param->madj_max = 76;
1419 param->dll2_finetune_step = 3;
1420 break;
1421 case 576:
1422 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1423 param->wodt = 1;
1424 param->rodt = 1;
1425 param->reg_AC1 = 0x43402915;
1426 param->reg_AC2 = 0xFF44E027;
1427 param->reg_DQSIC = 0x0000013F;
1428 param->reg_MRS = 0x00000E72;
1429 param->reg_EMRS = 0x00000004;
1430 param->reg_DRV = 0x000000F5;
1431 param->reg_IOZ = 0x00000045;
1432 param->reg_DQIDLY = 0x000000B3;
1433 param->reg_FREQ = 0x000057C0;
1434 param->madj_max = 76;
1435 param->dll2_finetune_step = 3;
1436 break;
1439 switch (param->dram_chipid) {
1440 case AST_DRAM_512Mx16:
1441 param->dram_config = 0x100;
1442 break;
1443 default:
1444 case AST_DRAM_1Gx16:
1445 param->dram_config = 0x121;
1446 break;
1447 case AST_DRAM_2Gx16:
1448 param->dram_config = 0x122;
1449 break;
1450 case AST_DRAM_4Gx16:
1451 param->dram_config = 0x123;
1452 break;
1453 } /* switch size */
1455 switch (param->vram_size) {
1456 default:
1457 case AST_VIDMEM_SIZE_8M:
1458 param->dram_config |= 0x00;
1459 break;
1460 case AST_VIDMEM_SIZE_16M:
1461 param->dram_config |= 0x04;
1462 break;
1463 case AST_VIDMEM_SIZE_32M:
1464 param->dram_config |= 0x08;
1465 break;
1466 case AST_VIDMEM_SIZE_64M:
1467 param->dram_config |= 0x0c;
1468 break;
1472 static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1474 u32 data, data2, retry = 0;
1476 ddr2_init_start:
1477 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1478 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1479 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1480 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1481 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1482 udelay(10);
1483 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1484 udelay(10);
1486 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1487 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1488 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1489 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1490 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1491 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1492 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1493 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1494 ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
1495 ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
1496 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1497 ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
1498 ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
1499 ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
1500 ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
1501 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1502 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1503 ast_moutdwm(ast, 0x1E6E0054, 0);
1504 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1505 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1506 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1507 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1508 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1509 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1511 /* Wait MCLK2X lock to MCLK */
1512 do {
1513 data = ast_mindwm(ast, 0x1E6E001C);
1514 } while (!(data & 0x08000000));
1515 data = ast_mindwm(ast, 0x1E6E001C);
1516 data = (data >> 8) & 0xff;
1517 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1518 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1519 if ((data2 & 0xff) > param->madj_max) {
1520 break;
1522 ast_moutdwm(ast, 0x1E6E0064, data2);
1523 if (data2 & 0x00100000) {
1524 data2 = ((data2 & 0xff) >> 3) + 3;
1525 } else {
1526 data2 = ((data2 & 0xff) >> 2) + 5;
1528 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1529 data2 += data & 0xff;
1530 data = data | (data2 << 8);
1531 ast_moutdwm(ast, 0x1E6E0068, data);
1532 udelay(10);
1533 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1534 udelay(10);
1535 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1536 ast_moutdwm(ast, 0x1E6E0018, data);
1537 data = data | 0x200;
1538 ast_moutdwm(ast, 0x1E6E0018, data);
1539 do {
1540 data = ast_mindwm(ast, 0x1E6E001C);
1541 } while (!(data & 0x08000000));
1543 data = ast_mindwm(ast, 0x1E6E001C);
1544 data = (data >> 8) & 0xff;
1546 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
1547 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1548 ast_moutdwm(ast, 0x1E6E0018, data);
1550 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1551 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1552 udelay(50);
1553 /* Mode Register Setting */
1554 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1555 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1556 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1557 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1558 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1559 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1561 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1562 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1563 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1564 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1565 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1566 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1567 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1569 ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1570 data = 0;
1571 if (param->wodt) {
1572 data = 0x500;
1574 if (param->rodt) {
1575 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1577 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1578 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1580 /* Calibrate the DQSI delay */
1581 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1582 goto ddr2_init_start;
1584 /* ECC Memory Initialization */
1585 #ifdef ECC
1586 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1587 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1588 do {
1589 data = ast_mindwm(ast, 0x1E6E0070);
1590 } while (!(data & 0x00001000));
1591 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1592 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1593 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1594 #endif
1598 static void ast_post_chip_2300(struct drm_device *dev)
1600 struct ast_private *ast = dev->dev_private;
1601 struct ast2300_dram_param param;
1602 u32 temp;
1603 u8 reg;
1605 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1606 if ((reg & 0x80) == 0) {/* vga only */
1607 ast_write32(ast, 0xf004, 0x1e6e0000);
1608 ast_write32(ast, 0xf000, 0x1);
1609 ast_write32(ast, 0x12000, 0x1688a8a8);
1610 do {
1612 } while (ast_read32(ast, 0x12000) != 0x1);
1614 ast_write32(ast, 0x10000, 0xfc600309);
1615 do {
1617 } while (ast_read32(ast, 0x10000) != 0x1);
1619 /* Slow down CPU/AHB CLK in VGA only mode */
1620 temp = ast_read32(ast, 0x12008);
1621 temp |= 0x73;
1622 ast_write32(ast, 0x12008, temp);
1624 param.dram_freq = 396;
1625 param.dram_type = AST_DDR3;
1626 temp = ast_mindwm(ast, 0x1e6e2070);
1627 if (temp & 0x01000000)
1628 param.dram_type = AST_DDR2;
1629 switch (temp & 0x18000000) {
1630 case 0:
1631 param.dram_chipid = AST_DRAM_512Mx16;
1632 break;
1633 default:
1634 case 0x08000000:
1635 param.dram_chipid = AST_DRAM_1Gx16;
1636 break;
1637 case 0x10000000:
1638 param.dram_chipid = AST_DRAM_2Gx16;
1639 break;
1640 case 0x18000000:
1641 param.dram_chipid = AST_DRAM_4Gx16;
1642 break;
1644 switch (temp & 0x0c) {
1645 default:
1646 case 0x00:
1647 param.vram_size = AST_VIDMEM_SIZE_8M;
1648 break;
1650 case 0x04:
1651 param.vram_size = AST_VIDMEM_SIZE_16M;
1652 break;
1654 case 0x08:
1655 param.vram_size = AST_VIDMEM_SIZE_32M;
1656 break;
1658 case 0x0c:
1659 param.vram_size = AST_VIDMEM_SIZE_64M;
1660 break;
1663 if (param.dram_type == AST_DDR3) {
1664 get_ddr3_info(ast, &param);
1665 ddr3_init(ast, &param);
1666 } else {
1667 get_ddr2_info(ast, &param);
1668 ddr2_init(ast, &param);
1671 temp = ast_mindwm(ast, 0x1e6e2040);
1672 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
1675 /* wait ready */
1676 do {
1677 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1678 } while ((reg & 0x40) == 0);
1681 static bool cbr_test_2500(struct ast_private *ast)
1683 ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
1684 ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
1685 if (!mmc_test_burst(ast, 0))
1686 return false;
1687 if (!mmc_test_single_2500(ast, 0))
1688 return false;
1689 return true;
1692 static bool ddr_test_2500(struct ast_private *ast)
1694 ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
1695 ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
1696 if (!mmc_test_burst(ast, 0))
1697 return false;
1698 if (!mmc_test_burst(ast, 1))
1699 return false;
1700 if (!mmc_test_burst(ast, 2))
1701 return false;
1702 if (!mmc_test_burst(ast, 3))
1703 return false;
1704 if (!mmc_test_single_2500(ast, 0))
1705 return false;
1706 return true;
1709 static void ddr_init_common_2500(struct ast_private *ast)
1711 ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
1712 ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
1713 ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF);
1714 ast_moutdwm(ast, 0x1E6E0040, 0x88448844);
1715 ast_moutdwm(ast, 0x1E6E0044, 0x24422288);
1716 ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1717 ast_moutdwm(ast, 0x1E6E004C, 0x22222222);
1718 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1719 ast_moutdwm(ast, 0x1E6E0208, 0x00000000);
1720 ast_moutdwm(ast, 0x1E6E0218, 0x00000000);
1721 ast_moutdwm(ast, 0x1E6E0220, 0x00000000);
1722 ast_moutdwm(ast, 0x1E6E0228, 0x00000000);
1723 ast_moutdwm(ast, 0x1E6E0230, 0x00000000);
1724 ast_moutdwm(ast, 0x1E6E02A8, 0x00000000);
1725 ast_moutdwm(ast, 0x1E6E02B0, 0x00000000);
1726 ast_moutdwm(ast, 0x1E6E0240, 0x86000000);
1727 ast_moutdwm(ast, 0x1E6E0244, 0x00008600);
1728 ast_moutdwm(ast, 0x1E6E0248, 0x80000000);
1729 ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
1732 static void ddr_phy_init_2500(struct ast_private *ast)
1734 u32 data, pass, timecnt;
1736 pass = 0;
1737 ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
1738 while (!pass) {
1739 for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
1740 data = ast_mindwm(ast, 0x1E6E0060) & 0x1;
1741 if (!data)
1742 break;
1744 if (timecnt != TIMEOUT) {
1745 data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000;
1746 if (!data)
1747 pass = 1;
1749 if (!pass) {
1750 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1751 udelay(10); /* delay 10 us */
1752 ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
1756 ast_moutdwm(ast, 0x1E6E0060, 0x00000006);
1760 * Check DRAM Size
1761 * 1Gb : 0x80000000 ~ 0x87FFFFFF
1762 * 2Gb : 0x80000000 ~ 0x8FFFFFFF
1763 * 4Gb : 0x80000000 ~ 0x9FFFFFFF
1764 * 8Gb : 0x80000000 ~ 0xBFFFFFFF
1766 static void check_dram_size_2500(struct ast_private *ast, u32 tRFC)
1768 u32 reg_04, reg_14;
1770 reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc;
1771 reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00;
1773 ast_moutdwm(ast, 0xA0100000, 0x41424344);
1774 ast_moutdwm(ast, 0x90100000, 0x35363738);
1775 ast_moutdwm(ast, 0x88100000, 0x292A2B2C);
1776 ast_moutdwm(ast, 0x80100000, 0x1D1E1F10);
1778 /* Check 8Gbit */
1779 if (ast_mindwm(ast, 0xA0100000) == 0x41424344) {
1780 reg_04 |= 0x03;
1781 reg_14 |= (tRFC >> 24) & 0xFF;
1782 /* Check 4Gbit */
1783 } else if (ast_mindwm(ast, 0x90100000) == 0x35363738) {
1784 reg_04 |= 0x02;
1785 reg_14 |= (tRFC >> 16) & 0xFF;
1786 /* Check 2Gbit */
1787 } else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) {
1788 reg_04 |= 0x01;
1789 reg_14 |= (tRFC >> 8) & 0xFF;
1790 } else {
1791 reg_14 |= tRFC & 0xFF;
1793 ast_moutdwm(ast, 0x1E6E0004, reg_04);
1794 ast_moutdwm(ast, 0x1E6E0014, reg_14);
1797 static void enable_cache_2500(struct ast_private *ast)
1799 u32 reg_04, data;
1801 reg_04 = ast_mindwm(ast, 0x1E6E0004);
1802 ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000);
1805 data = ast_mindwm(ast, 0x1E6E0004);
1806 while (!(data & 0x80000));
1807 ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
1810 static void set_mpll_2500(struct ast_private *ast)
1812 u32 addr, data, param;
1814 /* Reset MMC */
1815 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1816 ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
1817 for (addr = 0x1e6e0004; addr < 0x1e6e0090;) {
1818 ast_moutdwm(ast, addr, 0x0);
1819 addr += 4;
1821 ast_moutdwm(ast, 0x1E6E0034, 0x00020000);
1823 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1824 data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000;
1825 if (data) {
1826 /* CLKIN = 25MHz */
1827 param = 0x930023E0;
1828 ast_moutdwm(ast, 0x1E6E2160, 0x00011320);
1829 } else {
1830 /* CLKIN = 24MHz */
1831 param = 0x93002400;
1833 ast_moutdwm(ast, 0x1E6E2020, param);
1834 udelay(100);
1837 static void reset_mmc_2500(struct ast_private *ast)
1839 ast_moutdwm(ast, 0x1E78505C, 0x00000004);
1840 ast_moutdwm(ast, 0x1E785044, 0x00000001);
1841 ast_moutdwm(ast, 0x1E785048, 0x00004755);
1842 ast_moutdwm(ast, 0x1E78504C, 0x00000013);
1843 mdelay(100);
1844 ast_moutdwm(ast, 0x1E785054, 0x00000077);
1845 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1848 static void ddr3_init_2500(struct ast_private *ast, const u32 *ddr_table)
1851 ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
1852 ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
1853 ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
1854 ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
1855 ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
1856 ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
1857 ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
1858 ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
1860 /* DDR PHY Setting */
1861 ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE);
1862 ast_moutdwm(ast, 0x1E6E0204, 0x00001001);
1863 ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
1864 ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
1865 ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
1866 ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
1867 ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
1868 ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
1869 ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
1870 ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
1871 ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
1872 ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
1873 ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
1874 ast_moutdwm(ast, 0x1E6E02C0, 0x00000006);
1876 /* Controller Setting */
1877 ast_moutdwm(ast, 0x1E6E0034, 0x00020091);
1879 /* Wait DDR PHY init done */
1880 ddr_phy_init_2500(ast);
1882 ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
1883 ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
1884 ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
1886 check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
1887 enable_cache_2500(ast);
1888 ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
1889 ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
1892 static void ddr4_init_2500(struct ast_private *ast, const u32 *ddr_table)
1894 u32 data, data2, pass, retrycnt;
1895 u32 ddr_vref, phy_vref;
1896 u32 min_ddr_vref = 0, min_phy_vref = 0;
1897 u32 max_ddr_vref = 0, max_phy_vref = 0;
1899 ast_moutdwm(ast, 0x1E6E0004, 0x00000313);
1900 ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
1901 ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
1902 ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
1903 ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
1904 ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
1905 ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
1906 ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
1908 /* DDR PHY Setting */
1909 ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE);
1910 ast_moutdwm(ast, 0x1E6E0204, 0x09002000);
1911 ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
1912 ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
1913 ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
1914 ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
1915 ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
1916 ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
1917 ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
1918 ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
1919 ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
1920 ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
1921 ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
1922 ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C);
1923 ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E);
1925 /* Controller Setting */
1926 ast_moutdwm(ast, 0x1E6E0034, 0x0001A991);
1928 /* Train PHY Vref first */
1929 pass = 0;
1931 for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
1932 max_phy_vref = 0x0;
1933 pass = 0;
1934 ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06);
1935 for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
1936 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1937 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1938 ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8));
1939 /* Fire DFI Init */
1940 ddr_phy_init_2500(ast);
1941 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1942 if (cbr_test_2500(ast)) {
1943 pass++;
1944 data = ast_mindwm(ast, 0x1E6E03D0);
1945 data2 = data >> 8;
1946 data = data & 0xff;
1947 if (data > data2)
1948 data = data2;
1949 if (max_phy_vref < data) {
1950 max_phy_vref = data;
1951 min_phy_vref = phy_vref;
1953 } else if (pass > 0)
1954 break;
1957 ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8));
1959 /* Train DDR Vref next */
1960 pass = 0;
1962 for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
1963 min_ddr_vref = 0xFF;
1964 max_ddr_vref = 0x0;
1965 pass = 0;
1966 for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
1967 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1968 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1969 ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
1970 /* Fire DFI Init */
1971 ddr_phy_init_2500(ast);
1972 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1973 if (cbr_test_2500(ast)) {
1974 pass++;
1975 if (min_ddr_vref > ddr_vref)
1976 min_ddr_vref = ddr_vref;
1977 if (max_ddr_vref < ddr_vref)
1978 max_ddr_vref = ddr_vref;
1979 } else if (pass != 0)
1980 break;
1984 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1985 ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1986 ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
1987 ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
1989 /* Wait DDR PHY init done */
1990 ddr_phy_init_2500(ast);
1992 ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
1993 ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
1994 ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
1996 check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
1997 enable_cache_2500(ast);
1998 ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
1999 ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
2002 static bool ast_dram_init_2500(struct ast_private *ast)
2004 u32 data;
2005 u32 max_tries = 5;
2007 do {
2008 if (max_tries-- == 0)
2009 return false;
2010 set_mpll_2500(ast);
2011 reset_mmc_2500(ast);
2012 ddr_init_common_2500(ast);
2014 data = ast_mindwm(ast, 0x1E6E2070);
2015 if (data & 0x01000000)
2016 ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
2017 else
2018 ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
2019 } while (!ddr_test_2500(ast));
2021 ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41);
2023 /* Patch code */
2024 data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF;
2025 ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000);
2027 return true;
2030 void ast_post_chip_2500(struct drm_device *dev)
2032 struct ast_private *ast = dev->dev_private;
2033 u32 temp;
2034 u8 reg;
2036 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
2037 if ((reg & 0x80) == 0) {/* vga only */
2038 /* Clear bus lock condition */
2039 ast_moutdwm(ast, 0x1e600000, 0xAEED1A03);
2040 ast_moutdwm(ast, 0x1e600084, 0x00010000);
2041 ast_moutdwm(ast, 0x1e600088, 0x00000000);
2042 ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8);
2043 ast_write32(ast, 0xf004, 0x1e6e0000);
2044 ast_write32(ast, 0xf000, 0x1);
2045 ast_write32(ast, 0x12000, 0x1688a8a8);
2046 while (ast_read32(ast, 0x12000) != 0x1)
2049 ast_write32(ast, 0x10000, 0xfc600309);
2050 while (ast_read32(ast, 0x10000) != 0x1)
2053 /* Slow down CPU/AHB CLK in VGA only mode */
2054 temp = ast_read32(ast, 0x12008);
2055 temp |= 0x73;
2056 ast_write32(ast, 0x12008, temp);
2058 /* Reset USB port to patch USB unknown device issue */
2059 ast_moutdwm(ast, 0x1e6e2090, 0x20000000);
2060 temp = ast_mindwm(ast, 0x1e6e2094);
2061 temp |= 0x00004000;
2062 ast_moutdwm(ast, 0x1e6e2094, temp);
2063 temp = ast_mindwm(ast, 0x1e6e2070);
2064 if (temp & 0x00800000) {
2065 ast_moutdwm(ast, 0x1e6e207c, 0x00800000);
2066 mdelay(100);
2067 ast_moutdwm(ast, 0x1e6e2070, 0x00800000);
2070 if (!ast_dram_init_2500(ast))
2071 DRM_ERROR("DRAM init failed !\n");
2073 temp = ast_mindwm(ast, 0x1e6e2040);
2074 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
2077 /* wait ready */
2078 do {
2079 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
2080 } while ((reg & 0x40) == 0);