Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/drm/ast/ast_2500.c
26493 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 <drm/drm_print.h>
32
33
#include "ast_drv.h"
34
#include "ast_post.h"
35
36
/*
37
* POST
38
*/
39
40
/*
41
* AST2500 DRAM settings modules
42
*/
43
44
#define REGTBL_NUM 17
45
#define REGIDX_010 0
46
#define REGIDX_014 1
47
#define REGIDX_018 2
48
#define REGIDX_020 3
49
#define REGIDX_024 4
50
#define REGIDX_02C 5
51
#define REGIDX_030 6
52
#define REGIDX_214 7
53
#define REGIDX_2E0 8
54
#define REGIDX_2E4 9
55
#define REGIDX_2E8 10
56
#define REGIDX_2EC 11
57
#define REGIDX_2F0 12
58
#define REGIDX_2F4 13
59
#define REGIDX_2F8 14
60
#define REGIDX_RFC 15
61
#define REGIDX_PLL 16
62
63
static const u32 ast2500_ddr3_1600_timing_table[REGTBL_NUM] = {
64
0x64604D38, /* 0x010 */
65
0x29690599, /* 0x014 */
66
0x00000300, /* 0x018 */
67
0x00000000, /* 0x020 */
68
0x00000000, /* 0x024 */
69
0x02181E70, /* 0x02C */
70
0x00000040, /* 0x030 */
71
0x00000024, /* 0x214 */
72
0x02001300, /* 0x2E0 */
73
0x0E0000A0, /* 0x2E4 */
74
0x000E001B, /* 0x2E8 */
75
0x35B8C105, /* 0x2EC */
76
0x08090408, /* 0x2F0 */
77
0x9B000800, /* 0x2F4 */
78
0x0E400A00, /* 0x2F8 */
79
0x9971452F, /* tRFC */
80
0x000071C1 /* PLL */
81
};
82
83
static const u32 ast2500_ddr4_1600_timing_table[REGTBL_NUM] = {
84
0x63604E37, /* 0x010 */
85
0xE97AFA99, /* 0x014 */
86
0x00019000, /* 0x018 */
87
0x08000000, /* 0x020 */
88
0x00000400, /* 0x024 */
89
0x00000410, /* 0x02C */
90
0x00000101, /* 0x030 */
91
0x00000024, /* 0x214 */
92
0x03002900, /* 0x2E0 */
93
0x0E0000A0, /* 0x2E4 */
94
0x000E001C, /* 0x2E8 */
95
0x35B8C106, /* 0x2EC */
96
0x08080607, /* 0x2F0 */
97
0x9B000900, /* 0x2F4 */
98
0x0E400A00, /* 0x2F8 */
99
0x99714545, /* tRFC */
100
0x000071C1 /* PLL */
101
};
102
103
#define TIMEOUT 5000000
104
105
void ast_2500_patch_ahb(void __iomem *regs)
106
{
107
u32 data;
108
109
/* Clear bus lock condition */
110
__ast_moutdwm(regs, 0x1e600000, 0xAEED1A03);
111
__ast_moutdwm(regs, 0x1e600084, 0x00010000);
112
__ast_moutdwm(regs, 0x1e600088, 0x00000000);
113
__ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
114
115
data = __ast_mindwm(regs, 0x1e6e2070);
116
if (data & 0x08000000) { /* check fast reset */
117
/*
118
* If "Fast restet" is enabled for ARM-ICE debugger,
119
* then WDT needs to enable, that
120
* WDT04 is WDT#1 Reload reg.
121
* WDT08 is WDT#1 counter restart reg to avoid system deadlock
122
* WDT0C is WDT#1 control reg
123
* [6:5]:= 01:Full chip
124
* [4]:= 1:1MHz clock source
125
* [1]:= 1:WDT will be cleeared and disabled after timeout occurs
126
* [0]:= 1:WDT enable
127
*/
128
__ast_moutdwm(regs, 0x1E785004, 0x00000010);
129
__ast_moutdwm(regs, 0x1E785008, 0x00004755);
130
__ast_moutdwm(regs, 0x1E78500c, 0x00000033);
131
udelay(1000);
132
}
133
134
do {
135
__ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
136
data = __ast_mindwm(regs, 0x1e6e2000);
137
} while (data != 1);
138
139
__ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */
140
}
141
142
static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
143
{
144
return mmc_test(ast, datagen, 0x85);
145
}
146
147
static bool cbr_test_2500(struct ast_device *ast)
148
{
149
ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
150
ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
151
if (!mmc_test_burst(ast, 0))
152
return false;
153
if (!mmc_test_single_2500(ast, 0))
154
return false;
155
return true;
156
}
157
158
static bool ddr_test_2500(struct ast_device *ast)
159
{
160
ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
161
ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
162
if (!mmc_test_burst(ast, 0))
163
return false;
164
if (!mmc_test_burst(ast, 1))
165
return false;
166
if (!mmc_test_burst(ast, 2))
167
return false;
168
if (!mmc_test_burst(ast, 3))
169
return false;
170
if (!mmc_test_single_2500(ast, 0))
171
return false;
172
return true;
173
}
174
175
static void ddr_init_common_2500(struct ast_device *ast)
176
{
177
ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
178
ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
179
ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF);
180
ast_moutdwm(ast, 0x1E6E0040, 0x88448844);
181
ast_moutdwm(ast, 0x1E6E0044, 0x24422288);
182
ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
183
ast_moutdwm(ast, 0x1E6E004C, 0x22222222);
184
ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
185
ast_moutdwm(ast, 0x1E6E0208, 0x00000000);
186
ast_moutdwm(ast, 0x1E6E0218, 0x00000000);
187
ast_moutdwm(ast, 0x1E6E0220, 0x00000000);
188
ast_moutdwm(ast, 0x1E6E0228, 0x00000000);
189
ast_moutdwm(ast, 0x1E6E0230, 0x00000000);
190
ast_moutdwm(ast, 0x1E6E02A8, 0x00000000);
191
ast_moutdwm(ast, 0x1E6E02B0, 0x00000000);
192
ast_moutdwm(ast, 0x1E6E0240, 0x86000000);
193
ast_moutdwm(ast, 0x1E6E0244, 0x00008600);
194
ast_moutdwm(ast, 0x1E6E0248, 0x80000000);
195
ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
196
}
197
198
static void ddr_phy_init_2500(struct ast_device *ast)
199
{
200
u32 data, pass, timecnt;
201
202
pass = 0;
203
ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
204
while (!pass) {
205
for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
206
data = ast_mindwm(ast, 0x1E6E0060) & 0x1;
207
if (!data)
208
break;
209
}
210
if (timecnt != TIMEOUT) {
211
data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000;
212
if (!data)
213
pass = 1;
214
}
215
if (!pass) {
216
ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
217
udelay(10); /* delay 10 us */
218
ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
219
}
220
}
221
222
ast_moutdwm(ast, 0x1E6E0060, 0x00000006);
223
}
224
225
/*
226
* Check DRAM Size
227
* 1Gb : 0x80000000 ~ 0x87FFFFFF
228
* 2Gb : 0x80000000 ~ 0x8FFFFFFF
229
* 4Gb : 0x80000000 ~ 0x9FFFFFFF
230
* 8Gb : 0x80000000 ~ 0xBFFFFFFF
231
*/
232
static void check_dram_size_2500(struct ast_device *ast, u32 tRFC)
233
{
234
u32 reg_04, reg_14;
235
236
reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc;
237
reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00;
238
239
ast_moutdwm(ast, 0xA0100000, 0x41424344);
240
ast_moutdwm(ast, 0x90100000, 0x35363738);
241
ast_moutdwm(ast, 0x88100000, 0x292A2B2C);
242
ast_moutdwm(ast, 0x80100000, 0x1D1E1F10);
243
244
/* Check 8Gbit */
245
if (ast_mindwm(ast, 0xA0100000) == 0x41424344) {
246
reg_04 |= 0x03;
247
reg_14 |= (tRFC >> 24) & 0xFF;
248
/* Check 4Gbit */
249
} else if (ast_mindwm(ast, 0x90100000) == 0x35363738) {
250
reg_04 |= 0x02;
251
reg_14 |= (tRFC >> 16) & 0xFF;
252
/* Check 2Gbit */
253
} else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) {
254
reg_04 |= 0x01;
255
reg_14 |= (tRFC >> 8) & 0xFF;
256
} else {
257
reg_14 |= tRFC & 0xFF;
258
}
259
ast_moutdwm(ast, 0x1E6E0004, reg_04);
260
ast_moutdwm(ast, 0x1E6E0014, reg_14);
261
}
262
263
static void enable_cache_2500(struct ast_device *ast)
264
{
265
u32 reg_04, data;
266
267
reg_04 = ast_mindwm(ast, 0x1E6E0004);
268
ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000);
269
270
do
271
data = ast_mindwm(ast, 0x1E6E0004);
272
while (!(data & 0x80000));
273
ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
274
}
275
276
static void set_mpll_2500(struct ast_device *ast)
277
{
278
u32 addr, data, param;
279
280
/* Reset MMC */
281
ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
282
ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
283
for (addr = 0x1e6e0004; addr < 0x1e6e0090;) {
284
ast_moutdwm(ast, addr, 0x0);
285
addr += 4;
286
}
287
ast_moutdwm(ast, 0x1E6E0034, 0x00020000);
288
289
ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
290
data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000;
291
if (data) {
292
/* CLKIN = 25MHz */
293
param = 0x930023E0;
294
ast_moutdwm(ast, 0x1E6E2160, 0x00011320);
295
} else {
296
/* CLKIN = 24MHz */
297
param = 0x93002400;
298
}
299
ast_moutdwm(ast, 0x1E6E2020, param);
300
udelay(100);
301
}
302
303
static void reset_mmc_2500(struct ast_device *ast)
304
{
305
ast_moutdwm(ast, 0x1E78505C, 0x00000004);
306
ast_moutdwm(ast, 0x1E785044, 0x00000001);
307
ast_moutdwm(ast, 0x1E785048, 0x00004755);
308
ast_moutdwm(ast, 0x1E78504C, 0x00000013);
309
mdelay(100);
310
ast_moutdwm(ast, 0x1E785054, 0x00000077);
311
ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
312
}
313
314
static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table)
315
{
316
ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
317
ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
318
ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
319
ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
320
ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
321
ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
322
ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
323
ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
324
325
/* DDR PHY Setting */
326
ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE);
327
ast_moutdwm(ast, 0x1E6E0204, 0x00001001);
328
ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
329
ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
330
ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
331
ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
332
ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
333
ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
334
ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
335
ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
336
ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
337
ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
338
ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
339
ast_moutdwm(ast, 0x1E6E02C0, 0x00000006);
340
341
/* Controller Setting */
342
ast_moutdwm(ast, 0x1E6E0034, 0x00020091);
343
344
/* Wait DDR PHY init done */
345
ddr_phy_init_2500(ast);
346
347
ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
348
ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
349
ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
350
351
check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
352
enable_cache_2500(ast);
353
ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
354
ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
355
}
356
357
static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table)
358
{
359
u32 data, data2, pass, retrycnt;
360
u32 ddr_vref, phy_vref;
361
u32 min_ddr_vref = 0, min_phy_vref = 0;
362
u32 max_ddr_vref = 0, max_phy_vref = 0;
363
364
ast_moutdwm(ast, 0x1E6E0004, 0x00000313);
365
ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
366
ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
367
ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
368
ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */
369
ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */
370
ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
371
ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */
372
373
/* DDR PHY Setting */
374
ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE);
375
ast_moutdwm(ast, 0x1E6E0204, 0x09002000);
376
ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
377
ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
378
ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
379
ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
380
ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
381
ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
382
ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
383
ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
384
ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
385
ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
386
ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
387
ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C);
388
ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E);
389
390
/* Controller Setting */
391
ast_moutdwm(ast, 0x1E6E0034, 0x0001A991);
392
393
/* Train PHY Vref first */
394
pass = 0;
395
396
for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
397
max_phy_vref = 0x0;
398
pass = 0;
399
ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06);
400
for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
401
ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
402
ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
403
ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8));
404
/* Fire DFI Init */
405
ddr_phy_init_2500(ast);
406
ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
407
if (cbr_test_2500(ast)) {
408
pass++;
409
data = ast_mindwm(ast, 0x1E6E03D0);
410
data2 = data >> 8;
411
data = data & 0xff;
412
if (data > data2)
413
data = data2;
414
if (max_phy_vref < data) {
415
max_phy_vref = data;
416
min_phy_vref = phy_vref;
417
}
418
} else if (pass > 0) {
419
break;
420
}
421
}
422
}
423
ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8));
424
425
/* Train DDR Vref next */
426
pass = 0;
427
428
for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
429
min_ddr_vref = 0xFF;
430
max_ddr_vref = 0x0;
431
pass = 0;
432
for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
433
ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
434
ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
435
ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
436
/* Fire DFI Init */
437
ddr_phy_init_2500(ast);
438
ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
439
if (cbr_test_2500(ast)) {
440
pass++;
441
if (min_ddr_vref > ddr_vref)
442
min_ddr_vref = ddr_vref;
443
if (max_ddr_vref < ddr_vref)
444
max_ddr_vref = ddr_vref;
445
} else if (pass != 0) {
446
break;
447
}
448
}
449
}
450
451
ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
452
ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
453
ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
454
ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
455
456
/* Wait DDR PHY init done */
457
ddr_phy_init_2500(ast);
458
459
ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
460
ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
461
ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
462
463
check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
464
enable_cache_2500(ast);
465
ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
466
ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
467
}
468
469
static bool ast_dram_init_2500(struct ast_device *ast)
470
{
471
u32 data;
472
u32 max_tries = 5;
473
474
do {
475
if (max_tries-- == 0)
476
return false;
477
set_mpll_2500(ast);
478
reset_mmc_2500(ast);
479
ddr_init_common_2500(ast);
480
481
data = ast_mindwm(ast, 0x1E6E2070);
482
if (data & 0x01000000)
483
ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
484
else
485
ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
486
} while (!ddr_test_2500(ast));
487
488
ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41);
489
490
/* Patch code */
491
data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF;
492
ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000);
493
494
return true;
495
}
496
497
static void ast_post_chip_2500(struct ast_device *ast)
498
{
499
struct drm_device *dev = &ast->base;
500
u32 temp;
501
u8 reg;
502
503
reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
504
if ((reg & AST_IO_VGACRD0_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
505
/* Clear bus lock condition */
506
ast_2500_patch_ahb(ast->regs);
507
508
/* Disable watchdog */
509
ast_moutdwm(ast, 0x1E78502C, 0x00000000);
510
ast_moutdwm(ast, 0x1E78504C, 0x00000000);
511
512
/*
513
* Reset USB port to patch USB unknown device issue
514
* SCU90 is Multi-function Pin Control #5
515
* [29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub
516
* port).
517
* SCU94 is Multi-function Pin Control #6
518
* [14:13]:= 1x:USB2.0 Host2 controller
519
* SCU70 is Hardware Strap reg
520
* [23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by
521
* [18]: 0(24)/1(48) MHz)
522
* SCU7C is Write clear reg to SCU70
523
* [23]:= write 1 and then SCU70[23] will be clear as 0b.
524
*/
525
ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
526
ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
527
if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
528
ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
529
mdelay(100);
530
ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
531
}
532
/* Modify eSPI reset pin */
533
temp = ast_mindwm(ast, 0x1E6E2070);
534
if (temp & 0x02000000)
535
ast_moutdwm(ast, 0x1E6E207C, 0x00004000);
536
537
/* Slow down CPU/AHB CLK in VGA only mode */
538
temp = ast_read32(ast, 0x12008);
539
temp |= 0x73;
540
ast_write32(ast, 0x12008, temp);
541
542
if (!ast_dram_init_2500(ast))
543
drm_err(dev, "DRAM init failed !\n");
544
545
temp = ast_mindwm(ast, 0x1e6e2040);
546
ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
547
}
548
549
/* wait ready */
550
do {
551
reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
552
} while ((reg & 0x40) == 0);
553
}
554
555
int ast_2500_post(struct ast_device *ast)
556
{
557
ast_2300_set_def_ext_reg(ast);
558
559
if (ast->config_mode == ast_use_p2a) {
560
ast_post_chip_2500(ast);
561
} else {
562
if (ast->tx_chip == AST_TX_SIL164) {
563
/* Enable DVO */
564
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
565
}
566
}
567
568
return 0;
569
}
570
571