Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ast_post.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
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:
11  *
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.
19  *
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.
23  *
24  */
25 /*
26  * Authors: Dave Airlie <[email protected]>
27  */
28 
29 #include <drm/drmP.h>
30 #include "ast_drv.h"
31 
32 #include "ast_dram_tables.h"
33 
34 static void ast_init_dram_2300(struct drm_device *dev);
35 
36 static void
37 ast_enable_vga(struct drm_device *dev)
38 {
39  struct ast_private *ast = dev->dev_private;
40 
41  ast_io_write8(ast, 0x43, 0x01);
42  ast_io_write8(ast, 0x42, 0x01);
43 }
44 
45 #if 0 /* will use later */
46 static bool
47 ast_is_vga_enabled(struct drm_device *dev)
48 {
49  struct ast_private *ast = dev->dev_private;
50  u8 ch;
51 
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;
60  }
61  }
62  return 0;
63 }
64 #endif
65 
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 };
69 
70 static void
71 ast_set_def_ext_reg(struct drm_device *dev)
72 {
73  struct ast_private *ast = dev->dev_private;
74  u8 i, index, reg;
75  const u8 *ext_reg_info;
76 
77  /* reset scratch */
78  for (i = 0x81; i <= 0x8f; i++)
79  ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
80 
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;
88 
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++;
94  }
95 
96  /* disable standard IO/MEM decode if secondary */
97  /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
98 
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);
102 
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);
108 }
109 
110 static inline u32 mindwm(struct ast_private *ast, u32 r)
111 {
112  ast_write32(ast, 0xf004, r & 0xffff0000);
113  ast_write32(ast, 0xf000, 0x1);
114 
115  return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
116 }
117 
118 static inline void moutdwm(struct ast_private *ast, u32 r, u32 v)
119 {
120  ast_write32(ast, 0xf004, r & 0xffff0000);
121  ast_write32(ast, 0xf000, 0x1);
122  ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
123 }
124 
125 /*
126  * AST2100/2150 DLL CBR Setting
127  */
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
133 
134 #define CBR_PATNUM_AST2150 8
135 
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
151 };
152 
153 static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
154 {
155  u32 data, timeout;
156 
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;
165  }
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;
175  }
176  } while (!data);
177  data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
178  moutdwm(ast, 0x1e6e0070, 0x00000000);
179  return data;
180 }
181 
182 #if 0 /* unused in DDX driver - here for completeness */
183 static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
184 {
185  u32 data, timeout;
186 
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;
195  }
196  } while (!data);
197  data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
198  moutdwm(ast, 0x1e6e0070, 0x00000000);
199  return data;
200 }
201 #endif
202 
203 static int cbrtest_ast2150(struct ast_private *ast)
204 {
205  int i;
206 
207  for (i = 0; i < 8; i++)
208  if (mmctestburst2_ast2150(ast, i))
209  return 0;
210  return 1;
211 }
212 
213 static int cbrscan_ast2150(struct ast_private *ast, int busw)
214 {
215  u32 patcnt, loop;
216 
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;
222  }
223  if (loop == CBR_PASSNUM_AST2150)
224  return 0;
225  }
226  return 1;
227 }
228 
229 
230 static void cbrdlli_ast2150(struct ast_private *ast, int busw)
231 {
232  u32 dll_min[4], dll_max[4], dlli, data, passcnt;
233 
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;
238 
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;
248  }
249  passcnt++;
250  } else if (passcnt >= CBR_THRESHOLD_AST2150)
251  goto cbr_start;
252  }
253  if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
254  goto cbr_start;
255 
256  dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
257  moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
258 }
259 
260 
261 
262 static void ast_init_dram_reg(struct drm_device *dev)
263 {
264  struct ast_private *ast = dev->dev_private;
265  u8 j;
266  u32 data, temp, i;
267  const struct ast_dramstruct *dram_reg_info;
268 
269  j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
270 
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);
277 
278  do {
279  ;
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;
286 
287  ast_write32(ast, 0xf004, 0x1e6e0000);
288  ast_write32(ast, 0xf000, 0x1);
289  ast_write32(ast, 0x12000, 0x1688A8A8);
290  do {
291  ;
292  } while (ast_read32(ast, 0x12000) != 0x01);
293 
294  ast_write32(ast, 0x10000, 0xfc600309);
295  do {
296  ;
297  } while (ast_read32(ast, 0x10000) != 0x01);
298  }
299 
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;
310 
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++;
318  }
319 
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 */
328  }
329 
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;
346  }
347  }
348 
349  /* wait ready */
350  do {
351  j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
352  } while ((j & 0x40) == 0);
353 }
354 
355 void ast_post_gpu(struct drm_device *dev)
356 {
357  u32 reg;
358  struct ast_private *ast = dev->dev_private;
359 
360  pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
361  reg |= 0x3;
362  pci_write_config_dword(ast->dev->pdev, 0x04, reg);
363 
364  ast_enable_vga(dev);
365  ast_open_key(ast);
366  ast_set_def_ext_reg(dev);
367 
368  if (ast->chip == AST2300)
369  ast_init_dram_2300(dev);
370  else
371  ast_init_dram_reg(dev);
372 }
373 
374 /* AST 2300 DRAM settings */
375 #define AST_DDR3 0
376 #define AST_DDR2 1
377 
401 };
402 
403 /*
404  * DQSI DLL CBR Setting
405  */
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
414 
415 static const u32 pattern[8] = {
416  0xFF00FF00,
417  0xCC33CC33,
418  0xAA55AA55,
419  0x88778877,
420  0x92CC4D6E,
421  0x543D3CDE,
422  0xF1E843C7,
423  0x7C61D253
424 };
425 
426 #if 0 /* unused in DDX, included for completeness */
427 static int mmc_test_burst(struct ast_private *ast, u32 datagen)
428 {
429  u32 data, timeout;
430 
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;
438  }
439  if (++timeout > TIMEOUT) {
440  moutdwm(ast, 0x1e6e0070, 0x00000000);
441  return 0;
442  }
443  } while (!data);
444  moutdwm(ast, 0x1e6e0070, 0x00000000);
445  return 1;
446 }
447 #endif
448 
449 static int mmc_test_burst2(struct ast_private *ast, u32 datagen)
450 {
451  u32 data, timeout;
452 
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;
461  }
462  } while (!data);
463  data = mindwm(ast, 0x1e6e0078);
464  data = (data | (data >> 16)) & 0xffff;
465  moutdwm(ast, 0x1e6e0070, 0x0);
466  return data;
467 }
468 
469 #if 0 /* Unused in DDX here for completeness */
470 static int mmc_test_single(struct ast_private *ast, u32 datagen)
471 {
472  u32 data, timeout;
473 
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;
484  }
485  } while (!data);
486  moutdwm(ast, 0x1e6e0070, 0x0);
487  return 1;
488 }
489 #endif
490 
491 static int mmc_test_single2(struct ast_private *ast, u32 datagen)
492 {
493  u32 data, timeout;
494 
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;
503  }
504  } while (!data);
505  data = mindwm(ast, 0x1e6e0078);
506  data = (data | (data >> 16)) & 0xffff;
507  moutdwm(ast, 0x1e6e0070, 0x0);
508  return data;
509 }
510 
511 static int cbr_test(struct ast_private *ast)
512 {
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;
522  }
523  if (!data)
524  return 3;
525  else if (data & 0xff)
526  return 2;
527  return 1;
528 }
529 
530 static int cbr_scan(struct ast_private *ast)
531 {
532  u32 data, data2, patcnt, loop;
533 
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;
543  }
544  }
545  if (loop == CBR_PASSNUM2)
546  return 0;
547  }
548  return data2;
549 }
550 
551 static u32 cbr_test2(struct ast_private *ast)
552 {
553  u32 data;
554 
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;
561 
562  return ~data & 0xffff;
563 }
564 
565 static u32 cbr_scan2(struct ast_private *ast)
566 {
567  u32 data, data2, patcnt, loop;
568 
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;
578  }
579  }
580  if (loop == CBR_PASSNUM2)
581  return 0;
582  }
583  return data2;
584 }
585 
586 #if 0 /* unused in DDX - added for completeness */
587 static void finetuneDQI(struct ast_private *ast, struct ast2300_dram_param *param)
588 {
589  u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
590 
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];
596 
597  for (cnt = 0; cnt < 16; cnt++) {
598  dllmin[cnt] = 0xff;
599  dllmax[cnt] = 0x0;
600  }
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);
611 
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;
620  }
621  if (dllmax[cnt] < dlli) {
622  dllmax[cnt] = dlli;
623  }
624  }
625  mask <<= 1;
626  }
627  passcnt++;
628  } else if (passcnt >= CBR_THRESHOLD) {
629  break;
630  }
631  }
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;
641  }
642  } else {
643  dlli = (dlli - gold_sadj[0]) >> 1;
644  if (dlli > 4) {
645  dlli = 4;
646  }
647  dlli = (8 - dlli) & 0x7;
648  }
649  data |= dlli << 21;
650  }
651  }
652  moutdwm(ast, 0x1E6E0080, data);
653 
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;
665  }
666  } else {
667  dlli = (dlli - gold_sadj[1]) >> 1;
668  dlli += 1;
669  if (dlli > 4) {
670  dlli = 4;
671  }
672  dlli = (8 - dlli) & 0x7;
673  }
674  data |= dlli << 21;
675  }
676  }
677  moutdwm(ast, 0x1E6E0084, data);
678 
679 } /* finetuneDQI */
680 #endif
681 
682 static void finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
683 {
684  u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
685 
686 FINETUNE_START:
687  for (cnt = 0; cnt < 16; cnt++) {
688  dllmin[cnt] = 0xff;
689  dllmax[cnt] = 0x0;
690  }
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);
701 
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;
710  }
711  if (dllmax[cnt] < dlli) {
712  dllmax[cnt] = dlli;
713  }
714  }
715  mask <<= 1;
716  }
717  passcnt++;
718  } else if (passcnt >= CBR_THRESHOLD2) {
719  break;
720  }
721  }
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++;
728  }
729  }
730  if (passcnt != 16) {
731  goto FINETUNE_START;
732  }
733  gold_sadj[0] = gold_sadj[0] >> 4;
734  gold_sadj[1] = gold_sadj[0];
735 
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;
745  }
746  } else {
747  dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
748  if (dlli > 4) {
749  dlli = 4;
750  }
751  dlli = (8 - dlli) & 0x7;
752  }
753  data |= dlli << 21;
754  }
755  }
756  moutdwm(ast, 0x1E6E0080, data);
757 
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;
769  }
770  } else {
771  dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
772  dlli += 1;
773  if (dlli > 4) {
774  dlli = 4;
775  }
776  dlli = (8 - dlli) & 0x7;
777  }
778  data |= dlli << 21;
779  }
780  }
781  moutdwm(ast, 0x1E6E0084, data);
782 
783 } /* finetuneDQI_L */
784 
785 static void finetuneDQI_L2(struct ast_private *ast, struct ast2300_dram_param *param)
786 {
787  u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, data2;
788 
789  for (cnt = 0; cnt < 16; cnt++) {
790  dllmin[cnt] = 0xff;
791  dllmax[cnt] = 0x0;
792  }
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);
803 
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;
812  }
813  if (dllmax[cnt] < dlli) {
814  dllmax[cnt] = dlli;
815  }
816  }
817  mask <<= 1;
818  }
819  passcnt++;
820  } else if (passcnt >= CBR_THRESHOLD2) {
821  break;
822  }
823  }
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];
830  }
831  if (gold_sadj[1] > dllmax[cnt]) {
832  gold_sadj[1] = dllmax[cnt];
833  }
834  }
835  }
836  gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
837  gold_sadj[1] = mindwm(ast, 0x1E6E0080);
838 
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;
850  }
851  if (data2 != 3) {
852  data2 = (data2 + dlli) & 0x7;
853  }
854  } else {
855  dlli = (dlli - gold_sadj[0]) >> 1;
856  if (dlli > 0) {
857  dlli = 1;
858  }
859  if (data2 != 4) {
860  data2 = (data2 - dlli) & 0x7;
861  }
862  }
863  }
864  data |= data2 << 21;
865  }
866  moutdwm(ast, 0x1E6E0080, data);
867 
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];
874  }
875  if (gold_sadj[1] > dllmax[cnt]) {
876  gold_sadj[1] = dllmax[cnt];
877  }
878  }
879  }
880  gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
881  gold_sadj[1] = mindwm(ast, 0x1E6E0084);
882 
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;
894  }
895  if (data2 != 3) {
896  data2 = (data2 + dlli) & 0x7;
897  }
898  } else {
899  dlli = (dlli - gold_sadj[0]) >> 1;
900  if (dlli > 0) {
901  dlli = 1;
902  }
903  if (data2 != 4) {
904  data2 = (data2 - dlli) & 0x7;
905  }
906  }
907  }
908  data |= data2 << 21;
909  }
910  moutdwm(ast, 0x1E6E0084, data);
911 
912 } /* finetuneDQI_L2 */
913 
914 static void cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
915 {
916  u32 dllmin[2], dllmax[2], dlli, data, data2, passcnt;
917 
918 
919  finetuneDQI_L(ast, param);
920  finetuneDQI_L2(ast, param);
921 
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);
935 
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;
942  }
943  if (dllmax[0] < dlli) {
944  dllmax[0] = dlli;
945  }
946  }
947  if (data & 0x2) {
948  if (dllmin[1] > dlli) {
949  dllmin[1] = dlli;
950  }
951  if (dllmax[1] < dlli) {
952  dllmax[1] = dlli;
953  }
954  }
955  passcnt++;
956  } else if (passcnt >= CBR_THRESHOLD) {
957  break;
958  }
959  }
960  if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
961  goto CBR_START2;
962  }
963  if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
964  goto CBR_START2;
965  }
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));
970 
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));
975 
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 */
989 
990 static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
991 {
992  u32 trap, trap_AC2, trap_MRS;
993 
994  moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
995 
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);
1002 
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;
1008 
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;
1039 
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;
1052  }
1053  break;
1054 
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;
1069 
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;
1082  }
1083 
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 */
1184 
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 */
1200 
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;
1215  }
1216 
1217 }
1218 
1219 static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1220 {
1221  u32 data, data2;
1222 
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);
1233 
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;
1273  }
1274  moutdwm(ast, 0x1E6E0064, data2);
1275  if (data2 & 0x00100000) {
1276  data2 = ((data2 & 0xff) >> 3) + 3;
1277  } else {
1278  data2 = ((data2 & 0xff) >> 2) + 5;
1279  }
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));
1294 
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;
1302  }
1303  data = mindwm(ast, 0x1E6E0018) | 0xC00;
1304  moutdwm(ast, 0x1E6E0018, data);
1305 
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);
1319 
1320  moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1321  data = 0;
1322  if (param->wodt) {
1323  data = 0x300;
1324  }
1325  if (param->rodt) {
1326  data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1327  }
1328  moutdwm(ast, 0x1E6E0034, data | 0x3);
1329 
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);
1340 
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
1353 
1354 
1355 }
1356 
1357 static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1358 {
1359  u32 trap, trap_AC2, trap_MRS;
1360 
1361  moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1362 
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);
1368 
1369 
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;
1375 
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;
1423 
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;
1438  }
1439 
1440  break;
1441 
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;
1457 
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;
1472  }
1473 
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;
1554  }
1555 
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 */
1571 
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;
1586  }
1587 }
1588 
1589 static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1590 {
1591  u32 data, data2;
1592 
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);
1601 
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);
1626 
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;
1642  }
1643  moutdwm(ast, 0x1E6E0064, data2);
1644  if (data2 & 0x00100000) {
1645  data2 = ((data2 & 0xff) >> 3) + 3;
1646  } else {
1647  data2 = ((data2 & 0xff) >> 2) + 5;
1648  }
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));
1663 
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;
1671  }
1672  data = mindwm(ast, 0x1E6E0018) | 0xC00;
1673  moutdwm(ast, 0x1E6E0018, data);
1674 
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);
1685 
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);
1693 
1694  moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1695  data = 0;
1696  if (param->wodt) {
1697  data = 0x500;
1698  }
1699  if (param->rodt) {
1700  data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1701  }
1702  moutdwm(ast, 0x1E6E0034, data | 0x3);
1703  moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1704 
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);
1715 
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
1727 
1728 }
1729 
1730 static void ast_init_dram_2300(struct drm_device *dev)
1731 {
1732  struct ast_private *ast = dev->dev_private;
1733  struct ast2300_dram_param param;
1734  u32 temp;
1735  u8 reg;
1736 
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 {
1743  ;
1744  } while (ast_read32(ast, 0x12000) != 0x1);
1745 
1746  ast_write32(ast, 0x10000, 0xfc600309);
1747  do {
1748  ;
1749  } while (ast_read32(ast, 0x10000) != 0x1);
1750 
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);
1755 
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;
1762 
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);
1769  }
1770 
1771  temp = mindwm(ast, 0x1e6e2040);
1772  moutdwm(ast, 0x1e6e2040, temp | 0x40);
1773  }
1774 
1775  /* wait ready */
1776  do {
1777  reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1778  } while ((reg & 0x40) == 0);
1779 }
1780