drm/omap: Fix error handling path in 'omap_dmm_probe()'
[linux/fpc-iii.git] / drivers / gpu / drm / ast / ast_post.c
blobc7c58becb25d70169c26b5dfcd5f6f45b3d20574
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 return !!(ch & 0x01);
63 return false;
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 || ast->chip == AST2400) {
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 || ast->chip == AST2400)
106 reg |= 0x20;
107 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
110 u32 ast_mindwm(struct ast_private *ast, u32 r)
112 uint32_t data;
114 ast_write32(ast, 0xf004, r & 0xffff0000);
115 ast_write32(ast, 0xf000, 0x1);
117 do {
118 data = ast_read32(ast, 0xf004) & 0xffff0000;
119 } while (data != (r & 0xffff0000));
120 return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
123 void ast_moutdwm(struct ast_private *ast, u32 r, u32 v)
125 uint32_t data;
126 ast_write32(ast, 0xf004, r & 0xffff0000);
127 ast_write32(ast, 0xf000, 0x1);
128 do {
129 data = ast_read32(ast, 0xf004) & 0xffff0000;
130 } while (data != (r & 0xffff0000));
131 ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
135 * AST2100/2150 DLL CBR Setting
137 #define CBR_SIZE_AST2150 ((16 << 10) - 1)
138 #define CBR_PASSNUM_AST2150 5
139 #define CBR_THRESHOLD_AST2150 10
140 #define CBR_THRESHOLD2_AST2150 10
141 #define TIMEOUT_AST2150 5000000
143 #define CBR_PATNUM_AST2150 8
145 static const u32 pattern_AST2150[14] = {
146 0xFF00FF00,
147 0xCC33CC33,
148 0xAA55AA55,
149 0xFFFE0001,
150 0x683501FE,
151 0x0F1929B0,
152 0x2D0B4346,
153 0x60767F02,
154 0x6FBE36A6,
155 0x3A253035,
156 0x3019686D,
157 0x41C6167E,
158 0x620152BF,
159 0x20F050E0
162 static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
164 u32 data, timeout;
166 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
167 ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
168 timeout = 0;
169 do {
170 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
171 if (++timeout > TIMEOUT_AST2150) {
172 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
173 return 0xffffffff;
175 } while (!data);
176 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
177 ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
178 timeout = 0;
179 do {
180 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
181 if (++timeout > TIMEOUT_AST2150) {
182 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
183 return 0xffffffff;
185 } while (!data);
186 data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
187 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
188 return data;
191 #if 0 /* unused in DDX driver - here for completeness */
192 static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
194 u32 data, timeout;
196 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
197 ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
198 timeout = 0;
199 do {
200 data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
201 if (++timeout > TIMEOUT_AST2150) {
202 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
203 return 0xffffffff;
205 } while (!data);
206 data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
207 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
208 return data;
210 #endif
212 static int cbrtest_ast2150(struct ast_private *ast)
214 int i;
216 for (i = 0; i < 8; i++)
217 if (mmctestburst2_ast2150(ast, i))
218 return 0;
219 return 1;
222 static int cbrscan_ast2150(struct ast_private *ast, int busw)
224 u32 patcnt, loop;
226 for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
227 ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
228 for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
229 if (cbrtest_ast2150(ast))
230 break;
232 if (loop == CBR_PASSNUM_AST2150)
233 return 0;
235 return 1;
239 static void cbrdlli_ast2150(struct ast_private *ast, int busw)
241 u32 dll_min[4], dll_max[4], dlli, data, passcnt;
243 cbr_start:
244 dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
245 dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
246 passcnt = 0;
248 for (dlli = 0; dlli < 100; dlli++) {
249 ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
250 data = cbrscan_ast2150(ast, busw);
251 if (data != 0) {
252 if (data & 0x1) {
253 if (dll_min[0] > dlli)
254 dll_min[0] = dlli;
255 if (dll_max[0] < dlli)
256 dll_max[0] = dlli;
258 passcnt++;
259 } else if (passcnt >= CBR_THRESHOLD_AST2150)
260 goto cbr_start;
262 if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
263 goto cbr_start;
265 dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
266 ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
271 static void ast_init_dram_reg(struct drm_device *dev)
273 struct ast_private *ast = dev->dev_private;
274 u8 j;
275 u32 data, temp, i;
276 const struct ast_dramstruct *dram_reg_info;
278 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
280 if ((j & 0x80) == 0) { /* VGA only */
281 if (ast->chip == AST2000) {
282 dram_reg_info = ast2000_dram_table_data;
283 ast_write32(ast, 0xf004, 0x1e6e0000);
284 ast_write32(ast, 0xf000, 0x1);
285 ast_write32(ast, 0x10100, 0xa8);
287 do {
289 } while (ast_read32(ast, 0x10100) != 0xa8);
290 } else {/* AST2100/1100 */
291 if (ast->chip == AST2100 || ast->chip == 2200)
292 dram_reg_info = ast2100_dram_table_data;
293 else
294 dram_reg_info = ast1100_dram_table_data;
296 ast_write32(ast, 0xf004, 0x1e6e0000);
297 ast_write32(ast, 0xf000, 0x1);
298 ast_write32(ast, 0x12000, 0x1688A8A8);
299 do {
301 } while (ast_read32(ast, 0x12000) != 0x01);
303 ast_write32(ast, 0x10000, 0xfc600309);
304 do {
306 } while (ast_read32(ast, 0x10000) != 0x01);
309 while (dram_reg_info->index != 0xffff) {
310 if (dram_reg_info->index == 0xff00) {/* delay fn */
311 for (i = 0; i < 15; i++)
312 udelay(dram_reg_info->data);
313 } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
314 data = dram_reg_info->data;
315 if (ast->dram_type == AST_DRAM_1Gx16)
316 data = 0x00000d89;
317 else if (ast->dram_type == AST_DRAM_1Gx32)
318 data = 0x00000c8d;
320 temp = ast_read32(ast, 0x12070);
321 temp &= 0xc;
322 temp <<= 2;
323 ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
324 } else
325 ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
326 dram_reg_info++;
329 /* AST 2100/2150 DRAM calibration */
330 data = ast_read32(ast, 0x10120);
331 if (data == 0x5061) { /* 266Mhz */
332 data = ast_read32(ast, 0x10004);
333 if (data & 0x40)
334 cbrdlli_ast2150(ast, 16); /* 16 bits */
335 else
336 cbrdlli_ast2150(ast, 32); /* 32 bits */
339 switch (ast->chip) {
340 case AST2000:
341 temp = ast_read32(ast, 0x10140);
342 ast_write32(ast, 0x10140, temp | 0x40);
343 break;
344 case AST1100:
345 case AST2100:
346 case AST2200:
347 case AST2150:
348 temp = ast_read32(ast, 0x1200c);
349 ast_write32(ast, 0x1200c, temp & 0xfffffffd);
350 temp = ast_read32(ast, 0x12040);
351 ast_write32(ast, 0x12040, temp | 0x40);
352 break;
353 default:
354 break;
358 /* wait ready */
359 do {
360 j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
361 } while ((j & 0x40) == 0);
364 void ast_post_gpu(struct drm_device *dev)
366 u32 reg;
367 struct ast_private *ast = dev->dev_private;
369 pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
370 reg |= 0x3;
371 pci_write_config_dword(ast->dev->pdev, 0x04, reg);
373 ast_enable_vga(dev);
374 ast_open_key(ast);
375 ast_enable_mmio(dev);
376 ast_set_def_ext_reg(dev);
378 if (ast->config_mode == ast_use_p2a) {
379 if (ast->chip == AST2300 || ast->chip == AST2400)
380 ast_init_dram_2300(dev);
381 else
382 ast_init_dram_reg(dev);
384 ast_init_3rdtx(dev);
385 } else {
386 if (ast->tx_chip_type != AST_TX_NONE)
387 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */
391 /* AST 2300 DRAM settings */
392 #define AST_DDR3 0
393 #define AST_DDR2 1
395 struct ast2300_dram_param {
396 u32 dram_type;
397 u32 dram_chipid;
398 u32 dram_freq;
399 u32 vram_size;
400 u32 odt;
401 u32 wodt;
402 u32 rodt;
403 u32 dram_config;
404 u32 reg_PERIOD;
405 u32 reg_MADJ;
406 u32 reg_SADJ;
407 u32 reg_MRS;
408 u32 reg_EMRS;
409 u32 reg_AC1;
410 u32 reg_AC2;
411 u32 reg_DQSIC;
412 u32 reg_DRV;
413 u32 reg_IOZ;
414 u32 reg_DQIDLY;
415 u32 reg_FREQ;
416 u32 madj_max;
417 u32 dll2_finetune_step;
421 * DQSI DLL CBR Setting
423 #define CBR_SIZE0 ((1 << 10) - 1)
424 #define CBR_SIZE1 ((4 << 10) - 1)
425 #define CBR_SIZE2 ((64 << 10) - 1)
426 #define CBR_PASSNUM 5
427 #define CBR_PASSNUM2 5
428 #define CBR_THRESHOLD 10
429 #define CBR_THRESHOLD2 10
430 #define TIMEOUT 5000000
431 #define CBR_PATNUM 8
433 static const u32 pattern[8] = {
434 0xFF00FF00,
435 0xCC33CC33,
436 0xAA55AA55,
437 0x88778877,
438 0x92CC4D6E,
439 0x543D3CDE,
440 0xF1E843C7,
441 0x7C61D253
444 static int mmc_test_burst(struct ast_private *ast, u32 datagen)
446 u32 data, timeout;
448 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
449 ast_moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3));
450 timeout = 0;
451 do {
452 data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
453 if (data & 0x2000) {
454 return 0;
456 if (++timeout > TIMEOUT) {
457 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
458 return 0;
460 } while (!data);
461 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
462 return 1;
465 static int mmc_test_burst2(struct ast_private *ast, u32 datagen)
467 u32 data, timeout;
469 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
470 ast_moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3));
471 timeout = 0;
472 do {
473 data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
474 if (++timeout > TIMEOUT) {
475 ast_moutdwm(ast, 0x1e6e0070, 0x0);
476 return -1;
478 } while (!data);
479 data = ast_mindwm(ast, 0x1e6e0078);
480 data = (data | (data >> 16)) & 0xffff;
481 ast_moutdwm(ast, 0x1e6e0070, 0x0);
482 return data;
485 static int mmc_test_single(struct ast_private *ast, u32 datagen)
487 u32 data, timeout;
489 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
490 ast_moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3));
491 timeout = 0;
492 do {
493 data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
494 if (data & 0x2000)
495 return 0;
496 if (++timeout > TIMEOUT) {
497 ast_moutdwm(ast, 0x1e6e0070, 0x0);
498 return 0;
500 } while (!data);
501 ast_moutdwm(ast, 0x1e6e0070, 0x0);
502 return 1;
505 static int mmc_test_single2(struct ast_private *ast, u32 datagen)
507 u32 data, timeout;
509 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
510 ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
511 timeout = 0;
512 do {
513 data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
514 if (++timeout > TIMEOUT) {
515 ast_moutdwm(ast, 0x1e6e0070, 0x0);
516 return -1;
518 } while (!data);
519 data = ast_mindwm(ast, 0x1e6e0078);
520 data = (data | (data >> 16)) & 0xffff;
521 ast_moutdwm(ast, 0x1e6e0070, 0x0);
522 return data;
525 static int cbr_test(struct ast_private *ast)
527 u32 data;
528 int i;
529 data = mmc_test_single2(ast, 0);
530 if ((data & 0xff) && (data & 0xff00))
531 return 0;
532 for (i = 0; i < 8; i++) {
533 data = mmc_test_burst2(ast, i);
534 if ((data & 0xff) && (data & 0xff00))
535 return 0;
537 if (!data)
538 return 3;
539 else if (data & 0xff)
540 return 2;
541 return 1;
544 static int cbr_scan(struct ast_private *ast)
546 u32 data, data2, patcnt, loop;
548 data2 = 3;
549 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
550 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
551 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
552 if ((data = cbr_test(ast)) != 0) {
553 data2 &= data;
554 if (!data2)
555 return 0;
556 break;
559 if (loop == CBR_PASSNUM2)
560 return 0;
562 return data2;
565 static u32 cbr_test2(struct ast_private *ast)
567 u32 data;
569 data = mmc_test_burst2(ast, 0);
570 if (data == 0xffff)
571 return 0;
572 data |= mmc_test_single2(ast, 0);
573 if (data == 0xffff)
574 return 0;
576 return ~data & 0xffff;
579 static u32 cbr_scan2(struct ast_private *ast)
581 u32 data, data2, patcnt, loop;
583 data2 = 0xffff;
584 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
585 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
586 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
587 if ((data = cbr_test2(ast)) != 0) {
588 data2 &= data;
589 if (!data2)
590 return 0;
591 break;
594 if (loop == CBR_PASSNUM2)
595 return 0;
597 return data2;
600 static u32 cbr_test3(struct ast_private *ast)
602 if (!mmc_test_burst(ast, 0))
603 return 0;
604 if (!mmc_test_single(ast, 0))
605 return 0;
606 return 1;
609 static u32 cbr_scan3(struct ast_private *ast)
611 u32 patcnt, loop;
613 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
614 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
615 for (loop = 0; loop < 2; loop++) {
616 if (cbr_test3(ast))
617 break;
619 if (loop == 2)
620 return 0;
622 return 1;
625 static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
627 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
628 bool status = false;
629 FINETUNE_START:
630 for (cnt = 0; cnt < 16; cnt++) {
631 dllmin[cnt] = 0xff;
632 dllmax[cnt] = 0x0;
634 passcnt = 0;
635 for (dlli = 0; dlli < 76; dlli++) {
636 ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
637 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
638 data = cbr_scan2(ast);
639 if (data != 0) {
640 mask = 0x00010001;
641 for (cnt = 0; cnt < 16; cnt++) {
642 if (data & mask) {
643 if (dllmin[cnt] > dlli) {
644 dllmin[cnt] = dlli;
646 if (dllmax[cnt] < dlli) {
647 dllmax[cnt] = dlli;
650 mask <<= 1;
652 passcnt++;
653 } else if (passcnt >= CBR_THRESHOLD2) {
654 break;
657 gold_sadj[0] = 0x0;
658 passcnt = 0;
659 for (cnt = 0; cnt < 16; cnt++) {
660 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
661 gold_sadj[0] += dllmin[cnt];
662 passcnt++;
665 if (retry++ > 10)
666 goto FINETUNE_DONE;
667 if (passcnt != 16) {
668 goto FINETUNE_START;
670 status = true;
671 FINETUNE_DONE:
672 gold_sadj[0] = gold_sadj[0] >> 4;
673 gold_sadj[1] = gold_sadj[0];
675 data = 0;
676 for (cnt = 0; cnt < 8; cnt++) {
677 data >>= 3;
678 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
679 dlli = dllmin[cnt];
680 if (gold_sadj[0] >= dlli) {
681 dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
682 if (dlli > 3) {
683 dlli = 3;
685 } else {
686 dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
687 if (dlli > 4) {
688 dlli = 4;
690 dlli = (8 - dlli) & 0x7;
692 data |= dlli << 21;
695 ast_moutdwm(ast, 0x1E6E0080, data);
697 data = 0;
698 for (cnt = 8; cnt < 16; cnt++) {
699 data >>= 3;
700 if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
701 dlli = dllmin[cnt];
702 if (gold_sadj[1] >= dlli) {
703 dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
704 if (dlli > 3) {
705 dlli = 3;
706 } else {
707 dlli = (dlli - 1) & 0x7;
709 } else {
710 dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
711 dlli += 1;
712 if (dlli > 4) {
713 dlli = 4;
715 dlli = (8 - dlli) & 0x7;
717 data |= dlli << 21;
720 ast_moutdwm(ast, 0x1E6E0084, data);
721 return status;
722 } /* finetuneDQI_L */
724 static void finetuneDQSI(struct ast_private *ast)
726 u32 dlli, dqsip, dqidly;
727 u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
728 u32 g_dqidly, g_dqsip, g_margin, g_side;
729 u16 pass[32][2][2];
730 char tag[2][76];
732 /* Disable DQI CBR */
733 reg_mcr0c = ast_mindwm(ast, 0x1E6E000C);
734 reg_mcr18 = ast_mindwm(ast, 0x1E6E0018);
735 reg_mcr18 &= 0x0000ffff;
736 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
738 for (dlli = 0; dlli < 76; dlli++) {
739 tag[0][dlli] = 0x0;
740 tag[1][dlli] = 0x0;
742 for (dqidly = 0; dqidly < 32; dqidly++) {
743 pass[dqidly][0][0] = 0xff;
744 pass[dqidly][0][1] = 0x0;
745 pass[dqidly][1][0] = 0xff;
746 pass[dqidly][1][1] = 0x0;
748 for (dqidly = 0; dqidly < 32; dqidly++) {
749 passcnt[0] = passcnt[1] = 0;
750 for (dqsip = 0; dqsip < 2; dqsip++) {
751 ast_moutdwm(ast, 0x1E6E000C, 0);
752 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
753 ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
754 for (dlli = 0; dlli < 76; dlli++) {
755 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
756 ast_moutdwm(ast, 0x1E6E0070, 0);
757 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
758 if (cbr_scan3(ast)) {
759 if (dlli == 0)
760 break;
761 passcnt[dqsip]++;
762 tag[dqsip][dlli] = 'P';
763 if (dlli < pass[dqidly][dqsip][0])
764 pass[dqidly][dqsip][0] = (u16) dlli;
765 if (dlli > pass[dqidly][dqsip][1])
766 pass[dqidly][dqsip][1] = (u16) dlli;
767 } else if (passcnt[dqsip] >= 5)
768 break;
769 else {
770 pass[dqidly][dqsip][0] = 0xff;
771 pass[dqidly][dqsip][1] = 0x0;
775 if (passcnt[0] == 0 && passcnt[1] == 0)
776 dqidly++;
778 /* Search margin */
779 g_dqidly = g_dqsip = g_margin = g_side = 0;
781 for (dqidly = 0; dqidly < 32; dqidly++) {
782 for (dqsip = 0; dqsip < 2; dqsip++) {
783 if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
784 continue;
785 diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
786 if ((diff+2) < g_margin)
787 continue;
788 passcnt[0] = passcnt[1] = 0;
789 for (dlli = pass[dqidly][dqsip][0]; dlli > 0 && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++);
790 for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++);
791 if (passcnt[0] > passcnt[1])
792 passcnt[0] = passcnt[1];
793 passcnt[1] = 0;
794 if (passcnt[0] > g_side)
795 passcnt[1] = passcnt[0] - g_side;
796 if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
797 g_margin = diff;
798 g_dqidly = dqidly;
799 g_dqsip = dqsip;
800 g_side = passcnt[0];
801 } else if (passcnt[1] > 1 && g_side < 8) {
802 if (diff > g_margin)
803 g_margin = diff;
804 g_dqidly = dqidly;
805 g_dqsip = dqsip;
806 g_side = passcnt[0];
810 reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
811 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
814 static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
816 u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
817 bool status = false;
819 finetuneDQSI(ast);
820 if (finetuneDQI_L(ast, param) == false)
821 return status;
823 CBR_START2:
824 dllmin[0] = dllmin[1] = 0xff;
825 dllmax[0] = dllmax[1] = 0x0;
826 passcnt = 0;
827 for (dlli = 0; dlli < 76; dlli++) {
828 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
829 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
830 data = cbr_scan(ast);
831 if (data != 0) {
832 if (data & 0x1) {
833 if (dllmin[0] > dlli) {
834 dllmin[0] = dlli;
836 if (dllmax[0] < dlli) {
837 dllmax[0] = dlli;
840 if (data & 0x2) {
841 if (dllmin[1] > dlli) {
842 dllmin[1] = dlli;
844 if (dllmax[1] < dlli) {
845 dllmax[1] = dlli;
848 passcnt++;
849 } else if (passcnt >= CBR_THRESHOLD) {
850 break;
853 if (retry++ > 10)
854 goto CBR_DONE2;
855 if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
856 goto CBR_START2;
858 if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
859 goto CBR_START2;
861 status = true;
862 CBR_DONE2:
863 dlli = (dllmin[1] + dllmax[1]) >> 1;
864 dlli <<= 8;
865 dlli += (dllmin[0] + dllmax[0]) >> 1;
866 ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
867 return status;
868 } /* CBRDLL2 */
870 static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
872 u32 trap, trap_AC2, trap_MRS;
874 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
876 /* Ger trap info */
877 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
878 trap_AC2 = 0x00020000 + (trap << 16);
879 trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
880 trap_MRS = 0x00000010 + (trap << 4);
881 trap_MRS |= ((trap & 0x2) << 18);
883 param->reg_MADJ = 0x00034C4C;
884 param->reg_SADJ = 0x00001800;
885 param->reg_DRV = 0x000000F0;
886 param->reg_PERIOD = param->dram_freq;
887 param->rodt = 0;
889 switch (param->dram_freq) {
890 case 336:
891 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
892 param->wodt = 0;
893 param->reg_AC1 = 0x22202725;
894 param->reg_AC2 = 0xAA007613 | trap_AC2;
895 param->reg_DQSIC = 0x000000BA;
896 param->reg_MRS = 0x04001400 | trap_MRS;
897 param->reg_EMRS = 0x00000000;
898 param->reg_IOZ = 0x00000023;
899 param->reg_DQIDLY = 0x00000074;
900 param->reg_FREQ = 0x00004DC0;
901 param->madj_max = 96;
902 param->dll2_finetune_step = 3;
903 switch (param->dram_chipid) {
904 default:
905 case AST_DRAM_512Mx16:
906 case AST_DRAM_1Gx16:
907 param->reg_AC2 = 0xAA007613 | trap_AC2;
908 break;
909 case AST_DRAM_2Gx16:
910 param->reg_AC2 = 0xAA00761C | trap_AC2;
911 break;
912 case AST_DRAM_4Gx16:
913 param->reg_AC2 = 0xAA007636 | trap_AC2;
914 break;
916 break;
917 default:
918 case 396:
919 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
920 param->wodt = 1;
921 param->reg_AC1 = 0x33302825;
922 param->reg_AC2 = 0xCC009617 | trap_AC2;
923 param->reg_DQSIC = 0x000000E2;
924 param->reg_MRS = 0x04001600 | trap_MRS;
925 param->reg_EMRS = 0x00000000;
926 param->reg_IOZ = 0x00000034;
927 param->reg_DRV = 0x000000FA;
928 param->reg_DQIDLY = 0x00000089;
929 param->reg_FREQ = 0x00005040;
930 param->madj_max = 96;
931 param->dll2_finetune_step = 4;
933 switch (param->dram_chipid) {
934 default:
935 case AST_DRAM_512Mx16:
936 case AST_DRAM_1Gx16:
937 param->reg_AC2 = 0xCC009617 | trap_AC2;
938 break;
939 case AST_DRAM_2Gx16:
940 param->reg_AC2 = 0xCC009622 | trap_AC2;
941 break;
942 case AST_DRAM_4Gx16:
943 param->reg_AC2 = 0xCC00963F | trap_AC2;
944 break;
946 break;
948 case 408:
949 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
950 param->wodt = 1;
951 param->reg_AC1 = 0x33302825;
952 param->reg_AC2 = 0xCC009617 | trap_AC2;
953 param->reg_DQSIC = 0x000000E2;
954 param->reg_MRS = 0x04001600 | trap_MRS;
955 param->reg_EMRS = 0x00000000;
956 param->reg_IOZ = 0x00000023;
957 param->reg_DRV = 0x000000FA;
958 param->reg_DQIDLY = 0x00000089;
959 param->reg_FREQ = 0x000050C0;
960 param->madj_max = 96;
961 param->dll2_finetune_step = 4;
963 switch (param->dram_chipid) {
964 default:
965 case AST_DRAM_512Mx16:
966 case AST_DRAM_1Gx16:
967 param->reg_AC2 = 0xCC009617 | trap_AC2;
968 break;
969 case AST_DRAM_2Gx16:
970 param->reg_AC2 = 0xCC009622 | trap_AC2;
971 break;
972 case AST_DRAM_4Gx16:
973 param->reg_AC2 = 0xCC00963F | trap_AC2;
974 break;
977 break;
978 case 456:
979 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
980 param->wodt = 0;
981 param->reg_AC1 = 0x33302926;
982 param->reg_AC2 = 0xCD44961A;
983 param->reg_DQSIC = 0x000000FC;
984 param->reg_MRS = 0x00081830;
985 param->reg_EMRS = 0x00000000;
986 param->reg_IOZ = 0x00000045;
987 param->reg_DQIDLY = 0x00000097;
988 param->reg_FREQ = 0x000052C0;
989 param->madj_max = 88;
990 param->dll2_finetune_step = 4;
991 break;
992 case 504:
993 ast_moutdwm(ast, 0x1E6E2020, 0x0270);
994 param->wodt = 1;
995 param->reg_AC1 = 0x33302926;
996 param->reg_AC2 = 0xDE44A61D;
997 param->reg_DQSIC = 0x00000117;
998 param->reg_MRS = 0x00081A30;
999 param->reg_EMRS = 0x00000000;
1000 param->reg_IOZ = 0x070000BB;
1001 param->reg_DQIDLY = 0x000000A0;
1002 param->reg_FREQ = 0x000054C0;
1003 param->madj_max = 79;
1004 param->dll2_finetune_step = 4;
1005 break;
1006 case 528:
1007 ast_moutdwm(ast, 0x1E6E2020, 0x0290);
1008 param->wodt = 1;
1009 param->rodt = 1;
1010 param->reg_AC1 = 0x33302926;
1011 param->reg_AC2 = 0xEF44B61E;
1012 param->reg_DQSIC = 0x00000125;
1013 param->reg_MRS = 0x00081A30;
1014 param->reg_EMRS = 0x00000040;
1015 param->reg_DRV = 0x000000F5;
1016 param->reg_IOZ = 0x00000023;
1017 param->reg_DQIDLY = 0x00000088;
1018 param->reg_FREQ = 0x000055C0;
1019 param->madj_max = 76;
1020 param->dll2_finetune_step = 3;
1021 break;
1022 case 576:
1023 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1024 param->reg_MADJ = 0x00136868;
1025 param->reg_SADJ = 0x00004534;
1026 param->wodt = 1;
1027 param->rodt = 1;
1028 param->reg_AC1 = 0x33302A37;
1029 param->reg_AC2 = 0xEF56B61E;
1030 param->reg_DQSIC = 0x0000013F;
1031 param->reg_MRS = 0x00101A50;
1032 param->reg_EMRS = 0x00000040;
1033 param->reg_DRV = 0x000000FA;
1034 param->reg_IOZ = 0x00000023;
1035 param->reg_DQIDLY = 0x00000078;
1036 param->reg_FREQ = 0x000057C0;
1037 param->madj_max = 136;
1038 param->dll2_finetune_step = 3;
1039 break;
1040 case 600:
1041 ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
1042 param->reg_MADJ = 0x00136868;
1043 param->reg_SADJ = 0x00004534;
1044 param->wodt = 1;
1045 param->rodt = 1;
1046 param->reg_AC1 = 0x32302A37;
1047 param->reg_AC2 = 0xDF56B61F;
1048 param->reg_DQSIC = 0x0000014D;
1049 param->reg_MRS = 0x00101A50;
1050 param->reg_EMRS = 0x00000004;
1051 param->reg_DRV = 0x000000F5;
1052 param->reg_IOZ = 0x00000023;
1053 param->reg_DQIDLY = 0x00000078;
1054 param->reg_FREQ = 0x000058C0;
1055 param->madj_max = 132;
1056 param->dll2_finetune_step = 3;
1057 break;
1058 case 624:
1059 ast_moutdwm(ast, 0x1E6E2020, 0x0160);
1060 param->reg_MADJ = 0x00136868;
1061 param->reg_SADJ = 0x00004534;
1062 param->wodt = 1;
1063 param->rodt = 1;
1064 param->reg_AC1 = 0x32302A37;
1065 param->reg_AC2 = 0xEF56B621;
1066 param->reg_DQSIC = 0x0000015A;
1067 param->reg_MRS = 0x02101A50;
1068 param->reg_EMRS = 0x00000004;
1069 param->reg_DRV = 0x000000F5;
1070 param->reg_IOZ = 0x00000034;
1071 param->reg_DQIDLY = 0x00000078;
1072 param->reg_FREQ = 0x000059C0;
1073 param->madj_max = 128;
1074 param->dll2_finetune_step = 3;
1075 break;
1076 } /* switch freq */
1078 switch (param->dram_chipid) {
1079 case AST_DRAM_512Mx16:
1080 param->dram_config = 0x130;
1081 break;
1082 default:
1083 case AST_DRAM_1Gx16:
1084 param->dram_config = 0x131;
1085 break;
1086 case AST_DRAM_2Gx16:
1087 param->dram_config = 0x132;
1088 break;
1089 case AST_DRAM_4Gx16:
1090 param->dram_config = 0x133;
1091 break;
1092 } /* switch size */
1094 switch (param->vram_size) {
1095 default:
1096 case AST_VIDMEM_SIZE_8M:
1097 param->dram_config |= 0x00;
1098 break;
1099 case AST_VIDMEM_SIZE_16M:
1100 param->dram_config |= 0x04;
1101 break;
1102 case AST_VIDMEM_SIZE_32M:
1103 param->dram_config |= 0x08;
1104 break;
1105 case AST_VIDMEM_SIZE_64M:
1106 param->dram_config |= 0x0c;
1107 break;
1112 static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1114 u32 data, data2, retry = 0;
1116 ddr3_init_start:
1117 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1118 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1119 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1120 ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
1121 udelay(10);
1122 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1123 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1124 udelay(10);
1125 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1126 udelay(10);
1128 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1129 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1130 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1131 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1132 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1133 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1134 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1135 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1136 ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
1137 ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
1138 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1139 ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
1140 ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
1141 ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1142 ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
1143 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1144 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1145 ast_moutdwm(ast, 0x1E6E0054, 0);
1146 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1147 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1148 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1149 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1150 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1151 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1152 /* Wait MCLK2X lock to MCLK */
1153 do {
1154 data = ast_mindwm(ast, 0x1E6E001C);
1155 } while (!(data & 0x08000000));
1156 data = ast_mindwm(ast, 0x1E6E001C);
1157 data = (data >> 8) & 0xff;
1158 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1159 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1160 if ((data2 & 0xff) > param->madj_max) {
1161 break;
1163 ast_moutdwm(ast, 0x1E6E0064, data2);
1164 if (data2 & 0x00100000) {
1165 data2 = ((data2 & 0xff) >> 3) + 3;
1166 } else {
1167 data2 = ((data2 & 0xff) >> 2) + 5;
1169 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1170 data2 += data & 0xff;
1171 data = data | (data2 << 8);
1172 ast_moutdwm(ast, 0x1E6E0068, data);
1173 udelay(10);
1174 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1175 udelay(10);
1176 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1177 ast_moutdwm(ast, 0x1E6E0018, data);
1178 data = data | 0x200;
1179 ast_moutdwm(ast, 0x1E6E0018, data);
1180 do {
1181 data = ast_mindwm(ast, 0x1E6E001C);
1182 } while (!(data & 0x08000000));
1184 data = ast_mindwm(ast, 0x1E6E001C);
1185 data = (data >> 8) & 0xff;
1187 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
1188 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1189 ast_moutdwm(ast, 0x1E6E0018, data);
1191 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1192 ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
1193 udelay(50);
1194 /* Mode Register Setting */
1195 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1196 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1197 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1198 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1199 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1200 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1201 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1202 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1203 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1205 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1206 data = 0;
1207 if (param->wodt) {
1208 data = 0x300;
1210 if (param->rodt) {
1211 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1213 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1215 /* Calibrate the DQSI delay */
1216 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1217 goto ddr3_init_start;
1219 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1220 /* ECC Memory Initialization */
1221 #ifdef ECC
1222 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1223 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1224 do {
1225 data = ast_mindwm(ast, 0x1E6E0070);
1226 } while (!(data & 0x00001000));
1227 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1228 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1229 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1230 #endif
1235 static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1237 u32 trap, trap_AC2, trap_MRS;
1239 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1241 /* Ger trap info */
1242 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1243 trap_AC2 = (trap << 20) | (trap << 16);
1244 trap_AC2 += 0x00110000;
1245 trap_MRS = 0x00000040 | (trap << 4);
1248 param->reg_MADJ = 0x00034C4C;
1249 param->reg_SADJ = 0x00001800;
1250 param->reg_DRV = 0x000000F0;
1251 param->reg_PERIOD = param->dram_freq;
1252 param->rodt = 0;
1254 switch (param->dram_freq) {
1255 case 264:
1256 ast_moutdwm(ast, 0x1E6E2020, 0x0130);
1257 param->wodt = 0;
1258 param->reg_AC1 = 0x11101513;
1259 param->reg_AC2 = 0x78117011;
1260 param->reg_DQSIC = 0x00000092;
1261 param->reg_MRS = 0x00000842;
1262 param->reg_EMRS = 0x00000000;
1263 param->reg_DRV = 0x000000F0;
1264 param->reg_IOZ = 0x00000034;
1265 param->reg_DQIDLY = 0x0000005A;
1266 param->reg_FREQ = 0x00004AC0;
1267 param->madj_max = 138;
1268 param->dll2_finetune_step = 3;
1269 break;
1270 case 336:
1271 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
1272 param->wodt = 1;
1273 param->reg_AC1 = 0x22202613;
1274 param->reg_AC2 = 0xAA009016 | trap_AC2;
1275 param->reg_DQSIC = 0x000000BA;
1276 param->reg_MRS = 0x00000A02 | trap_MRS;
1277 param->reg_EMRS = 0x00000040;
1278 param->reg_DRV = 0x000000FA;
1279 param->reg_IOZ = 0x00000034;
1280 param->reg_DQIDLY = 0x00000074;
1281 param->reg_FREQ = 0x00004DC0;
1282 param->madj_max = 96;
1283 param->dll2_finetune_step = 3;
1284 switch (param->dram_chipid) {
1285 default:
1286 case AST_DRAM_512Mx16:
1287 param->reg_AC2 = 0xAA009012 | trap_AC2;
1288 break;
1289 case AST_DRAM_1Gx16:
1290 param->reg_AC2 = 0xAA009016 | trap_AC2;
1291 break;
1292 case AST_DRAM_2Gx16:
1293 param->reg_AC2 = 0xAA009023 | trap_AC2;
1294 break;
1295 case AST_DRAM_4Gx16:
1296 param->reg_AC2 = 0xAA00903B | trap_AC2;
1297 break;
1299 break;
1300 default:
1301 case 396:
1302 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
1303 param->wodt = 1;
1304 param->rodt = 0;
1305 param->reg_AC1 = 0x33302714;
1306 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1307 param->reg_DQSIC = 0x000000E2;
1308 param->reg_MRS = 0x00000C02 | trap_MRS;
1309 param->reg_EMRS = 0x00000040;
1310 param->reg_DRV = 0x000000FA;
1311 param->reg_IOZ = 0x00000034;
1312 param->reg_DQIDLY = 0x00000089;
1313 param->reg_FREQ = 0x00005040;
1314 param->madj_max = 96;
1315 param->dll2_finetune_step = 4;
1317 switch (param->dram_chipid) {
1318 case AST_DRAM_512Mx16:
1319 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1320 break;
1321 default:
1322 case AST_DRAM_1Gx16:
1323 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1324 break;
1325 case AST_DRAM_2Gx16:
1326 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1327 break;
1328 case AST_DRAM_4Gx16:
1329 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1330 break;
1333 break;
1335 case 408:
1336 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
1337 param->wodt = 1;
1338 param->rodt = 0;
1339 param->reg_AC1 = 0x33302714;
1340 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1341 param->reg_DQSIC = 0x000000E2;
1342 param->reg_MRS = 0x00000C02 | trap_MRS;
1343 param->reg_EMRS = 0x00000040;
1344 param->reg_DRV = 0x000000FA;
1345 param->reg_IOZ = 0x00000034;
1346 param->reg_DQIDLY = 0x00000089;
1347 param->reg_FREQ = 0x000050C0;
1348 param->madj_max = 96;
1349 param->dll2_finetune_step = 4;
1351 switch (param->dram_chipid) {
1352 case AST_DRAM_512Mx16:
1353 param->reg_AC2 = 0xCC00B016 | trap_AC2;
1354 break;
1355 default:
1356 case AST_DRAM_1Gx16:
1357 param->reg_AC2 = 0xCC00B01B | trap_AC2;
1358 break;
1359 case AST_DRAM_2Gx16:
1360 param->reg_AC2 = 0xCC00B02B | trap_AC2;
1361 break;
1362 case AST_DRAM_4Gx16:
1363 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1364 break;
1367 break;
1368 case 456:
1369 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
1370 param->wodt = 0;
1371 param->reg_AC1 = 0x33302815;
1372 param->reg_AC2 = 0xCD44B01E;
1373 param->reg_DQSIC = 0x000000FC;
1374 param->reg_MRS = 0x00000E72;
1375 param->reg_EMRS = 0x00000000;
1376 param->reg_DRV = 0x00000000;
1377 param->reg_IOZ = 0x00000034;
1378 param->reg_DQIDLY = 0x00000097;
1379 param->reg_FREQ = 0x000052C0;
1380 param->madj_max = 88;
1381 param->dll2_finetune_step = 3;
1382 break;
1383 case 504:
1384 ast_moutdwm(ast, 0x1E6E2020, 0x0261);
1385 param->wodt = 1;
1386 param->rodt = 1;
1387 param->reg_AC1 = 0x33302815;
1388 param->reg_AC2 = 0xDE44C022;
1389 param->reg_DQSIC = 0x00000117;
1390 param->reg_MRS = 0x00000E72;
1391 param->reg_EMRS = 0x00000040;
1392 param->reg_DRV = 0x0000000A;
1393 param->reg_IOZ = 0x00000045;
1394 param->reg_DQIDLY = 0x000000A0;
1395 param->reg_FREQ = 0x000054C0;
1396 param->madj_max = 79;
1397 param->dll2_finetune_step = 3;
1398 break;
1399 case 528:
1400 ast_moutdwm(ast, 0x1E6E2020, 0x0120);
1401 param->wodt = 1;
1402 param->rodt = 1;
1403 param->reg_AC1 = 0x33302815;
1404 param->reg_AC2 = 0xEF44D024;
1405 param->reg_DQSIC = 0x00000125;
1406 param->reg_MRS = 0x00000E72;
1407 param->reg_EMRS = 0x00000004;
1408 param->reg_DRV = 0x000000F9;
1409 param->reg_IOZ = 0x00000045;
1410 param->reg_DQIDLY = 0x000000A7;
1411 param->reg_FREQ = 0x000055C0;
1412 param->madj_max = 76;
1413 param->dll2_finetune_step = 3;
1414 break;
1415 case 552:
1416 ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
1417 param->wodt = 1;
1418 param->rodt = 1;
1419 param->reg_AC1 = 0x43402915;
1420 param->reg_AC2 = 0xFF44E025;
1421 param->reg_DQSIC = 0x00000132;
1422 param->reg_MRS = 0x00000E72;
1423 param->reg_EMRS = 0x00000040;
1424 param->reg_DRV = 0x0000000A;
1425 param->reg_IOZ = 0x00000045;
1426 param->reg_DQIDLY = 0x000000AD;
1427 param->reg_FREQ = 0x000056C0;
1428 param->madj_max = 76;
1429 param->dll2_finetune_step = 3;
1430 break;
1431 case 576:
1432 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1433 param->wodt = 1;
1434 param->rodt = 1;
1435 param->reg_AC1 = 0x43402915;
1436 param->reg_AC2 = 0xFF44E027;
1437 param->reg_DQSIC = 0x0000013F;
1438 param->reg_MRS = 0x00000E72;
1439 param->reg_EMRS = 0x00000004;
1440 param->reg_DRV = 0x000000F5;
1441 param->reg_IOZ = 0x00000045;
1442 param->reg_DQIDLY = 0x000000B3;
1443 param->reg_FREQ = 0x000057C0;
1444 param->madj_max = 76;
1445 param->dll2_finetune_step = 3;
1446 break;
1449 switch (param->dram_chipid) {
1450 case AST_DRAM_512Mx16:
1451 param->dram_config = 0x100;
1452 break;
1453 default:
1454 case AST_DRAM_1Gx16:
1455 param->dram_config = 0x121;
1456 break;
1457 case AST_DRAM_2Gx16:
1458 param->dram_config = 0x122;
1459 break;
1460 case AST_DRAM_4Gx16:
1461 param->dram_config = 0x123;
1462 break;
1463 } /* switch size */
1465 switch (param->vram_size) {
1466 default:
1467 case AST_VIDMEM_SIZE_8M:
1468 param->dram_config |= 0x00;
1469 break;
1470 case AST_VIDMEM_SIZE_16M:
1471 param->dram_config |= 0x04;
1472 break;
1473 case AST_VIDMEM_SIZE_32M:
1474 param->dram_config |= 0x08;
1475 break;
1476 case AST_VIDMEM_SIZE_64M:
1477 param->dram_config |= 0x0c;
1478 break;
1482 static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1484 u32 data, data2, retry = 0;
1486 ddr2_init_start:
1487 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1488 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1489 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1490 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1491 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1492 udelay(10);
1493 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1494 udelay(10);
1496 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1497 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1498 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1499 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1500 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1501 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1502 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1503 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1504 ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
1505 ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
1506 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1507 ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
1508 ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
1509 ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
1510 ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
1511 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1512 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1513 ast_moutdwm(ast, 0x1E6E0054, 0);
1514 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1515 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1516 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1517 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1518 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1519 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1521 /* Wait MCLK2X lock to MCLK */
1522 do {
1523 data = ast_mindwm(ast, 0x1E6E001C);
1524 } while (!(data & 0x08000000));
1525 data = ast_mindwm(ast, 0x1E6E001C);
1526 data = (data >> 8) & 0xff;
1527 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1528 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1529 if ((data2 & 0xff) > param->madj_max) {
1530 break;
1532 ast_moutdwm(ast, 0x1E6E0064, data2);
1533 if (data2 & 0x00100000) {
1534 data2 = ((data2 & 0xff) >> 3) + 3;
1535 } else {
1536 data2 = ((data2 & 0xff) >> 2) + 5;
1538 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1539 data2 += data & 0xff;
1540 data = data | (data2 << 8);
1541 ast_moutdwm(ast, 0x1E6E0068, data);
1542 udelay(10);
1543 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1544 udelay(10);
1545 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1546 ast_moutdwm(ast, 0x1E6E0018, data);
1547 data = data | 0x200;
1548 ast_moutdwm(ast, 0x1E6E0018, data);
1549 do {
1550 data = ast_mindwm(ast, 0x1E6E001C);
1551 } while (!(data & 0x08000000));
1553 data = ast_mindwm(ast, 0x1E6E001C);
1554 data = (data >> 8) & 0xff;
1556 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
1557 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1558 ast_moutdwm(ast, 0x1E6E0018, data);
1560 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1561 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1562 udelay(50);
1563 /* Mode Register Setting */
1564 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1565 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1566 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1567 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1568 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1569 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1571 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1572 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1573 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1574 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1575 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1576 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1577 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1579 ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1580 data = 0;
1581 if (param->wodt) {
1582 data = 0x500;
1584 if (param->rodt) {
1585 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1587 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1588 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1590 /* Calibrate the DQSI delay */
1591 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1592 goto ddr2_init_start;
1594 /* ECC Memory Initialization */
1595 #ifdef ECC
1596 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1597 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1598 do {
1599 data = ast_mindwm(ast, 0x1E6E0070);
1600 } while (!(data & 0x00001000));
1601 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1602 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1603 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1604 #endif
1608 static void ast_init_dram_2300(struct drm_device *dev)
1610 struct ast_private *ast = dev->dev_private;
1611 struct ast2300_dram_param param;
1612 u32 temp;
1613 u8 reg;
1615 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1616 if ((reg & 0x80) == 0) {/* vga only */
1617 ast_write32(ast, 0xf004, 0x1e6e0000);
1618 ast_write32(ast, 0xf000, 0x1);
1619 ast_write32(ast, 0x12000, 0x1688a8a8);
1620 do {
1622 } while (ast_read32(ast, 0x12000) != 0x1);
1624 ast_write32(ast, 0x10000, 0xfc600309);
1625 do {
1627 } while (ast_read32(ast, 0x10000) != 0x1);
1629 /* Slow down CPU/AHB CLK in VGA only mode */
1630 temp = ast_read32(ast, 0x12008);
1631 temp |= 0x73;
1632 ast_write32(ast, 0x12008, temp);
1634 param.dram_freq = 396;
1635 param.dram_type = AST_DDR3;
1636 temp = ast_mindwm(ast, 0x1e6e2070);
1637 if (temp & 0x01000000)
1638 param.dram_type = AST_DDR2;
1639 switch (temp & 0x18000000) {
1640 case 0:
1641 param.dram_chipid = AST_DRAM_512Mx16;
1642 break;
1643 default:
1644 case 0x08000000:
1645 param.dram_chipid = AST_DRAM_1Gx16;
1646 break;
1647 case 0x10000000:
1648 param.dram_chipid = AST_DRAM_2Gx16;
1649 break;
1650 case 0x18000000:
1651 param.dram_chipid = AST_DRAM_4Gx16;
1652 break;
1654 switch (temp & 0x0c) {
1655 default:
1656 case 0x00:
1657 param.vram_size = AST_VIDMEM_SIZE_8M;
1658 break;
1660 case 0x04:
1661 param.vram_size = AST_VIDMEM_SIZE_16M;
1662 break;
1664 case 0x08:
1665 param.vram_size = AST_VIDMEM_SIZE_32M;
1666 break;
1668 case 0x0c:
1669 param.vram_size = AST_VIDMEM_SIZE_64M;
1670 break;
1673 if (param.dram_type == AST_DDR3) {
1674 get_ddr3_info(ast, &param);
1675 ddr3_init(ast, &param);
1676 } else {
1677 get_ddr2_info(ast, &param);
1678 ddr2_init(ast, &param);
1681 temp = ast_mindwm(ast, 0x1e6e2040);
1682 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
1685 /* wait ready */
1686 do {
1687 reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1688 } while ((reg & 0x40) == 0);