PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / gpu / drm / ast / ast_post.c
blob977cfb35837a004b6078fb121125d239464df90a
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_init_dram_2300(struct drm_device *dev);
36 static void
37 ast_enable_vga(struct drm_device *dev)
39 struct ast_private *ast = dev->dev_private;
41 ast_io_write8(ast, 0x43, 0x01);
42 ast_io_write8(ast, 0x42, 0x01);
45 #if 0 /* will use later */
46 static bool
47 ast_is_vga_enabled(struct drm_device *dev)
49 struct ast_private *ast = dev->dev_private;
50 u8 ch;
52 if (ast->chip == AST1180) {
53 /* TODO 1180 */
54 } else {
55 ch = ast_io_read8(ast, 0x43);
56 if (ch) {
57 ast_open_key(ast);
58 ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
59 return ch & 0x04;
62 return 0;
64 #endif
66 static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
67 static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
68 static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
70 static void
71 ast_set_def_ext_reg(struct drm_device *dev)
73 struct ast_private *ast = dev->dev_private;
74 u8 i, index, reg;
75 const u8 *ext_reg_info;
77 /* reset scratch */
78 for (i = 0x81; i <= 0x8f; i++)
79 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
81 if (ast->chip == AST2300) {
82 if (dev->pdev->revision >= 0x20)
83 ext_reg_info = extreginfo_ast2300;
84 else
85 ext_reg_info = extreginfo_ast2300a0;
86 } else
87 ext_reg_info = extreginfo;
89 index = 0xa0;
90 while (*ext_reg_info != 0xff) {
91 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
92 index++;
93 ext_reg_info++;
96 /* disable standard IO/MEM decode if secondary */
97 /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
99 /* Set Ext. Default */
100 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
101 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
103 /* Enable RAMDAC for A1 */
104 reg = 0x04;
105 if (ast->chip == AST2300)
106 reg |= 0x20;
107 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
110 static inline u32 mindwm(struct ast_private *ast, u32 r)
112 ast_write32(ast, 0xf004, r & 0xffff0000);
113 ast_write32(ast, 0xf000, 0x1);
115 return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
118 static inline void moutdwm(struct ast_private *ast, u32 r, u32 v)
120 ast_write32(ast, 0xf004, r & 0xffff0000);
121 ast_write32(ast, 0xf000, 0x1);
122 ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
126 * AST2100/2150 DLL CBR Setting
128 #define CBR_SIZE_AST2150 ((16 << 10) - 1)
129 #define CBR_PASSNUM_AST2150 5
130 #define CBR_THRESHOLD_AST2150 10
131 #define CBR_THRESHOLD2_AST2150 10
132 #define TIMEOUT_AST2150 5000000
134 #define CBR_PATNUM_AST2150 8
136 static const u32 pattern_AST2150[14] = {
137 0xFF00FF00,
138 0xCC33CC33,
139 0xAA55AA55,
140 0xFFFE0001,
141 0x683501FE,
142 0x0F1929B0,
143 0x2D0B4346,
144 0x60767F02,
145 0x6FBE36A6,
146 0x3A253035,
147 0x3019686D,
148 0x41C6167E,
149 0x620152BF,
150 0x20F050E0
153 static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
155 u32 data, timeout;
157 moutdwm(ast, 0x1e6e0070, 0x00000000);
158 moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
159 timeout = 0;
160 do {
161 data = mindwm(ast, 0x1e6e0070) & 0x40;
162 if (++timeout > TIMEOUT_AST2150) {
163 moutdwm(ast, 0x1e6e0070, 0x00000000);
164 return 0xffffffff;
166 } while (!data);
167 moutdwm(ast, 0x1e6e0070, 0x00000000);
168 moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
169 timeout = 0;
170 do {
171 data = mindwm(ast, 0x1e6e0070) & 0x40;
172 if (++timeout > TIMEOUT_AST2150) {
173 moutdwm(ast, 0x1e6e0070, 0x00000000);
174 return 0xffffffff;
176 } while (!data);
177 data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
178 moutdwm(ast, 0x1e6e0070, 0x00000000);
179 return data;
182 #if 0 /* unused in DDX driver - here for completeness */
183 static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
185 u32 data, timeout;
187 moutdwm(ast, 0x1e6e0070, 0x00000000);
188 moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
189 timeout = 0;
190 do {
191 data = mindwm(ast, 0x1e6e0070) & 0x40;
192 if (++timeout > TIMEOUT_AST2150) {
193 moutdwm(ast, 0x1e6e0070, 0x00000000);
194 return 0xffffffff;
196 } while (!data);
197 data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
198 moutdwm(ast, 0x1e6e0070, 0x00000000);
199 return data;
201 #endif
203 static int cbrtest_ast2150(struct ast_private *ast)
205 int i;
207 for (i = 0; i < 8; i++)
208 if (mmctestburst2_ast2150(ast, i))
209 return 0;
210 return 1;
213 static int cbrscan_ast2150(struct ast_private *ast, int busw)
215 u32 patcnt, loop;
217 for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
218 moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
219 for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
220 if (cbrtest_ast2150(ast))
221 break;
223 if (loop == CBR_PASSNUM_AST2150)
224 return 0;
226 return 1;
230 static void cbrdlli_ast2150(struct ast_private *ast, int busw)
232 u32 dll_min[4], dll_max[4], dlli, data, passcnt;
234 cbr_start:
235 dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
236 dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
237 passcnt = 0;
239 for (dlli = 0; dlli < 100; dlli++) {
240 moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
241 data = cbrscan_ast2150(ast, busw);
242 if (data != 0) {
243 if (data & 0x1) {
244 if (dll_min[0] > dlli)
245 dll_min[0] = dlli;
246 if (dll_max[0] < dlli)
247 dll_max[0] = dlli;
249 passcnt++;
250 } else if (passcnt >= CBR_THRESHOLD_AST2150)
251 goto cbr_start;
253 if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
254 goto cbr_start;
256 dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
257 moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
262 static void ast_init_dram_reg(struct drm_device *dev)
264 struct ast_private *ast = dev->dev_private;
265 u8 j;
266 u32 data, temp, i;
267 const struct ast_dramstruct *dram_reg_info;
269 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
271 if ((j & 0x80) == 0) { /* VGA only */
272 if (ast->chip == AST2000) {
273 dram_reg_info = ast2000_dram_table_data;
274 ast_write32(ast, 0xf004, 0x1e6e0000);
275 ast_write32(ast, 0xf000, 0x1);
276 ast_write32(ast, 0x10100, 0xa8);
278 do {
280 } while (ast_read32(ast, 0x10100) != 0xa8);
281 } else {/* AST2100/1100 */
282 if (ast->chip == AST2100 || ast->chip == 2200)
283 dram_reg_info = ast2100_dram_table_data;
284 else
285 dram_reg_info = ast1100_dram_table_data;
287 ast_write32(ast, 0xf004, 0x1e6e0000);
288 ast_write32(ast, 0xf000, 0x1);
289 ast_write32(ast, 0x12000, 0x1688A8A8);
290 do {
292 } while (ast_read32(ast, 0x12000) != 0x01);
294 ast_write32(ast, 0x10000, 0xfc600309);
295 do {
297 } while (ast_read32(ast, 0x10000) != 0x01);
300 while (dram_reg_info->index != 0xffff) {
301 if (dram_reg_info->index == 0xff00) {/* delay fn */
302 for (i = 0; i < 15; i++)
303 udelay(dram_reg_info->data);
304 } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
305 data = dram_reg_info->data;
306 if (ast->dram_type == AST_DRAM_1Gx16)
307 data = 0x00000d89;
308 else if (ast->dram_type == AST_DRAM_1Gx32)
309 data = 0x00000c8d;
311 temp = ast_read32(ast, 0x12070);
312 temp &= 0xc;
313 temp <<= 2;
314 ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
315 } else
316 ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
317 dram_reg_info++;
320 /* AST 2100/2150 DRAM calibration */
321 data = ast_read32(ast, 0x10120);
322 if (data == 0x5061) { /* 266Mhz */
323 data = ast_read32(ast, 0x10004);
324 if (data & 0x40)
325 cbrdlli_ast2150(ast, 16); /* 16 bits */
326 else
327 cbrdlli_ast2150(ast, 32); /* 32 bits */
330 switch (ast->chip) {
331 case AST2000:
332 temp = ast_read32(ast, 0x10140);
333 ast_write32(ast, 0x10140, temp | 0x40);
334 break;
335 case AST1100:
336 case AST2100:
337 case AST2200:
338 case AST2150:
339 temp = ast_read32(ast, 0x1200c);
340 ast_write32(ast, 0x1200c, temp & 0xfffffffd);
341 temp = ast_read32(ast, 0x12040);
342 ast_write32(ast, 0x12040, temp | 0x40);
343 break;
344 default:
345 break;
349 /* wait ready */
350 do {
351 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
352 } while ((j & 0x40) == 0);
355 void ast_post_gpu(struct drm_device *dev)
357 u32 reg;
358 struct ast_private *ast = dev->dev_private;
360 pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
361 reg |= 0x3;
362 pci_write_config_dword(ast->dev->pdev, 0x04, reg);
364 ast_enable_vga(dev);
365 ast_open_key(ast);
366 ast_set_def_ext_reg(dev);
368 if (ast->chip == AST2300)
369 ast_init_dram_2300(dev);
370 else
371 ast_init_dram_reg(dev);
374 /* AST 2300 DRAM settings */
375 #define AST_DDR3 0
376 #define AST_DDR2 1
378 struct ast2300_dram_param {
379 u32 dram_type;
380 u32 dram_chipid;
381 u32 dram_freq;
382 u32 vram_size;
383 u32 odt;
384 u32 wodt;
385 u32 rodt;
386 u32 dram_config;
387 u32 reg_PERIOD;
388 u32 reg_MADJ;
389 u32 reg_SADJ;
390 u32 reg_MRS;
391 u32 reg_EMRS;
392 u32 reg_AC1;
393 u32 reg_AC2;
394 u32 reg_DQSIC;
395 u32 reg_DRV;
396 u32 reg_IOZ;
397 u32 reg_DQIDLY;
398 u32 reg_FREQ;
399 u32 madj_max;
400 u32 dll2_finetune_step;
404 * DQSI DLL CBR Setting
406 #define CBR_SIZE1 ((4 << 10) - 1)
407 #define CBR_SIZE2 ((64 << 10) - 1)
408 #define CBR_PASSNUM 5
409 #define CBR_PASSNUM2 5
410 #define CBR_THRESHOLD 10
411 #define CBR_THRESHOLD2 10
412 #define TIMEOUT 5000000
413 #define CBR_PATNUM 8
415 static const u32 pattern[8] = {
416 0xFF00FF00,
417 0xCC33CC33,
418 0xAA55AA55,
419 0x88778877,
420 0x92CC4D6E,
421 0x543D3CDE,
422 0xF1E843C7,
423 0x7C61D253
426 #if 0 /* unused in DDX, included for completeness */
427 static int mmc_test_burst(struct ast_private *ast, u32 datagen)
429 u32 data, timeout;
431 moutdwm(ast, 0x1e6e0070, 0x00000000);
432 moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3));
433 timeout = 0;
434 do {
435 data = mindwm(ast, 0x1e6e0070) & 0x3000;
436 if (data & 0x2000) {
437 return 0;
439 if (++timeout > TIMEOUT) {
440 moutdwm(ast, 0x1e6e0070, 0x00000000);
441 return 0;
443 } while (!data);
444 moutdwm(ast, 0x1e6e0070, 0x00000000);
445 return 1;
447 #endif
449 static int mmc_test_burst2(struct ast_private *ast, u32 datagen)
451 u32 data, timeout;
453 moutdwm(ast, 0x1e6e0070, 0x00000000);
454 moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3));
455 timeout = 0;
456 do {
457 data = mindwm(ast, 0x1e6e0070) & 0x1000;
458 if (++timeout > TIMEOUT) {
459 moutdwm(ast, 0x1e6e0070, 0x0);
460 return -1;
462 } while (!data);
463 data = mindwm(ast, 0x1e6e0078);
464 data = (data | (data >> 16)) & 0xffff;
465 moutdwm(ast, 0x1e6e0070, 0x0);
466 return data;
469 #if 0 /* Unused in DDX here for completeness */
470 static int mmc_test_single(struct ast_private *ast, u32 datagen)
472 u32 data, timeout;
474 moutdwm(ast, 0x1e6e0070, 0x00000000);
475 moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3));
476 timeout = 0;
477 do {
478 data = mindwm(ast, 0x1e6e0070) & 0x3000;
479 if (data & 0x2000)
480 return 0;
481 if (++timeout > TIMEOUT) {
482 moutdwm(ast, 0x1e6e0070, 0x0);
483 return 0;
485 } while (!data);
486 moutdwm(ast, 0x1e6e0070, 0x0);
487 return 1;
489 #endif
491 static int mmc_test_single2(struct ast_private *ast, u32 datagen)
493 u32 data, timeout;
495 moutdwm(ast, 0x1e6e0070, 0x00000000);
496 moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
497 timeout = 0;
498 do {
499 data = mindwm(ast, 0x1e6e0070) & 0x1000;
500 if (++timeout > TIMEOUT) {
501 moutdwm(ast, 0x1e6e0070, 0x0);
502 return -1;
504 } while (!data);
505 data = mindwm(ast, 0x1e6e0078);
506 data = (data | (data >> 16)) & 0xffff;
507 moutdwm(ast, 0x1e6e0070, 0x0);
508 return data;
511 static int cbr_test(struct ast_private *ast)
513 u32 data;
514 int i;
515 data = mmc_test_single2(ast, 0);
516 if ((data & 0xff) && (data & 0xff00))
517 return 0;
518 for (i = 0; i < 8; i++) {
519 data = mmc_test_burst2(ast, i);
520 if ((data & 0xff) && (data & 0xff00))
521 return 0;
523 if (!data)
524 return 3;
525 else if (data & 0xff)
526 return 2;
527 return 1;
530 static int cbr_scan(struct ast_private *ast)
532 u32 data, data2, patcnt, loop;
534 data2 = 3;
535 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
536 moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
537 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
538 if ((data = cbr_test(ast)) != 0) {
539 data2 &= data;
540 if (!data2)
541 return 0;
542 break;
545 if (loop == CBR_PASSNUM2)
546 return 0;
548 return data2;
551 static u32 cbr_test2(struct ast_private *ast)
553 u32 data;
555 data = mmc_test_burst2(ast, 0);
556 if (data == 0xffff)
557 return 0;
558 data |= mmc_test_single2(ast, 0);
559 if (data == 0xffff)
560 return 0;
562 return ~data & 0xffff;
565 static u32 cbr_scan2(struct ast_private *ast)
567 u32 data, data2, patcnt, loop;
569 data2 = 0xffff;
570 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
571 moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
572 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
573 if ((data = cbr_test2(ast)) != 0) {
574 data2 &= data;
575 if (!data)
576 return 0;
577 break;
580 if (loop == CBR_PASSNUM2)
581 return 0;
583 return data2;
586 #if 0 /* unused in DDX - added for completeness */
587 static void finetuneDQI(struct ast_private *ast, struct ast2300_dram_param *param)
589 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
591 gold_sadj[0] = (mindwm(ast, 0x1E6E0024) >> 16) & 0xffff;
592 gold_sadj[1] = gold_sadj[0] >> 8;
593 gold_sadj[0] = gold_sadj[0] & 0xff;
594 gold_sadj[0] = (gold_sadj[0] + gold_sadj[1]) >> 1;
595 gold_sadj[1] = gold_sadj[0];
597 for (cnt = 0; cnt < 16; cnt++) {
598 dllmin[cnt] = 0xff;
599 dllmax[cnt] = 0x0;
601 passcnt = 0;
602 for (dlli = 0; dlli < 76; dlli++) {
603 moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
604 /* Wait DQSI latch phase calibration */
605 moutdwm(ast, 0x1E6E0074, 0x00000010);
606 moutdwm(ast, 0x1E6E0070, 0x00000003);
607 do {
608 data = mindwm(ast, 0x1E6E0070);
609 } while (!(data & 0x00001000));
610 moutdwm(ast, 0x1E6E0070, 0x00000000);
612 moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
613 data = cbr_scan2(ast);
614 if (data != 0) {
615 mask = 0x00010001;
616 for (cnt = 0; cnt < 16; cnt++) {
617 if (data & mask) {
618 if (dllmin[cnt] > dlli) {
619 dllmin[cnt] = dlli;
621 if (dllmax[cnt] < dlli) {
622 dllmax[cnt] = dlli;
625 mask <<= 1;
627 passcnt++;
628 } else if (passcnt >= CBR_THRESHOLD) {
629 break;
632 data = 0;
633 for (cnt = 0; cnt < 8; cnt++) {
634 data >>= 3;
635 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD)) {
636 dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
637 if (gold_sadj[0] >= dlli) {
638 dlli = (gold_sadj[0] - dlli) >> 1;
639 if (dlli > 3) {
640 dlli = 3;
642 } else {
643 dlli = (dlli - gold_sadj[0]) >> 1;
644 if (dlli > 4) {
645 dlli = 4;
647 dlli = (8 - dlli) & 0x7;
649 data |= dlli << 21;
652 moutdwm(ast, 0x1E6E0080, data);
654 data = 0;
655 for (cnt = 8; cnt < 16; cnt++) {
656 data >>= 3;
657 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD)) {
658 dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
659 if (gold_sadj[1] >= dlli) {
660 dlli = (gold_sadj[1] - dlli) >> 1;
661 if (dlli > 3) {
662 dlli = 3;
663 } else {
664 dlli = (dlli - 1) & 0x7;
666 } else {
667 dlli = (dlli - gold_sadj[1]) >> 1;
668 dlli += 1;
669 if (dlli > 4) {
670 dlli = 4;
672 dlli = (8 - dlli) & 0x7;
674 data |= dlli << 21;
677 moutdwm(ast, 0x1E6E0084, data);
679 } /* finetuneDQI */
680 #endif
682 static void finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
684 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
686 FINETUNE_START:
687 for (cnt = 0; cnt < 16; cnt++) {
688 dllmin[cnt] = 0xff;
689 dllmax[cnt] = 0x0;
691 passcnt = 0;
692 for (dlli = 0; dlli < 76; dlli++) {
693 moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
694 /* Wait DQSI latch phase calibration */
695 moutdwm(ast, 0x1E6E0074, 0x00000010);
696 moutdwm(ast, 0x1E6E0070, 0x00000003);
697 do {
698 data = mindwm(ast, 0x1E6E0070);
699 } while (!(data & 0x00001000));
700 moutdwm(ast, 0x1E6E0070, 0x00000000);
702 moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
703 data = cbr_scan2(ast);
704 if (data != 0) {
705 mask = 0x00010001;
706 for (cnt = 0; cnt < 16; cnt++) {
707 if (data & mask) {
708 if (dllmin[cnt] > dlli) {
709 dllmin[cnt] = dlli;
711 if (dllmax[cnt] < dlli) {
712 dllmax[cnt] = dlli;
715 mask <<= 1;
717 passcnt++;
718 } else if (passcnt >= CBR_THRESHOLD2) {
719 break;
722 gold_sadj[0] = 0x0;
723 passcnt = 0;
724 for (cnt = 0; cnt < 16; cnt++) {
725 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
726 gold_sadj[0] += dllmin[cnt];
727 passcnt++;
730 if (passcnt != 16) {
731 goto FINETUNE_START;
733 gold_sadj[0] = gold_sadj[0] >> 4;
734 gold_sadj[1] = gold_sadj[0];
736 data = 0;
737 for (cnt = 0; cnt < 8; cnt++) {
738 data >>= 3;
739 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
740 dlli = dllmin[cnt];
741 if (gold_sadj[0] >= dlli) {
742 dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
743 if (dlli > 3) {
744 dlli = 3;
746 } else {
747 dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
748 if (dlli > 4) {
749 dlli = 4;
751 dlli = (8 - dlli) & 0x7;
753 data |= dlli << 21;
756 moutdwm(ast, 0x1E6E0080, data);
758 data = 0;
759 for (cnt = 8; cnt < 16; cnt++) {
760 data >>= 3;
761 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
762 dlli = dllmin[cnt];
763 if (gold_sadj[1] >= dlli) {
764 dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
765 if (dlli > 3) {
766 dlli = 3;
767 } else {
768 dlli = (dlli - 1) & 0x7;
770 } else {
771 dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
772 dlli += 1;
773 if (dlli > 4) {
774 dlli = 4;
776 dlli = (8 - dlli) & 0x7;
778 data |= dlli << 21;
781 moutdwm(ast, 0x1E6E0084, data);
783 } /* finetuneDQI_L */
785 static void finetuneDQI_L2(struct ast_private *ast, struct ast2300_dram_param *param)
787 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, data2;
789 for (cnt = 0; cnt < 16; cnt++) {
790 dllmin[cnt] = 0xff;
791 dllmax[cnt] = 0x0;
793 passcnt = 0;
794 for (dlli = 0; dlli < 76; dlli++) {
795 moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
796 /* Wait DQSI latch phase calibration */
797 moutdwm(ast, 0x1E6E0074, 0x00000010);
798 moutdwm(ast, 0x1E6E0070, 0x00000003);
799 do {
800 data = mindwm(ast, 0x1E6E0070);
801 } while (!(data & 0x00001000));
802 moutdwm(ast, 0x1E6E0070, 0x00000000);
804 moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
805 data = cbr_scan2(ast);
806 if (data != 0) {
807 mask = 0x00010001;
808 for (cnt = 0; cnt < 16; cnt++) {
809 if (data & mask) {
810 if (dllmin[cnt] > dlli) {
811 dllmin[cnt] = dlli;
813 if (dllmax[cnt] < dlli) {
814 dllmax[cnt] = dlli;
817 mask <<= 1;
819 passcnt++;
820 } else if (passcnt >= CBR_THRESHOLD2) {
821 break;
824 gold_sadj[0] = 0x0;
825 gold_sadj[1] = 0xFF;
826 for (cnt = 0; cnt < 8; cnt++) {
827 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
828 if (gold_sadj[0] < dllmin[cnt]) {
829 gold_sadj[0] = dllmin[cnt];
831 if (gold_sadj[1] > dllmax[cnt]) {
832 gold_sadj[1] = dllmax[cnt];
836 gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
837 gold_sadj[1] = mindwm(ast, 0x1E6E0080);
839 data = 0;
840 for (cnt = 0; cnt < 8; cnt++) {
841 data >>= 3;
842 data2 = gold_sadj[1] & 0x7;
843 gold_sadj[1] >>= 3;
844 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
845 dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
846 if (gold_sadj[0] >= dlli) {
847 dlli = (gold_sadj[0] - dlli) >> 1;
848 if (dlli > 0) {
849 dlli = 1;
851 if (data2 != 3) {
852 data2 = (data2 + dlli) & 0x7;
854 } else {
855 dlli = (dlli - gold_sadj[0]) >> 1;
856 if (dlli > 0) {
857 dlli = 1;
859 if (data2 != 4) {
860 data2 = (data2 - dlli) & 0x7;
864 data |= data2 << 21;
866 moutdwm(ast, 0x1E6E0080, data);
868 gold_sadj[0] = 0x0;
869 gold_sadj[1] = 0xFF;
870 for (cnt = 8; cnt < 16; cnt++) {
871 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
872 if (gold_sadj[0] < dllmin[cnt]) {
873 gold_sadj[0] = dllmin[cnt];
875 if (gold_sadj[1] > dllmax[cnt]) {
876 gold_sadj[1] = dllmax[cnt];
880 gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
881 gold_sadj[1] = mindwm(ast, 0x1E6E0084);
883 data = 0;
884 for (cnt = 8; cnt < 16; cnt++) {
885 data >>= 3;
886 data2 = gold_sadj[1] & 0x7;
887 gold_sadj[1] >>= 3;
888 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
889 dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
890 if (gold_sadj[0] >= dlli) {
891 dlli = (gold_sadj[0] - dlli) >> 1;
892 if (dlli > 0) {
893 dlli = 1;
895 if (data2 != 3) {
896 data2 = (data2 + dlli) & 0x7;
898 } else {
899 dlli = (dlli - gold_sadj[0]) >> 1;
900 if (dlli > 0) {
901 dlli = 1;
903 if (data2 != 4) {
904 data2 = (data2 - dlli) & 0x7;
908 data |= data2 << 21;
910 moutdwm(ast, 0x1E6E0084, data);
912 } /* finetuneDQI_L2 */
914 static void cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
916 u32 dllmin[2], dllmax[2], dlli, data, data2, passcnt;
919 finetuneDQI_L(ast, param);
920 finetuneDQI_L2(ast, param);
922 CBR_START2:
923 dllmin[0] = dllmin[1] = 0xff;
924 dllmax[0] = dllmax[1] = 0x0;
925 passcnt = 0;
926 for (dlli = 0; dlli < 76; dlli++) {
927 moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
928 /* Wait DQSI latch phase calibration */
929 moutdwm(ast, 0x1E6E0074, 0x00000010);
930 moutdwm(ast, 0x1E6E0070, 0x00000003);
931 do {
932 data = mindwm(ast, 0x1E6E0070);
933 } while (!(data & 0x00001000));
934 moutdwm(ast, 0x1E6E0070, 0x00000000);
936 moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
937 data = cbr_scan(ast);
938 if (data != 0) {
939 if (data & 0x1) {
940 if (dllmin[0] > dlli) {
941 dllmin[0] = dlli;
943 if (dllmax[0] < dlli) {
944 dllmax[0] = dlli;
947 if (data & 0x2) {
948 if (dllmin[1] > dlli) {
949 dllmin[1] = dlli;
951 if (dllmax[1] < dlli) {
952 dllmax[1] = dlli;
955 passcnt++;
956 } else if (passcnt >= CBR_THRESHOLD) {
957 break;
960 if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
961 goto CBR_START2;
963 if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
964 goto CBR_START2;
966 dlli = (dllmin[1] + dllmax[1]) >> 1;
967 dlli <<= 8;
968 dlli += (dllmin[0] + dllmax[0]) >> 1;
969 moutdwm(ast, 0x1E6E0068, (mindwm(ast, 0x1E6E0068) & 0xFFFF) | (dlli << 16));
971 data = (mindwm(ast, 0x1E6E0080) >> 24) & 0x1F;
972 data2 = (mindwm(ast, 0x1E6E0018) & 0xff80ffff) | (data << 16);
973 moutdwm(ast, 0x1E6E0018, data2);
974 moutdwm(ast, 0x1E6E0024, 0x8001 | (data << 1) | (param->dll2_finetune_step << 8));
976 /* Wait DQSI latch phase calibration */
977 moutdwm(ast, 0x1E6E0074, 0x00000010);
978 moutdwm(ast, 0x1E6E0070, 0x00000003);
979 do {
980 data = mindwm(ast, 0x1E6E0070);
981 } while (!(data & 0x00001000));
982 moutdwm(ast, 0x1E6E0070, 0x00000000);
983 moutdwm(ast, 0x1E6E0070, 0x00000003);
984 do {
985 data = mindwm(ast, 0x1E6E0070);
986 } while (!(data & 0x00001000));
987 moutdwm(ast, 0x1E6E0070, 0x00000000);
988 } /* CBRDLL2 */
990 static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
992 u32 trap, trap_AC2, trap_MRS;
994 moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
996 /* Ger trap info */
997 trap = (mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
998 trap_AC2 = 0x00020000 + (trap << 16);
999 trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
1000 trap_MRS = 0x00000010 + (trap << 4);
1001 trap_MRS |= ((trap & 0x2) << 18);
1003 param->reg_MADJ = 0x00034C4C;
1004 param->reg_SADJ = 0x00001800;
1005 param->reg_DRV = 0x000000F0;
1006 param->reg_PERIOD = param->dram_freq;
1007 param->rodt = 0;
1009 switch (param->dram_freq) {
1010 case 336:
1011 moutdwm(ast, 0x1E6E2020, 0x0190);
1012 param->wodt = 0;
1013 param->reg_AC1 = 0x22202725;
1014 param->reg_AC2 = 0xAA007613 | trap_AC2;
1015 param->reg_DQSIC = 0x000000BA;
1016 param->reg_MRS = 0x04001400 | trap_MRS;
1017 param->reg_EMRS = 0x00000000;
1018 param->reg_IOZ = 0x00000034;
1019 param->reg_DQIDLY = 0x00000074;
1020 param->reg_FREQ = 0x00004DC0;
1021 param->madj_max = 96;
1022 param->dll2_finetune_step = 3;
1023 break;
1024 default:
1025 case 396:
1026 moutdwm(ast, 0x1E6E2020, 0x03F1);
1027 param->wodt = 1;
1028 param->reg_AC1 = 0x33302825;
1029 param->reg_AC2 = 0xCC009617 | trap_AC2;
1030 param->reg_DQSIC = 0x000000E2;
1031 param->reg_MRS = 0x04001600 | trap_MRS;
1032 param->reg_EMRS = 0x00000000;
1033 param->reg_IOZ = 0x00000034;
1034 param->reg_DRV = 0x000000FA;
1035 param->reg_DQIDLY = 0x00000089;
1036 param->reg_FREQ = 0x000050C0;
1037 param->madj_max = 96;
1038 param->dll2_finetune_step = 4;
1040 switch (param->dram_chipid) {
1041 default:
1042 case AST_DRAM_512Mx16:
1043 case AST_DRAM_1Gx16:
1044 param->reg_AC2 = 0xCC009617 | trap_AC2;
1045 break;
1046 case AST_DRAM_2Gx16:
1047 param->reg_AC2 = 0xCC009622 | trap_AC2;
1048 break;
1049 case AST_DRAM_4Gx16:
1050 param->reg_AC2 = 0xCC00963F | trap_AC2;
1051 break;
1053 break;
1055 case 408:
1056 moutdwm(ast, 0x1E6E2020, 0x01F0);
1057 param->wodt = 1;
1058 param->reg_AC1 = 0x33302825;
1059 param->reg_AC2 = 0xCC009617 | trap_AC2;
1060 param->reg_DQSIC = 0x000000E2;
1061 param->reg_MRS = 0x04001600 | trap_MRS;
1062 param->reg_EMRS = 0x00000000;
1063 param->reg_IOZ = 0x00000034;
1064 param->reg_DRV = 0x000000FA;
1065 param->reg_DQIDLY = 0x00000089;
1066 param->reg_FREQ = 0x000050C0;
1067 param->madj_max = 96;
1068 param->dll2_finetune_step = 4;
1070 switch (param->dram_chipid) {
1071 default:
1072 case AST_DRAM_512Mx16:
1073 case AST_DRAM_1Gx16:
1074 param->reg_AC2 = 0xCC009617 | trap_AC2;
1075 break;
1076 case AST_DRAM_2Gx16:
1077 param->reg_AC2 = 0xCC009622 | trap_AC2;
1078 break;
1079 case AST_DRAM_4Gx16:
1080 param->reg_AC2 = 0xCC00963F | trap_AC2;
1081 break;
1084 break;
1085 case 456:
1086 moutdwm(ast, 0x1E6E2020, 0x0230);
1087 param->wodt = 0;
1088 param->reg_AC1 = 0x33302926;
1089 param->reg_AC2 = 0xCD44961A;
1090 param->reg_DQSIC = 0x000000FC;
1091 param->reg_MRS = 0x00081830;
1092 param->reg_EMRS = 0x00000000;
1093 param->reg_IOZ = 0x00000045;
1094 param->reg_DQIDLY = 0x00000097;
1095 param->reg_FREQ = 0x000052C0;
1096 param->madj_max = 88;
1097 param->dll2_finetune_step = 4;
1098 break;
1099 case 504:
1100 moutdwm(ast, 0x1E6E2020, 0x0270);
1101 param->wodt = 1;
1102 param->reg_AC1 = 0x33302926;
1103 param->reg_AC2 = 0xDE44A61D;
1104 param->reg_DQSIC = 0x00000117;
1105 param->reg_MRS = 0x00081A30;
1106 param->reg_EMRS = 0x00000000;
1107 param->reg_IOZ = 0x070000BB;
1108 param->reg_DQIDLY = 0x000000A0;
1109 param->reg_FREQ = 0x000054C0;
1110 param->madj_max = 79;
1111 param->dll2_finetune_step = 4;
1112 break;
1113 case 528:
1114 moutdwm(ast, 0x1E6E2020, 0x0290);
1115 param->wodt = 1;
1116 param->rodt = 1;
1117 param->reg_AC1 = 0x33302926;
1118 param->reg_AC2 = 0xEF44B61E;
1119 param->reg_DQSIC = 0x00000125;
1120 param->reg_MRS = 0x00081A30;
1121 param->reg_EMRS = 0x00000040;
1122 param->reg_DRV = 0x000000F5;
1123 param->reg_IOZ = 0x00000023;
1124 param->reg_DQIDLY = 0x00000088;
1125 param->reg_FREQ = 0x000055C0;
1126 param->madj_max = 76;
1127 param->dll2_finetune_step = 3;
1128 break;
1129 case 576:
1130 moutdwm(ast, 0x1E6E2020, 0x0140);
1131 param->reg_MADJ = 0x00136868;
1132 param->reg_SADJ = 0x00004534;
1133 param->wodt = 1;
1134 param->rodt = 1;
1135 param->reg_AC1 = 0x33302A37;
1136 param->reg_AC2 = 0xEF56B61E;
1137 param->reg_DQSIC = 0x0000013F;
1138 param->reg_MRS = 0x00101A50;
1139 param->reg_EMRS = 0x00000040;
1140 param->reg_DRV = 0x000000FA;
1141 param->reg_IOZ = 0x00000023;
1142 param->reg_DQIDLY = 0x00000078;
1143 param->reg_FREQ = 0x000057C0;
1144 param->madj_max = 136;
1145 param->dll2_finetune_step = 3;
1146 break;
1147 case 600:
1148 moutdwm(ast, 0x1E6E2020, 0x02E1);
1149 param->reg_MADJ = 0x00136868;
1150 param->reg_SADJ = 0x00004534;
1151 param->wodt = 1;
1152 param->rodt = 1;
1153 param->reg_AC1 = 0x32302A37;
1154 param->reg_AC2 = 0xDF56B61F;
1155 param->reg_DQSIC = 0x0000014D;
1156 param->reg_MRS = 0x00101A50;
1157 param->reg_EMRS = 0x00000004;
1158 param->reg_DRV = 0x000000F5;
1159 param->reg_IOZ = 0x00000023;
1160 param->reg_DQIDLY = 0x00000078;
1161 param->reg_FREQ = 0x000058C0;
1162 param->madj_max = 132;
1163 param->dll2_finetune_step = 3;
1164 break;
1165 case 624:
1166 moutdwm(ast, 0x1E6E2020, 0x0160);
1167 param->reg_MADJ = 0x00136868;
1168 param->reg_SADJ = 0x00004534;
1169 param->wodt = 1;
1170 param->rodt = 1;
1171 param->reg_AC1 = 0x32302A37;
1172 param->reg_AC2 = 0xEF56B621;
1173 param->reg_DQSIC = 0x0000015A;
1174 param->reg_MRS = 0x02101A50;
1175 param->reg_EMRS = 0x00000004;
1176 param->reg_DRV = 0x000000F5;
1177 param->reg_IOZ = 0x00000034;
1178 param->reg_DQIDLY = 0x00000078;
1179 param->reg_FREQ = 0x000059C0;
1180 param->madj_max = 128;
1181 param->dll2_finetune_step = 3;
1182 break;
1183 } /* switch freq */
1185 switch (param->dram_chipid) {
1186 case AST_DRAM_512Mx16:
1187 param->dram_config = 0x130;
1188 break;
1189 default:
1190 case AST_DRAM_1Gx16:
1191 param->dram_config = 0x131;
1192 break;
1193 case AST_DRAM_2Gx16:
1194 param->dram_config = 0x132;
1195 break;
1196 case AST_DRAM_4Gx16:
1197 param->dram_config = 0x133;
1198 break;
1199 }; /* switch size */
1201 switch (param->vram_size) {
1202 default:
1203 case AST_VIDMEM_SIZE_8M:
1204 param->dram_config |= 0x00;
1205 break;
1206 case AST_VIDMEM_SIZE_16M:
1207 param->dram_config |= 0x04;
1208 break;
1209 case AST_VIDMEM_SIZE_32M:
1210 param->dram_config |= 0x08;
1211 break;
1212 case AST_VIDMEM_SIZE_64M:
1213 param->dram_config |= 0x0c;
1214 break;
1219 static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1221 u32 data, data2;
1223 moutdwm(ast, 0x1E6E0000, 0xFC600309);
1224 moutdwm(ast, 0x1E6E0018, 0x00000100);
1225 moutdwm(ast, 0x1E6E0024, 0x00000000);
1226 moutdwm(ast, 0x1E6E0034, 0x00000000);
1227 udelay(10);
1228 moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1229 moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1230 udelay(10);
1231 moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1232 udelay(10);
1234 moutdwm(ast, 0x1E6E0004, param->dram_config);
1235 moutdwm(ast, 0x1E6E0008, 0x90040f);
1236 moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1237 moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1238 moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1239 moutdwm(ast, 0x1E6E0080, 0x00000000);
1240 moutdwm(ast, 0x1E6E0084, 0x00000000);
1241 moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1242 moutdwm(ast, 0x1E6E0018, 0x4040A170);
1243 moutdwm(ast, 0x1E6E0018, 0x20402370);
1244 moutdwm(ast, 0x1E6E0038, 0x00000000);
1245 moutdwm(ast, 0x1E6E0040, 0xFF444444);
1246 moutdwm(ast, 0x1E6E0044, 0x22222222);
1247 moutdwm(ast, 0x1E6E0048, 0x22222222);
1248 moutdwm(ast, 0x1E6E004C, 0x00000002);
1249 moutdwm(ast, 0x1E6E0050, 0x80000000);
1250 moutdwm(ast, 0x1E6E0050, 0x00000000);
1251 moutdwm(ast, 0x1E6E0054, 0);
1252 moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1253 moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1254 moutdwm(ast, 0x1E6E0070, 0x00000000);
1255 moutdwm(ast, 0x1E6E0074, 0x00000000);
1256 moutdwm(ast, 0x1E6E0078, 0x00000000);
1257 moutdwm(ast, 0x1E6E007C, 0x00000000);
1258 /* Wait MCLK2X lock to MCLK */
1259 do {
1260 data = mindwm(ast, 0x1E6E001C);
1261 } while (!(data & 0x08000000));
1262 moutdwm(ast, 0x1E6E0034, 0x00000001);
1263 moutdwm(ast, 0x1E6E000C, 0x00005C04);
1264 udelay(10);
1265 moutdwm(ast, 0x1E6E000C, 0x00000000);
1266 moutdwm(ast, 0x1E6E0034, 0x00000000);
1267 data = mindwm(ast, 0x1E6E001C);
1268 data = (data >> 8) & 0xff;
1269 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1270 data2 = (mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1271 if ((data2 & 0xff) > param->madj_max) {
1272 break;
1274 moutdwm(ast, 0x1E6E0064, data2);
1275 if (data2 & 0x00100000) {
1276 data2 = ((data2 & 0xff) >> 3) + 3;
1277 } else {
1278 data2 = ((data2 & 0xff) >> 2) + 5;
1280 data = mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1281 data2 += data & 0xff;
1282 data = data | (data2 << 8);
1283 moutdwm(ast, 0x1E6E0068, data);
1284 udelay(10);
1285 moutdwm(ast, 0x1E6E0064, mindwm(ast, 0x1E6E0064) | 0xC0000);
1286 udelay(10);
1287 data = mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1288 moutdwm(ast, 0x1E6E0018, data);
1289 data = data | 0x200;
1290 moutdwm(ast, 0x1E6E0018, data);
1291 do {
1292 data = mindwm(ast, 0x1E6E001C);
1293 } while (!(data & 0x08000000));
1295 moutdwm(ast, 0x1E6E0034, 0x00000001);
1296 moutdwm(ast, 0x1E6E000C, 0x00005C04);
1297 udelay(10);
1298 moutdwm(ast, 0x1E6E000C, 0x00000000);
1299 moutdwm(ast, 0x1E6E0034, 0x00000000);
1300 data = mindwm(ast, 0x1E6E001C);
1301 data = (data >> 8) & 0xff;
1303 data = mindwm(ast, 0x1E6E0018) | 0xC00;
1304 moutdwm(ast, 0x1E6E0018, data);
1306 moutdwm(ast, 0x1E6E0034, 0x00000001);
1307 moutdwm(ast, 0x1E6E000C, 0x00000040);
1308 udelay(50);
1309 /* Mode Register Setting */
1310 moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1311 moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1312 moutdwm(ast, 0x1E6E0028, 0x00000005);
1313 moutdwm(ast, 0x1E6E0028, 0x00000007);
1314 moutdwm(ast, 0x1E6E0028, 0x00000003);
1315 moutdwm(ast, 0x1E6E0028, 0x00000001);
1316 moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1317 moutdwm(ast, 0x1E6E000C, 0x00005C08);
1318 moutdwm(ast, 0x1E6E0028, 0x00000001);
1320 moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1321 data = 0;
1322 if (param->wodt) {
1323 data = 0x300;
1325 if (param->rodt) {
1326 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1328 moutdwm(ast, 0x1E6E0034, data | 0x3);
1330 /* Wait DQI delay lock */
1331 do {
1332 data = mindwm(ast, 0x1E6E0080);
1333 } while (!(data & 0x40000000));
1334 /* Wait DQSI delay lock */
1335 do {
1336 data = mindwm(ast, 0x1E6E0020);
1337 } while (!(data & 0x00000800));
1338 /* Calibrate the DQSI delay */
1339 cbr_dll2(ast, param);
1341 moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1342 /* ECC Memory Initialization */
1343 #ifdef ECC
1344 moutdwm(ast, 0x1E6E007C, 0x00000000);
1345 moutdwm(ast, 0x1E6E0070, 0x221);
1346 do {
1347 data = mindwm(ast, 0x1E6E0070);
1348 } while (!(data & 0x00001000));
1349 moutdwm(ast, 0x1E6E0070, 0x00000000);
1350 moutdwm(ast, 0x1E6E0050, 0x80000000);
1351 moutdwm(ast, 0x1E6E0050, 0x00000000);
1352 #endif
1357 static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1359 u32 trap, trap_AC2, trap_MRS;
1361 moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1363 /* Ger trap info */
1364 trap = (mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1365 trap_AC2 = (trap << 20) | (trap << 16);
1366 trap_AC2 += 0x00110000;
1367 trap_MRS = 0x00000040 | (trap << 4);
1370 param->reg_MADJ = 0x00034C4C;
1371 param->reg_SADJ = 0x00001800;
1372 param->reg_DRV = 0x000000F0;
1373 param->reg_PERIOD = param->dram_freq;
1374 param->rodt = 0;
1376 switch (param->dram_freq) {
1377 case 264:
1378 moutdwm(ast, 0x1E6E2020, 0x0130);
1379 param->wodt = 0;
1380 param->reg_AC1 = 0x11101513;
1381 param->reg_AC2 = 0x78117011;
1382 param->reg_DQSIC = 0x00000092;
1383 param->reg_MRS = 0x00000842;
1384 param->reg_EMRS = 0x00000000;
1385 param->reg_DRV = 0x000000F0;
1386 param->reg_IOZ = 0x00000034;
1387 param->reg_DQIDLY = 0x0000005A;
1388 param->reg_FREQ = 0x00004AC0;
1389 param->madj_max = 138;
1390 param->dll2_finetune_step = 3;
1391 break;
1392 case 336:
1393 moutdwm(ast, 0x1E6E2020, 0x0190);
1394 param->wodt = 1;
1395 param->reg_AC1 = 0x22202613;
1396 param->reg_AC2 = 0xAA009016 | trap_AC2;
1397 param->reg_DQSIC = 0x000000BA;
1398 param->reg_MRS = 0x00000A02 | trap_MRS;
1399 param->reg_EMRS = 0x00000040;
1400 param->reg_DRV = 0x000000FA;
1401 param->reg_IOZ = 0x00000034;
1402 param->reg_DQIDLY = 0x00000074;
1403 param->reg_FREQ = 0x00004DC0;
1404 param->madj_max = 96;
1405 param->dll2_finetune_step = 3;
1406 break;
1407 default:
1408 case 396:
1409 moutdwm(ast, 0x1E6E2020, 0x03F1);
1410 param->wodt = 1;
1411 param->rodt = 0;
1412 param->reg_AC1 = 0x33302714;
1413 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1414 param->reg_DQSIC = 0x000000E2;
1415 param->reg_MRS = 0x00000C02 | trap_MRS;
1416 param->reg_EMRS = 0x00000040;
1417 param->reg_DRV = 0x000000FA;
1418 param->reg_IOZ = 0x00000034;
1419 param->reg_DQIDLY = 0x00000089;
1420 param->reg_FREQ = 0x000050C0;
1421 param->madj_max = 96;
1422 param->dll2_finetune_step = 4;
1424 switch (param->dram_chipid) {
1425 case AST_DRAM_512Mx16:
1426 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1427 break;
1428 default:
1429 case AST_DRAM_1Gx16:
1430 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1431 break;
1432 case AST_DRAM_2Gx16:
1433 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1434 break;
1435 case AST_DRAM_4Gx16:
1436 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1437 break;
1440 break;
1442 case 408:
1443 moutdwm(ast, 0x1E6E2020, 0x01F0);
1444 param->wodt = 1;
1445 param->rodt = 0;
1446 param->reg_AC1 = 0x33302714;
1447 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1448 param->reg_DQSIC = 0x000000E2;
1449 param->reg_MRS = 0x00000C02 | trap_MRS;
1450 param->reg_EMRS = 0x00000040;
1451 param->reg_DRV = 0x000000FA;
1452 param->reg_IOZ = 0x00000034;
1453 param->reg_DQIDLY = 0x00000089;
1454 param->reg_FREQ = 0x000050C0;
1455 param->madj_max = 96;
1456 param->dll2_finetune_step = 4;
1458 switch (param->dram_chipid) {
1459 case AST_DRAM_512Mx16:
1460 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1461 break;
1462 default:
1463 case AST_DRAM_1Gx16:
1464 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1465 break;
1466 case AST_DRAM_2Gx16:
1467 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1468 break;
1469 case AST_DRAM_4Gx16:
1470 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1471 break;
1474 break;
1475 case 456:
1476 moutdwm(ast, 0x1E6E2020, 0x0230);
1477 param->wodt = 0;
1478 param->reg_AC1 = 0x33302815;
1479 param->reg_AC2 = 0xCD44B01E;
1480 param->reg_DQSIC = 0x000000FC;
1481 param->reg_MRS = 0x00000E72;
1482 param->reg_EMRS = 0x00000000;
1483 param->reg_DRV = 0x00000000;
1484 param->reg_IOZ = 0x00000034;
1485 param->reg_DQIDLY = 0x00000097;
1486 param->reg_FREQ = 0x000052C0;
1487 param->madj_max = 88;
1488 param->dll2_finetune_step = 3;
1489 break;
1490 case 504:
1491 moutdwm(ast, 0x1E6E2020, 0x0261);
1492 param->wodt = 1;
1493 param->rodt = 1;
1494 param->reg_AC1 = 0x33302815;
1495 param->reg_AC2 = 0xDE44C022;
1496 param->reg_DQSIC = 0x00000117;
1497 param->reg_MRS = 0x00000E72;
1498 param->reg_EMRS = 0x00000040;
1499 param->reg_DRV = 0x0000000A;
1500 param->reg_IOZ = 0x00000045;
1501 param->reg_DQIDLY = 0x000000A0;
1502 param->reg_FREQ = 0x000054C0;
1503 param->madj_max = 79;
1504 param->dll2_finetune_step = 3;
1505 break;
1506 case 528:
1507 moutdwm(ast, 0x1E6E2020, 0x0120);
1508 param->wodt = 1;
1509 param->rodt = 1;
1510 param->reg_AC1 = 0x33302815;
1511 param->reg_AC2 = 0xEF44D024;
1512 param->reg_DQSIC = 0x00000125;
1513 param->reg_MRS = 0x00000E72;
1514 param->reg_EMRS = 0x00000004;
1515 param->reg_DRV = 0x000000F9;
1516 param->reg_IOZ = 0x00000045;
1517 param->reg_DQIDLY = 0x000000A7;
1518 param->reg_FREQ = 0x000055C0;
1519 param->madj_max = 76;
1520 param->dll2_finetune_step = 3;
1521 break;
1522 case 552:
1523 moutdwm(ast, 0x1E6E2020, 0x02A1);
1524 param->wodt = 1;
1525 param->rodt = 1;
1526 param->reg_AC1 = 0x43402915;
1527 param->reg_AC2 = 0xFF44E025;
1528 param->reg_DQSIC = 0x00000132;
1529 param->reg_MRS = 0x00000E72;
1530 param->reg_EMRS = 0x00000040;
1531 param->reg_DRV = 0x0000000A;
1532 param->reg_IOZ = 0x00000045;
1533 param->reg_DQIDLY = 0x000000AD;
1534 param->reg_FREQ = 0x000056C0;
1535 param->madj_max = 76;
1536 param->dll2_finetune_step = 3;
1537 break;
1538 case 576:
1539 moutdwm(ast, 0x1E6E2020, 0x0140);
1540 param->wodt = 1;
1541 param->rodt = 1;
1542 param->reg_AC1 = 0x43402915;
1543 param->reg_AC2 = 0xFF44E027;
1544 param->reg_DQSIC = 0x0000013F;
1545 param->reg_MRS = 0x00000E72;
1546 param->reg_EMRS = 0x00000004;
1547 param->reg_DRV = 0x000000F5;
1548 param->reg_IOZ = 0x00000045;
1549 param->reg_DQIDLY = 0x000000B3;
1550 param->reg_FREQ = 0x000057C0;
1551 param->madj_max = 76;
1552 param->dll2_finetune_step = 3;
1553 break;
1556 switch (param->dram_chipid) {
1557 case AST_DRAM_512Mx16:
1558 param->dram_config = 0x100;
1559 break;
1560 default:
1561 case AST_DRAM_1Gx16:
1562 param->dram_config = 0x121;
1563 break;
1564 case AST_DRAM_2Gx16:
1565 param->dram_config = 0x122;
1566 break;
1567 case AST_DRAM_4Gx16:
1568 param->dram_config = 0x123;
1569 break;
1570 }; /* switch size */
1572 switch (param->vram_size) {
1573 default:
1574 case AST_VIDMEM_SIZE_8M:
1575 param->dram_config |= 0x00;
1576 break;
1577 case AST_VIDMEM_SIZE_16M:
1578 param->dram_config |= 0x04;
1579 break;
1580 case AST_VIDMEM_SIZE_32M:
1581 param->dram_config |= 0x08;
1582 break;
1583 case AST_VIDMEM_SIZE_64M:
1584 param->dram_config |= 0x0c;
1585 break;
1589 static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1591 u32 data, data2;
1593 moutdwm(ast, 0x1E6E0000, 0xFC600309);
1594 moutdwm(ast, 0x1E6E0018, 0x00000100);
1595 moutdwm(ast, 0x1E6E0024, 0x00000000);
1596 moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1597 moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1598 udelay(10);
1599 moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1600 udelay(10);
1602 moutdwm(ast, 0x1E6E0004, param->dram_config);
1603 moutdwm(ast, 0x1E6E0008, 0x90040f);
1604 moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1605 moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1606 moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1607 moutdwm(ast, 0x1E6E0080, 0x00000000);
1608 moutdwm(ast, 0x1E6E0084, 0x00000000);
1609 moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1610 moutdwm(ast, 0x1E6E0018, 0x4040A130);
1611 moutdwm(ast, 0x1E6E0018, 0x20402330);
1612 moutdwm(ast, 0x1E6E0038, 0x00000000);
1613 moutdwm(ast, 0x1E6E0040, 0xFF808000);
1614 moutdwm(ast, 0x1E6E0044, 0x88848466);
1615 moutdwm(ast, 0x1E6E0048, 0x44440008);
1616 moutdwm(ast, 0x1E6E004C, 0x00000000);
1617 moutdwm(ast, 0x1E6E0050, 0x80000000);
1618 moutdwm(ast, 0x1E6E0050, 0x00000000);
1619 moutdwm(ast, 0x1E6E0054, 0);
1620 moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1621 moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1622 moutdwm(ast, 0x1E6E0070, 0x00000000);
1623 moutdwm(ast, 0x1E6E0074, 0x00000000);
1624 moutdwm(ast, 0x1E6E0078, 0x00000000);
1625 moutdwm(ast, 0x1E6E007C, 0x00000000);
1627 /* Wait MCLK2X lock to MCLK */
1628 do {
1629 data = mindwm(ast, 0x1E6E001C);
1630 } while (!(data & 0x08000000));
1631 moutdwm(ast, 0x1E6E0034, 0x00000001);
1632 moutdwm(ast, 0x1E6E000C, 0x00005C04);
1633 udelay(10);
1634 moutdwm(ast, 0x1E6E000C, 0x00000000);
1635 moutdwm(ast, 0x1E6E0034, 0x00000000);
1636 data = mindwm(ast, 0x1E6E001C);
1637 data = (data >> 8) & 0xff;
1638 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1639 data2 = (mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1640 if ((data2 & 0xff) > param->madj_max) {
1641 break;
1643 moutdwm(ast, 0x1E6E0064, data2);
1644 if (data2 & 0x00100000) {
1645 data2 = ((data2 & 0xff) >> 3) + 3;
1646 } else {
1647 data2 = ((data2 & 0xff) >> 2) + 5;
1649 data = mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1650 data2 += data & 0xff;
1651 data = data | (data2 << 8);
1652 moutdwm(ast, 0x1E6E0068, data);
1653 udelay(10);
1654 moutdwm(ast, 0x1E6E0064, mindwm(ast, 0x1E6E0064) | 0xC0000);
1655 udelay(10);
1656 data = mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1657 moutdwm(ast, 0x1E6E0018, data);
1658 data = data | 0x200;
1659 moutdwm(ast, 0x1E6E0018, data);
1660 do {
1661 data = mindwm(ast, 0x1E6E001C);
1662 } while (!(data & 0x08000000));
1664 moutdwm(ast, 0x1E6E0034, 0x00000001);
1665 moutdwm(ast, 0x1E6E000C, 0x00005C04);
1666 udelay(10);
1667 moutdwm(ast, 0x1E6E000C, 0x00000000);
1668 moutdwm(ast, 0x1E6E0034, 0x00000000);
1669 data = mindwm(ast, 0x1E6E001C);
1670 data = (data >> 8) & 0xff;
1672 data = mindwm(ast, 0x1E6E0018) | 0xC00;
1673 moutdwm(ast, 0x1E6E0018, data);
1675 moutdwm(ast, 0x1E6E0034, 0x00000001);
1676 moutdwm(ast, 0x1E6E000C, 0x00000000);
1677 udelay(50);
1678 /* Mode Register Setting */
1679 moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1680 moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1681 moutdwm(ast, 0x1E6E0028, 0x00000005);
1682 moutdwm(ast, 0x1E6E0028, 0x00000007);
1683 moutdwm(ast, 0x1E6E0028, 0x00000003);
1684 moutdwm(ast, 0x1E6E0028, 0x00000001);
1686 moutdwm(ast, 0x1E6E000C, 0x00005C08);
1687 moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1688 moutdwm(ast, 0x1E6E0028, 0x00000001);
1689 moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1690 moutdwm(ast, 0x1E6E0028, 0x00000003);
1691 moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1692 moutdwm(ast, 0x1E6E0028, 0x00000003);
1694 moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1695 data = 0;
1696 if (param->wodt) {
1697 data = 0x500;
1699 if (param->rodt) {
1700 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1702 moutdwm(ast, 0x1E6E0034, data | 0x3);
1703 moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1705 /* Wait DQI delay lock */
1706 do {
1707 data = mindwm(ast, 0x1E6E0080);
1708 } while (!(data & 0x40000000));
1709 /* Wait DQSI delay lock */
1710 do {
1711 data = mindwm(ast, 0x1E6E0020);
1712 } while (!(data & 0x00000800));
1713 /* Calibrate the DQSI delay */
1714 cbr_dll2(ast, param);
1716 /* ECC Memory Initialization */
1717 #ifdef ECC
1718 moutdwm(ast, 0x1E6E007C, 0x00000000);
1719 moutdwm(ast, 0x1E6E0070, 0x221);
1720 do {
1721 data = mindwm(ast, 0x1E6E0070);
1722 } while (!(data & 0x00001000));
1723 moutdwm(ast, 0x1E6E0070, 0x00000000);
1724 moutdwm(ast, 0x1E6E0050, 0x80000000);
1725 moutdwm(ast, 0x1E6E0050, 0x00000000);
1726 #endif
1730 static void ast_init_dram_2300(struct drm_device *dev)
1732 struct ast_private *ast = dev->dev_private;
1733 struct ast2300_dram_param param;
1734 u32 temp;
1735 u8 reg;
1737 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1738 if ((reg & 0x80) == 0) {/* vga only */
1739 ast_write32(ast, 0xf004, 0x1e6e0000);
1740 ast_write32(ast, 0xf000, 0x1);
1741 ast_write32(ast, 0x12000, 0x1688a8a8);
1742 do {
1744 } while (ast_read32(ast, 0x12000) != 0x1);
1746 ast_write32(ast, 0x10000, 0xfc600309);
1747 do {
1749 } while (ast_read32(ast, 0x10000) != 0x1);
1751 /* Slow down CPU/AHB CLK in VGA only mode */
1752 temp = ast_read32(ast, 0x12008);
1753 temp |= 0x73;
1754 ast_write32(ast, 0x12008, temp);
1756 param.dram_type = AST_DDR3;
1757 if (temp & 0x01000000)
1758 param.dram_type = AST_DDR2;
1759 param.dram_chipid = ast->dram_type;
1760 param.dram_freq = ast->mclk;
1761 param.vram_size = ast->vram_size;
1763 if (param.dram_type == AST_DDR3) {
1764 get_ddr3_info(ast, &param);
1765 ddr3_init(ast, &param);
1766 } else {
1767 get_ddr2_info(ast, &param);
1768 ddr2_init(ast, &param);
1771 temp = mindwm(ast, 0x1e6e2040);
1772 moutdwm(ast, 0x1e6e2040, temp | 0x40);
1775 /* wait ready */
1776 do {
1777 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1778 } while ((reg & 0x40) == 0);