1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2012 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 */
25 /*
26 * Authors: Dave Airlie <airlied@redhat.com>
27 */
28
29 #include <linux/delay.h>
30 #include <linux/pci.h>
31 #include <linux/sizes.h>
32
33 #include <drm/drm_drv.h>
34 #include <drm/drm_managed.h>
35 #include <drm/drm_print.h>
36
37 #include "ast_drv.h"
38 #include "ast_post.h"
39
40 /*
41 * POST
42 */
43
ast_2300_set_def_ext_reg(struct ast_device * ast)44 void ast_2300_set_def_ext_reg(struct ast_device *ast)
45 {
46 static const u8 extreginfo[] = { 0x0f, 0x04, 0x1f, 0xff };
47 u8 i, index, reg;
48 const u8 *ext_reg_info;
49
50 /* reset scratch */
51 for (i = 0x81; i <= 0x9f; i++)
52 ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00);
53
54 ext_reg_info = extreginfo;
55 index = 0xa0;
56 while (*ext_reg_info != 0xff) {
57 ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info);
58 index++;
59 ext_reg_info++;
60 }
61
62 /* disable standard IO/MEM decode if secondary */
63 /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */
64
65 /* Set Ext. Default */
66 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01);
67 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00);
68
69 /* Enable RAMDAC for A1 */
70 reg = 0x04;
71 reg |= 0x20;
72 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg);
73 }
74
75 /* AST 2300 DRAM settings */
76 #define AST_DDR3 0
77 #define AST_DDR2 1
78
79 struct ast2300_dram_param {
80 u32 dram_type;
81 u32 dram_chipid;
82 u32 dram_freq;
83 u32 vram_size;
84 u32 odt;
85 u32 wodt;
86 u32 rodt;
87 u32 dram_config;
88 u32 reg_PERIOD;
89 u32 reg_MADJ;
90 u32 reg_SADJ;
91 u32 reg_MRS;
92 u32 reg_EMRS;
93 u32 reg_AC1;
94 u32 reg_AC2;
95 u32 reg_DQSIC;
96 u32 reg_DRV;
97 u32 reg_IOZ;
98 u32 reg_DQIDLY;
99 u32 reg_FREQ;
100 u32 madj_max;
101 u32 dll2_finetune_step;
102 };
103
104 /*
105 * DQSI DLL CBR Setting
106 */
107 #define CBR_SIZE0 ((1 << 10) - 1)
108 #define CBR_SIZE1 ((4 << 10) - 1)
109 #define CBR_SIZE2 ((64 << 10) - 1)
110 #define CBR_PASSNUM 5
111 #define CBR_PASSNUM2 5
112 #define CBR_THRESHOLD 10
113 #define CBR_THRESHOLD2 10
114 #define TIMEOUT 5000000
115 #define CBR_PATNUM 8
116
117 static const u32 pattern[8] = {
118 0xFF00FF00,
119 0xCC33CC33,
120 0xAA55AA55,
121 0x88778877,
122 0x92CC4D6E,
123 0x543D3CDE,
124 0xF1E843C7,
125 0x7C61D253
126 };
127
mmc_test2(struct ast_device * ast,u32 datagen,u8 test_ctl)128 static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl)
129 {
130 u32 data, timeout;
131
132 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
133 ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
134 timeout = 0;
135 do {
136 data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
137 if (++timeout > TIMEOUT) {
138 ast_moutdwm(ast, 0x1e6e0070, 0x0);
139 return 0xffffffff;
140 }
141 } while (!data);
142 data = ast_mindwm(ast, 0x1e6e0078);
143 data = (data | (data >> 16)) & 0xffff;
144 ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
145 return data;
146 }
147
mmc_test_burst2(struct ast_device * ast,u32 datagen)148 static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen)
149 {
150 return mmc_test2(ast, datagen, 0x41);
151 }
152
mmc_test_single(struct ast_device * ast,u32 datagen)153 static bool mmc_test_single(struct ast_device *ast, u32 datagen)
154 {
155 return mmc_test(ast, datagen, 0xc5);
156 }
157
mmc_test_single2(struct ast_device * ast,u32 datagen)158 static u32 mmc_test_single2(struct ast_device *ast, u32 datagen)
159 {
160 return mmc_test2(ast, datagen, 0x05);
161 }
162
cbr_test(struct ast_device * ast)163 static int cbr_test(struct ast_device *ast)
164 {
165 u32 data;
166 int i;
167
168 data = mmc_test_single2(ast, 0);
169 if ((data & 0xff) && (data & 0xff00))
170 return 0;
171 for (i = 0; i < 8; i++) {
172 data = mmc_test_burst2(ast, i);
173 if ((data & 0xff) && (data & 0xff00))
174 return 0;
175 }
176 if (!data)
177 return 3;
178 else if (data & 0xff)
179 return 2;
180 return 1;
181 }
182
cbr_scan(struct ast_device * ast)183 static int cbr_scan(struct ast_device *ast)
184 {
185 u32 data, data2, patcnt, loop;
186
187 data2 = 3;
188 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
189 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
190 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
191 data = cbr_test(ast);
192 if (data != 0) {
193 data2 &= data;
194 if (!data2)
195 return 0;
196 break;
197 }
198 }
199 if (loop == CBR_PASSNUM2)
200 return 0;
201 }
202 return data2;
203 }
204
cbr_test2(struct ast_device * ast)205 static u32 cbr_test2(struct ast_device *ast)
206 {
207 u32 data;
208
209 data = mmc_test_burst2(ast, 0);
210 if (data == 0xffff)
211 return 0;
212 data |= mmc_test_single2(ast, 0);
213 if (data == 0xffff)
214 return 0;
215
216 return ~data & 0xffff;
217 }
218
cbr_scan2(struct ast_device * ast)219 static u32 cbr_scan2(struct ast_device *ast)
220 {
221 u32 data, data2, patcnt, loop;
222
223 data2 = 0xffff;
224 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
225 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
226 for (loop = 0; loop < CBR_PASSNUM2; loop++) {
227 data = cbr_test2(ast);
228 if (data != 0) {
229 data2 &= data;
230 if (!data2)
231 return 0;
232 break;
233 }
234 }
235 if (loop == CBR_PASSNUM2)
236 return 0;
237 }
238 return data2;
239 }
240
cbr_test3(struct ast_device * ast)241 static bool cbr_test3(struct ast_device *ast)
242 {
243 if (!mmc_test_burst(ast, 0))
244 return false;
245 if (!mmc_test_single(ast, 0))
246 return false;
247 return true;
248 }
249
cbr_scan3(struct ast_device * ast)250 static bool cbr_scan3(struct ast_device *ast)
251 {
252 u32 patcnt, loop;
253
254 for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
255 ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
256 for (loop = 0; loop < 2; loop++) {
257 if (cbr_test3(ast))
258 break;
259 }
260 if (loop == 2)
261 return false;
262 }
263 return true;
264 }
265
finetuneDQI_L(struct ast_device * ast,struct ast2300_dram_param * param)266 static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param)
267 {
268 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
269 bool status = false;
270 FINETUNE_START:
271 for (cnt = 0; cnt < 16; cnt++) {
272 dllmin[cnt] = 0xff;
273 dllmax[cnt] = 0x0;
274 }
275 passcnt = 0;
276 for (dlli = 0; dlli < 76; dlli++) {
277 ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
278 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
279 data = cbr_scan2(ast);
280 if (data != 0) {
281 mask = 0x00010001;
282 for (cnt = 0; cnt < 16; cnt++) {
283 if (data & mask) {
284 if (dllmin[cnt] > dlli)
285 dllmin[cnt] = dlli;
286 if (dllmax[cnt] < dlli)
287 dllmax[cnt] = dlli;
288 }
289 mask <<= 1;
290 }
291 passcnt++;
292 } else if (passcnt >= CBR_THRESHOLD2) {
293 break;
294 }
295 }
296 gold_sadj[0] = 0x0;
297 passcnt = 0;
298 for (cnt = 0; cnt < 16; cnt++) {
299 if ((dllmax[cnt] > dllmin[cnt]) &&
300 ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
301 gold_sadj[0] += dllmin[cnt];
302 passcnt++;
303 }
304 }
305 if (retry++ > 10)
306 goto FINETUNE_DONE;
307 if (passcnt != 16)
308 goto FINETUNE_START;
309 status = true;
310 FINETUNE_DONE:
311 gold_sadj[0] = gold_sadj[0] >> 4;
312 gold_sadj[1] = gold_sadj[0];
313
314 data = 0;
315 for (cnt = 0; cnt < 8; cnt++) {
316 data >>= 3;
317 if ((dllmax[cnt] > dllmin[cnt]) &&
318 ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
319 dlli = dllmin[cnt];
320 if (gold_sadj[0] >= dlli) {
321 dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
322 if (dlli > 3)
323 dlli = 3;
324 } else {
325 dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
326 if (dlli > 4)
327 dlli = 4;
328 dlli = (8 - dlli) & 0x7;
329 }
330 data |= dlli << 21;
331 }
332 }
333 ast_moutdwm(ast, 0x1E6E0080, data);
334
335 data = 0;
336 for (cnt = 8; cnt < 16; cnt++) {
337 data >>= 3;
338 if ((dllmax[cnt] > dllmin[cnt]) &&
339 ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
340 dlli = dllmin[cnt];
341 if (gold_sadj[1] >= dlli) {
342 dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
343 if (dlli > 3)
344 dlli = 3;
345 else
346 dlli = (dlli - 1) & 0x7;
347 } else {
348 dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
349 dlli += 1;
350 if (dlli > 4)
351 dlli = 4;
352 dlli = (8 - dlli) & 0x7;
353 }
354 data |= dlli << 21;
355 }
356 }
357 ast_moutdwm(ast, 0x1E6E0084, data);
358 return status;
359 } /* finetuneDQI_L */
360
finetuneDQSI(struct ast_device * ast)361 static void finetuneDQSI(struct ast_device *ast)
362 {
363 u32 dlli, dqsip, dqidly;
364 u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
365 u32 g_dqidly, g_dqsip, g_margin, g_side;
366 u16 pass[32][2][2];
367 char tag[2][76];
368
369 /* Disable DQI CBR */
370 reg_mcr0c = ast_mindwm(ast, 0x1E6E000C);
371 reg_mcr18 = ast_mindwm(ast, 0x1E6E0018);
372 reg_mcr18 &= 0x0000ffff;
373 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
374
375 for (dlli = 0; dlli < 76; dlli++) {
376 tag[0][dlli] = 0x0;
377 tag[1][dlli] = 0x0;
378 }
379 for (dqidly = 0; dqidly < 32; dqidly++) {
380 pass[dqidly][0][0] = 0xff;
381 pass[dqidly][0][1] = 0x0;
382 pass[dqidly][1][0] = 0xff;
383 pass[dqidly][1][1] = 0x0;
384 }
385 for (dqidly = 0; dqidly < 32; dqidly++) {
386 passcnt[0] = 0;
387 passcnt[1] = 0;
388 for (dqsip = 0; dqsip < 2; dqsip++) {
389 ast_moutdwm(ast, 0x1E6E000C, 0);
390 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
391 ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
392 for (dlli = 0; dlli < 76; dlli++) {
393 ast_moutdwm(ast, 0x1E6E0068,
394 0x00001300 | (dlli << 16) | (dlli << 24));
395 ast_moutdwm(ast, 0x1E6E0070, 0);
396 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
397 if (cbr_scan3(ast)) {
398 if (dlli == 0)
399 break;
400 passcnt[dqsip]++;
401 tag[dqsip][dlli] = 'P';
402 if (dlli < pass[dqidly][dqsip][0])
403 pass[dqidly][dqsip][0] = (u16)dlli;
404 if (dlli > pass[dqidly][dqsip][1])
405 pass[dqidly][dqsip][1] = (u16)dlli;
406 } else if (passcnt[dqsip] >= 5) {
407 break;
408 } else {
409 pass[dqidly][dqsip][0] = 0xff;
410 pass[dqidly][dqsip][1] = 0x0;
411 }
412 }
413 }
414 if (passcnt[0] == 0 && passcnt[1] == 0)
415 dqidly++;
416 }
417 /* Search margin */
418 g_dqidly = 0;
419 g_dqsip = 0;
420 g_margin = 0;
421 g_side = 0;
422
423 for (dqidly = 0; dqidly < 32; dqidly++) {
424 for (dqsip = 0; dqsip < 2; dqsip++) {
425 if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
426 continue;
427 diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
428 if ((diff + 2) < g_margin)
429 continue;
430 passcnt[0] = 0;
431 passcnt[1] = 0;
432 for (dlli = pass[dqidly][dqsip][0];
433 dlli > 0 && tag[dqsip][dlli] != 0;
434 dlli--, passcnt[0]++) {
435 }
436 for (dlli = pass[dqidly][dqsip][1];
437 dlli < 76 && tag[dqsip][dlli] != 0;
438 dlli++, passcnt[1]++) {
439 }
440 if (passcnt[0] > passcnt[1])
441 passcnt[0] = passcnt[1];
442 passcnt[1] = 0;
443 if (passcnt[0] > g_side)
444 passcnt[1] = passcnt[0] - g_side;
445 if (diff > (g_margin + 1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
446 g_margin = diff;
447 g_dqidly = dqidly;
448 g_dqsip = dqsip;
449 g_side = passcnt[0];
450 } else if (passcnt[1] > 1 && g_side < 8) {
451 if (diff > g_margin)
452 g_margin = diff;
453 g_dqidly = dqidly;
454 g_dqsip = dqsip;
455 g_side = passcnt[0];
456 }
457 }
458 }
459 reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
460 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
461 }
462
cbr_dll2(struct ast_device * ast,struct ast2300_dram_param * param)463 static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param)
464 {
465 u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
466 bool status = false;
467
468 finetuneDQSI(ast);
469 if (finetuneDQI_L(ast, param) == false)
470 return status;
471
472 CBR_START2:
473 dllmin[0] = 0xff;
474 dllmin[1] = 0xff;
475 dllmax[0] = 0x0;
476 dllmax[1] = 0x0;
477 passcnt = 0;
478 for (dlli = 0; dlli < 76; dlli++) {
479 ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
480 ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
481 data = cbr_scan(ast);
482 if (data != 0) {
483 if (data & 0x1) {
484 if (dllmin[0] > dlli)
485 dllmin[0] = dlli;
486 if (dllmax[0] < dlli)
487 dllmax[0] = dlli;
488 }
489 if (data & 0x2) {
490 if (dllmin[1] > dlli)
491 dllmin[1] = dlli;
492 if (dllmax[1] < dlli)
493 dllmax[1] = dlli;
494 }
495 passcnt++;
496 } else if (passcnt >= CBR_THRESHOLD) {
497 break;
498 }
499 }
500 if (retry++ > 10)
501 goto CBR_DONE2;
502 if (dllmax[0] == 0 || (dllmax[0] - dllmin[0]) < CBR_THRESHOLD)
503 goto CBR_START2;
504 if (dllmax[1] == 0 || (dllmax[1] - dllmin[1]) < CBR_THRESHOLD)
505 goto CBR_START2;
506 status = true;
507 CBR_DONE2:
508 dlli = (dllmin[1] + dllmax[1]) >> 1;
509 dlli <<= 8;
510 dlli += (dllmin[0] + dllmax[0]) >> 1;
511 ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
512 return status;
513 } /* CBRDLL2 */
514
get_ddr3_info(struct ast_device * ast,struct ast2300_dram_param * param)515 static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param)
516 {
517 u32 trap, trap_AC2, trap_MRS;
518
519 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
520
521 /* Ger trap info */
522 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
523 trap_AC2 = 0x00020000 + (trap << 16);
524 trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
525 trap_MRS = 0x00000010 + (trap << 4);
526 trap_MRS |= ((trap & 0x2) << 18);
527
528 param->reg_MADJ = 0x00034C4C;
529 param->reg_SADJ = 0x00001800;
530 param->reg_DRV = 0x000000F0;
531 param->reg_PERIOD = param->dram_freq;
532 param->rodt = 0;
533
534 switch (param->dram_freq) {
535 case 336:
536 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
537 param->wodt = 0;
538 param->reg_AC1 = 0x22202725;
539 param->reg_AC2 = 0xAA007613 | trap_AC2;
540 param->reg_DQSIC = 0x000000BA;
541 param->reg_MRS = 0x04001400 | trap_MRS;
542 param->reg_EMRS = 0x00000000;
543 param->reg_IOZ = 0x00000023;
544 param->reg_DQIDLY = 0x00000074;
545 param->reg_FREQ = 0x00004DC0;
546 param->madj_max = 96;
547 param->dll2_finetune_step = 3;
548 switch (param->dram_chipid) {
549 default:
550 case AST_DRAM_512Mx16:
551 case AST_DRAM_1Gx16:
552 param->reg_AC2 = 0xAA007613 | trap_AC2;
553 break;
554 case AST_DRAM_2Gx16:
555 param->reg_AC2 = 0xAA00761C | trap_AC2;
556 break;
557 case AST_DRAM_4Gx16:
558 param->reg_AC2 = 0xAA007636 | trap_AC2;
559 break;
560 }
561 break;
562 default:
563 case 396:
564 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
565 param->wodt = 1;
566 param->reg_AC1 = 0x33302825;
567 param->reg_AC2 = 0xCC009617 | trap_AC2;
568 param->reg_DQSIC = 0x000000E2;
569 param->reg_MRS = 0x04001600 | trap_MRS;
570 param->reg_EMRS = 0x00000000;
571 param->reg_IOZ = 0x00000034;
572 param->reg_DRV = 0x000000FA;
573 param->reg_DQIDLY = 0x00000089;
574 param->reg_FREQ = 0x00005040;
575 param->madj_max = 96;
576 param->dll2_finetune_step = 4;
577
578 switch (param->dram_chipid) {
579 default:
580 case AST_DRAM_512Mx16:
581 case AST_DRAM_1Gx16:
582 param->reg_AC2 = 0xCC009617 | trap_AC2;
583 break;
584 case AST_DRAM_2Gx16:
585 param->reg_AC2 = 0xCC009622 | trap_AC2;
586 break;
587 case AST_DRAM_4Gx16:
588 param->reg_AC2 = 0xCC00963F | trap_AC2;
589 break;
590 }
591 break;
592
593 case 408:
594 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
595 param->wodt = 1;
596 param->reg_AC1 = 0x33302825;
597 param->reg_AC2 = 0xCC009617 | trap_AC2;
598 param->reg_DQSIC = 0x000000E2;
599 param->reg_MRS = 0x04001600 | trap_MRS;
600 param->reg_EMRS = 0x00000000;
601 param->reg_IOZ = 0x00000023;
602 param->reg_DRV = 0x000000FA;
603 param->reg_DQIDLY = 0x00000089;
604 param->reg_FREQ = 0x000050C0;
605 param->madj_max = 96;
606 param->dll2_finetune_step = 4;
607
608 switch (param->dram_chipid) {
609 default:
610 case AST_DRAM_512Mx16:
611 case AST_DRAM_1Gx16:
612 param->reg_AC2 = 0xCC009617 | trap_AC2;
613 break;
614 case AST_DRAM_2Gx16:
615 param->reg_AC2 = 0xCC009622 | trap_AC2;
616 break;
617 case AST_DRAM_4Gx16:
618 param->reg_AC2 = 0xCC00963F | trap_AC2;
619 break;
620 }
621
622 break;
623 case 456:
624 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
625 param->wodt = 0;
626 param->reg_AC1 = 0x33302926;
627 param->reg_AC2 = 0xCD44961A;
628 param->reg_DQSIC = 0x000000FC;
629 param->reg_MRS = 0x00081830;
630 param->reg_EMRS = 0x00000000;
631 param->reg_IOZ = 0x00000045;
632 param->reg_DQIDLY = 0x00000097;
633 param->reg_FREQ = 0x000052C0;
634 param->madj_max = 88;
635 param->dll2_finetune_step = 4;
636 break;
637 case 504:
638 ast_moutdwm(ast, 0x1E6E2020, 0x0270);
639 param->wodt = 1;
640 param->reg_AC1 = 0x33302926;
641 param->reg_AC2 = 0xDE44A61D;
642 param->reg_DQSIC = 0x00000117;
643 param->reg_MRS = 0x00081A30;
644 param->reg_EMRS = 0x00000000;
645 param->reg_IOZ = 0x070000BB;
646 param->reg_DQIDLY = 0x000000A0;
647 param->reg_FREQ = 0x000054C0;
648 param->madj_max = 79;
649 param->dll2_finetune_step = 4;
650 break;
651 case 528:
652 ast_moutdwm(ast, 0x1E6E2020, 0x0290);
653 param->wodt = 1;
654 param->rodt = 1;
655 param->reg_AC1 = 0x33302926;
656 param->reg_AC2 = 0xEF44B61E;
657 param->reg_DQSIC = 0x00000125;
658 param->reg_MRS = 0x00081A30;
659 param->reg_EMRS = 0x00000040;
660 param->reg_DRV = 0x000000F5;
661 param->reg_IOZ = 0x00000023;
662 param->reg_DQIDLY = 0x00000088;
663 param->reg_FREQ = 0x000055C0;
664 param->madj_max = 76;
665 param->dll2_finetune_step = 3;
666 break;
667 case 576:
668 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
669 param->reg_MADJ = 0x00136868;
670 param->reg_SADJ = 0x00004534;
671 param->wodt = 1;
672 param->rodt = 1;
673 param->reg_AC1 = 0x33302A37;
674 param->reg_AC2 = 0xEF56B61E;
675 param->reg_DQSIC = 0x0000013F;
676 param->reg_MRS = 0x00101A50;
677 param->reg_EMRS = 0x00000040;
678 param->reg_DRV = 0x000000FA;
679 param->reg_IOZ = 0x00000023;
680 param->reg_DQIDLY = 0x00000078;
681 param->reg_FREQ = 0x000057C0;
682 param->madj_max = 136;
683 param->dll2_finetune_step = 3;
684 break;
685 case 600:
686 ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
687 param->reg_MADJ = 0x00136868;
688 param->reg_SADJ = 0x00004534;
689 param->wodt = 1;
690 param->rodt = 1;
691 param->reg_AC1 = 0x32302A37;
692 param->reg_AC2 = 0xDF56B61F;
693 param->reg_DQSIC = 0x0000014D;
694 param->reg_MRS = 0x00101A50;
695 param->reg_EMRS = 0x00000004;
696 param->reg_DRV = 0x000000F5;
697 param->reg_IOZ = 0x00000023;
698 param->reg_DQIDLY = 0x00000078;
699 param->reg_FREQ = 0x000058C0;
700 param->madj_max = 132;
701 param->dll2_finetune_step = 3;
702 break;
703 case 624:
704 ast_moutdwm(ast, 0x1E6E2020, 0x0160);
705 param->reg_MADJ = 0x00136868;
706 param->reg_SADJ = 0x00004534;
707 param->wodt = 1;
708 param->rodt = 1;
709 param->reg_AC1 = 0x32302A37;
710 param->reg_AC2 = 0xEF56B621;
711 param->reg_DQSIC = 0x0000015A;
712 param->reg_MRS = 0x02101A50;
713 param->reg_EMRS = 0x00000004;
714 param->reg_DRV = 0x000000F5;
715 param->reg_IOZ = 0x00000034;
716 param->reg_DQIDLY = 0x00000078;
717 param->reg_FREQ = 0x000059C0;
718 param->madj_max = 128;
719 param->dll2_finetune_step = 3;
720 break;
721 } /* switch freq */
722
723 switch (param->dram_chipid) {
724 case AST_DRAM_512Mx16:
725 param->dram_config = 0x130;
726 break;
727 default:
728 case AST_DRAM_1Gx16:
729 param->dram_config = 0x131;
730 break;
731 case AST_DRAM_2Gx16:
732 param->dram_config = 0x132;
733 break;
734 case AST_DRAM_4Gx16:
735 param->dram_config = 0x133;
736 break;
737 } /* switch size */
738
739 switch (param->vram_size) {
740 default:
741 case SZ_8M:
742 param->dram_config |= 0x00;
743 break;
744 case SZ_16M:
745 param->dram_config |= 0x04;
746 break;
747 case SZ_32M:
748 param->dram_config |= 0x08;
749 break;
750 case SZ_64M:
751 param->dram_config |= 0x0c;
752 break;
753 }
754 }
755
ddr3_init(struct ast_device * ast,struct ast2300_dram_param * param)756 static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param)
757 {
758 u32 data, data2, retry = 0;
759
760 ddr3_init_start:
761 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
762 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
763 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
764 ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
765 udelay(10);
766 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
767 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
768 udelay(10);
769 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
770 udelay(10);
771
772 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
773 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
774 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
775 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
776 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
777 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
778 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
779 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
780 ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
781 ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
782 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
783 ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
784 ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
785 ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
786 ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
787 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
788 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
789 ast_moutdwm(ast, 0x1E6E0054, 0);
790 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
791 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
792 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
793 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
794 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
795 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
796 /* Wait MCLK2X lock to MCLK */
797 do {
798 data = ast_mindwm(ast, 0x1E6E001C);
799 } while (!(data & 0x08000000));
800 data = ast_mindwm(ast, 0x1E6E001C);
801 data = (data >> 8) & 0xff;
802 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
803 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
804 if ((data2 & 0xff) > param->madj_max)
805 break;
806 ast_moutdwm(ast, 0x1E6E0064, data2);
807 if (data2 & 0x00100000)
808 data2 = ((data2 & 0xff) >> 3) + 3;
809 else
810 data2 = ((data2 & 0xff) >> 2) + 5;
811 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
812 data2 += data & 0xff;
813 data = data | (data2 << 8);
814 ast_moutdwm(ast, 0x1E6E0068, data);
815 udelay(10);
816 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
817 udelay(10);
818 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
819 ast_moutdwm(ast, 0x1E6E0018, data);
820 data = data | 0x200;
821 ast_moutdwm(ast, 0x1E6E0018, data);
822 do {
823 data = ast_mindwm(ast, 0x1E6E001C);
824 } while (!(data & 0x08000000));
825
826 data = ast_mindwm(ast, 0x1E6E001C);
827 data = (data >> 8) & 0xff;
828 }
829 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
830 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
831 ast_moutdwm(ast, 0x1E6E0018, data);
832
833 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
834 ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
835 udelay(50);
836 /* Mode Register Setting */
837 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
838 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
839 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
840 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
841 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
842 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
843 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
844 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
845 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
846
847 ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
848 data = 0;
849 if (param->wodt)
850 data = 0x300;
851 if (param->rodt)
852 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
853 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
854
855 /* Calibrate the DQSI delay */
856 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
857 goto ddr3_init_start;
858
859 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
860 /* ECC Memory Initialization */
861 #ifdef ECC
862 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
863 ast_moutdwm(ast, 0x1E6E0070, 0x221);
864 do {
865 data = ast_mindwm(ast, 0x1E6E0070);
866 } while (!(data & 0x00001000));
867 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
868 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
869 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
870 #endif
871 }
872
get_ddr2_info(struct ast_device * ast,struct ast2300_dram_param * param)873 static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param)
874 {
875 u32 trap, trap_AC2, trap_MRS;
876
877 ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
878
879 /* Ger trap info */
880 trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
881 trap_AC2 = (trap << 20) | (trap << 16);
882 trap_AC2 += 0x00110000;
883 trap_MRS = 0x00000040 | (trap << 4);
884
885 param->reg_MADJ = 0x00034C4C;
886 param->reg_SADJ = 0x00001800;
887 param->reg_DRV = 0x000000F0;
888 param->reg_PERIOD = param->dram_freq;
889 param->rodt = 0;
890
891 switch (param->dram_freq) {
892 case 264:
893 ast_moutdwm(ast, 0x1E6E2020, 0x0130);
894 param->wodt = 0;
895 param->reg_AC1 = 0x11101513;
896 param->reg_AC2 = 0x78117011;
897 param->reg_DQSIC = 0x00000092;
898 param->reg_MRS = 0x00000842;
899 param->reg_EMRS = 0x00000000;
900 param->reg_DRV = 0x000000F0;
901 param->reg_IOZ = 0x00000034;
902 param->reg_DQIDLY = 0x0000005A;
903 param->reg_FREQ = 0x00004AC0;
904 param->madj_max = 138;
905 param->dll2_finetune_step = 3;
906 break;
907 case 336:
908 ast_moutdwm(ast, 0x1E6E2020, 0x0190);
909 param->wodt = 1;
910 param->reg_AC1 = 0x22202613;
911 param->reg_AC2 = 0xAA009016 | trap_AC2;
912 param->reg_DQSIC = 0x000000BA;
913 param->reg_MRS = 0x00000A02 | trap_MRS;
914 param->reg_EMRS = 0x00000040;
915 param->reg_DRV = 0x000000FA;
916 param->reg_IOZ = 0x00000034;
917 param->reg_DQIDLY = 0x00000074;
918 param->reg_FREQ = 0x00004DC0;
919 param->madj_max = 96;
920 param->dll2_finetune_step = 3;
921 switch (param->dram_chipid) {
922 default:
923 case AST_DRAM_512Mx16:
924 param->reg_AC2 = 0xAA009012 | trap_AC2;
925 break;
926 case AST_DRAM_1Gx16:
927 param->reg_AC2 = 0xAA009016 | trap_AC2;
928 break;
929 case AST_DRAM_2Gx16:
930 param->reg_AC2 = 0xAA009023 | trap_AC2;
931 break;
932 case AST_DRAM_4Gx16:
933 param->reg_AC2 = 0xAA00903B | trap_AC2;
934 break;
935 }
936 break;
937 default:
938 case 396:
939 ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
940 param->wodt = 1;
941 param->rodt = 0;
942 param->reg_AC1 = 0x33302714;
943 param->reg_AC2 = 0xCC00B01B | trap_AC2;
944 param->reg_DQSIC = 0x000000E2;
945 param->reg_MRS = 0x00000C02 | trap_MRS;
946 param->reg_EMRS = 0x00000040;
947 param->reg_DRV = 0x000000FA;
948 param->reg_IOZ = 0x00000034;
949 param->reg_DQIDLY = 0x00000089;
950 param->reg_FREQ = 0x00005040;
951 param->madj_max = 96;
952 param->dll2_finetune_step = 4;
953
954 switch (param->dram_chipid) {
955 case AST_DRAM_512Mx16:
956 param->reg_AC2 = 0xCC00B016 | trap_AC2;
957 break;
958 default:
959 case AST_DRAM_1Gx16:
960 param->reg_AC2 = 0xCC00B01B | trap_AC2;
961 break;
962 case AST_DRAM_2Gx16:
963 param->reg_AC2 = 0xCC00B02B | trap_AC2;
964 break;
965 case AST_DRAM_4Gx16:
966 param->reg_AC2 = 0xCC00B03F | trap_AC2;
967 break;
968 }
969
970 break;
971
972 case 408:
973 ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
974 param->wodt = 1;
975 param->rodt = 0;
976 param->reg_AC1 = 0x33302714;
977 param->reg_AC2 = 0xCC00B01B | trap_AC2;
978 param->reg_DQSIC = 0x000000E2;
979 param->reg_MRS = 0x00000C02 | trap_MRS;
980 param->reg_EMRS = 0x00000040;
981 param->reg_DRV = 0x000000FA;
982 param->reg_IOZ = 0x00000034;
983 param->reg_DQIDLY = 0x00000089;
984 param->reg_FREQ = 0x000050C0;
985 param->madj_max = 96;
986 param->dll2_finetune_step = 4;
987
988 switch (param->dram_chipid) {
989 case AST_DRAM_512Mx16:
990 param->reg_AC2 = 0xCC00B016 | trap_AC2;
991 break;
992 default:
993 case AST_DRAM_1Gx16:
994 param->reg_AC2 = 0xCC00B01B | trap_AC2;
995 break;
996 case AST_DRAM_2Gx16:
997 param->reg_AC2 = 0xCC00B02B | trap_AC2;
998 break;
999 case AST_DRAM_4Gx16:
1000 param->reg_AC2 = 0xCC00B03F | trap_AC2;
1001 break;
1002 }
1003
1004 break;
1005 case 456:
1006 ast_moutdwm(ast, 0x1E6E2020, 0x0230);
1007 param->wodt = 0;
1008 param->reg_AC1 = 0x33302815;
1009 param->reg_AC2 = 0xCD44B01E;
1010 param->reg_DQSIC = 0x000000FC;
1011 param->reg_MRS = 0x00000E72;
1012 param->reg_EMRS = 0x00000000;
1013 param->reg_DRV = 0x00000000;
1014 param->reg_IOZ = 0x00000034;
1015 param->reg_DQIDLY = 0x00000097;
1016 param->reg_FREQ = 0x000052C0;
1017 param->madj_max = 88;
1018 param->dll2_finetune_step = 3;
1019 break;
1020 case 504:
1021 ast_moutdwm(ast, 0x1E6E2020, 0x0261);
1022 param->wodt = 1;
1023 param->rodt = 1;
1024 param->reg_AC1 = 0x33302815;
1025 param->reg_AC2 = 0xDE44C022;
1026 param->reg_DQSIC = 0x00000117;
1027 param->reg_MRS = 0x00000E72;
1028 param->reg_EMRS = 0x00000040;
1029 param->reg_DRV = 0x0000000A;
1030 param->reg_IOZ = 0x00000045;
1031 param->reg_DQIDLY = 0x000000A0;
1032 param->reg_FREQ = 0x000054C0;
1033 param->madj_max = 79;
1034 param->dll2_finetune_step = 3;
1035 break;
1036 case 528:
1037 ast_moutdwm(ast, 0x1E6E2020, 0x0120);
1038 param->wodt = 1;
1039 param->rodt = 1;
1040 param->reg_AC1 = 0x33302815;
1041 param->reg_AC2 = 0xEF44D024;
1042 param->reg_DQSIC = 0x00000125;
1043 param->reg_MRS = 0x00000E72;
1044 param->reg_EMRS = 0x00000004;
1045 param->reg_DRV = 0x000000F9;
1046 param->reg_IOZ = 0x00000045;
1047 param->reg_DQIDLY = 0x000000A7;
1048 param->reg_FREQ = 0x000055C0;
1049 param->madj_max = 76;
1050 param->dll2_finetune_step = 3;
1051 break;
1052 case 552:
1053 ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
1054 param->wodt = 1;
1055 param->rodt = 1;
1056 param->reg_AC1 = 0x43402915;
1057 param->reg_AC2 = 0xFF44E025;
1058 param->reg_DQSIC = 0x00000132;
1059 param->reg_MRS = 0x00000E72;
1060 param->reg_EMRS = 0x00000040;
1061 param->reg_DRV = 0x0000000A;
1062 param->reg_IOZ = 0x00000045;
1063 param->reg_DQIDLY = 0x000000AD;
1064 param->reg_FREQ = 0x000056C0;
1065 param->madj_max = 76;
1066 param->dll2_finetune_step = 3;
1067 break;
1068 case 576:
1069 ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1070 param->wodt = 1;
1071 param->rodt = 1;
1072 param->reg_AC1 = 0x43402915;
1073 param->reg_AC2 = 0xFF44E027;
1074 param->reg_DQSIC = 0x0000013F;
1075 param->reg_MRS = 0x00000E72;
1076 param->reg_EMRS = 0x00000004;
1077 param->reg_DRV = 0x000000F5;
1078 param->reg_IOZ = 0x00000045;
1079 param->reg_DQIDLY = 0x000000B3;
1080 param->reg_FREQ = 0x000057C0;
1081 param->madj_max = 76;
1082 param->dll2_finetune_step = 3;
1083 break;
1084 }
1085
1086 switch (param->dram_chipid) {
1087 case AST_DRAM_512Mx16:
1088 param->dram_config = 0x100;
1089 break;
1090 default:
1091 case AST_DRAM_1Gx16:
1092 param->dram_config = 0x121;
1093 break;
1094 case AST_DRAM_2Gx16:
1095 param->dram_config = 0x122;
1096 break;
1097 case AST_DRAM_4Gx16:
1098 param->dram_config = 0x123;
1099 break;
1100 } /* switch size */
1101
1102 switch (param->vram_size) {
1103 default:
1104 case SZ_8M:
1105 param->dram_config |= 0x00;
1106 break;
1107 case SZ_16M:
1108 param->dram_config |= 0x04;
1109 break;
1110 case SZ_32M:
1111 param->dram_config |= 0x08;
1112 break;
1113 case SZ_64M:
1114 param->dram_config |= 0x0c;
1115 break;
1116 }
1117 }
1118
ddr2_init(struct ast_device * ast,struct ast2300_dram_param * param)1119 static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param)
1120 {
1121 u32 data, data2, retry = 0;
1122
1123 ddr2_init_start:
1124 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1125 ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1126 ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1127 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1128 ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1129 udelay(10);
1130 ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1131 udelay(10);
1132
1133 ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1134 ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1135 ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1136 ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1137 ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1138 ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1139 ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1140 ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1141 ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
1142 ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
1143 ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1144 ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
1145 ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
1146 ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
1147 ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
1148 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1149 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1150 ast_moutdwm(ast, 0x1E6E0054, 0);
1151 ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1152 ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1153 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1154 ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1155 ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1156 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1157
1158 /* Wait MCLK2X lock to MCLK */
1159 do {
1160 data = ast_mindwm(ast, 0x1E6E001C);
1161 } while (!(data & 0x08000000));
1162 data = ast_mindwm(ast, 0x1E6E001C);
1163 data = (data >> 8) & 0xff;
1164 while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1165 data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1166 if ((data2 & 0xff) > param->madj_max)
1167 break;
1168 ast_moutdwm(ast, 0x1E6E0064, data2);
1169 if (data2 & 0x00100000)
1170 data2 = ((data2 & 0xff) >> 3) + 3;
1171 else
1172 data2 = ((data2 & 0xff) >> 2) + 5;
1173 data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1174 data2 += data & 0xff;
1175 data = data | (data2 << 8);
1176 ast_moutdwm(ast, 0x1E6E0068, data);
1177 udelay(10);
1178 ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1179 udelay(10);
1180 data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1181 ast_moutdwm(ast, 0x1E6E0018, data);
1182 data = data | 0x200;
1183 ast_moutdwm(ast, 0x1E6E0018, data);
1184 do {
1185 data = ast_mindwm(ast, 0x1E6E001C);
1186 } while (!(data & 0x08000000));
1187
1188 data = ast_mindwm(ast, 0x1E6E001C);
1189 data = (data >> 8) & 0xff;
1190 }
1191 ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
1192 data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1193 ast_moutdwm(ast, 0x1E6E0018, data);
1194
1195 ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1196 ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1197 udelay(50);
1198 /* Mode Register Setting */
1199 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1200 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1201 ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1202 ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1203 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1204 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1205
1206 ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1207 ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1208 ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1209 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1210 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1211 ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1212 ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1213
1214 ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1215 data = 0;
1216 if (param->wodt)
1217 data = 0x500;
1218 if (param->rodt)
1219 data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1220 ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1221 ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1222
1223 /* Calibrate the DQSI delay */
1224 if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1225 goto ddr2_init_start;
1226
1227 /* ECC Memory Initialization */
1228 #ifdef ECC
1229 ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1230 ast_moutdwm(ast, 0x1E6E0070, 0x221);
1231 do {
1232 data = ast_mindwm(ast, 0x1E6E0070);
1233 } while (!(data & 0x00001000));
1234 ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1235 ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1236 ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1237 #endif
1238 }
1239
ast_post_chip_2300(struct ast_device * ast)1240 static void ast_post_chip_2300(struct ast_device *ast)
1241 {
1242 struct ast2300_dram_param param;
1243 u32 temp;
1244 u8 reg;
1245
1246 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
1247 if ((reg & 0x80) == 0) {/* vga only */
1248 ast_write32(ast, 0xf004, 0x1e6e0000);
1249 ast_write32(ast, 0xf000, 0x1);
1250 ast_write32(ast, 0x12000, 0x1688a8a8);
1251 do {
1252 ;
1253 } while (ast_read32(ast, 0x12000) != 0x1);
1254
1255 ast_write32(ast, 0x10000, 0xfc600309);
1256 do {
1257 ;
1258 } while (ast_read32(ast, 0x10000) != 0x1);
1259
1260 /* Slow down CPU/AHB CLK in VGA only mode */
1261 temp = ast_read32(ast, 0x12008);
1262 temp |= 0x73;
1263 ast_write32(ast, 0x12008, temp);
1264
1265 param.dram_freq = 396;
1266 param.dram_type = AST_DDR3;
1267 temp = ast_mindwm(ast, 0x1e6e2070);
1268 if (temp & 0x01000000)
1269 param.dram_type = AST_DDR2;
1270 switch (temp & 0x18000000) {
1271 case 0:
1272 param.dram_chipid = AST_DRAM_512Mx16;
1273 break;
1274 default:
1275 case 0x08000000:
1276 param.dram_chipid = AST_DRAM_1Gx16;
1277 break;
1278 case 0x10000000:
1279 param.dram_chipid = AST_DRAM_2Gx16;
1280 break;
1281 case 0x18000000:
1282 param.dram_chipid = AST_DRAM_4Gx16;
1283 break;
1284 }
1285 switch (temp & 0x0c) {
1286 default:
1287 case 0x00:
1288 param.vram_size = SZ_8M;
1289 break;
1290 case 0x04:
1291 param.vram_size = SZ_16M;
1292 break;
1293 case 0x08:
1294 param.vram_size = SZ_32M;
1295 break;
1296 case 0x0c:
1297 param.vram_size = SZ_64M;
1298 break;
1299 }
1300
1301 if (param.dram_type == AST_DDR3) {
1302 get_ddr3_info(ast, ¶m);
1303 ddr3_init(ast, ¶m);
1304 } else {
1305 get_ddr2_info(ast, ¶m);
1306 ddr2_init(ast, ¶m);
1307 }
1308
1309 temp = ast_mindwm(ast, 0x1e6e2040);
1310 ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
1311 }
1312
1313 /* wait ready */
1314 do {
1315 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
1316 } while ((reg & 0x40) == 0);
1317 }
1318
ast_2300_post(struct ast_device * ast)1319 int ast_2300_post(struct ast_device *ast)
1320 {
1321 ast_2300_set_def_ext_reg(ast);
1322
1323 if (ast->config_mode == ast_use_p2a) {
1324 ast_post_chip_2300(ast);
1325 ast_init_3rdtx(ast);
1326 } else {
1327 if (ast->tx_chip == AST_TX_SIL164) {
1328 /* Enable DVO */
1329 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
1330 }
1331 }
1332
1333 return 0;
1334 }
1335
1336 /*
1337 * Device initialization
1338 */
1339
ast_2300_detect_tx_chip(struct ast_device * ast)1340 void ast_2300_detect_tx_chip(struct ast_device *ast)
1341 {
1342 enum ast_tx_chip tx_chip = AST_TX_NONE;
1343 struct drm_device *dev = &ast->base;
1344 u8 vgacrd1;
1345
1346 /*
1347 * On AST GEN4+, look at the configuration set by the SoC in
1348 * the SOC scratch register #1 bits 11:8 (interestingly marked
1349 * as "reserved" in the spec)
1350 */
1351 vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1,
1352 AST_IO_VGACRD1_TX_TYPE_MASK);
1353 switch (vgacrd1) {
1354 /*
1355 * GEN4 to GEN6
1356 */
1357 case AST_IO_VGACRD1_TX_SIL164_VBIOS:
1358 tx_chip = AST_TX_SIL164;
1359 break;
1360 case AST_IO_VGACRD1_TX_DP501_VBIOS:
1361 ast->dp501_fw_addr = drmm_kzalloc(dev, SZ_32K, GFP_KERNEL);
1362 if (ast->dp501_fw_addr) {
1363 /* backup firmware */
1364 if (ast_backup_fw(ast, ast->dp501_fw_addr, SZ_32K)) {
1365 drmm_kfree(dev, ast->dp501_fw_addr);
1366 ast->dp501_fw_addr = NULL;
1367 }
1368 }
1369 fallthrough;
1370 case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW:
1371 tx_chip = AST_TX_DP501;
1372 break;
1373 /*
1374 * GEN7+
1375 */
1376 case AST_IO_VGACRD1_TX_ASTDP:
1377 tx_chip = AST_TX_ASTDP;
1378 break;
1379 /*
1380 * Several of the listed TX chips are not explicitly supported
1381 * by the ast driver. If these exist in real-world devices, they
1382 * are most likely reported as VGA or SIL164 outputs. We warn here
1383 * to get bug reports for these devices. If none come in for some
1384 * time, we can begin to fail device probing on these values.
1385 */
1386 case AST_IO_VGACRD1_TX_ITE66121_VBIOS:
1387 drm_warn(dev, "ITE IT66121 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast));
1388 break;
1389 case AST_IO_VGACRD1_TX_CH7003_VBIOS:
1390 drm_warn(dev, "Chrontel CH7003 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast));
1391 break;
1392 case AST_IO_VGACRD1_TX_ANX9807_VBIOS:
1393 drm_warn(dev, "Analogix ANX9807 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast));
1394 break;
1395 }
1396
1397 __ast_device_set_tx_chip(ast, tx_chip);
1398 }
1399
ast_2300_detect_widescreen(struct ast_device * ast)1400 static void ast_2300_detect_widescreen(struct ast_device *ast)
1401 {
1402 if (__ast_2100_detect_wsxga_p(ast) || ast->chip == AST1300) {
1403 ast->support_wsxga_p = true;
1404 ast->support_fullhd = true;
1405 }
1406 if (__ast_2100_detect_wuxga(ast))
1407 ast->support_wuxga = true;
1408 }
1409
1410 static const struct ast_device_quirks ast_2300_device_quirks = {
1411 .crtc_mem_req_threshold_low = 96,
1412 .crtc_mem_req_threshold_high = 120,
1413 };
1414
ast_2300_device_create(struct pci_dev * pdev,const struct drm_driver * drv,enum ast_chip chip,enum ast_config_mode config_mode,void __iomem * regs,void __iomem * ioregs,bool need_post)1415 struct drm_device *ast_2300_device_create(struct pci_dev *pdev,
1416 const struct drm_driver *drv,
1417 enum ast_chip chip,
1418 enum ast_config_mode config_mode,
1419 void __iomem *regs,
1420 void __iomem *ioregs,
1421 bool need_post)
1422 {
1423 struct drm_device *dev;
1424 struct ast_device *ast;
1425 int ret;
1426
1427 ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base);
1428 if (IS_ERR(ast))
1429 return ERR_CAST(ast);
1430 dev = &ast->base;
1431
1432 ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2300_device_quirks);
1433
1434 ast->dclk_table = ast_2000_dclk_table;
1435
1436 ast_2300_detect_tx_chip(ast);
1437
1438 if (need_post) {
1439 ret = ast_post_gpu(ast);
1440 if (ret)
1441 return ERR_PTR(ret);
1442 }
1443
1444 ret = ast_mm_init(ast);
1445 if (ret)
1446 return ERR_PTR(ret);
1447
1448 /* map reserved buffer */
1449 ast->dp501_fw_buf = NULL;
1450 if (ast->vram_size < pci_resource_len(pdev, 0)) {
1451 ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0);
1452 if (!ast->dp501_fw_buf)
1453 drm_info(dev, "failed to map reserved buffer!\n");
1454 }
1455
1456 ast_2300_detect_widescreen(ast);
1457
1458 ret = ast_mode_config_init(ast);
1459 if (ret)
1460 return ERR_PTR(ret);
1461
1462 return dev;
1463 }
1464