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
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
ast_2500_patch_ahb(void __iomem * regs)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
mmc_test_single_2500(struct ast_device * ast,u32 datagen)142 static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
143 {
144 return mmc_test(ast, datagen, 0x85);
145 }
146
cbr_test_2500(struct ast_device * ast)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
ddr_test_2500(struct ast_device * ast)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
ddr_init_common_2500(struct ast_device * ast)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
ddr_phy_init_2500(struct ast_device * ast)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 */
check_dram_size_2500(struct ast_device * ast,u32 tRFC)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
enable_cache_2500(struct ast_device * ast)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
set_mpll_2500(struct ast_device * ast)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
reset_mmc_2500(struct ast_device * ast)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
ddr3_init_2500(struct ast_device * ast,const u32 * ddr_table)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
ddr4_init_2500(struct ast_device * ast,const u32 * ddr_table)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
ast_dram_init_2500(struct ast_device * ast)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
ast_post_chip_2500(struct ast_device * ast)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
ast_2500_post(struct ast_device * ast)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