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