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