1 /*
2 * Copyright (c) 2005 ASPEED Technology Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. The authors makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include "xf86.h"
27 #include "xf86_OSproc.h"
28 #include "xf86cmap.h"
29 #include "compiler.h"
30 #include "vgaHW.h"
31 #include "mipointer.h"
32 #include "micmap.h"
33
34 #include "fb.h"
35 #include "regionstr.h"
36 #include "xf86xv.h"
37 #include <X11/extensions/Xv.h>
38
39 #include "xf86Pci.h"
40
41 /* framebuffer offscreen manager */
42 #include "xf86fbman.h"
43
44 /* include xaa includes */
45 #include "xaarop.h"
46
47 /* H/W cursor support */
48 #include "xf86Cursor.h"
49
50 /* usleep() */
51 #include <unistd.h>
52
53 /* Driver specific headers */
54 #include "ast.h"
55 #include "ast_vgatool.h"
56 #include "ast_dp501fw.h"
57
MIndwm(UCHAR * mmiobase,ULONG r)58 __inline ULONG MIndwm(UCHAR *mmiobase, ULONG r)
59 {
60 ULONG ulData;
61
62 *(ULONG *) (mmiobase + 0xF004) = r & 0xFFFF0000;
63 *(ULONG *) (mmiobase + 0xF000) = 0x1;
64
65 do {
66 ulData = *(volatile ULONG *) (mmiobase + 0xF004) & 0xFFFF0000;
67 } while (ulData != (r & 0xFFFF0000) );
68
69 return ( *(volatile ULONG *) (mmiobase + 0x10000 + (r & 0x0000FFFF)) );
70
71 }
72
MOutdwm(UCHAR * mmiobase,ULONG r,ULONG v)73 __inline void MOutdwm(UCHAR *mmiobase, ULONG r, ULONG v)
74 {
75 ULONG ulData;
76
77 *(ULONG *) (mmiobase + 0xF004) = r & 0xFFFF0000;
78 *(ULONG *) (mmiobase + 0xF000) = 0x1;
79
80 do {
81 ulData = *(volatile ULONG *) (mmiobase + 0xF004) & 0xFFFF0000;
82 } while (ulData != (r & 0xFFFF0000) );
83
84 *(volatile ULONG *) (mmiobase + 0x10000 + (r & 0x0000FFFF)) = v;
85 }
86
87 /*
88 * BMCI2C
89 */
90 #define I2C_BASE 0x1e780000
91
92
GetFWBase(ScrnInfoPtr pScrn)93 static ULONG GetFWBase(ScrnInfoPtr pScrn)
94 {
95 ASTRecPtr pAST = ASTPTR(pScrn);
96 UCHAR *mmiobase;
97
98 mmiobase = pAST->MMIOVirtualAddr;
99 return (MIndwm(mmiobase, 0x1e6e2104) & 0x7FFFFFFF);
100 }
101
send_ack(ScrnInfoPtr pScrn)102 static void send_ack(ScrnInfoPtr pScrn)
103 {
104 ASTRecPtr pAST = ASTPTR(pScrn);
105 UCHAR SendACK;
106
107 GetIndexRegMask(CRTC_PORT, 0x9b, 0xFF, SendACK);
108 SendACK |= 0x80;
109 SetIndexRegMask(CRTC_PORT, 0x9B, 0x00, SendACK);
110 }
111
send_nack(ScrnInfoPtr pScrn)112 static void send_nack(ScrnInfoPtr pScrn)
113 {
114 ASTRecPtr pAST = ASTPTR(pScrn);
115 UCHAR SendACK;
116
117 GetIndexRegMask(CRTC_PORT, 0x9b, 0xFF, SendACK);
118 SendACK &= ~0x80;
119 SetIndexRegMask(CRTC_PORT, 0x9B, 0x00, SendACK);
120 }
121
wait_ack(ScrnInfoPtr pScrn)122 static Bool wait_ack(ScrnInfoPtr pScrn)
123 {
124 ASTRecPtr pAST = ASTPTR(pScrn);
125 UCHAR WaitACK;
126 ULONG retry=0;
127
128 do {
129 GetIndexRegMask(CRTC_PORT, 0xd2, 0xFF, WaitACK);
130 WaitACK &= 0x80;
131 DelayUS(100);
132 } while ( (!WaitACK) && (retry++ < 1000) );
133
134 if (retry < 1000)
135 return TRUE;
136 else
137 return FALSE;
138 }
139
wait_nack(ScrnInfoPtr pScrn)140 static Bool wait_nack(ScrnInfoPtr pScrn)
141 {
142 ASTRecPtr pAST = ASTPTR(pScrn);
143 UCHAR WaitACK;
144 ULONG retry=0;
145
146 do {
147 GetIndexRegMask(CRTC_PORT, 0xd2, 0xFF, WaitACK);
148 WaitACK &= 0x80;
149 DelayUS(100);
150 } while ( (WaitACK) && (retry++ < 1000) );
151
152 if (retry < 1000)
153 return TRUE;
154 else
155 return FALSE;
156 }
157
set_cmd_trigger(ScrnInfoPtr pScrn)158 static void set_cmd_trigger(ScrnInfoPtr pScrn)
159 {
160 ASTRecPtr pAST = ASTPTR(pScrn);
161
162 SetIndexRegMask(CRTC_PORT, 0x9B, ~0x40, 0x40);
163 }
164
clear_cmd_trigger(ScrnInfoPtr pScrn)165 static void clear_cmd_trigger(ScrnInfoPtr pScrn)
166 {
167 ASTRecPtr pAST = ASTPTR(pScrn);
168
169 SetIndexRegMask(CRTC_PORT, 0x9B, ~0x40, 0x00);
170 }
171
write_cmd(ScrnInfoPtr pScrn,UCHAR data)172 static Bool write_cmd(ScrnInfoPtr pScrn, UCHAR data)
173 {
174 ASTRecPtr pAST = ASTPTR(pScrn);
175 UCHAR retry = 0;
176
177 if (wait_nack(pScrn))
178 {
179 send_nack(pScrn);
180 SetIndexRegMask(CRTC_PORT, 0x9a, 0x00, data);
181 send_ack(pScrn);
182 set_cmd_trigger(pScrn);
183 do {
184 if (wait_ack(pScrn))
185 {
186 clear_cmd_trigger(pScrn);
187 send_nack(pScrn);
188 return TRUE;
189 }
190 } while (retry++ < 100);
191 }
192
193 clear_cmd_trigger(pScrn);
194 send_nack(pScrn);
195 return FALSE;
196 }
197
write_data(ScrnInfoPtr pScrn,UCHAR data)198 static Bool write_data(ScrnInfoPtr pScrn, UCHAR data)
199 {
200 ASTRecPtr pAST = ASTPTR(pScrn);
201
202 if (wait_nack(pScrn))
203 {
204 send_nack(pScrn);
205 SetIndexRegMask(CRTC_PORT, 0x9a, 0x00, data);
206 send_ack(pScrn);
207 if (wait_ack(pScrn))
208 {
209 send_nack(pScrn);
210 return TRUE;
211 }
212 }
213
214 send_nack(pScrn);
215 return FALSE;
216 }
217
SetDP501VideoOutput(ScrnInfoPtr pScrn,UCHAR Mode)218 static void SetDP501VideoOutput(ScrnInfoPtr pScrn, UCHAR Mode)
219 {
220 write_cmd(pScrn, 0x40);
221 write_data(pScrn, Mode);
222
223 DelayMS(10); /* delay 10ms */
224
225 } /* SetDP501VideoOutput */
226
BackupM68KFW(ScrnInfoPtr pScrn,UCHAR * addr,ULONG size)227 static BOOL BackupM68KFW(ScrnInfoPtr pScrn, UCHAR *addr, ULONG size)
228 {
229 ASTRecPtr pAST = ASTPTR(pScrn);
230 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
231 ULONG i, Data;
232 ULONG BootAddress;
233
234 Data = MIndwm(mmiobase, 0x1e6e2100) & 0x01;
235 if (Data) /* FW had been load */
236 {
237 /* copy image to buffer */
238 BootAddress = GetFWBase(pScrn);
239 for (i=0; i<size; i+=4)
240 {
241 *(ULONG *)(addr + i) = MIndwm(mmiobase, BootAddress + i);
242 }
243 return TRUE;
244 } /* UEFI Driver Handling */
245
246 return FALSE;
247 } /* BackupM68KFW */
248
LaunchM68K(ScrnInfoPtr pScrn)249 static BOOL LaunchM68K(ScrnInfoPtr pScrn)
250 {
251 ASTRecPtr pAST = ASTPTR(pScrn);
252 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
253 ULONG i, Data, Len;
254 ULONG BootAddress;
255 UCHAR *pFWAddr;
256 UCHAR jReg;
257
258 Data = MIndwm(mmiobase, 0x1e6e2100) & 0x03;
259 if (Data != 0x01) /* UEFI Driver Handling */
260 {
261 /* Reset Co-processor */
262 MOutdwm(mmiobase, 0x1e6e2100, 0x03);
263 do {
264 Data = MIndwm(mmiobase, 0x1e6e2100);
265 } while (Data != 0x03);
266
267 if (pAST->pDP501FWBufferVirtualAddress)
268 {
269 pFWAddr = pAST->pDP501FWBufferVirtualAddress;
270 Len = 32*1024; /* 32K */
271 }
272 else
273 {
274 pFWAddr = AST_DP501_firmware;
275 Len = sizeof(AST_DP501_firmware) / sizeof(AST_DP501_firmware[0]);
276 }
277
278 /* Get BootAddress */
279 MOutdwm(mmiobase, 0x1e6e2000, 0x1688a8a8); /* open passwd */
280 Data = MIndwm(mmiobase, 0x1e6e0004);
281 switch (Data & 0x03)
282 {
283 case 0x00: /* 64M */
284 BootAddress = 0x44000000;
285 break;
286 default:
287 case 0x01: /* 128MB */
288 BootAddress = 0x48000000;
289 break;
290 case 0x02: /* 256MB */
291 BootAddress = 0x50000000;
292 break;
293 case 0x03: /* 512MB */
294 BootAddress = 0x60000000;
295 break;
296 }
297 BootAddress -= 0x200000; /* - 2MB */
298
299 /* copy image to buffer */
300 for (i=0; i<Len; i+=4)
301 {
302 Data = *(ULONG *)(pFWAddr + i);
303 MOutdwm(mmiobase, BootAddress + i, Data);
304 }
305
306 /* Init SCU */
307 MOutdwm(mmiobase, 0x1e6e2000, 0x1688a8a8); /* open passwd */
308
309 /* Launch FW */
310 MOutdwm(mmiobase, 0x1e6e2104, 0x80000000 + BootAddress);
311 MOutdwm(mmiobase, 0x1e6e2100, 1);
312
313 /* Update Scratch */
314 Data = MIndwm(mmiobase, 0x1e6e2040) & 0xFFFFF1FF; /* D[11:9] = 100b: UEFI handling */
315 Data |= 0x0800;
316 MOutdwm(mmiobase, 0x1e6e2040, Data);
317
318 GetIndexRegMask(CRTC_PORT, 0x99, 0xFC, jReg); /* D[1:0]: Reserved Video Buffer */
319 jReg |= 0x02; /* 2MB */
320 SetIndexReg(CRTC_PORT, 0x99, jReg);
321
322 } /* UEFI Driver Handling */
323
324 return TRUE;
325 } /* LaunchM68K */
326
327 /*
328 * DP501 external
329 */
ASTReadEDID_M68K(ScrnInfoPtr pScrn,BYTE * pEDIDData)330 Bool ASTReadEDID_M68K(ScrnInfoPtr pScrn, BYTE *pEDIDData)
331 {
332 ASTRecPtr pAST = ASTPTR(pScrn);
333 UCHAR *mmiobase;
334 ULONG i, BootAddress, Offset, Data;
335
336 /* init value */
337 mmiobase = pAST->MMIOVirtualAddr;
338 BootAddress = GetFWBase(pScrn);
339
340 /* validate FW version */
341 Offset = 0xF000;
342 Data = MIndwm(mmiobase, BootAddress + Offset);
343 if ((Data & 0xF0) != 0x10) /* version: 1x */
344 return FALSE;
345
346 /* validate PnP Monitor */
347 Offset = 0xF010;
348 Data = MIndwm(mmiobase, BootAddress + Offset);
349 if (!(Data & 0x01))
350 return FALSE;
351
352 /* Read EDID */
353 Offset = 0xF020;
354 for (i=0; i<128; i+=4)
355 {
356 Data = MIndwm(mmiobase, BootAddress + Offset + i);
357 *(ULONG *)(pEDIDData + i) = Data;
358 }
359
360 return TRUE;
361 } /* ReadEDID_M68K */
362
ASTGetLinkMaxCLK(ScrnInfoPtr pScrn)363 UCHAR ASTGetLinkMaxCLK(ScrnInfoPtr pScrn)
364 {
365 ASTRecPtr pAST = ASTPTR(pScrn);
366 UCHAR *mmiobase;
367 ULONG BootAddress, Offset, Data;
368 UCHAR LinkCap[4], LinkRate, LinkLanes, MaxClk = 0xFF;
369
370 /* init value */
371 mmiobase = pAST->MMIOVirtualAddr;
372 BootAddress = GetFWBase(pScrn);
373
374 /* validate FW version */
375 Offset = 0xF000;
376 Data = MIndwm(mmiobase, BootAddress + Offset);
377 if ((Data & 0xF0) != 0x10) /* version: 1x */
378 return MaxClk;
379
380 /* Read Link Capability */
381 Offset = 0xF014;
382 *(ULONG *)(LinkCap) = MIndwm(mmiobase, BootAddress + Offset);
383 if (LinkCap[2] == 0) /* no Max. CLK Assigned */
384 {
385 LinkRate = LinkCap[0];
386 LinkLanes = LinkCap[1];
387 Data = (LinkRate == 0x0A) ? (90 * LinkLanes): (54 * LinkLanes);
388 if (Data > 255) Data = 255; /* Max. */
389 MaxClk = (UCHAR)(Data);
390 }
391
392 return MaxClk;
393
394 } /* ASTGetLinkMaxCLK */
395
396 /*
397 * VGA Modules
398 */
399 void
vASTOpenKey(ScrnInfoPtr pScrn)400 vASTOpenKey(ScrnInfoPtr pScrn)
401 {
402 ASTRecPtr pAST = ASTPTR(pScrn);
403
404 SetIndexReg(CRTC_PORT,0x80, 0xA8);
405
406 }
407
408 Bool
bASTRegInit(ScrnInfoPtr pScrn)409 bASTRegInit(ScrnInfoPtr pScrn)
410 {
411 ASTRecPtr pAST = ASTPTR(pScrn);
412
413 /* Enable MMIO */
414 SetIndexRegMask(CRTC_PORT,0xA1, 0xFF, 0x04);
415
416 /* Enable Big-Endian */
417 #if defined(__sparc__)
418 SetIndexRegMask(CRTC_PORT,0xA2, 0xFF, 0x80);
419 #endif
420
421 return (TRUE);
422
423 }
424
425 void
ASTGetDRAMInfo(ScrnInfoPtr pScrn)426 ASTGetDRAMInfo(ScrnInfoPtr pScrn)
427 {
428 ASTRecPtr pAST = ASTPTR(pScrn);
429 ULONG ulRefPLL, ulDeNumerator, ulNumerator, ulDivider;
430 ULONG ulData, ulData2;
431
432 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
433 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
434
435 /* Based on the Linux DRM driver we might not be able to access this
436 * If we can't just use some sane defaults.
437 *
438 * See drm/drivers/gpu/drm/ast/ast_main.c line 295.
439 */
440
441 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309;
442 for (ulData = 10000; ulData > 0; ulData--)
443 if (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) == 0x01)
444 break;
445
446 if (ulData == 0) {
447 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unable to read DRAM information, using defaults\n");
448 pAST->ulDRAMBusWidth = 16;
449 pAST->jDRAMType = DRAMTYPE_1Gx16;
450 if (pAST->jChipType == AST2500)
451 pAST->ulMCLK = 800;
452 else
453 pAST->ulMCLK = 396;
454 return;
455 }
456 ulData = *(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10004);
457
458 /* Get BusWidth */
459 if (ulData & 0x40)
460 pAST->ulDRAMBusWidth = 16;
461 else
462 pAST->ulDRAMBusWidth = 32;
463
464 /* Get DRAM Type */
465 if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
466 {
467 switch (ulData & 0x03)
468 {
469 case 0x00:
470 pAST->jDRAMType = DRAMTYPE_512Mx16;
471 break;
472 default:
473 case 0x01:
474 pAST->jDRAMType = DRAMTYPE_1Gx16;
475 break;
476 case 0x02:
477 pAST->jDRAMType = DRAMTYPE_2Gx16;
478 break;
479 case 0x03:
480 pAST->jDRAMType = DRAMTYPE_4Gx16;
481 break;
482 }
483 }
484 else
485 {
486 switch (ulData & 0x0C)
487 {
488 case 0x00:
489 case 0x04:
490 pAST->jDRAMType = DRAMTYPE_512Mx16;
491 break;
492
493 case 0x08:
494 if (ulData & 0x40) /* 16bits */
495 pAST->jDRAMType = DRAMTYPE_1Gx16;
496 else /* 32bits */
497 pAST->jDRAMType = DRAMTYPE_512Mx32;
498 break;
499
500 case 0x0C:
501 pAST->jDRAMType = DRAMTYPE_1Gx32;
502 break;
503 }
504 }
505
506 /* Get MCLK */
507 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10120);
508 ulData2 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10170);
509 if (ulData2 & 0x2000)
510 ulRefPLL = 14318;
511 else
512 ulRefPLL = 12000;
513
514 ulDeNumerator = ulData & 0x1F;
515 ulNumerator = (ulData & 0x3FE0) >> 5;
516
517 ulData = (ulData & 0xC000) >> 14;
518 switch (ulData)
519 {
520 case 0x03:
521 ulDivider = 0x04;
522 break;
523 case 0x02:
524 case 0x01:
525 ulDivider = 0x02;
526 break;
527 default:
528 ulDivider = 0x01;
529 }
530 pAST->ulMCLK = ulRefPLL * (ulNumerator + 2) / ((ulDeNumerator + 2) * ulDivider * 1000);
531
532 } /* ASTGetDRAMInfo */
533
534 ULONG
ASTGetVRAMInfo(ScrnInfoPtr pScrn)535 ASTGetVRAMInfo(ScrnInfoPtr pScrn)
536 {
537 ASTRecPtr pAST = ASTPTR(pScrn);
538 ULONG ulVRAMSize;
539 UCHAR jReg;
540
541 vASTOpenKey(pScrn);
542
543 /* Get VRAMSize from H/W Trapping */
544 GetIndexRegMask(CRTC_PORT, 0xAA, 0xFF, jReg);
545 switch (jReg & 0x03)
546 {
547 default:
548 case 0x00:
549 ulVRAMSize = VIDEOMEM_SIZE_08M;
550 break;
551 case 0x01:
552 ulVRAMSize = VIDEOMEM_SIZE_16M;
553 break;
554 case 0x02:
555 ulVRAMSize = VIDEOMEM_SIZE_32M;
556 break;
557 case 0x03:
558 ulVRAMSize = VIDEOMEM_SIZE_64M;
559 break;
560 }
561
562 /* Adjust VRAMSize from Scratch */
563 GetIndexRegMask(CRTC_PORT, 0x99, 0xFF, jReg);
564 switch (jReg & 0x03)
565 {
566 case 0x01:
567 ulVRAMSize -= 0x100000;
568 break;
569 case 0x02:
570 ulVRAMSize -= 0x200000;
571 break;
572 case 0x03:
573 ulVRAMSize -= 0x400000;
574 break;
575 }
576
577 return (ulVRAMSize);
578 }
579
580 ULONG
ASTGetMaxDCLK(ScrnInfoPtr pScrn)581 ASTGetMaxDCLK(ScrnInfoPtr pScrn)
582 {
583 ASTRecPtr pAST = ASTPTR(pScrn);
584 UCHAR jReg;
585 ULONG ulDRAMBusWidth, ulMCLK, ulDRAMBandwidth, ActualDRAMBandwidth, DRAMEfficiency = 500;
586 ULONG ulDCLK;
587
588 ulMCLK = pAST->ulMCLK;
589 ulDRAMBusWidth = pAST->ulDRAMBusWidth;
590
591 /* Get Bandwidth */
592 /* Modify DARM utilization to 60% for AST1100/2100 16bits DRAM, ycchen@032508 */
593 if ( ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150)) && (ulDRAMBusWidth == 16) )
594 DRAMEfficiency = 600;
595 else if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
596 DRAMEfficiency = 400;
597 ulDRAMBandwidth = ulMCLK * ulDRAMBusWidth * 2 / 8;
598 ActualDRAMBandwidth = ulDRAMBandwidth * DRAMEfficiency / 1000;
599
600 /* Get Max DCLK */
601 if (pAST->jChipType == AST1180)
602 {
603 ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1) / 8);
604 }
605 else
606 {
607 /* Fixed Fixed KVM + CRT threshold issue on AST2100 8bpp modes, ycchen@100708 */
608 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
609 if ((jReg & 0x08) && (pAST->jChipType == AST2000))
610 ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1+16) / 8);
611 else if ((jReg & 0x08) && (pScrn->bitsPerPixel == 8))
612 ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1+24) / 8);
613 else
614 ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1) / 8);
615 }
616
617 /* Validate for DP501 */
618 if (pAST->jTxChipType == Tx_DP501)
619 {
620 if (ulDCLK > pAST->DP501_MaxVCLK) ulDCLK = pAST->DP501_MaxVCLK;
621 }
622
623 /* Add for AST2100, ycchen@061807 */
624 if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500) || (pAST->jChipType == AST1180) )
625 {
626 if (ulDCLK > 200) ulDCLK = 200;
627 }
628 else
629 {
630 if (ulDCLK > 165) ulDCLK = 165;
631 }
632
633 return(ulDCLK);
634
635 }
636
637 void
ASTGetChipType(ScrnInfoPtr pScrn)638 ASTGetChipType(ScrnInfoPtr pScrn)
639 {
640 ASTRecPtr pAST = ASTPTR(pScrn);
641 ULONG ulData;
642
643 pAST->jChipType = AST2100;
644
645 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
646 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
647 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1207c);
648 switch (ulData & 0x0300)
649 {
650 case 0x0200:
651 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "AST1100 Detected.\n");
652 pAST->jChipType = AST1100;
653 break;
654 case 0x0100:
655 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "AST2200 Detected.\n");
656 pAST->jChipType = AST2200;
657 break;
658 case 0x0000:
659 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "AST2150 Detected.\n");
660 pAST->jChipType = AST2150;
661 break;
662 default:
663 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "AST2100 Detected.\n");
664 pAST->jChipType = AST2100;
665 }
666
667 }
668
669 void
ASTGetScratchOptions(ScrnInfoPtr pScrn)670 ASTGetScratchOptions(ScrnInfoPtr pScrn)
671 {
672 ASTRecPtr pAST = ASTPTR(pScrn);
673 ULONG ulData;
674 UCHAR jReg;
675
676 /* VGA2 Clone Support */
677 GetIndexRegMask(CRTC_PORT, 0x90, 0xFF, jReg);
678 if (jReg & 0x10)
679 pAST->VGA2Clone = TRUE;
680
681 /* 3rd Tx Check */
682 pAST->pDP501FWBufferVirtualAddress = NULL;
683 pAST->jTxChipType = Tx_NONE;
684 /* Get 3rd Tx Info from HW Reg. */
685 GetIndexRegMask(CRTC_PORT, 0xA3, 0xFF, jReg);
686 if (jReg & 0x80)
687 pAST->jTxChipType = Tx_Sil164;
688 /* Get 3rd Tx Info from BMC Scratch */
689 if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
690 {
691 GetIndexRegMask(CRTC_PORT, 0xD1, 0x0E, jReg);
692 switch (jReg)
693 {
694 case 0x04:
695 pAST->jTxChipType = Tx_Sil164;
696 break;
697 case 0x08:
698 pAST->pDP501FWBufferVirtualAddress = (UCHAR*) calloc(1, 32*1024);
699 if (pAST->pDP501FWBufferVirtualAddress)
700 {
701 if (BackupM68KFW(pScrn, pAST->pDP501FWBufferVirtualAddress, 32*1024) == FALSE)
702 {
703 free(pAST->pDP501FWBufferVirtualAddress);
704 pAST->pDP501FWBufferVirtualAddress = NULL;
705 }
706 } /* Backup DP501 FW */
707 case 0x0c:
708 pAST->jTxChipType = Tx_DP501;
709 break;
710 }
711 }
712
713 /* WideScreen Support */
714 switch (pAST->jChipType)
715 {
716 case AST1180:
717 pAST->SupportWideScreen = TRUE;
718 break;
719 case AST2000:
720 pAST->SupportWideScreen = FALSE;
721 break;
722 default:
723 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
724 if (!(jReg & 0x80))
725 pAST->SupportWideScreen = TRUE;
726 else if (jReg & 0x01)
727 pAST->SupportWideScreen = TRUE;
728 else
729 {
730 pAST->SupportWideScreen = FALSE;
731 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
732 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
733 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1207c);
734 ulData &= 0x0300;
735 if ((pAST->jChipType == AST2300) && (ulData == 0x0000)) /* AST1300 */
736 pAST->SupportWideScreen = TRUE;
737 if ((pAST->jChipType == AST2400) && (ulData == 0x0100)) /* AST1400 */
738 pAST->SupportWideScreen = TRUE;
739 }
740 } /* switch case */
741
742 } /* GetScratchOptions */
743
744 void
vASTSetStartAddressCRT1(ASTRecPtr pAST,ULONG base)745 vASTSetStartAddressCRT1(ASTRecPtr pAST, ULONG base)
746 {
747 ULONG addr;
748
749 if (pAST->jChipType == AST1180)
750 {
751 addr = pAST->ulVRAMBase + base;
752 WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_STARTADDR, addr);
753 }
754 else
755 {
756 addr = base >> 2; /* DW unit */
757
758 SetIndexReg(CRTC_PORT,0x0D, (UCHAR) (addr & 0xFF));
759 SetIndexReg(CRTC_PORT,0x0C, (UCHAR) ((addr >> 8) & 0xFF));
760 SetIndexReg(CRTC_PORT,0xAF, (UCHAR) ((addr >> 16) & 0xFF));
761 }
762
763 }
764
765 void
vAST1000DisplayOff(ScrnInfoPtr pScrn)766 vAST1000DisplayOff(ScrnInfoPtr pScrn)
767 {
768 ASTRecPtr pAST = ASTPTR(pScrn);
769 ULONG ulData;
770
771 /* 3rd Tx */
772 if (pAST->jTxChipType == Tx_DP501)
773 SetDP501VideoOutput(pScrn, 0);
774
775 if (pAST->jChipType == AST1180)
776 {
777 ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData);
778 ulData |= 0x00100000;
779 WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData);
780 }
781 else
782 SetIndexRegMask(SEQ_PORT,0x01, 0xDF, 0x20);
783
784 }
785
786 void
vAST1000DisplayOn(ScrnInfoPtr pScrn)787 vAST1000DisplayOn(ScrnInfoPtr pScrn)
788 {
789
790 ASTRecPtr pAST = ASTPTR(pScrn);
791 ULONG ulData;
792
793 if (pAST->jChipType == AST1180)
794 {
795 ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData);
796 ulData &= 0xFFEFFFFF;
797 WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData);
798 }
799 else
800 SetIndexRegMask(SEQ_PORT,0x01, 0xDF, 0x00);
801
802 /* 3rd Tx */
803 if (pAST->jTxChipType == Tx_DP501)
804 SetDP501VideoOutput(pScrn, 1);
805 }
806
ASTBlankScreen(ScrnInfoPtr pScrn,Bool unblack)807 void ASTBlankScreen(ScrnInfoPtr pScrn, Bool unblack)
808 {
809 if (unblack)
810 vAST1000DisplayOn(pScrn);
811 else
812 vAST1000DisplayOff(pScrn);
813 }
814
815 void
vASTLoadPalette(ScrnInfoPtr pScrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)816 vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
817 VisualPtr pVisual)
818 {
819
820 ASTRecPtr pAST = ASTPTR(pScrn);
821 int i, j, index;
822 UCHAR DACIndex, DACR, DACG, DACB;
823
824 switch (pScrn->bitsPerPixel) {
825 case 15:
826 for(i=0; i<numColors; i++) {
827 index = indices[i];
828 for(j=0; j<8; j++) {
829 DACIndex = (index * 8) + j;
830 DACR = colors[index].red << (8- pScrn->rgbBits);
831 DACG = colors[index].green << (8- pScrn->rgbBits);
832 DACB = colors[index].blue << (8- pScrn->rgbBits);
833
834 VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB);
835 }
836 }
837 break;
838
839 case 16:
840 for(i=0; i<numColors; i++) {
841 index = indices[i];
842 for(j=0; j<4; j++) {
843 DACIndex = (index * 4) + j;
844 DACR = colors[index/2].red << (8- pScrn->rgbBits);
845 DACG = colors[index].green << (8- pScrn->rgbBits);
846 DACB = colors[index/2].blue << (8- pScrn->rgbBits);
847
848 VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB);
849 }
850 }
851 break;
852
853 case 24:
854 for(i=0; i<numColors; i++) {
855 index = indices[i];
856 DACIndex = index;
857 DACR = colors[index].red;
858 DACG = colors[index].green;
859 DACB = colors[index].blue;
860
861 VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB);
862 }
863 break;
864
865 default:
866 for(i=0; i<numColors; i++) {
867 index = indices[i];
868 DACIndex = index;
869 DACR = colors[index].red >> (8 - pScrn->rgbBits);
870 DACG = colors[index].green >> (8 - pScrn->rgbBits);
871 DACB = colors[index].blue >> (8 - pScrn->rgbBits);
872
873 VGA_LOAD_PALETTE_INDEX (DACIndex, DACR, DACG, DACB);
874 }
875
876 } /* end of switch */
877
878 } /* end of vASTLoadPalette */
879
880 void
ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn,int PowerManagementMode,int flags)881 ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
882 {
883 ASTRecPtr pAST;
884 UCHAR SEQ01, CRB6;
885 ULONG ulData, ulTemp;
886
887 pAST = ASTPTR(pScrn);
888 SEQ01=CRB6=0;
889 ulData = 0;
890
891 vASTOpenKey(pScrn);
892
893 switch (PowerManagementMode) {
894 case DPMSModeOn:
895 /* Screen: On; HSync: On, VSync: On */
896 SEQ01 = 0x00;
897 CRB6 = 0x00;
898 ulData = 0x00000000;
899 break;
900 case DPMSModeStandby:
901 /* Screen: Off; HSync: Off, VSync: On */
902 SEQ01 = 0x20;
903 CRB6 = 0x01;
904 ulData = 0x00140000;
905 break;
906 case DPMSModeSuspend:
907 /* Screen: Off; HSync: On, VSync: Off */
908 SEQ01 = 0x20;
909 CRB6 = 0x02;
910 ulData = 0x00180000;
911 break;
912 case DPMSModeOff:
913 /* Screen: Off; HSync: Off, VSync: Off */
914 SEQ01 = 0x20;
915 CRB6 = 0x03;
916 ulData = 0x001C0000;
917 break;
918 }
919
920 if (PowerManagementMode != DPMSModeOn)
921 { /* 3rd Tx */
922 if (pAST->jTxChipType == Tx_DP501) SetDP501VideoOutput(pScrn, 0);
923 }
924
925 if (pAST->jChipType == AST1180)
926 {
927 ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulTemp);
928 ulTemp &= 0xFFE3FFFF;
929 ulTemp |= ulData;
930 WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulTemp);
931 }
932 else
933 {
934 SetIndexRegMask(SEQ_PORT,0x01, 0xDF, SEQ01);
935 SetIndexRegMask(CRTC_PORT,0xB6, 0xFC, CRB6);
936 }
937
938 if (PowerManagementMode == DPMSModeOn)
939 { /* 3rd Tx */
940 if (pAST->jTxChipType == Tx_DP501) SetDP501VideoOutput(pScrn, 1);
941 }
942 }
943
944
945 #ifndef I2C_BASE
946 #define I2C_BASE 0x1e780000
947 #endif
948 #define I2C_OFFSET (0xA000 + 0x40 * 4) /* port4 */
949 #define I2C_DEVICEADDR 0x0A0 /* slave addr */
950
951 #define I2C_BASE_AST1180 0x80fc0000
952 #define I2C_OFFSET_AS1180 (0xB000 + 0x40 * 2) /* port2 */
953 #define I2C_DEVICEADDR_AST1180 0x0A0 /* slave addr */
954
955 Bool
ASTGetVGA2EDID(ScrnInfoPtr pScrn,unsigned char * pEDIDBuffer)956 ASTGetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer)
957 {
958 ASTRecPtr pAST = ASTPTR(pScrn);
959 ULONG i, ulData;
960 UCHAR *pjEDID;
961 ULONG base, deviceaddr;
962 UCHAR *offset;
963
964 pjEDID = pEDIDBuffer;
965
966 if (pAST->jChipType == AST1180)
967 {
968 base = I2C_BASE_AST1180;
969 offset = pAST->MMIOVirtualAddr + 0x10000 + I2C_OFFSET_AS1180;
970 deviceaddr = I2C_DEVICEADDR_AST1180;
971 }
972 else
973 {
974 base = I2C_BASE;
975 offset = pAST->MMIOVirtualAddr + 0x10000 + I2C_OFFSET;
976 deviceaddr = I2C_DEVICEADDR;
977
978 /* SCU settings */
979 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
980 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
981 usleep(10000);
982
983 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8;
984 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004);
985 ulData &= 0xfffffffb;
986 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004) = ulData;
987 usleep(10000);
988 }
989
990 /* I2C settings */
991 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = base;
992 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
993 usleep(10000);
994
995 /* I2C Start */
996 *(ULONG *) (offset + 0x00) = 0x0;
997 *(ULONG *) (offset + 0x04) = 0x77777355;
998 *(ULONG *) (offset + 0x08) = 0x0;
999 *(ULONG *) (offset + 0x10) = 0xffffffff;
1000 *(ULONG *) (offset + 0x00) = 0x1;
1001 *(ULONG *) (offset + 0x0C) = 0xAF;
1002 *(ULONG *) (offset + 0x20) = deviceaddr;
1003 *(ULONG *) (offset + 0x14) = 0x03;
1004 do {
1005 ulData = *(volatile ULONG *) (offset + 0x10);
1006 } while (!(ulData & 0x03));
1007 if (ulData & 0x02) /* NACK */
1008 return (FALSE);
1009 *(ULONG *) (offset + 0x10) = 0xffffffff;
1010 *(ULONG *) (offset + 0x20) = (ULONG) 0; /* Offset */
1011 *(ULONG *) (offset + 0x14) = 0x02;
1012 do {
1013 ulData = *(volatile ULONG *) (offset + 0x10);
1014 } while (!(ulData & 0x01));
1015 *(ULONG *) (offset + 0x10) = 0xffffffff;
1016 *(ULONG *) (offset + 0x20) = deviceaddr + 1;
1017 *(ULONG *) (offset + 0x14) = 0x03;
1018 do {
1019 ulData = *(volatile ULONG *) (offset + 0x10);
1020 } while (!(ulData & 0x01));
1021
1022 /* I2C Read */
1023 for (i=0; i<127; i++)
1024 {
1025 *(ULONG *) (offset + 0x10) = 0xffffffff;
1026 *(ULONG *) (offset + 0x0C) |= 0x10;
1027 *(ULONG *) (offset + 0x14) = 0x08;
1028 do {
1029 ulData = *(volatile ULONG *) (offset + 0x10);
1030 } while (!(ulData & 0x04));
1031 *(ULONG *) (offset + 0x10) = 0xffffffff;
1032 *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (offset + 0x20) & 0xFF00) >> 8);
1033 }
1034
1035 /* Read Last Byte */
1036 *(ULONG *) (offset + 0x10) = 0xffffffff;
1037 *(ULONG *) (offset + 0x0C) |= 0x10;
1038 *(ULONG *) (offset + 0x14) = 0x18;
1039 do {
1040 ulData = *(volatile ULONG *) (offset + 0x10);
1041 } while (!(ulData & 0x04));
1042 *(ULONG *) (offset + 0x10) = 0xffffffff;
1043 *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (offset + 0x20) & 0xFF00) >> 8);
1044
1045 /* I2C Stop */
1046 *(ULONG *) (offset + 0x10) = 0xffffffff;
1047 *(ULONG *) (offset + 0x14) = 0x20;
1048 do {
1049 ulData = *(volatile ULONG *) (offset + 0x10);
1050 } while (!(ulData & 0x10));
1051 *(ULONG *) (offset + 0x0C) &= 0xffffffef;
1052 *(ULONG *) (offset + 0x10) = 0xffffffff;
1053
1054 return (TRUE);
1055
1056 } /* ASTGetVGA2EDID */
1057
1058 /* Init VGA */
bASTIsVGAEnabled(ScrnInfoPtr pScrn)1059 Bool bASTIsVGAEnabled(ScrnInfoPtr pScrn)
1060 {
1061 ASTRecPtr pAST;
1062 UCHAR ch;
1063 ULONG ulData;
1064
1065 pAST = ASTPTR(pScrn);
1066
1067 if (pAST->jChipType == AST1180)
1068 {
1069 WriteAST1180SOC(AST1180_MMC_BASE+0x00, 0xFC600309); /* unlock */
1070 ReadAST1180SOC(AST1180_MMC_BASE+0x08, ulData);
1071 return (ulData);
1072 }
1073 else
1074 {
1075 ch = inb(pAST->RelocateIO + 0x43);
1076
1077 if (ch == 0x01)
1078 {
1079 outw(pAST->RelocateIO + 0x54, 0xa880);
1080 outb(pAST->RelocateIO + 0x54, 0xb6);
1081 ch = inb(pAST->RelocateIO + 0x55);
1082
1083 return (ch & 0x04);
1084 }
1085 }
1086
1087 return (0);
1088 }
1089
vEnableVGA(ScrnInfoPtr pScrn)1090 static void vEnableVGA(ScrnInfoPtr pScrn)
1091 {
1092 ASTRecPtr pAST;
1093
1094 pAST = ASTPTR(pScrn);
1095
1096 SetReg(VGA_ENABLE_PORT, 0x01);
1097 SetReg(MISC_PORT_WRITE, 0x01);
1098
1099 }
1100
1101 static UCHAR ExtRegInfo[] = {
1102 0x0F,
1103 0x04,
1104 0x1C,
1105 0xFF
1106 };
1107
1108 static UCHAR ExtRegInfo_AST2300A0[] = {
1109 0x0F,
1110 0x04,
1111 0x1C,
1112 0xFF
1113 };
1114
1115 static UCHAR ExtRegInfo_AST2300[] = {
1116 0x0F,
1117 0x04,
1118 0x1F,
1119 0xFF
1120 };
1121
vSetDefExtReg(ScrnInfoPtr pScrn)1122 static void vSetDefExtReg(ScrnInfoPtr pScrn)
1123 {
1124 ASTRecPtr pAST;
1125 UCHAR i, jIndex, jReg, *pjExtRegInfo;
1126
1127 pAST = ASTPTR(pScrn);
1128
1129 /* Reset Scratch */
1130 for (i=0x81; i<=0x8F; i++)
1131 {
1132 SetIndexReg(CRTC_PORT, i, 0x00);
1133 }
1134
1135 /* Set Ext. Reg */
1136 if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
1137 {
1138 if (PCI_DEV_REVISION(pAST->PciInfo) > 0x20)
1139 pjExtRegInfo = ExtRegInfo_AST2300;
1140 else
1141 pjExtRegInfo = ExtRegInfo_AST2300A0;
1142 }
1143 else
1144 pjExtRegInfo = ExtRegInfo;
1145
1146 jIndex = 0xA0;
1147 while (*(UCHAR *) (pjExtRegInfo) != 0xFF)
1148 {
1149 SetIndexRegMask(CRTC_PORT,jIndex, 0x00, *(UCHAR *) (pjExtRegInfo));
1150 jIndex++;
1151 pjExtRegInfo++;
1152 }
1153
1154 /* disable standard IO/MEM decode if secondary */
1155 if (!xf86IsPrimaryPci(pAST->PciInfo))
1156 SetIndexRegMask(CRTC_PORT,0xA1, 0xFF, 0x03);
1157
1158 /* Set Ext. Default */
1159 SetIndexRegMask(CRTC_PORT,0x8C, 0x00, 0x01);
1160 SetIndexRegMask(CRTC_PORT,0xB7, 0x00, 0x00);
1161
1162 /* Enable RAMDAC for A1, ycchen@113005 */
1163 jReg = 0x04;
1164 if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2400))
1165 jReg |= 0x20;
1166 SetIndexRegMask(CRTC_PORT,0xB6, 0xFF, jReg);
1167
1168 }
1169
vSetDefVCLK(ScrnInfoPtr pScrn)1170 static void vSetDefVCLK(ScrnInfoPtr pScrn)
1171 {
1172 ASTRecPtr pAST = ASTPTR(pScrn);
1173
1174 if ((pAST->jChipType == AST2500) && (PCI_DEV_REVISION(pAST->PciInfo) == 0x40))
1175 {
1176 SetIndexRegMask(CRTC_PORT, 0xbc, 0x00, 0x40);
1177 SetIndexRegMask(CRTC_PORT, 0xbd, 0x00, 0x38);
1178 SetIndexRegMask(CRTC_PORT, 0xbe, 0x00, 0x3a);
1179 SetIndexRegMask(CRTC_PORT, 0xbf, 0x00, 0x38);
1180 SetIndexRegMask(CRTC_PORT, 0xcf, 0x00, 0x70);
1181 SetIndexRegMask(CRTC_PORT, 0xb5, 0x00, 0xa8);
1182 SetIndexRegMask(CRTC_PORT, 0xbb, 0x00, 0x43);
1183 }
1184 }
1185
1186 /*
1187 * AST2100/2150 DLL CBR Setting
1188 */
1189 #define CBR_SIZE_AST2150 ((16 << 10) - 1)
1190 #define CBR_PASSNUM_AST2150 5
1191 #define CBR_THRESHOLD_AST2150 10
1192 #define CBR_THRESHOLD2_AST2150 10
1193 #define TIMEOUT_AST2150 5000000
1194
1195 #define CBR_PATNUM_AST2150 8
1196
1197 static ULONG pattern_AST2150[14] ={
1198 0xFF00FF00,
1199 0xCC33CC33,
1200 0xAA55AA55,
1201 0xFFFE0001,
1202 0x683501FE,
1203 0x0F1929B0,
1204 0x2D0B4346,
1205 0x60767F02,
1206 0x6FBE36A6,
1207 0x3A253035,
1208 0x3019686D,
1209 0x41C6167E,
1210 0x620152BF,
1211 0x20F050E0};
1212
1213 typedef struct _AST2150DRAMParam {
1214 UCHAR *pjMMIOVirtualAddress;
1215 } AST2150DRAMParam, *PAST2150DRAMParam;
1216
MMCTestBurst2_AST2150(PAST2150DRAMParam param,ULONG datagen)1217 static ULONG MMCTestBurst2_AST2150(PAST2150DRAMParam param, ULONG datagen)
1218 {
1219 ULONG data, timeout;
1220 UCHAR *mmiobase;
1221
1222 mmiobase = param->pjMMIOVirtualAddress;
1223
1224 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1225 MOutdwm(mmiobase, 0x1E6E0070, 0x00000001 | (datagen << 3));
1226 timeout = 0;
1227 do{
1228 data = MIndwm(mmiobase, 0x1E6E0070) & 0x40;
1229 if(++timeout > TIMEOUT_AST2150){
1230 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1231 return(-1);
1232 }
1233 }while(!data);
1234 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1235 MOutdwm(mmiobase, 0x1E6E0070, 0x00000003 | (datagen << 3));
1236 timeout = 0;
1237 do{
1238 data = MIndwm(mmiobase, 0x1E6E0070) & 0x40;
1239 if(++timeout > TIMEOUT_AST2150){
1240 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1241 return(-1);
1242 }
1243 }while(!data);
1244 data = (MIndwm(mmiobase, 0x1E6E0070) & 0x80) >> 7;
1245 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1246 return(data);
1247 }
1248
MMCTestSingle2_AST2150(PAST2150DRAMParam param,ULONG datagen)1249 static ULONG MMCTestSingle2_AST2150(PAST2150DRAMParam param, ULONG datagen)
1250 {
1251 ULONG data, timeout;
1252 UCHAR *mmiobase;
1253
1254 mmiobase = param->pjMMIOVirtualAddress;
1255
1256 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1257 MOutdwm(mmiobase, 0x1E6E0070, 0x00000005 | (datagen << 3));
1258 timeout = 0;
1259 do{
1260 data = MIndwm(mmiobase, 0x1E6E0070) & 0x40;
1261 if(++timeout > TIMEOUT_AST2150){
1262 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1263 return(-1);
1264 }
1265 }while(!data);
1266 data = (MIndwm(mmiobase, 0x1E6E0070) & 0x80) >> 7;
1267 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1268 return(data);
1269 }
1270
CBRTest_AST2150(PAST2150DRAMParam param)1271 static int CBRTest_AST2150(PAST2150DRAMParam param)
1272 {
1273 UCHAR *mmiobase;
1274
1275 mmiobase = param->pjMMIOVirtualAddress;
1276
1277 if(MMCTestBurst2_AST2150(param, 0) ) return(0);
1278 if(MMCTestBurst2_AST2150(param, 1) ) return(0);
1279 if(MMCTestBurst2_AST2150(param, 2) ) return(0);
1280 if(MMCTestBurst2_AST2150(param, 3) ) return(0);
1281 if(MMCTestBurst2_AST2150(param, 4) ) return(0);
1282 if(MMCTestBurst2_AST2150(param, 5) ) return(0);
1283 if(MMCTestBurst2_AST2150(param, 6) ) return(0);
1284 if(MMCTestBurst2_AST2150(param, 7) ) return(0);
1285 return(1);
1286
1287 }
1288
CBRScan_AST2150(PAST2150DRAMParam param,int busw)1289 static int CBRScan_AST2150(PAST2150DRAMParam param, int busw)
1290 {
1291 ULONG patcnt, loop;
1292 UCHAR *mmiobase;
1293
1294 mmiobase = param->pjMMIOVirtualAddress;
1295
1296 for(patcnt = 0;patcnt < CBR_PATNUM_AST2150;patcnt++){
1297 MOutdwm(mmiobase, 0x1E6E007C, pattern_AST2150[patcnt]);
1298 for(loop = 0;loop < CBR_PASSNUM_AST2150;loop++){
1299 if(CBRTest_AST2150(param)){
1300 break;
1301 }
1302 }
1303 if(loop == CBR_PASSNUM_AST2150){
1304 return(0);
1305 }
1306 }
1307 return(1);
1308
1309 }
1310
CBRDLLI_AST2150(PAST2150DRAMParam param,int busw)1311 static void CBRDLLI_AST2150(PAST2150DRAMParam param, int busw)
1312 {
1313 ULONG dllmin[4], dllmax[4], dlli, data, passcnt;
1314 UCHAR *mmiobase;
1315
1316 mmiobase = param->pjMMIOVirtualAddress;
1317
1318 CBR_START:
1319 dllmin[0] = dllmin[1] = dllmin[2] = dllmin[3] = 0xff;
1320 dllmax[0] = dllmax[1] = dllmax[2] = dllmax[3] = 0x0;
1321 passcnt = 0;
1322 MOutdwm(mmiobase, 0x1E6E0074, CBR_SIZE_AST2150);
1323 for(dlli = 0;dlli < 100;dlli++){
1324 MOutdwm(mmiobase, 0x1E6E0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
1325 data = CBRScan_AST2150(param, busw);
1326 if(data != 0){
1327 if(data & 0x1){
1328 if(dllmin[0] > dlli){
1329 dllmin[0] = dlli;
1330 }
1331 if(dllmax[0] < dlli){
1332 dllmax[0] = dlli;
1333 }
1334 }
1335 passcnt++;
1336 }else if(passcnt >= CBR_THRESHOLD_AST2150){
1337 break;
1338 }
1339 }
1340 if(dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD_AST2150){
1341 goto CBR_START;
1342 }
1343 dlli = dllmin[0] + (((dllmax[0] - dllmin[0]) * 7) >> 4);
1344 MOutdwm(mmiobase, 0x1E6E0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
1345 }
1346
1347 typedef struct _AST_DRAMStruct {
1348
1349 USHORT Index;
1350 ULONG Data;
1351
1352 } AST_DRAMStruct, *PAST_DRAMStruct;
1353
1354 static AST_DRAMStruct AST2000DRAMTableData[] = {
1355 { 0x0108, 0x00000000 },
1356 { 0x0120, 0x00004a21 },
1357 { 0xFF00, 0x00000043 },
1358 { 0x0000, 0xFFFFFFFF },
1359 { 0x0004, 0x00000089 },
1360 { 0x0008, 0x22331353 },
1361 { 0x000C, 0x0d07000b },
1362 { 0x0010, 0x11113333 },
1363 { 0x0020, 0x00110350 },
1364 { 0x0028, 0x1e0828f0 },
1365 { 0x0024, 0x00000001 },
1366 { 0x001C, 0x00000000 },
1367 { 0x0014, 0x00000003 },
1368 { 0xFF00, 0x00000043 },
1369 { 0x0018, 0x00000131 },
1370 { 0x0014, 0x00000001 },
1371 { 0xFF00, 0x00000043 },
1372 { 0x0018, 0x00000031 },
1373 { 0x0014, 0x00000001 },
1374 { 0xFF00, 0x00000043 },
1375 { 0x0028, 0x1e0828f1 },
1376 { 0x0024, 0x00000003 },
1377 { 0x002C, 0x1f0f28fb },
1378 { 0x0030, 0xFFFFFE01 },
1379 { 0xFFFF, 0xFFFFFFFF }
1380 };
1381
1382 static AST_DRAMStruct AST1100DRAMTableData[] = {
1383 { 0x2000, 0x1688a8a8 },
1384 { 0x2020, 0x000041f0 },
1385 { 0xFF00, 0x00000043 },
1386 { 0x0000, 0xfc600309 },
1387 { 0x006C, 0x00909090 },
1388 { 0x0064, 0x00050000 },
1389 { 0x0004, 0x00000585 },
1390 { 0x0008, 0x0011030f },
1391 { 0x0010, 0x22201724 },
1392 { 0x0018, 0x1e29011a },
1393 { 0x0020, 0x00c82222 },
1394 { 0x0014, 0x01001523 },
1395 { 0x001C, 0x1024010d },
1396 { 0x0024, 0x00cb2522 },
1397 { 0x0038, 0xffffff82 },
1398 { 0x003C, 0x00000000 },
1399 { 0x0040, 0x00000000 },
1400 { 0x0044, 0x00000000 },
1401 { 0x0048, 0x00000000 },
1402 { 0x004C, 0x00000000 },
1403 { 0x0050, 0x00000000 },
1404 { 0x0054, 0x00000000 },
1405 { 0x0058, 0x00000000 },
1406 { 0x005C, 0x00000000 },
1407 { 0x0060, 0x032aa02a },
1408 { 0x0064, 0x002d3000 },
1409 { 0x0068, 0x00000000 },
1410 { 0x0070, 0x00000000 },
1411 { 0x0074, 0x00000000 },
1412 { 0x0078, 0x00000000 },
1413 { 0x007C, 0x00000000 },
1414 { 0x0034, 0x00000001 },
1415 { 0xFF00, 0x00000043 },
1416 { 0x002C, 0x00000732 },
1417 { 0x0030, 0x00000040 },
1418 { 0x0028, 0x00000005 },
1419 { 0x0028, 0x00000007 },
1420 { 0x0028, 0x00000003 },
1421 { 0x0028, 0x00000001 },
1422 { 0x000C, 0x00005a08 },
1423 { 0x002C, 0x00000632 },
1424 { 0x0028, 0x00000001 },
1425 { 0x0030, 0x000003c0 },
1426 { 0x0028, 0x00000003 },
1427 { 0x0030, 0x00000040 },
1428 { 0x0028, 0x00000003 },
1429 { 0x000C, 0x00005a21 },
1430 { 0x0034, 0x00007c03 },
1431 { 0x0120, 0x00004c41 },
1432 { 0xffff, 0xffffffff },
1433 };
1434
1435 static AST_DRAMStruct AST2100DRAMTableData[] = {
1436 { 0x2000, 0x1688a8a8 },
1437 { 0x2020, 0x00004120 },
1438 { 0xFF00, 0x00000043 },
1439 { 0x0000, 0xfc600309 },
1440 { 0x006C, 0x00909090 },
1441 { 0x0064, 0x00070000 },
1442 { 0x0004, 0x00000489 },
1443 { 0x0008, 0x0011030f },
1444 { 0x0010, 0x32302926 },
1445 { 0x0018, 0x274c0122 },
1446 { 0x0020, 0x00ce2222 },
1447 { 0x0014, 0x01001523 },
1448 { 0x001C, 0x1024010d },
1449 { 0x0024, 0x00cb2522 },
1450 { 0x0038, 0xffffff82 },
1451 { 0x003C, 0x00000000 },
1452 { 0x0040, 0x00000000 },
1453 { 0x0044, 0x00000000 },
1454 { 0x0048, 0x00000000 },
1455 { 0x004C, 0x00000000 },
1456 { 0x0050, 0x00000000 },
1457 { 0x0054, 0x00000000 },
1458 { 0x0058, 0x00000000 },
1459 { 0x005C, 0x00000000 },
1460 { 0x0060, 0x0f2aa02a },
1461 { 0x0064, 0x003f3005 },
1462 { 0x0068, 0x02020202 },
1463 { 0x0070, 0x00000000 },
1464 { 0x0074, 0x00000000 },
1465 { 0x0078, 0x00000000 },
1466 { 0x007C, 0x00000000 },
1467 { 0x0034, 0x00000001 },
1468 { 0xFF00, 0x00000043 },
1469 { 0x002C, 0x00000942 },
1470 { 0x0030, 0x00000040 },
1471 { 0x0028, 0x00000005 },
1472 { 0x0028, 0x00000007 },
1473 { 0x0028, 0x00000003 },
1474 { 0x0028, 0x00000001 },
1475 { 0x000C, 0x00005a08 },
1476 { 0x002C, 0x00000842 },
1477 { 0x0028, 0x00000001 },
1478 { 0x0030, 0x000003c0 },
1479 { 0x0028, 0x00000003 },
1480 { 0x0030, 0x00000040 },
1481 { 0x0028, 0x00000003 },
1482 { 0x000C, 0x00005a21 },
1483 { 0x0034, 0x00007c03 },
1484 { 0x0120, 0x00005061 },
1485 { 0xffff, 0xffffffff },
1486 };
1487
vInitDRAMReg(ScrnInfoPtr pScrn)1488 static void vInitDRAMReg(ScrnInfoPtr pScrn)
1489 {
1490 AST_DRAMStruct *pjDRAMRegInfo;
1491 ASTRecPtr pAST = ASTPTR(pScrn);
1492 ULONG i, ulTemp, ulData;
1493 UCHAR jReg;
1494 AST2150DRAMParam param;
1495
1496 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
1497
1498 if ((jReg & 0x80) == 0) /* VGA only */
1499 {
1500 if (pAST->jChipType == AST2000)
1501 {
1502 pjDRAMRegInfo = AST2000DRAMTableData;
1503
1504 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
1505 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
1506 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10100) = 0xa8;
1507
1508 do {
1509 ;
1510 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10100) != 0xa8);
1511
1512 }
1513 else /* AST2100/1100 */
1514 {
1515 if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200))
1516 pjDRAMRegInfo = AST2100DRAMTableData;
1517 else
1518 pjDRAMRegInfo = AST1100DRAMTableData;
1519
1520 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
1521 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
1522
1523 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8;
1524 do {
1525 ;
1526 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x12000) != 0x01);
1527
1528 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309;
1529 do {
1530 ;
1531 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) != 0x01);
1532
1533 }
1534
1535 while (pjDRAMRegInfo->Index != 0xFFFF)
1536 {
1537 if (pjDRAMRegInfo->Index == 0xFF00) /* Delay function */
1538 {
1539 for (i=0; i<15; i++)
1540 usleep(pjDRAMRegInfo->Data);
1541 }
1542 else if ( (pjDRAMRegInfo->Index == 0x0004) && (pAST->jChipType != AST2000) )
1543 {
1544 ulData = pjDRAMRegInfo->Data;
1545
1546 if (pAST->jDRAMType == DRAMTYPE_1Gx16)
1547 ulData = 0x00000d89;
1548 else if (pAST->jDRAMType == DRAMTYPE_1Gx32)
1549 ulData = 0x00000c8d;
1550
1551 ulTemp = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12070);
1552 ulTemp &= 0x0000000C;
1553 ulTemp <<= 2;
1554 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + pjDRAMRegInfo->Index) = (ulData | ulTemp);
1555 }
1556 else
1557 {
1558 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + pjDRAMRegInfo->Index) = pjDRAMRegInfo->Data;
1559 }
1560 pjDRAMRegInfo++;
1561 }
1562
1563 /* AST2100/2150 DRAM Calibration, ycchen@021511 */
1564 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10120);
1565 if (ulData == 0x5061) /* 266MHz */
1566 {
1567 param.pjMMIOVirtualAddress = pAST->MMIOVirtualAddr;
1568 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10004);
1569 if (ulData & 0x40)
1570 CBRDLLI_AST2150(¶m, 16); /* 16bits */
1571 else
1572 CBRDLLI_AST2150(¶m, 32); /* 32bits */
1573 }
1574
1575 switch (pAST->jChipType)
1576 {
1577 case AST2000:
1578 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10140) |= 0x40;
1579 break;
1580
1581 case AST1100:
1582 case AST2100:
1583 case AST2200:
1584 case AST2150:
1585 ulTemp = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c);
1586 *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c) = (ulTemp & 0xFFFFFFFD);
1587
1588 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12040) |= 0x40;
1589 break;
1590 }
1591
1592 } /* Init DRAM */
1593
1594 /* wait ready */
1595 do {
1596 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
1597 } while ((jReg & 0x40) == 0);
1598
1599 } /* vInitDRAMReg */
1600
1601 /*
1602 * AST2300 DRAM settings modules
1603 */
1604 #define DDR3 0
1605 #define DDR2 1
1606
1607 typedef struct _AST2300DRAMParam {
1608 UCHAR *pjMMIOVirtualAddress;
1609 ULONG DRAM_Type;
1610 ULONG DRAM_ChipID;
1611 ULONG DRAM_Freq;
1612 ULONG VRAM_Size;
1613 ULONG ODT; /* 0/75/150 */
1614 ULONG WODT; /* 0/40/60/120 */
1615 ULONG RODT;
1616
1617 ULONG DRAM_CONFIG;
1618 ULONG REG_PERIOD;
1619 ULONG REG_MADJ;
1620 ULONG REG_SADJ;
1621 ULONG REG_MRS;
1622 ULONG REG_EMRS;
1623 ULONG REG_AC1;
1624 ULONG REG_AC2;
1625 ULONG REG_DQSIC;
1626 ULONG REG_DRV;
1627 ULONG REG_IOZ;
1628 ULONG REG_DQIDLY;
1629 ULONG REG_FREQ;
1630 ULONG MADJ_MAX;
1631 ULONG DLL2_FINETUNE_STEP;
1632
1633 } AST2300DRAMParam, *PAST2300DRAMParam;
1634
1635 /*
1636 * DQSI DLL CBR Setting
1637 */
1638 #define CBR_SIZE0 ((1 << 10) - 1)
1639 #define CBR_SIZE1 ((4 << 10) - 1)
1640 #define CBR_SIZE2 ((64 << 10) - 1)
1641 #define CBR_PASSNUM 5
1642 #define CBR_PASSNUM2 5
1643 #define CBR_THRESHOLD 10
1644 #define CBR_THRESHOLD2 10
1645 #define TIMEOUT 5000000
1646 #define CBR_PATNUM 8
1647
1648 ULONG pattern[8] ={
1649 0xFF00FF00,
1650 0xCC33CC33,
1651 0xAA55AA55,
1652 0x88778877,
1653 0x92CC4D6E,
1654 0x543D3CDE,
1655 0xF1E843C7,
1656 0x7C61D253};
1657
MMCTestBurst(PAST2300DRAMParam param,ULONG datagen)1658 static int MMCTestBurst(PAST2300DRAMParam param, ULONG datagen)
1659 {
1660 ULONG data, timeout;
1661 UCHAR *mmiobase;
1662
1663 mmiobase = param->pjMMIOVirtualAddress;
1664
1665 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1666 MOutdwm(mmiobase, 0x1E6E0070, 0x000000C1 | (datagen << 3));
1667 timeout = 0;
1668 do{
1669 data = MIndwm(mmiobase, 0x1E6E0070) & 0x3000;
1670 if(data & 0x2000){
1671 return(0);
1672 }
1673 if(++timeout > TIMEOUT){
1674 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1675 return(0);
1676 }
1677 }while(!data);
1678 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1679 return(1);
1680 }
1681
MMCTestBurst2(PAST2300DRAMParam param,ULONG datagen)1682 static int MMCTestBurst2(PAST2300DRAMParam param, ULONG datagen)
1683 {
1684 ULONG data, timeout;
1685 UCHAR *mmiobase;
1686
1687 mmiobase = param->pjMMIOVirtualAddress;
1688
1689 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1690 MOutdwm(mmiobase, 0x1E6E0070, 0x00000041 | (datagen << 3));
1691 timeout = 0;
1692 do{
1693 data = MIndwm(mmiobase, 0x1E6E0070) & 0x1000;
1694 if(++timeout > TIMEOUT){
1695 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1696 return(-1);
1697 }
1698 }while(!data);
1699 data = MIndwm(mmiobase, 0x1E6E0078);
1700 data = (data | (data >> 16)) & 0xFFFF;
1701 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1702 return(data);
1703 }
1704
MMCTestSingle(PAST2300DRAMParam param,ULONG datagen)1705 static int MMCTestSingle(PAST2300DRAMParam param, ULONG datagen)
1706 {
1707 ULONG data, timeout;
1708 UCHAR *mmiobase;
1709
1710 mmiobase = param->pjMMIOVirtualAddress;
1711
1712 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1713 MOutdwm(mmiobase, 0x1E6E0070, 0x000000C5 | (datagen << 3));
1714 timeout = 0;
1715 do{
1716 data = MIndwm(mmiobase, 0x1E6E0070) & 0x3000;
1717 if(data & 0x2000){
1718 return(0);
1719 }
1720 if(++timeout > TIMEOUT){
1721 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1722 return(0);
1723 }
1724 }while(!data);
1725 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1726 return(1);
1727 }
1728
MMCTestSingle2(PAST2300DRAMParam param,ULONG datagen)1729 static int MMCTestSingle2(PAST2300DRAMParam param, ULONG datagen)
1730 {
1731 ULONG data, timeout;
1732 UCHAR *mmiobase;
1733
1734 mmiobase = param->pjMMIOVirtualAddress;
1735
1736 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1737 MOutdwm(mmiobase, 0x1E6E0070, 0x00000005 | (datagen << 3));
1738 timeout = 0;
1739 do{
1740 data = MIndwm(mmiobase, 0x1E6E0070) & 0x1000;
1741 if(++timeout > TIMEOUT){
1742 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1743 return(-1);
1744 }
1745 }while(!data);
1746 data = MIndwm(mmiobase, 0x1E6E0078);
1747 data = (data | (data >> 16)) & 0xFFFF;
1748 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
1749 return(data);
1750 }
1751
CBRTest(PAST2300DRAMParam param)1752 static int CBRTest(PAST2300DRAMParam param)
1753 {
1754 ULONG data;
1755 UCHAR *mmiobase;
1756
1757 mmiobase = param->pjMMIOVirtualAddress;
1758
1759 data = MMCTestSingle2(param, 0); if((data & 0xff) && (data & 0xff00)) return(0);
1760 data |= MMCTestBurst2(param, 00); if((data & 0xff) && (data & 0xff00)) return(0);
1761 data |= MMCTestBurst2(param, 01); if((data & 0xff) && (data & 0xff00)) return(0);
1762 data |= MMCTestBurst2(param, 02); if((data & 0xff) && (data & 0xff00)) return(0);
1763 data |= MMCTestBurst2(param, 03); if((data & 0xff) && (data & 0xff00)) return(0);
1764 data |= MMCTestBurst2(param, 04); if((data & 0xff) && (data & 0xff00)) return(0);
1765 data |= MMCTestBurst2(param, 05); if((data & 0xff) && (data & 0xff00)) return(0);
1766 data |= MMCTestBurst2(param, 06); if((data & 0xff) && (data & 0xff00)) return(0);
1767 data |= MMCTestBurst2(param, 07); if((data & 0xff) && (data & 0xff00)) return(0);
1768 if(!data) return(3);
1769 else if(data & 0xff) return(2);
1770
1771 return(1);
1772 }
1773
CBRScan(PAST2300DRAMParam param)1774 static int CBRScan(PAST2300DRAMParam param)
1775 {
1776 ULONG data, data2, patcnt, loop;
1777 UCHAR *mmiobase;
1778
1779 mmiobase = param->pjMMIOVirtualAddress;
1780
1781 data2 = 3;
1782 for(patcnt = 0;patcnt < CBR_PATNUM;patcnt++){
1783 MOutdwm(mmiobase, 0x1E6E007C, pattern[patcnt]);
1784 for(loop = 0;loop < CBR_PASSNUM2;loop++){
1785 if((data = CBRTest(param)) != 0){
1786 data2 &= data;
1787 if(!data2){
1788 return(0);
1789 }
1790 break;
1791 }
1792 }
1793 if(loop == CBR_PASSNUM2){
1794 return(0);
1795 }
1796 }
1797 return(data2);
1798 }
1799
CBRTest2(PAST2300DRAMParam param)1800 static ULONG CBRTest2(PAST2300DRAMParam param)
1801 {
1802 ULONG data;
1803 UCHAR *mmiobase;
1804
1805 mmiobase = param->pjMMIOVirtualAddress;
1806
1807 data = MMCTestBurst2(param, 0); if(data == 0xffff) return(0);
1808 data |= MMCTestSingle2(param, 0); if(data == 0xffff) return(0);
1809 return(~data & 0xffff);
1810 }
1811
CBRScan2(PAST2300DRAMParam param)1812 static ULONG CBRScan2(PAST2300DRAMParam param)
1813 {
1814 ULONG data, data2, patcnt, loop;
1815 UCHAR *mmiobase;
1816
1817 mmiobase = param->pjMMIOVirtualAddress;
1818
1819 data2 = 0xffff;
1820 for(patcnt = 0;patcnt < CBR_PATNUM;patcnt++){
1821 MOutdwm(mmiobase, 0x1E6E007C, pattern[patcnt]);
1822 for(loop = 0;loop < CBR_PASSNUM2;loop++){
1823 if((data = CBRTest2(param)) != 0){
1824 data2 &= data;
1825 if(!data2){
1826 return(0);
1827 }
1828 break;
1829 }
1830 }
1831 if(loop == CBR_PASSNUM2){
1832 return(0);
1833 }
1834 }
1835 return(data2);
1836 }
1837
CBRTest3(PAST2300DRAMParam param)1838 static ULONG CBRTest3(PAST2300DRAMParam param)
1839 {
1840 if(!MMCTestBurst(param, 0)) return(0);
1841 if(!MMCTestSingle(param, 0)) return(0);
1842 return(1);
1843 }
1844
CBRScan3(PAST2300DRAMParam param)1845 static ULONG CBRScan3(PAST2300DRAMParam param)
1846 {
1847 ULONG patcnt, loop;
1848 UCHAR *mmiobase;
1849
1850 mmiobase = param->pjMMIOVirtualAddress;
1851
1852 for(patcnt = 0;patcnt < CBR_PATNUM;patcnt++){
1853 MOutdwm(mmiobase, 0x1E6E007C, pattern[patcnt]);
1854 for(loop = 0;loop < 2;loop++){
1855 if(CBRTest3(param)){
1856 break;
1857 }
1858 }
1859 if(loop == 2){
1860 return(0);
1861 }
1862 }
1863 return(1);
1864 }
1865
finetuneDQI_L(PAST2300DRAMParam param)1866 static Bool finetuneDQI_L(PAST2300DRAMParam param)
1867 {
1868 ULONG gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
1869 UCHAR *mmiobase;
1870 Bool status = FALSE;
1871
1872 mmiobase = param->pjMMIOVirtualAddress;
1873
1874 FINETUNE_START:
1875 for(cnt = 0;cnt < 16;cnt++){
1876 dllmin[cnt] = 0xff;
1877 dllmax[cnt] = 0x0;
1878 }
1879 passcnt = 0;
1880 for(dlli = 0;dlli < 76;dlli++){
1881 MOutdwm(mmiobase, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
1882 MOutdwm(mmiobase, 0x1E6E0074, CBR_SIZE1);
1883 data = CBRScan2(param);
1884 if(data != 0){
1885 mask = 0x00010001;
1886 for(cnt = 0;cnt < 16;cnt++){
1887 if(data & mask){
1888 if(dllmin[cnt] > dlli){
1889 dllmin[cnt] = dlli;
1890 }
1891 if(dllmax[cnt] < dlli){
1892 dllmax[cnt] = dlli;
1893 }
1894 }
1895 mask <<= 1;
1896 }
1897 passcnt++;
1898 }else if(passcnt >= CBR_THRESHOLD2){
1899 break;
1900 }
1901 }
1902 gold_sadj[0] = 0x0;
1903 passcnt = 0;
1904 for(cnt = 0;cnt < 16;cnt++){
1905 if((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)){
1906 gold_sadj[0] += dllmin[cnt];
1907 passcnt++;
1908 }
1909 }
1910 if (retry++ > 10)
1911 goto FINETUNE_DONE;
1912 if(passcnt != 16){
1913 goto FINETUNE_START;
1914 }
1915 status = TRUE;
1916
1917 FINETUNE_DONE:
1918 gold_sadj[0] = gold_sadj[0] >> 4;
1919 gold_sadj[1] = gold_sadj[0];
1920
1921 data = 0;
1922 for(cnt = 0;cnt < 8;cnt++){
1923 data >>= 3;
1924 if((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)){
1925 dlli = dllmin[cnt];
1926 if(gold_sadj[0] >= dlli){
1927 dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
1928 if(dlli > 3){
1929 dlli = 3;
1930 }
1931 }else{
1932 dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
1933 if(dlli > 4){
1934 dlli = 4;
1935 }
1936 dlli = (8 - dlli) & 0x7;
1937 }
1938 data |= dlli << 21;
1939 }
1940 }
1941 MOutdwm(mmiobase, 0x1E6E0080, data);
1942
1943 data = 0;
1944 for(cnt = 8;cnt < 16;cnt++){
1945 data >>= 3;
1946 if((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)){
1947 dlli = dllmin[cnt];
1948 if(gold_sadj[1] >= dlli){
1949 dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
1950 if(dlli > 3){
1951 dlli = 3;
1952 }else{
1953 dlli = (dlli - 1) & 0x7;
1954 }
1955 }else{
1956 dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
1957 dlli += 1;
1958 if(dlli > 4){
1959 dlli = 4;
1960 }
1961 dlli = (8 - dlli) & 0x7;
1962 }
1963 data |= dlli << 21;
1964 }
1965 }
1966 MOutdwm(mmiobase, 0x1E6E0084, data);
1967
1968 return status;
1969
1970 } /* finetuneDQI_L */
1971
finetuneDQSI(PAST2300DRAMParam param)1972 static void finetuneDQSI(PAST2300DRAMParam param)
1973 {
1974 ULONG dlli, dqsip, dqidly, cnt;
1975 ULONG reg_mcr18, reg_mcr0c, passcnt[2], diff;
1976 ULONG g_dqidly, g_dqsip, g_margin, g_side;
1977 unsigned short pass[32][2][2];
1978 char tag[2][76];
1979 UCHAR *mmiobase;
1980
1981 mmiobase = param->pjMMIOVirtualAddress;
1982
1983 /* Disable DQI CBR */
1984 reg_mcr0c = MIndwm(mmiobase, 0x1E6E000C);
1985 reg_mcr18 = MIndwm(mmiobase, 0x1E6E0018);
1986 reg_mcr18 &= 0x0000ffff;
1987 MOutdwm(mmiobase, 0x1E6E0018, reg_mcr18);
1988
1989 for(dlli = 0;dlli < 76;dlli++){
1990 tag[0][dlli] = 0x0;
1991 tag[1][dlli] = 0x0;
1992 }
1993 for(dqidly = 0;dqidly < 32;dqidly++){
1994 pass[dqidly][0][0] = 0xff;
1995 pass[dqidly][0][1] = 0x0;
1996 pass[dqidly][1][0] = 0xff;
1997 pass[dqidly][1][1] = 0x0;
1998 }
1999 for(dqidly = 0;dqidly < 32;dqidly++){
2000 passcnt[0] = passcnt[1] = 0;
2001 for(dqsip = 0;dqsip < 2;dqsip++){
2002 MOutdwm(mmiobase, 0x1E6E000C, 0);
2003 MOutdwm(mmiobase, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
2004 MOutdwm(mmiobase, 0x1E6E000C, reg_mcr0c);
2005 for(dlli = 0;dlli < 76;dlli++){
2006 MOutdwm(mmiobase, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
2007 MOutdwm(mmiobase, 0x1E6E0070, 0);
2008 MOutdwm(mmiobase, 0x1E6E0074, CBR_SIZE0);
2009 if(CBRScan3(param)){
2010 if(dlli == 0){
2011 break;
2012 }
2013 passcnt[dqsip]++;
2014 tag[dqsip][dlli] = 'P';
2015 if(dlli < pass[dqidly][dqsip][0]){
2016 pass[dqidly][dqsip][0] = (USHORT) dlli;
2017 }
2018 if(dlli > pass[dqidly][dqsip][1]){
2019 pass[dqidly][dqsip][1] = (USHORT) dlli;
2020 }
2021 }else if(passcnt[dqsip] >= 5){
2022 break;
2023 }else{
2024 pass[dqidly][dqsip][0] = 0xff;
2025 pass[dqidly][dqsip][1] = 0x0;
2026 }
2027 }
2028 }
2029 if(passcnt[0] == 0 && passcnt[1] == 0){
2030 dqidly++;
2031 }
2032 }
2033 /* Search margin */
2034 g_dqidly = g_dqsip = g_margin = g_side = 0;
2035
2036 for(dqidly = 0;dqidly < 32;dqidly++){
2037 for(dqsip = 0;dqsip < 2;dqsip++){
2038 if(pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1]){
2039 continue;
2040 }
2041 diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
2042 if((diff+2) < g_margin){
2043 continue;
2044 }
2045 passcnt[0] = passcnt[1] = 0;
2046 for(dlli = pass[dqidly][dqsip][0];dlli > 0 && tag[dqsip][dlli] != 0;dlli--,passcnt[0]++);
2047 for(dlli = pass[dqidly][dqsip][1];dlli < 76 && tag[dqsip][dlli] != 0;dlli++,passcnt[1]++);
2048 if(passcnt[0] > passcnt[1]){
2049 passcnt[0] = passcnt[1];
2050 }
2051 passcnt[1] = 0;
2052 if(passcnt[0] > g_side){
2053 passcnt[1] = passcnt[0] - g_side;
2054 }
2055 if(diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)){
2056 g_margin = diff;
2057 g_dqidly = dqidly;
2058 g_dqsip = dqsip;
2059 g_side = passcnt[0];
2060 }else if(passcnt[1] > 1 && g_side < 8){
2061 if(diff > g_margin){
2062 g_margin = diff;
2063 }
2064 g_dqidly = dqidly;
2065 g_dqsip = dqsip;
2066 g_side = passcnt[0];
2067 }
2068 }
2069 }
2070 reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
2071 MOutdwm(mmiobase, 0x1E6E0018, reg_mcr18);
2072 } /* finetuneDQSI */
2073
CBRDLL2(PAST2300DRAMParam param)2074 static Bool CBRDLL2(PAST2300DRAMParam param)
2075 {
2076 ULONG dllmin[2], dllmax[2], dlli, data, data2, passcnt, retry=0;
2077 UCHAR *mmiobase;
2078 BOOL status = FALSE;
2079
2080 mmiobase = param->pjMMIOVirtualAddress;
2081
2082 finetuneDQSI(param);
2083 if (finetuneDQI_L(param) == FALSE)
2084 return status;
2085
2086 CBR_START2:
2087 dllmin[0] = dllmin[1] = 0xff;
2088 dllmax[0] = dllmax[1] = 0x0;
2089 passcnt = 0;
2090 for(dlli = 0;dlli < 76;dlli++){
2091 MOutdwm(mmiobase, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
2092 MOutdwm(mmiobase, 0x1E6E0074, CBR_SIZE2);
2093 data = CBRScan(param);
2094 if(data != 0){
2095 if(data & 0x1){
2096 if(dllmin[0] > dlli){
2097 dllmin[0] = dlli;
2098 }
2099 if(dllmax[0] < dlli){
2100 dllmax[0] = dlli;
2101 }
2102 }
2103 if(data & 0x2){
2104 if(dllmin[1] > dlli){
2105 dllmin[1] = dlli;
2106 }
2107 if(dllmax[1] < dlli){
2108 dllmax[1] = dlli;
2109 }
2110 }
2111 passcnt++;
2112 }else if(passcnt >= CBR_THRESHOLD){
2113 break;
2114 }
2115 }
2116 if (retry++ > 10)
2117 goto CBR_DONE2;
2118 if(dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD){
2119 goto CBR_START2;
2120 }
2121 if(dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD){
2122 goto CBR_START2;
2123 }
2124 status = TRUE;
2125
2126 CBR_DONE2:
2127 dlli = (dllmin[1] + dllmax[1]) >> 1;
2128 dlli <<= 8;
2129 dlli += (dllmin[0] + dllmax[0]) >> 1;
2130 MOutdwm(mmiobase, 0x1E6E0068, MIndwm(mmiobase, 0x1E720058) | (dlli << 16));
2131
2132 return status;
2133
2134 } /* CBRDLL2 */
2135
GetDDR2Info(PAST2300DRAMParam param)2136 static void GetDDR2Info(PAST2300DRAMParam param)
2137 {
2138 UCHAR *mmiobase;
2139 ULONG trap, TRAP_AC2, TRAP_MRS;
2140
2141 mmiobase = param->pjMMIOVirtualAddress;
2142 MOutdwm(mmiobase, 0x1E6E2000, 0x1688A8A8);
2143
2144 /* Ger trap info */
2145 trap = (MIndwm(mmiobase, 0x1E6E2070) >> 25) & 0x3;
2146 TRAP_AC2 = (trap << 20) | (trap << 16);
2147 TRAP_AC2 += 0x00110000;
2148 TRAP_MRS = 0x00000040 | (trap << 4);
2149
2150
2151 param->REG_MADJ = 0x00034C4C;
2152 param->REG_SADJ = 0x00001800;
2153 param->REG_DRV = 0x000000F0;
2154 param->REG_PERIOD = param->DRAM_Freq;
2155 param->RODT = 0;
2156
2157 switch(param->DRAM_Freq){
2158 case 264 : MOutdwm(mmiobase, 0x1E6E2020, 0x0130);
2159 param->WODT = 0;
2160 param->REG_AC1 = 0x11101513;
2161 param->REG_AC2 = 0x78117011;
2162 param->REG_DQSIC = 0x00000092;
2163 param->REG_MRS = 0x00000842;
2164 param->REG_EMRS = 0x00000000;
2165 param->REG_DRV = 0x000000F0;
2166 param->REG_IOZ = 0x00000034;
2167 param->REG_DQIDLY = 0x0000005A;
2168 param->REG_FREQ = 0x00004AC0;
2169 param->MADJ_MAX = 138;
2170 param->DLL2_FINETUNE_STEP = 3;
2171 break;
2172 case 336 : MOutdwm(mmiobase, 0x1E6E2020, 0x0331);
2173 param->WODT = 1;
2174 param->REG_AC1 = 0x22202613;
2175 param->REG_AC2 = 0xAA009016 | TRAP_AC2;
2176 param->REG_DQSIC = 0x000000BA;
2177 param->REG_MRS = 0x00000A02 | TRAP_MRS;
2178 param->REG_EMRS = 0x00000040;
2179 param->REG_DRV = 0x000000FA;
2180 param->REG_IOZ = 0x00000013;
2181 param->REG_DQIDLY = 0x00000074;
2182 param->REG_FREQ = 0x00004DC0;
2183 param->MADJ_MAX = 96;
2184 param->DLL2_FINETUNE_STEP = 3;
2185
2186 switch (param->DRAM_ChipID)
2187 {
2188 case DRAMTYPE_512Mx16:
2189 param->REG_AC2 = 0xAA009012 | TRAP_AC2;
2190 break;
2191 default:
2192 case DRAMTYPE_1Gx16:
2193 param->REG_AC2 = 0xAA009016 | TRAP_AC2;
2194 break;
2195 case DRAMTYPE_2Gx16:
2196 param->REG_AC2 = 0xAA009023 | TRAP_AC2;
2197 break;
2198 case DRAMTYPE_4Gx16:
2199 param->REG_AC2 = 0xAA00903B | TRAP_AC2;
2200 break;
2201 }
2202
2203 break;
2204 default:
2205 case 396 : MOutdwm(mmiobase, 0x1E6E2020, 0x03F1);
2206 param->WODT = 1;
2207 param->RODT = 0;
2208 param->REG_AC1 = 0x33302714;
2209 param->REG_AC2 = 0xCC00B01B | TRAP_AC2;
2210 param->REG_DQSIC = 0x000000E2;
2211 param->REG_MRS = 0x00000C02 | TRAP_MRS;
2212 param->REG_EMRS = 0x00000040;
2213 param->REG_DRV = 0x000000FA;
2214 param->REG_IOZ = 0x00000034;
2215 param->REG_DQIDLY = 0x00000089;
2216 param->REG_FREQ = 0x00005040;
2217 param->MADJ_MAX = 96;
2218 param->DLL2_FINETUNE_STEP = 4;
2219
2220 switch (param->DRAM_ChipID)
2221 {
2222 case DRAMTYPE_512Mx16:
2223 param->REG_AC2 = 0xCC00B016 | TRAP_AC2;
2224 break;
2225 default:
2226 case DRAMTYPE_1Gx16:
2227 param->REG_AC2 = 0xCC00B01B | TRAP_AC2;
2228 break;
2229 case DRAMTYPE_2Gx16:
2230 param->REG_AC2 = 0xCC00B02B | TRAP_AC2;
2231 break;
2232 case DRAMTYPE_4Gx16:
2233 param->REG_AC2 = 0xCC00B03F | TRAP_AC2;
2234 break;
2235 }
2236
2237 break;
2238
2239 case 408 : MOutdwm(mmiobase, 0x1E6E2020, 0x01F0);
2240 param->WODT = 1;
2241 param->RODT = 0;
2242 param->REG_AC1 = 0x33302714;
2243 param->REG_AC2 = 0xCC00B01B | TRAP_AC2;
2244 param->REG_DQSIC = 0x000000E2;
2245 param->REG_MRS = 0x00000C02 | TRAP_MRS;
2246 param->REG_EMRS = 0x00000040;
2247 param->REG_DRV = 0x000000FA;
2248 param->REG_IOZ = 0x00000034;
2249 param->REG_DQIDLY = 0x00000089;
2250 param->REG_FREQ = 0x000050C0;
2251 param->MADJ_MAX = 96;
2252 param->DLL2_FINETUNE_STEP = 4;
2253
2254 switch (param->DRAM_ChipID)
2255 {
2256 case DRAMTYPE_512Mx16:
2257 param->REG_AC2 = 0xCC00B016 | TRAP_AC2;
2258 break;
2259 default:
2260 case DRAMTYPE_1Gx16:
2261 param->REG_AC2 = 0xCC00B01B | TRAP_AC2;
2262 break;
2263 case DRAMTYPE_2Gx16:
2264 param->REG_AC2 = 0xCC00B02B | TRAP_AC2;
2265 break;
2266 case DRAMTYPE_4Gx16:
2267 param->REG_AC2 = 0xCC00B03F | TRAP_AC2;
2268 break;
2269 }
2270
2271 break;
2272 case 456 : MOutdwm(mmiobase, 0x1E6E2020, 0x0230);
2273 param->WODT = 0;
2274 param->REG_AC1 = 0x33302815;
2275 param->REG_AC2 = 0xCD44B01E;
2276 param->REG_DQSIC = 0x000000FC;
2277 param->REG_MRS = 0x00000E72;
2278 param->REG_EMRS = 0x00000000;
2279 param->REG_DRV = 0x00000000;
2280 param->REG_IOZ = 0x00000034;
2281 param->REG_DQIDLY = 0x00000097;
2282 param->REG_FREQ = 0x000052C0;
2283 param->MADJ_MAX = 88;
2284 param->DLL2_FINETUNE_STEP = 3;
2285 break;
2286 case 504 : MOutdwm(mmiobase, 0x1E6E2020, 0x0261);
2287 param->WODT = 1;
2288 param->RODT = 1;
2289 param->REG_AC1 = 0x33302815;
2290 param->REG_AC2 = 0xDE44C022;
2291 param->REG_DQSIC = 0x00000117;
2292 param->REG_MRS = 0x00000E72;
2293 param->REG_EMRS = 0x00000040;
2294 param->REG_DRV = 0x0000000A;
2295 param->REG_IOZ = 0x00000045;
2296 param->REG_DQIDLY = 0x000000A0;
2297 param->REG_FREQ = 0x000054C0;
2298 param->MADJ_MAX = 79;
2299 param->DLL2_FINETUNE_STEP = 3;
2300 break;
2301 case 528 : MOutdwm(mmiobase, 0x1E6E2020, 0x0120);
2302 param->WODT = 1;
2303 param->RODT = 1;
2304 param->REG_AC1 = 0x33302815;
2305 param->REG_AC2 = 0xEF44D024;
2306 param->REG_DQSIC = 0x00000125;
2307 param->REG_MRS = 0x00000E72;
2308 param->REG_EMRS = 0x00000004;
2309 param->REG_DRV = 0x000000F9;
2310 param->REG_IOZ = 0x00000045;
2311 param->REG_DQIDLY = 0x000000A7;
2312 param->REG_FREQ = 0x000055C0;
2313 param->MADJ_MAX = 76;
2314 param->DLL2_FINETUNE_STEP = 3;
2315 break;
2316 case 552 : MOutdwm(mmiobase, 0x1E6E2020, 0x02A1);
2317 param->WODT = 1;
2318 param->RODT = 1;
2319 param->REG_AC1 = 0x43402915;
2320 param->REG_AC2 = 0xFF44E025;
2321 param->REG_DQSIC = 0x00000132;
2322 param->REG_MRS = 0x00000E72;
2323 param->REG_EMRS = 0x00000040;
2324 param->REG_DRV = 0x0000000A;
2325 param->REG_IOZ = 0x00000045;
2326 param->REG_DQIDLY = 0x000000AD;
2327 param->REG_FREQ = 0x000056C0;
2328 param->MADJ_MAX = 76;
2329 param->DLL2_FINETUNE_STEP = 3;
2330 break;
2331 case 576 : MOutdwm(mmiobase, 0x1E6E2020, 0x0140);
2332 param->WODT = 1;
2333 param->RODT = 1;
2334 param->REG_AC1 = 0x43402915;
2335 param->REG_AC2 = 0xFF44E027;
2336 param->REG_DQSIC = 0x0000013F;
2337 param->REG_MRS = 0x00000E72;
2338 param->REG_EMRS = 0x00000004;
2339 param->REG_DRV = 0x000000F5;
2340 param->REG_IOZ = 0x00000045;
2341 param->REG_DQIDLY = 0x000000B3;
2342 param->REG_FREQ = 0x000057C0;
2343 param->MADJ_MAX = 76;
2344 param->DLL2_FINETUNE_STEP = 3;
2345 break;
2346 }
2347
2348 switch (param->DRAM_ChipID)
2349 {
2350 case DRAMTYPE_512Mx16:
2351 param->DRAM_CONFIG = 0x100;
2352 break;
2353 default:
2354 case DRAMTYPE_1Gx16:
2355 param->DRAM_CONFIG = 0x121;
2356 break;
2357 case DRAMTYPE_2Gx16:
2358 param->DRAM_CONFIG = 0x122;
2359 break;
2360 case DRAMTYPE_4Gx16:
2361 param->DRAM_CONFIG = 0x123;
2362 break;
2363 }; /* switch size */
2364
2365 switch (param->VRAM_Size)
2366 {
2367 default:
2368 case VIDEOMEM_SIZE_08M:
2369 param->DRAM_CONFIG |= 0x00;
2370 break;
2371 case VIDEOMEM_SIZE_16M:
2372 param->DRAM_CONFIG |= 0x04;
2373 break;
2374 case VIDEOMEM_SIZE_32M:
2375 param->DRAM_CONFIG |= 0x08;
2376 break;
2377 case VIDEOMEM_SIZE_64M:
2378 param->DRAM_CONFIG |= 0x0c;
2379 break;
2380 }
2381
2382 }
2383
GetDDR3Info(PAST2300DRAMParam param)2384 static void GetDDR3Info(PAST2300DRAMParam param)
2385 {
2386 UCHAR *mmiobase;
2387 ULONG trap, TRAP_AC2, TRAP_MRS;
2388
2389 mmiobase = param->pjMMIOVirtualAddress;
2390 MOutdwm(mmiobase, 0x1E6E2000, 0x1688A8A8);
2391
2392 /* Ger trap info */
2393 trap = (MIndwm(mmiobase, 0x1E6E2070) >> 25) & 0x3;
2394 TRAP_AC2 = 0x00020000 + (trap << 16);
2395 TRAP_AC2 |= 0x00300000 +((trap & 0x2) << 19);
2396 TRAP_MRS = 0x00000010 + (trap << 4);
2397 TRAP_MRS |= ((trap & 0x2) << 18);
2398
2399 param->REG_MADJ = 0x00034C4C;
2400 param->REG_SADJ = 0x00001800;
2401 param->REG_DRV = 0x000000F0;
2402 param->REG_PERIOD = param->DRAM_Freq;
2403 param->RODT = 0;
2404
2405 switch(param->DRAM_Freq){
2406 case 336 : MOutdwm(mmiobase, 0x1E6E2020, 0x0331);
2407 param->WODT = 0;
2408 param->REG_AC1 = 0x22202725;
2409 param->REG_AC2 = 0xAA007613 | TRAP_AC2;
2410 param->REG_DQSIC = 0x000000BA;
2411 param->REG_MRS = 0x04001400 | TRAP_MRS;
2412 param->REG_EMRS = 0x00000000;
2413 param->REG_IOZ = 0x00000023;
2414 param->REG_DQIDLY = 0x00000074;
2415 param->REG_FREQ = 0x00004DC0;
2416 param->MADJ_MAX = 96;
2417 param->DLL2_FINETUNE_STEP = 3;
2418
2419 switch (param->DRAM_ChipID)
2420 {
2421 default:
2422 case DRAMTYPE_512Mx16:
2423 case DRAMTYPE_1Gx16:
2424 param->REG_AC2 = 0xAA007613 | TRAP_AC2;
2425 break;
2426 case DRAMTYPE_2Gx16:
2427 param->REG_AC2 = 0xAA00761c | TRAP_AC2;
2428 break;
2429 case DRAMTYPE_4Gx16:
2430 param->REG_AC2 = 0xAA007636 | TRAP_AC2;
2431 break;
2432 }
2433
2434 break;
2435 default:
2436 case 396 : MOutdwm(mmiobase, 0x1E6E2020, 0x03F1);
2437 param->WODT = 1;
2438 param->REG_AC1 = 0x33302825;
2439 param->REG_AC2 = 0xCC009617 | TRAP_AC2;
2440 param->REG_DQSIC = 0x000000E2;
2441 param->REG_MRS = 0x04001600 | TRAP_MRS;
2442 param->REG_EMRS = 0x00000000;
2443 param->REG_IOZ = 0x00000023;
2444 param->REG_DRV = 0x000000FA;
2445 param->REG_DQIDLY = 0x00000089;
2446 param->REG_FREQ = 0x00005040;
2447 param->MADJ_MAX = 96;
2448 param->DLL2_FINETUNE_STEP = 4;
2449
2450 switch (param->DRAM_ChipID)
2451 {
2452 default:
2453 case DRAMTYPE_512Mx16:
2454 case DRAMTYPE_1Gx16:
2455 param->REG_AC2 = 0xCC009617 | TRAP_AC2;
2456 break;
2457 case DRAMTYPE_2Gx16:
2458 param->REG_AC2 = 0xCC009622 | TRAP_AC2;
2459 break;
2460 case DRAMTYPE_4Gx16:
2461 param->REG_AC2 = 0xCC00963F | TRAP_AC2;
2462 break;
2463 }
2464
2465 break;
2466
2467 case 408 : MOutdwm(mmiobase, 0x1E6E2020, 0x01F0);
2468 param->WODT = 1;
2469 param->REG_AC1 = 0x33302825;
2470 param->REG_AC2 = 0xCC009617 | TRAP_AC2;
2471 param->REG_DQSIC = 0x000000E2;
2472 param->REG_MRS = 0x04001600 | TRAP_MRS;
2473 param->REG_EMRS = 0x00000000;
2474 param->REG_IOZ = 0x00000023;
2475 param->REG_DRV = 0x000000FA;
2476 param->REG_DQIDLY = 0x00000089;
2477 param->REG_FREQ = 0x000050C0;
2478 param->MADJ_MAX = 96;
2479 param->DLL2_FINETUNE_STEP = 4;
2480
2481 switch (param->DRAM_ChipID)
2482 {
2483 default:
2484 case DRAMTYPE_512Mx16:
2485 case DRAMTYPE_1Gx16:
2486 param->REG_AC2 = 0xCC009617 | TRAP_AC2;
2487 break;
2488 case DRAMTYPE_2Gx16:
2489 param->REG_AC2 = 0xCC009622 | TRAP_AC2;
2490 break;
2491 case DRAMTYPE_4Gx16:
2492 param->REG_AC2 = 0xCC00963F | TRAP_AC2;
2493 break;
2494 }
2495
2496 break;
2497 case 456 : MOutdwm(mmiobase, 0x1E6E2020, 0x0230);
2498 param->WODT = 0;
2499 param->REG_AC1 = 0x33302926;
2500 param->REG_AC2 = 0xCD44961A;
2501 param->REG_DQSIC = 0x000000FC;
2502 param->REG_MRS = 0x00081830;
2503 param->REG_EMRS = 0x00000000;
2504 param->REG_IOZ = 0x00000045;
2505 param->REG_DQIDLY = 0x00000097;
2506 param->REG_FREQ = 0x000052C0;
2507 param->MADJ_MAX = 88;
2508 param->DLL2_FINETUNE_STEP = 4;
2509 break;
2510 case 504 : MOutdwm(mmiobase, 0x1E6E2020, 0x0270);
2511 param->WODT = 1;
2512 param->REG_AC1 = 0x33302926;
2513 param->REG_AC2 = 0xDE44A61D;
2514 param->REG_DQSIC = 0x00000117;
2515 param->REG_MRS = 0x00081A30;
2516 param->REG_EMRS = 0x00000000;
2517 param->REG_IOZ = 0x070000BB;
2518 param->REG_DQIDLY = 0x000000A0;
2519 param->REG_FREQ = 0x000054C0;
2520 param->MADJ_MAX = 79;
2521 param->DLL2_FINETUNE_STEP = 4;
2522 break;
2523 case 528 : MOutdwm(mmiobase, 0x1E6E2020, 0x0290);
2524 param->WODT = 1;
2525 param->RODT = 1;
2526 param->REG_AC1 = 0x33302926;
2527 param->REG_AC2 = 0xEF44B61E;
2528 param->REG_DQSIC = 0x00000125;
2529 param->REG_MRS = 0x00081A30;
2530 param->REG_EMRS = 0x00000040;
2531 param->REG_DRV = 0x000000F5;
2532 param->REG_IOZ = 0x00000023;
2533 param->REG_DQIDLY = 0x00000088;
2534 param->REG_FREQ = 0x000055C0;
2535 param->MADJ_MAX = 76;
2536 param->DLL2_FINETUNE_STEP = 3;
2537 break;
2538 case 576 : MOutdwm(mmiobase, 0x1E6E2020, 0x0140);
2539 param->REG_MADJ = 0x00136868;
2540 param->REG_SADJ = 0x00004534;
2541 param->WODT = 1;
2542 param->RODT = 1;
2543 param->REG_AC1 = 0x33302A37;
2544 param->REG_AC2 = 0xEF56B61E;
2545 param->REG_DQSIC = 0x0000013F;
2546 param->REG_MRS = 0x00101A50;
2547 param->REG_EMRS = 0x00000040;
2548 param->REG_DRV = 0x000000FA;
2549 param->REG_IOZ = 0x00000023;
2550 param->REG_DQIDLY = 0x00000078;
2551 param->REG_FREQ = 0x000057C0;
2552 param->MADJ_MAX = 136;
2553 param->DLL2_FINETUNE_STEP = 3;
2554 break;
2555 case 600 : MOutdwm(mmiobase, 0x1E6E2020, 0x02E1);
2556 param->REG_MADJ = 0x00136868;
2557 param->REG_SADJ = 0x00004534;
2558 param->WODT = 1;
2559 param->RODT = 1;
2560 param->REG_AC1 = 0x32302A37;
2561 param->REG_AC2 = 0xDF56B61F;
2562 param->REG_DQSIC = 0x0000014D;
2563 param->REG_MRS = 0x00101A50;
2564 param->REG_EMRS = 0x00000004;
2565 param->REG_DRV = 0x000000F5;
2566 param->REG_IOZ = 0x00000023;
2567 param->REG_DQIDLY = 0x00000078;
2568 param->REG_FREQ = 0x000058C0;
2569 param->MADJ_MAX = 132;
2570 param->DLL2_FINETUNE_STEP = 3;
2571 break;
2572 case 624 : MOutdwm(mmiobase, 0x1E6E2020, 0x0160);
2573 param->REG_MADJ = 0x00136868;
2574 param->REG_SADJ = 0x00004534;
2575 param->WODT = 1;
2576 param->RODT = 1;
2577 param->REG_AC1 = 0x32302A37;
2578 param->REG_AC2 = 0xEF56B621;
2579 param->REG_DQSIC = 0x0000015A;
2580 param->REG_MRS = 0x02101A50;
2581 param->REG_EMRS = 0x00000004;
2582 param->REG_DRV = 0x000000F5;
2583 param->REG_IOZ = 0x00000034;
2584 param->REG_DQIDLY = 0x00000078;
2585 param->REG_FREQ = 0x000059C0;
2586 param->MADJ_MAX = 128;
2587 param->DLL2_FINETUNE_STEP = 3;
2588 break;
2589 } /* switch freq */
2590
2591 switch (param->DRAM_ChipID)
2592 {
2593 case DRAMTYPE_512Mx16:
2594 param->DRAM_CONFIG = 0x130;
2595 break;
2596 default:
2597 case DRAMTYPE_1Gx16:
2598 param->DRAM_CONFIG = 0x131;
2599 break;
2600 case DRAMTYPE_2Gx16:
2601 param->DRAM_CONFIG = 0x132;
2602 break;
2603 case DRAMTYPE_4Gx16:
2604 param->DRAM_CONFIG = 0x133;
2605 break;
2606 }; /* switch size */
2607
2608 switch (param->VRAM_Size)
2609 {
2610 default:
2611 case VIDEOMEM_SIZE_08M:
2612 param->DRAM_CONFIG |= 0x00;
2613 break;
2614 case VIDEOMEM_SIZE_16M:
2615 param->DRAM_CONFIG |= 0x04;
2616 break;
2617 case VIDEOMEM_SIZE_32M:
2618 param->DRAM_CONFIG |= 0x08;
2619 break;
2620 case VIDEOMEM_SIZE_64M:
2621 param->DRAM_CONFIG |= 0x0c;
2622 break;
2623 }
2624
2625 }
2626
DDR2_Init(PAST2300DRAMParam param)2627 static void DDR2_Init(PAST2300DRAMParam param)
2628 {
2629 ULONG data, data2, retry = 0;
2630 UCHAR *mmiobase;
2631
2632 mmiobase = param->pjMMIOVirtualAddress;
2633
2634 DDR2_Init_Start:
2635 MOutdwm(mmiobase, 0x1E6E0000, 0xFC600309);
2636 MOutdwm(mmiobase, 0x1E6E0064, 0x00000000);
2637 MOutdwm(mmiobase, 0x1E6E0034, 0x00000000);
2638 MOutdwm(mmiobase, 0x1E6E0018, 0x00000100);
2639 MOutdwm(mmiobase, 0x1E6E0024, 0x00000000);
2640 MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ);
2641 MOutdwm(mmiobase, 0x1E6E0068, param->REG_SADJ);
2642 usleep(10);
2643 MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0xC0000);
2644 usleep(10);
2645
2646 MOutdwm(mmiobase, 0x1E6E0004, param->DRAM_CONFIG);
2647 MOutdwm(mmiobase, 0x1E6E0008, 0x90040f);
2648 MOutdwm(mmiobase, 0x1E6E0010, param->REG_AC1);
2649 MOutdwm(mmiobase, 0x1E6E0014, param->REG_AC2);
2650 MOutdwm(mmiobase, 0x1E6E0020, param->REG_DQSIC);
2651 MOutdwm(mmiobase, 0x1E6E0080, 0x00000000);
2652 MOutdwm(mmiobase, 0x1E6E0084, 0x00FFFFFF);
2653 MOutdwm(mmiobase, 0x1E6E0088, param->REG_DQIDLY);
2654 MOutdwm(mmiobase, 0x1E6E0018, 0x4000A130);
2655 MOutdwm(mmiobase, 0x1E6E0018, 0x00002330);
2656 MOutdwm(mmiobase, 0x1E6E0038, 0x00000000);
2657 MOutdwm(mmiobase, 0x1E6E0040, 0xFF808000);
2658 MOutdwm(mmiobase, 0x1E6E0044, 0x88848466);
2659 MOutdwm(mmiobase, 0x1E6E0048, 0x44440008);
2660 MOutdwm(mmiobase, 0x1E6E004C, 0x00000000);
2661 MOutdwm(mmiobase, 0x1E6E0050, 0x80000000);
2662 MOutdwm(mmiobase, 0x1E6E0050, 0x00000000);
2663 MOutdwm(mmiobase, 0x1E6E0054, 0);
2664 MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV);
2665 MOutdwm(mmiobase, 0x1E6E006C, param->REG_IOZ);
2666 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
2667 MOutdwm(mmiobase, 0x1E6E0074, 0x00000000);
2668 MOutdwm(mmiobase, 0x1E6E0078, 0x00000000);
2669 MOutdwm(mmiobase, 0x1E6E007C, 0x00000000);
2670
2671 /* Wait MCLK2X lock to MCLK */
2672 do{
2673 data = MIndwm(mmiobase, 0x1E6E001C);
2674 }while(!(data & 0x08000000));
2675 data = MIndwm(mmiobase, 0x1E6E001C);
2676 data = (data >> 8) & 0xff;
2677 while((data & 0x08) || ((data & 0x7) < 2) || (data < 4)){
2678 data2 = (MIndwm(mmiobase, 0x1E6E0064) & 0xfff3ffff) + 4;
2679 if((data2 & 0xff) > param->MADJ_MAX){
2680 break;
2681 }
2682 MOutdwm(mmiobase, 0x1E6E0064, data2);
2683 if(data2 & 0x00100000){
2684 data2 = ((data2 & 0xff) >> 3) + 3;
2685 }else{
2686 data2 = ((data2 & 0xff) >> 2) + 5;
2687 }
2688 data = MIndwm(mmiobase, 0x1E6E0068) & 0xffff00ff;
2689 data2 += data & 0xff;
2690 data = data | (data2 << 8);
2691 MOutdwm(mmiobase, 0x1E6E0068, data);
2692 usleep(10);
2693 MOutdwm(mmiobase, 0x1E6E0064, MIndwm(mmiobase, 0x1E6E0064) | 0xC0000);
2694 usleep(10);
2695 data = MIndwm(mmiobase, 0x1E6E0018) & 0xfffff1ff;
2696 MOutdwm(mmiobase, 0x1E6E0018, data);
2697 data = data | 0x200;
2698 MOutdwm(mmiobase, 0x1E6E0018, data);
2699 do{
2700 data = MIndwm(mmiobase, 0x1E6E001C);
2701 }while(!(data & 0x08000000));
2702
2703 data = MIndwm(mmiobase, 0x1E6E001C);
2704 data = (data >> 8) & 0xff;
2705 }
2706 MOutdwm(mmiobase, 0x1E720058, MIndwm(mmiobase, 0x1E6E0068) & 0xffff);
2707 data = MIndwm(mmiobase, 0x1E6E0018) | 0xC00;
2708 MOutdwm(mmiobase, 0x1E6E0018, data);
2709
2710 MOutdwm(mmiobase, 0x1E6E0034, 0x00000001);
2711 MOutdwm(mmiobase, 0x1E6E000C, 0x00000000);
2712 usleep(50);
2713 /* Mode Register Setting */
2714 MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS | 0x100);
2715 MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS);
2716 MOutdwm(mmiobase, 0x1E6E0028, 0x00000005);
2717 MOutdwm(mmiobase, 0x1E6E0028, 0x00000007);
2718 MOutdwm(mmiobase, 0x1E6E0028, 0x00000003);
2719 MOutdwm(mmiobase, 0x1E6E0028, 0x00000001);
2720 MOutdwm(mmiobase, 0x1E6E000C, 0x00005C08);
2721 MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS);
2722 MOutdwm(mmiobase, 0x1E6E0028, 0x00000001);
2723 MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS | 0x380);
2724 MOutdwm(mmiobase, 0x1E6E0028, 0x00000003);
2725 MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS);
2726 MOutdwm(mmiobase, 0x1E6E0028, 0x00000003);
2727
2728 MOutdwm(mmiobase, 0x1E6E000C, 0x7FFF5C01);
2729 data = 0;
2730 if(param->WODT){
2731 data = 0x500;
2732 }
2733 if(param->RODT){
2734 data = data | 0x3000 | ((param->REG_AC2 & 0x60000) >> 3);
2735 }
2736 MOutdwm(mmiobase, 0x1E6E0034, data | 0x3);
2737 MOutdwm(mmiobase, 0x1E6E0120, param->REG_FREQ);
2738
2739 /* Calibrate the DQSI delay */
2740 if ((CBRDLL2(param)==FALSE) && (retry++ < 10))
2741 goto DDR2_Init_Start;
2742
2743
2744 /* ECC Memory Initialization */
2745 #ifdef ECC
2746 MOutdwm(mmiobase, 0x1E6E007C, 0x00000000);
2747 MOutdwm(mmiobase, 0x1E6E0070, 0x221);
2748 do{
2749 data = MIndwm(mmiobase, 0x1E6E0070);
2750 }while(!(data & 0x00001000));
2751 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
2752 MOutdwm(mmiobase, 0x1E6E0050, 0x80000000);
2753 MOutdwm(mmiobase, 0x1E6E0050, 0x00000000);
2754 #endif
2755 }
2756
DDR3_Init(PAST2300DRAMParam param)2757 static void DDR3_Init(PAST2300DRAMParam param)
2758 {
2759 ULONG data, data2, retry = 0;
2760 UCHAR *mmiobase;
2761
2762 mmiobase = param->pjMMIOVirtualAddress;
2763
2764 DDR3_Init_Start:
2765 MOutdwm(mmiobase, 0x1E6E0000, 0xFC600309);
2766 MOutdwm(mmiobase, 0x1E6E0064, 0x00000000);
2767 MOutdwm(mmiobase, 0x1E6E0034, 0x00000000);
2768 MOutdwm(mmiobase, 0x1E6E0018, 0x00000100);
2769 MOutdwm(mmiobase, 0x1E6E0024, 0x00000000);
2770 usleep(10);
2771 MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ);
2772 MOutdwm(mmiobase, 0x1E6E0068, param->REG_SADJ);
2773 usleep(10);
2774 MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0xC0000);
2775 usleep(10);
2776
2777 MOutdwm(mmiobase, 0x1E6E0004, param->DRAM_CONFIG);
2778 MOutdwm(mmiobase, 0x1E6E0008, 0x90040f);
2779 MOutdwm(mmiobase, 0x1E6E0010, param->REG_AC1);
2780 MOutdwm(mmiobase, 0x1E6E0014, param->REG_AC2);
2781 MOutdwm(mmiobase, 0x1E6E0020, param->REG_DQSIC);
2782 MOutdwm(mmiobase, 0x1E6E0080, 0x00000000);
2783 MOutdwm(mmiobase, 0x1E6E0084, 0x00FFFFFF);
2784 MOutdwm(mmiobase, 0x1E6E0088, param->REG_DQIDLY);
2785 MOutdwm(mmiobase, 0x1E6E0018, 0x4000A170);
2786 MOutdwm(mmiobase, 0x1E6E0018, 0x00002370);
2787 MOutdwm(mmiobase, 0x1E6E0038, 0x00000000);
2788 MOutdwm(mmiobase, 0x1E6E0040, 0xFF444444);
2789 MOutdwm(mmiobase, 0x1E6E0044, 0x22222222);
2790 MOutdwm(mmiobase, 0x1E6E0048, 0x22222222);
2791 MOutdwm(mmiobase, 0x1E6E004C, 0x00000002);
2792 MOutdwm(mmiobase, 0x1E6E0050, 0x80000000);
2793 MOutdwm(mmiobase, 0x1E6E0050, 0x00000000);
2794 MOutdwm(mmiobase, 0x1E6E0054, 0);
2795 MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV);
2796 MOutdwm(mmiobase, 0x1E6E006C, param->REG_IOZ);
2797 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
2798 MOutdwm(mmiobase, 0x1E6E0074, 0x00000000);
2799 MOutdwm(mmiobase, 0x1E6E0078, 0x00000000);
2800 MOutdwm(mmiobase, 0x1E6E007C, 0x00000000);
2801
2802 /* Wait MCLK2X lock to MCLK */
2803 do{
2804 data = MIndwm(mmiobase, 0x1E6E001C);
2805 }while(!(data & 0x08000000));
2806 data = MIndwm(mmiobase, 0x1E6E001C);
2807 data = (data >> 8) & 0xff;
2808 while((data & 0x08) || ((data & 0x7) < 2) || (data < 4)){
2809 data2 = (MIndwm(mmiobase, 0x1E6E0064) & 0xfff3ffff) + 4;
2810 if((data2 & 0xff) > param->MADJ_MAX){
2811 break;
2812 }
2813 MOutdwm(mmiobase, 0x1E6E0064, data2);
2814 if(data2 & 0x00100000){
2815 data2 = ((data2 & 0xff) >> 3) + 3;
2816 }else{
2817 data2 = ((data2 & 0xff) >> 2) + 5;
2818 }
2819 data = MIndwm(mmiobase, 0x1E6E0068) & 0xffff00ff;
2820 data2 += data & 0xff;
2821 data = data | (data2 << 8);
2822 MOutdwm(mmiobase, 0x1E6E0068, data);
2823 usleep(10);
2824 MOutdwm(mmiobase, 0x1E6E0064, MIndwm(mmiobase, 0x1E6E0064) | 0xC0000);
2825 usleep(10);
2826 data = MIndwm(mmiobase, 0x1E6E0018) & 0xfffff1ff;
2827 MOutdwm(mmiobase, 0x1E6E0018, data);
2828 data = data | 0x200;
2829 MOutdwm(mmiobase, 0x1E6E0018, data);
2830 do{
2831 data = MIndwm(mmiobase, 0x1E6E001C);
2832 }while(!(data & 0x08000000));
2833
2834 data = MIndwm(mmiobase, 0x1E6E001C);
2835 data = (data >> 8) & 0xff;
2836 }
2837 MOutdwm(mmiobase, 0x1E720058, MIndwm(mmiobase, 0x1E6E0068) & 0xffff);
2838 data = MIndwm(mmiobase, 0x1E6E0018) | 0xC00;
2839 MOutdwm(mmiobase, 0x1E6E0018, data);
2840
2841 MOutdwm(mmiobase, 0x1E6E0034, 0x00000001);
2842 MOutdwm(mmiobase, 0x1E6E000C, 0x00000040);
2843 usleep(50);
2844 /* Mode Register Setting */
2845 MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS | 0x100);
2846 MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS);
2847 MOutdwm(mmiobase, 0x1E6E0028, 0x00000005);
2848 MOutdwm(mmiobase, 0x1E6E0028, 0x00000007);
2849 MOutdwm(mmiobase, 0x1E6E0028, 0x00000003);
2850 MOutdwm(mmiobase, 0x1E6E0028, 0x00000001);
2851 MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS);
2852 MOutdwm(mmiobase, 0x1E6E000C, 0x00005C08);
2853 MOutdwm(mmiobase, 0x1E6E0028, 0x00000001);
2854
2855 MOutdwm(mmiobase, 0x1E6E000C, 0x00005C01);
2856 data = 0;
2857 if(param->WODT){
2858 data = 0x300;
2859 }
2860 if(param->RODT){
2861 data = data | 0x3000 | ((param->REG_AC2 & 0x60000) >> 3);
2862 }
2863 MOutdwm(mmiobase, 0x1E6E0034, data | 0x3);
2864
2865 /* Calibrate the DQSI delay */
2866 if ((CBRDLL2(param)==FALSE) && (retry++ < 10))
2867 goto DDR3_Init_Start;
2868
2869 MOutdwm(mmiobase, 0x1E6E0120, param->REG_FREQ);
2870 /* ECC Memory Initialization */
2871 #ifdef ECC
2872 MOutdwm(mmiobase, 0x1E6E007C, 0x00000000);
2873 MOutdwm(mmiobase, 0x1E6E0070, 0x221);
2874 do{
2875 data = MIndwm(mmiobase, 0x1E6E0070);
2876 }while(!(data & 0x00001000));
2877 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
2878 MOutdwm(mmiobase, 0x1E6E0050, 0x80000000);
2879 MOutdwm(mmiobase, 0x1E6E0050, 0x00000000);
2880 #endif
2881 }
2882
vInitAST2300DRAMReg(ScrnInfoPtr pScrn)2883 static void vInitAST2300DRAMReg(ScrnInfoPtr pScrn)
2884 {
2885 ASTRecPtr pAST = ASTPTR(pScrn);
2886 AST2300DRAMParam param;
2887 ULONG i, ulTemp;
2888 UCHAR jReg;
2889
2890 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
2891
2892 if ((jReg & 0x80) == 0) /* VGA only */
2893 {
2894 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
2895 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
2896
2897 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8;
2898 do {
2899 ;
2900 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x12000) != 0x01);
2901
2902 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309;
2903 do {
2904 ;
2905 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) != 0x01);
2906
2907 /* Slow down CPU/AHB CLK in VGA only mode */
2908 ulTemp = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12008);
2909 ulTemp |= 0x73;
2910 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12008) = ulTemp;
2911
2912 param.pjMMIOVirtualAddress = pAST->MMIOVirtualAddr;
2913 param.DRAM_Type = DDR3; /* DDR3 */
2914 ulTemp = MIndwm(param.pjMMIOVirtualAddress, 0x1E6E2070);
2915 if (ulTemp & 0x01000000)
2916 param.DRAM_Type = DDR2; /* DDR2 */
2917 param.DRAM_ChipID = (ULONG) pAST->jDRAMType;
2918 param.DRAM_Freq = pAST->ulMCLK;
2919 param.VRAM_Size = pAST->ulVRAMSize;
2920
2921 if (param.DRAM_Type == DDR3)
2922 {
2923 GetDDR3Info(¶m);
2924 DDR3_Init(¶m);
2925 }
2926 else
2927 {
2928 GetDDR2Info(¶m);
2929 DDR2_Init(¶m);
2930 }
2931
2932 ulTemp = MIndwm(param.pjMMIOVirtualAddress, 0x1E6E2040);
2933 MOutdwm(param.pjMMIOVirtualAddress, 0x1E6E2040, ulTemp | 0x40);
2934 }
2935
2936 /* wait ready */
2937 do {
2938 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
2939 } while ((jReg & 0x40) == 0);
2940
2941 } /* vInitAST2300DRAMReg */
2942
2943 /*
2944 * AST2500 DRAM settings modules
2945 */
2946 #define REGTBL_NUM 17
2947 #define REGIDX_010 0
2948 #define REGIDX_014 1
2949 #define REGIDX_018 2
2950 #define REGIDX_020 3
2951 #define REGIDX_024 4
2952 #define REGIDX_02C 5
2953 #define REGIDX_030 6
2954 #define REGIDX_214 7
2955 #define REGIDX_2E0 8
2956 #define REGIDX_2E4 9
2957 #define REGIDX_2E8 10
2958 #define REGIDX_2EC 11
2959 #define REGIDX_2F0 12
2960 #define REGIDX_2F4 13
2961 #define REGIDX_2F8 14
2962 #define REGIDX_RFC 15
2963 #define REGIDX_PLL 16
2964
2965 ULONG ddr3_1600_timing_table[REGTBL_NUM] = {
2966 0x64604D38, /* 0x010 */
2967 0x29690599, /* 0x014 */
2968 0x00000300, /* 0x018 */
2969 0x00000000, /* 0x020 */
2970 0x00000000, /* 0x024 */
2971 0x02181E70, /* 0x02C */
2972 0x00000040, /* 0x030 */
2973 0x00000024, /* 0x214 */
2974 0x02001300, /* 0x2E0 */
2975 0x0E0000A0, /* 0x2E4 */
2976 0x000E001B, /* 0x2E8 */
2977 0x35B8C105, /* 0x2EC */
2978 0x08090408, /* 0x2F0 */
2979 0x9B000800, /* 0x2F4 */
2980 0x0E400A00, /* 0x2F8 */
2981 0x9971452F, /* tRFC */
2982 0x000071C1}; /* PLL */
2983
2984 ULONG ddr4_1600_timing_table[REGTBL_NUM] = {
2985 0x63604E37, /* 0x010 */
2986 0xE97AFA99, /* 0x014 */
2987 0x00019000, /* 0x018 */
2988 0x08000000, /* 0x020 */
2989 0x00000400, /* 0x024 */
2990 0x00000410, /* 0x02C */
2991 0x00000101, /* 0x030 */
2992 0x00000024, /* 0x214 */
2993 0x03002900, /* 0x2E0 */
2994 0x0E0000A0, /* 0x2E4 */
2995 0x000E001C, /* 0x2E8 */
2996 0x35B8C106, /* 0x2EC */
2997 0x08080607, /* 0x2F0 */
2998 0x9B000900, /* 0x2F4 */
2999 0x0E400A00, /* 0x2F8 */
3000 0x99714545, /* tRFC */
3001 0x000071C1}; /* PLL */
3002
MMCTestBurst_AST2500(ScrnInfoPtr pScrn,ULONG datagen)3003 static int MMCTestBurst_AST2500(ScrnInfoPtr pScrn, ULONG datagen)
3004 {
3005 ASTRecPtr pAST = ASTPTR(pScrn);
3006 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3007 ULONG data, timecnt;
3008
3009 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
3010 MOutdwm(mmiobase, 0x1E6E0070, 0x000000C1 | (datagen << 3));
3011 timecnt = 0;
3012 do{
3013 data = MIndwm(mmiobase, 0x1E6E0070) & 0x3000;
3014 if(data & 0x2000){
3015 return(0);
3016 }
3017 if(++timecnt > TIMEOUT){
3018 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
3019 return(0);
3020 }
3021 }while(!data);
3022 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
3023 return(1);
3024 }
3025
MMCTestSingle_AST2500(ScrnInfoPtr pScrn,ULONG datagen)3026 static int MMCTestSingle_AST2500(ScrnInfoPtr pScrn, ULONG datagen)
3027 {
3028 ASTRecPtr pAST = ASTPTR(pScrn);
3029 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3030 ULONG data, timecnt;
3031
3032 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
3033 MOutdwm(mmiobase, 0x1E6E0070, 0x00000085 | (datagen << 3));
3034 timecnt = 0;
3035 do{
3036 data = MIndwm(mmiobase, 0x1E6E0070) & 0x3000;
3037 if(data & 0x2000){
3038 return(0);
3039 }
3040 if(++timecnt > TIMEOUT){
3041 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
3042 return(0);
3043 }
3044 }while(!data);
3045 MOutdwm(mmiobase, 0x1E6E0070, 0x00000000);
3046 return(1);
3047 }
3048
CBRTest_AST2500(ScrnInfoPtr pScrn)3049 static ULONG CBRTest_AST2500(ScrnInfoPtr pScrn)
3050 {
3051 ASTRecPtr pAST = ASTPTR(pScrn);
3052 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3053
3054 MOutdwm(mmiobase, 0x1E6E0074, 0x0000FFFF);
3055 MOutdwm(mmiobase, 0x1E6E007C, 0xFF00FF00);
3056 if(!MMCTestBurst_AST2500(pScrn, 0)) return(0);
3057 if(!MMCTestSingle_AST2500(pScrn, 0)) return(0);
3058 return(1);
3059 }
3060
DDR_Init_Common(ScrnInfoPtr pScrn)3061 static void DDR_Init_Common(ScrnInfoPtr pScrn)
3062 {
3063 ASTRecPtr pAST = ASTPTR(pScrn);
3064 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3065
3066 MOutdwm(mmiobase, 0x1E6E0034,0x00020080);
3067 MOutdwm(mmiobase, 0x1E6E0008,0x2003000F);
3068 MOutdwm(mmiobase, 0x1E6E0038,0x00000FFF);
3069 MOutdwm(mmiobase, 0x1E6E0040,0x88448844);
3070 MOutdwm(mmiobase, 0x1E6E0044,0x24422288);
3071 MOutdwm(mmiobase, 0x1E6E0048,0x22222222);
3072 MOutdwm(mmiobase, 0x1E6E004C,0x22222222);
3073 MOutdwm(mmiobase, 0x1E6E0050,0x80000000);
3074 MOutdwm(mmiobase, 0x1E6E0208,0x00000000);
3075 MOutdwm(mmiobase, 0x1E6E0218,0x00000000);
3076 MOutdwm(mmiobase, 0x1E6E0220,0x00000000);
3077 MOutdwm(mmiobase, 0x1E6E0228,0x00000000);
3078 MOutdwm(mmiobase, 0x1E6E0230,0x00000000);
3079 MOutdwm(mmiobase, 0x1E6E02A8,0x00000000);
3080 MOutdwm(mmiobase, 0x1E6E02B0,0x00000000);
3081 MOutdwm(mmiobase, 0x1E6E0240,0x86000000);
3082 MOutdwm(mmiobase, 0x1E6E0244,0x00008600);
3083 MOutdwm(mmiobase, 0x1E6E0248,0x80000000);
3084 MOutdwm(mmiobase, 0x1E6E024C,0x80808080);
3085 }
3086
Do_DDRPHY_Init(ScrnInfoPtr pScrn)3087 static void Do_DDRPHY_Init(ScrnInfoPtr pScrn)
3088 {
3089 ASTRecPtr pAST = ASTPTR(pScrn);
3090 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3091 ULONG data, pass, timecnt;
3092
3093 pass = 0;
3094 MOutdwm(mmiobase, 0x1E6E0060,0x00000005);
3095 while(!pass){
3096 for(timecnt = 0;timecnt < TIMEOUT;timecnt++){
3097 data = MIndwm(mmiobase, 0x1E6E0060) & 0x1;
3098 if(!data){
3099 break;
3100 }
3101 }
3102 if(timecnt != TIMEOUT){
3103 data = MIndwm(mmiobase, 0x1E6E0300) & 0x000A0000;
3104 if(!data){
3105 pass = 1;
3106 }
3107 }
3108 if(!pass){
3109 MOutdwm(mmiobase, 0x1E6E0060,0x00000000);
3110 usleep(10); /* delay 10 us */
3111 MOutdwm(mmiobase, 0x1E6E0060,0x00000005);
3112 }
3113 }
3114
3115 MOutdwm(mmiobase, 0x1E6E0060,0x00000006);
3116 }
3117
3118 /******************************************************************************
3119 Check DRAM Size
3120 1Gb : 0x80000000 ~ 0x87FFFFFF
3121 2Gb : 0x80000000 ~ 0x8FFFFFFF
3122 4Gb : 0x80000000 ~ 0x9FFFFFFF
3123 8Gb : 0x80000000 ~ 0xBFFFFFFF
3124 *****************************************************************************/
Check_DRAM_Size(ScrnInfoPtr pScrn,ULONG tRFC)3125 static void Check_DRAM_Size(ScrnInfoPtr pScrn, ULONG tRFC)
3126 {
3127 ASTRecPtr pAST = ASTPTR(pScrn);
3128 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3129 ULONG reg_04, reg_14;
3130
3131 reg_04 = MIndwm(mmiobase, 0x1E6E0004) & 0xfffffffc;
3132 reg_14 = MIndwm(mmiobase, 0x1E6E0014) & 0xffffff00;
3133
3134 MOutdwm(mmiobase, 0xA0100000, 0x41424344);
3135 MOutdwm(mmiobase, 0x90100000, 0x35363738);
3136 MOutdwm(mmiobase, 0x88100000, 0x292A2B2C);
3137 MOutdwm(mmiobase, 0x80100000, 0x1D1E1F10);
3138
3139 /* Check 8Gbit */
3140 if(MIndwm(mmiobase, 0xA0100000) == 0x41424344){
3141 reg_04 |= 0x03;
3142 reg_14 |= (tRFC >> 24) & 0xFF;
3143 /* Check 4Gbit */
3144 }else if(MIndwm(mmiobase, 0x90100000) == 0x35363738){
3145 reg_04 |= 0x02;
3146 reg_14 |= (tRFC >> 16) & 0xFF;
3147 /* Check 2Gbit */
3148 }else if(MIndwm(mmiobase, 0x88100000) == 0x292A2B2C){
3149 reg_04 |= 0x01;
3150 reg_14 |= (tRFC >> 8) & 0xFF;
3151 }else{
3152 reg_14 |= tRFC & 0xFF;
3153 }
3154 MOutdwm(mmiobase, 0x1E6E0004, reg_04);
3155 MOutdwm(mmiobase, 0x1E6E0014, reg_14);
3156 }
3157
Enable_Cache(ScrnInfoPtr pScrn)3158 static void Enable_Cache(ScrnInfoPtr pScrn)
3159 {
3160 ASTRecPtr pAST = ASTPTR(pScrn);
3161 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3162 ULONG reg_04, data;
3163
3164 reg_04 = MIndwm(mmiobase, 0x1E6E0004);
3165 MOutdwm(mmiobase, 0x1E6E0004, reg_04 | 0x1000);
3166
3167 do{
3168 data = MIndwm(mmiobase, 0x1E6E0004);
3169 }while(!(data & 0x80000));
3170 MOutdwm(mmiobase, 0x1E6E0004, reg_04 | 0x400);
3171 }
3172
Set_MPLL(ScrnInfoPtr pScrn)3173 static void Set_MPLL(ScrnInfoPtr pScrn)
3174 {
3175 ASTRecPtr pAST = ASTPTR(pScrn);
3176 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3177 ULONG addr, data, param;
3178
3179 /* Reset MMC */
3180 MOutdwm(mmiobase, 0x1E6E0000,0xFC600309);
3181 MOutdwm(mmiobase, 0x1E6E0034,0x00020080);
3182 for(addr = 0x1e6e0004;addr < 0x1e6e0090;){
3183 MOutdwm(mmiobase, addr, 0x0);
3184 addr += 4;
3185 }
3186 MOutdwm(mmiobase, 0x1E6E0034,0x00020000);
3187
3188 MOutdwm(mmiobase, 0x1E6E2000, 0x1688A8A8);
3189 data = MIndwm(mmiobase, 0x1E6E2070) & 0x00800000;
3190 if(data){ /* CLKIN = 25MHz */
3191 param = 0x930023E0;
3192 }else{ /* CLKIN = 24MHz */
3193 param = 0x93002400;
3194 }
3195 MOutdwm(mmiobase, 0x1E6E2020, param);
3196 usleep(100);
3197 }
3198
DDR3_Init_AST2500(ScrnInfoPtr pScrn,ULONG * ddr_table)3199 static void DDR3_Init_AST2500(ScrnInfoPtr pScrn, ULONG *ddr_table)
3200 {
3201 ASTRecPtr pAST = ASTPTR(pScrn);
3202 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3203
3204 MOutdwm(mmiobase, 0x1E6E0004,0x00000303);
3205 MOutdwm(mmiobase, 0x1E6E0010,ddr_table[REGIDX_010]);
3206 MOutdwm(mmiobase, 0x1E6E0014,ddr_table[REGIDX_014]);
3207 MOutdwm(mmiobase, 0x1E6E0018,ddr_table[REGIDX_018]);
3208 MOutdwm(mmiobase, 0x1E6E0020,ddr_table[REGIDX_020]); /* MODEREG4/6 */
3209 MOutdwm(mmiobase, 0x1E6E0024,ddr_table[REGIDX_024]); /* MODEREG5 */
3210 MOutdwm(mmiobase, 0x1E6E002C,ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
3211 MOutdwm(mmiobase, 0x1E6E0030,ddr_table[REGIDX_030]); /* MODEREG1/3 */
3212
3213 /* DDR PHY Setting */
3214 MOutdwm(mmiobase, 0x1E6E0200,0x02492AAE);
3215 MOutdwm(mmiobase, 0x1E6E0204,0x00001001);
3216 MOutdwm(mmiobase, 0x1E6E020C,0x55E00B0B);
3217 MOutdwm(mmiobase, 0x1E6E0210,0x20000000);
3218 MOutdwm(mmiobase, 0x1E6E0214,ddr_table[REGIDX_214]);
3219 MOutdwm(mmiobase, 0x1E6E02E0,ddr_table[REGIDX_2E0]);
3220 MOutdwm(mmiobase, 0x1E6E02E4,ddr_table[REGIDX_2E4]);
3221 MOutdwm(mmiobase, 0x1E6E02E8,ddr_table[REGIDX_2E8]);
3222 MOutdwm(mmiobase, 0x1E6E02EC,ddr_table[REGIDX_2EC]);
3223 MOutdwm(mmiobase, 0x1E6E02F0,ddr_table[REGIDX_2F0]);
3224 MOutdwm(mmiobase, 0x1E6E02F4,ddr_table[REGIDX_2F4]);
3225 MOutdwm(mmiobase, 0x1E6E02F8,ddr_table[REGIDX_2F8]);
3226 MOutdwm(mmiobase, 0x1E6E0290,0x00100008);
3227 MOutdwm(mmiobase, 0x1E6E02C0,0x00000006);
3228
3229 /* Controller Setting */
3230 MOutdwm(mmiobase, 0x1E6E0034,0x00020091);
3231
3232 /* Wait DDR PHY init done */
3233 Do_DDRPHY_Init(pScrn);
3234
3235 MOutdwm(mmiobase, 0x1E6E0120,ddr_table[REGIDX_PLL]);
3236 MOutdwm(mmiobase, 0x1E6E000C,0x42AA5C81);
3237 MOutdwm(mmiobase, 0x1E6E0034,0x0001AF93);
3238
3239 Check_DRAM_Size(pScrn, ddr_table[REGIDX_RFC]);
3240 Enable_Cache(pScrn);
3241 MOutdwm(mmiobase, 0x1E6E001C,0x00000008);
3242 MOutdwm(mmiobase, 0x1E6E0038,0xFFFFFF00);
3243 }
3244
DDR4_Init_AST2500(ScrnInfoPtr pScrn,ULONG * ddr_table)3245 static void DDR4_Init_AST2500(ScrnInfoPtr pScrn, ULONG *ddr_table)
3246 {
3247 ASTRecPtr pAST = ASTPTR(pScrn);
3248 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3249 ULONG data, data2, pass;
3250 ULONG ddr_vref, phy_vref;
3251 ULONG min_ddr_vref, min_phy_vref;
3252 ULONG max_ddr_vref, max_phy_vref;
3253
3254 MOutdwm(mmiobase, 0x1E6E0004,0x00000313);
3255 MOutdwm(mmiobase, 0x1E6E0010,ddr_table[REGIDX_010]);
3256 MOutdwm(mmiobase, 0x1E6E0014,ddr_table[REGIDX_014]);
3257 MOutdwm(mmiobase, 0x1E6E0018,ddr_table[REGIDX_018]);
3258 MOutdwm(mmiobase, 0x1E6E0020,ddr_table[REGIDX_020]); /* MODEREG4/6 */
3259 MOutdwm(mmiobase, 0x1E6E0024,ddr_table[REGIDX_024]); /* MODEREG5 */
3260 MOutdwm(mmiobase, 0x1E6E002C,ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
3261 MOutdwm(mmiobase, 0x1E6E0030,ddr_table[REGIDX_030]); /* MODEREG1/3 */
3262
3263 /* DDR PHY Setting */
3264 MOutdwm(mmiobase, 0x1E6E0200,0x42492AAE);
3265 MOutdwm(mmiobase, 0x1E6E0204,0x09002000);
3266 MOutdwm(mmiobase, 0x1E6E020C,0x55E00B0B);
3267 MOutdwm(mmiobase, 0x1E6E0210,0x20000000);
3268 MOutdwm(mmiobase, 0x1E6E0214,ddr_table[REGIDX_214]);
3269 MOutdwm(mmiobase, 0x1E6E02E0,ddr_table[REGIDX_2E0]);
3270 MOutdwm(mmiobase, 0x1E6E02E4,ddr_table[REGIDX_2E4]);
3271 MOutdwm(mmiobase, 0x1E6E02E8,ddr_table[REGIDX_2E8]);
3272 MOutdwm(mmiobase, 0x1E6E02EC,ddr_table[REGIDX_2EC]);
3273 MOutdwm(mmiobase, 0x1E6E02F0,ddr_table[REGIDX_2F0]);
3274 MOutdwm(mmiobase, 0x1E6E02F4,ddr_table[REGIDX_2F4]);
3275 MOutdwm(mmiobase, 0x1E6E02F8,ddr_table[REGIDX_2F8]);
3276 MOutdwm(mmiobase, 0x1E6E0290,0x00100008);
3277 MOutdwm(mmiobase, 0x1E6E02C4,0x3C183C3C);
3278 MOutdwm(mmiobase, 0x1E6E02C8,0x00631E0E);
3279
3280 /* Controller Setting */
3281 MOutdwm(mmiobase, 0x1E6E0034,0x0001A991);
3282
3283 /* Train PHY Vref first */
3284 min_phy_vref = max_phy_vref = 0x0;
3285 pass = 0;
3286 MOutdwm(mmiobase, 0x1E6E02C0,0x00001C06);
3287 for(phy_vref = 0x40;phy_vref < 0x80;phy_vref++){
3288 MOutdwm(mmiobase, 0x1E6E000C,0x00000000);
3289 MOutdwm(mmiobase, 0x1E6E0060,0x00000000);
3290 MOutdwm(mmiobase, 0x1E6E02CC,phy_vref | (phy_vref << 8));
3291 /* Fire DFI Init */
3292 Do_DDRPHY_Init(pScrn);
3293 MOutdwm(mmiobase, 0x1E6E000C,0x00005C01);
3294 if(CBRTest_AST2500(pScrn)){
3295 pass++;
3296 data = MIndwm(mmiobase, 0x1E6E03D0);
3297 data2 = data >> 8;
3298 data = data & 0xff;
3299 if(data > data2){
3300 data = data2;
3301 }
3302
3303 if(max_phy_vref < data){
3304 max_phy_vref = data;
3305 min_phy_vref = phy_vref;
3306 }
3307 }else if(pass > 0){
3308 break;
3309 }
3310 }
3311 MOutdwm(mmiobase, 0x1E6E02CC,min_phy_vref | (min_phy_vref << 8));
3312
3313 /* Train DDR Vref next */
3314 min_ddr_vref = 0xFF;
3315 max_ddr_vref = 0x0;
3316 pass = 0;
3317 for(ddr_vref = 0x00;ddr_vref < 0x40;ddr_vref++){
3318 MOutdwm(mmiobase, 0x1E6E000C,0x00000000);
3319 MOutdwm(mmiobase, 0x1E6E0060,0x00000000);
3320 MOutdwm(mmiobase, 0x1E6E02C0,0x00000006 | (ddr_vref << 8));
3321 /* Fire DFI Init */
3322 Do_DDRPHY_Init(pScrn);
3323 MOutdwm(mmiobase, 0x1E6E000C,0x00005C01);
3324 if(CBRTest_AST2500(pScrn)){
3325 pass++;
3326 if(min_ddr_vref > ddr_vref){
3327 min_ddr_vref = ddr_vref;
3328 }
3329 if(max_ddr_vref < ddr_vref){
3330 max_ddr_vref = ddr_vref;
3331 }
3332 }else if(pass != 0){
3333 break;
3334 }
3335 }
3336 MOutdwm(mmiobase, 0x1E6E000C,0x00000000);
3337 MOutdwm(mmiobase, 0x1E6E0060,0x00000000);
3338 ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
3339 MOutdwm(mmiobase, 0x1E6E02C0,0x00000006 | (ddr_vref << 8));
3340
3341 /* Wait DDR PHY init done */
3342 Do_DDRPHY_Init(pScrn);
3343
3344 MOutdwm(mmiobase, 0x1E6E0120,ddr_table[REGIDX_PLL]);
3345 MOutdwm(mmiobase, 0x1E6E000C,0x42AA5C81);
3346 MOutdwm(mmiobase, 0x1E6E0034,0x0001AF93);
3347
3348 Check_DRAM_Size(pScrn, ddr_table[REGIDX_RFC]);
3349 Enable_Cache(pScrn);
3350 MOutdwm(mmiobase, 0x1E6E001C,0x00000008);
3351 MOutdwm(mmiobase, 0x1E6E0038,0xFFFFFF00);
3352 }
3353
DRAM_Init_AST2500(ScrnInfoPtr pScrn)3354 static int DRAM_Init_AST2500(ScrnInfoPtr pScrn)
3355 {
3356 ASTRecPtr pAST = ASTPTR(pScrn);
3357 UCHAR *mmiobase = pAST->MMIOVirtualAddr;
3358 ULONG data;
3359
3360 Set_MPLL(pScrn);
3361 DDR_Init_Common(pScrn);
3362 data = MIndwm(mmiobase, 0x1E6E2070);
3363 if(data & 0x01000000){
3364 DDR4_Init_AST2500(pScrn, ddr4_1600_timing_table);
3365 }else{
3366 DDR3_Init_AST2500(pScrn, ddr3_1600_timing_table);
3367 }
3368 MOutdwm(mmiobase, 0x1E6E2040, MIndwm(mmiobase, 0x1E6E2040) | 0x41);
3369 /* Patch code */
3370 data = MIndwm(mmiobase, 0x1E6E200C) & 0xF9FFFFFF;
3371 MOutdwm(mmiobase, 0x1E6E200C, data | 0x10000000);
3372 return(1);
3373 }
3374
vInitAST2500DRAMReg(ScrnInfoPtr pScrn)3375 static void vInitAST2500DRAMReg(ScrnInfoPtr pScrn)
3376 {
3377 ASTRecPtr pAST = ASTPTR(pScrn);
3378 ULONG ulTemp;
3379 UCHAR jReg;
3380
3381 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
3382
3383 if ((jReg & 0x80) == 0) /* VGA only */
3384 {
3385 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
3386 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
3387
3388 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8;
3389 do {
3390 ;
3391 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x12000) != 0x01);
3392
3393 *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309;
3394 do {
3395 ;
3396 } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) != 0x01);
3397
3398 /* Slow down CPU/AHB CLK in VGA only mode */
3399 ulTemp = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12008);
3400 ulTemp |= 0x73;
3401 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12008) = ulTemp;
3402
3403 DRAM_Init_AST2500(pScrn);
3404
3405 ulTemp = MIndwm(pAST->MMIOVirtualAddr, 0x1E6E2040);
3406 MOutdwm(pAST->MMIOVirtualAddr, 0x1E6E2040, ulTemp | 0x40);
3407 }
3408
3409 /* wait ready */
3410 do {
3411 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
3412 } while ((jReg & 0x40) == 0);
3413
3414 } /* vInitAST2500DRAMReg */
3415
vGetDefaultSettings(ScrnInfoPtr pScrn)3416 void static vGetDefaultSettings(ScrnInfoPtr pScrn)
3417 {
3418 ASTRecPtr pAST = ASTPTR(pScrn);
3419 ULONG ulData;
3420
3421 if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
3422 {
3423 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
3424 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
3425 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12070);
3426 switch (ulData & 0x18000000)
3427 {
3428 case 0x00000000:
3429 pAST->jDRAMType = DRAMTYPE_512Mx16;
3430 break;
3431 case 0x08000000:
3432 pAST->jDRAMType = DRAMTYPE_1Gx16;
3433 break;
3434 case 0x10000000:
3435 pAST->jDRAMType = DRAMTYPE_2Gx16;
3436 break;
3437 case 0x18000000:
3438 pAST->jDRAMType = DRAMTYPE_4Gx16;
3439 break;
3440 }
3441 }
3442 else if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200))
3443 {
3444 pAST->jDRAMType = DRAMTYPE_512Mx32;
3445 }
3446 else if ((pAST->jChipType == AST1100) || (pAST->jChipType == AST2150))
3447 {
3448 pAST->jDRAMType = DRAMTYPE_1Gx16;
3449 }
3450
3451 } /* vGetDefaultSettings */
3452
InitDVO(ScrnInfoPtr pScrn)3453 static Bool InitDVO(ScrnInfoPtr pScrn)
3454 {
3455 ASTRecPtr pAST = ASTPTR(pScrn);
3456 ULONG ulData;
3457 UCHAR jReg;
3458
3459 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000;
3460 *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1;
3461 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8;
3462
3463 GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg);
3464 if (!(jReg & 0x80)) /* Init SCU DVO Settings */
3465 {
3466 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12008); /* delay phase */
3467 ulData &= 0xfffff8ff;
3468 ulData |= 0x00000500;
3469 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12008) = ulData;
3470
3471 if (pAST->jChipType == AST2300)
3472 {
3473 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12084); /* multi-pins for DVO single-edge */
3474 ulData |= 0xfffe0000;
3475 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12084) = ulData;
3476
3477 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12088); /* multi-pins for DVO single-edge */
3478 ulData |= 0x000fffff;
3479 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12088) = ulData;
3480
3481 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12090); /* multi-pins for DVO single-edge */
3482 ulData &= 0xffffffcf;
3483 ulData |= 0x00000020;
3484 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12090) = ulData;
3485 }
3486 else /* AST2400 */
3487 {
3488 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12088); /* multi-pins for DVO single-edge */
3489 ulData |= 0x30000000;
3490 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12088) = ulData;
3491
3492 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1208c); /* multi-pins for DVO single-edge */
3493 ulData |= 0x000000cf;
3494 *(ULONG *) (pAST->MMIOVirtualAddr + 0x1208c) = ulData;
3495
3496 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x120a4); /* multi-pins for DVO single-edge */
3497 ulData |= 0xffff0000;
3498 *(ULONG *) (pAST->MMIOVirtualAddr + 0x120a4) = ulData;
3499
3500 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x120a8); /* multi-pins for DVO single-edge */
3501 ulData |= 0x0000000f;
3502 *(ULONG *) (pAST->MMIOVirtualAddr + 0x120a8) = ulData;
3503
3504 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12094); /* multi-pins for DVO single-edge */
3505 ulData |= 0x00000002;
3506 *(ULONG *) (pAST->MMIOVirtualAddr + 0x12094) = ulData;
3507 }
3508 }
3509
3510 /* Force to DVO */
3511 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1202c);
3512 ulData &= 0xfffbffff;
3513 *(ULONG *) (pAST->MMIOVirtualAddr + 0x1202c) = ulData;
3514
3515 /* Init VGA DVO Settings */
3516 SetIndexRegMask(CRTC_PORT, 0xA3, 0xCF, 0x80); /* enable DVO, single-edge */
3517
3518 return TRUE;
3519 } /* InitDVO */
3520
vInit3rdTX(ScrnInfoPtr pScrn)3521 static void vInit3rdTX(ScrnInfoPtr pScrn)
3522 {
3523 ASTRecPtr pAST = ASTPTR(pScrn);
3524 ULONG ulData;
3525 UCHAR jReg;
3526
3527 /* Only support on AST2300/2400 */
3528 if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500))
3529 {
3530 GetIndexRegMask(CRTC_PORT, 0xD1, 0xFF, jReg); /* D[1]: DVO Enable */
3531 switch (jReg & 0x0E) /* D[11:9] */
3532 {
3533 case 0x04: /* Sil164 */
3534 InitDVO(pScrn);
3535 break;
3536 case 0x08: /* DP501 with VBIOS launch FW */
3537 LaunchM68K(pScrn);
3538 case 0x0C: /* DP501 with BMC launch FW */
3539 InitDVO(pScrn);
3540 break;
3541 default: /* Force to VGA */
3542 if (pAST->jTxChipType == Tx_Sil164)
3543 InitDVO(pScrn);
3544 else
3545 {
3546 *(ULONG *)(pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8;
3547 ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1202c);
3548 ulData &= 0xfffcffff;
3549 *(ULONG *)(pAST->MMIOVirtualAddr) = ulData;
3550 }
3551 }
3552 }
3553
3554 } /* vInit3rdTX */
3555
3556 /*
3557 * Flags: 0: POST init
3558 * 1: resume from power management
3559 */
ASTInitVGA(ScrnInfoPtr pScrn,ULONG Flags)3560 Bool ASTInitVGA(ScrnInfoPtr pScrn, ULONG Flags)
3561 {
3562 ASTRecPtr pAST;
3563 uint32_t ulData;
3564
3565 pAST = ASTPTR(pScrn);
3566
3567 {
3568 /* Enable PCI */
3569 PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04);
3570 ulData |= 0x03;
3571 PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04);
3572
3573 /* Enable VGA */
3574 vEnableVGA(pScrn);
3575
3576 vASTOpenKey(pScrn);
3577 vSetDefVCLK(pScrn);
3578 vSetDefExtReg(pScrn);
3579
3580 if (Flags == 0)
3581 vGetDefaultSettings(pScrn);
3582
3583 if (pAST->jChipType == AST2500)
3584 vInitAST2500DRAMReg(pScrn);
3585 else if ((pAST->jChipType == AST2300) || (pAST->jChipType == AST2400))
3586 vInitAST2300DRAMReg(pScrn);
3587 else
3588 vInitDRAMReg(pScrn);
3589
3590 vInit3rdTX(pScrn);
3591 }
3592
3593 return (TRUE);
3594 } /* Init VGA */
3595
3596 /* Get EDID */
3597 void
I2CWriteClock(ASTRecPtr pAST,UCHAR data)3598 I2CWriteClock(ASTRecPtr pAST, UCHAR data)
3599 {
3600 UCHAR ujCRB7, jtemp;
3601 ULONG i;
3602
3603 for (i=0;i<0x10000; i++)
3604 {
3605 ujCRB7 = ((data & 0x01) ? 0:1); /* low active */
3606 SetIndexRegMask(CRTC_PORT, 0xB7, 0xFE, ujCRB7);
3607 GetIndexRegMask(CRTC_PORT, 0xB7, 0x01, jtemp);
3608 if (ujCRB7 == jtemp) break;
3609 }
3610
3611 }
3612
3613 void
I2CWriteData(ASTRecPtr pAST,UCHAR data)3614 I2CWriteData(ASTRecPtr pAST, UCHAR data)
3615 {
3616 UCHAR volatile ujCRB7, jtemp;
3617 ULONG i;
3618
3619 for (i=0;i<0x1000; i++)
3620 {
3621 ujCRB7 = ((data & 0x01) ? 0:1) << 2; /* low active */
3622 SetIndexRegMask(CRTC_PORT, 0xB7, 0xFB, ujCRB7);
3623 GetIndexRegMask(CRTC_PORT, 0xB7, 0x04, jtemp);
3624 if (ujCRB7 == jtemp) break;
3625 }
3626
3627 }
3628
3629 Bool
I2CReadClock(ASTRecPtr pAST)3630 I2CReadClock(ASTRecPtr pAST)
3631 {
3632 UCHAR volatile ujCRB7;
3633
3634 GetIndexRegMask(CRTC_PORT, 0xB7, 0x10, ujCRB7);
3635 ujCRB7 >>= 4;
3636
3637 return ((ujCRB7 & 0x01) ? 1:0);
3638 }
3639
3640 Bool
I2CReadData(ASTRecPtr pAST)3641 I2CReadData(ASTRecPtr pAST)
3642 {
3643 UCHAR volatile ujCRB7;
3644
3645 GetIndexRegMask(CRTC_PORT, 0xB7, 0x20, ujCRB7);
3646 ujCRB7 >>= 5;
3647
3648 return ((ujCRB7 & 0x01) ? 1:0);
3649
3650 }
3651
3652
3653 void
I2CDelay(ASTRecPtr pAST)3654 I2CDelay(ASTRecPtr pAST)
3655 {
3656 ULONG i;
3657 UCHAR jtemp;
3658
3659 for (i=0;i<150;i++)
3660 jtemp = GetReg(SEQ_PORT);
3661
3662 }
3663
3664 void
I2CStart(ASTRecPtr pAST)3665 I2CStart(ASTRecPtr pAST)
3666 {
3667 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3668 I2CDelay(pAST);
3669 I2CWriteData(pAST, 0x01); /* Set Data High */
3670 I2CDelay(pAST);
3671 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3672 I2CDelay(pAST);
3673 I2CWriteData(pAST, 0x00); /* Set Data Low */
3674 I2CDelay(pAST);
3675 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3676 I2CDelay(pAST);
3677 }
3678
3679 void
I2CStop(ASTRecPtr pAST)3680 I2CStop(ASTRecPtr pAST)
3681 {
3682 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3683 I2CDelay(pAST);
3684 I2CWriteData(pAST, 0x00); /* Set Data Low */
3685 I2CDelay(pAST);
3686 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3687 I2CDelay(pAST);
3688 I2CWriteData(pAST, 0x01); /* Set Data High */
3689 I2CDelay(pAST);
3690 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3691 I2CDelay(pAST);
3692
3693 }
3694
3695 Bool
CheckACK(ASTRecPtr pAST)3696 CheckACK(ASTRecPtr pAST)
3697 {
3698 UCHAR Data;
3699
3700 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3701 I2CDelay(pAST);
3702 I2CWriteData(pAST, 0x01); /* Set Data High */
3703 I2CDelay(pAST);
3704 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3705 I2CDelay(pAST);
3706 Data = (UCHAR) I2CReadData(pAST); /* Set Data High */
3707
3708 return ((Data & 0x01) ? 0:1);
3709
3710 }
3711
3712
3713 void
SendACK(ASTRecPtr pAST)3714 SendACK(ASTRecPtr pAST)
3715 {
3716
3717 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3718 I2CDelay(pAST);
3719 I2CWriteData(pAST, 0x00); /* Set Data low */
3720 I2CDelay(pAST);
3721 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3722 I2CDelay(pAST);
3723
3724 }
3725
3726 void
SendNACK(ASTRecPtr pAST)3727 SendNACK(ASTRecPtr pAST)
3728 {
3729
3730 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3731 I2CDelay(pAST);
3732 I2CWriteData(pAST, 0x01); /* Set Data high */
3733 I2CDelay(pAST);
3734 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3735 I2CDelay(pAST);
3736
3737 }
3738
3739 void
SendI2CDataByte(ASTRecPtr pAST,UCHAR data)3740 SendI2CDataByte(ASTRecPtr pAST, UCHAR data)
3741 {
3742 UCHAR jData;
3743 LONG i;
3744
3745 for (i=7;i>=0;i--)
3746 {
3747 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3748 I2CDelay(pAST);
3749
3750 jData = ((data >> i) & 0x01) ? 1:0;
3751 I2CWriteData(pAST, jData); /* Set Data Low */
3752 I2CDelay(pAST);
3753
3754 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3755 I2CDelay(pAST);
3756 }
3757 }
3758
3759 UCHAR
ReceiveI2CDataByte(ASTRecPtr pAST)3760 ReceiveI2CDataByte(ASTRecPtr pAST)
3761 {
3762 UCHAR jData=0, jTempData;
3763 LONG i, j;
3764
3765 for (i=7;i>=0;i--)
3766 {
3767 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3768 I2CDelay(pAST);
3769
3770 I2CWriteData(pAST, 0x01); /* Set Data High */
3771 I2CDelay(pAST);
3772
3773 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3774 I2CDelay(pAST);
3775
3776 for (j=0; j<0x1000; j++)
3777 {
3778 if (I2CReadClock(pAST)) break;
3779 }
3780
3781 jTempData = I2CReadData(pAST);
3782 jData |= ((jTempData & 0x01) << i);
3783
3784 I2CWriteClock(pAST, 0x0); /* Set Clk Low */
3785 I2CDelay(pAST);
3786 }
3787
3788 return ((UCHAR)jData);
3789 }
3790
3791 Bool
ASTGetVGAEDID(ScrnInfoPtr pScrn,unsigned char * pEDIDBuffer)3792 ASTGetVGAEDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer)
3793 {
3794 ASTRecPtr pAST;
3795 UCHAR *pjDstEDID;
3796 UCHAR jData;
3797 ULONG i;
3798
3799 pAST = ASTPTR(pScrn);
3800 pjDstEDID = (UCHAR *) pEDIDBuffer;
3801
3802 /* Force to DDC2 */
3803 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3804 I2CDelay(pAST);
3805 I2CWriteClock(pAST, 0x00); /* Set Clk Low */
3806 I2CDelay(pAST);
3807 I2CWriteClock(pAST, 0x01); /* Set Clk High */
3808 I2CDelay(pAST);
3809
3810 /* Validate SCL */
3811 if (I2CReadClock(pAST) == 0) /* chk SCL failed */
3812 {
3813 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check SCL Failed \n");
3814 return (FALSE);
3815 }
3816
3817 I2CStart(pAST);
3818
3819 SendI2CDataByte(pAST, 0xA0);
3820 if (!CheckACK(pAST))
3821 {
3822 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check ACK Failed \n");
3823 return (FALSE);
3824 }
3825
3826 SendI2CDataByte(pAST, 0x00);
3827 if (!CheckACK(pAST))
3828 {
3829 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check ACK Failed \n");
3830 return (FALSE);
3831 }
3832
3833 I2CStart(pAST);
3834
3835 SendI2CDataByte(pAST, 0xA1);
3836 if (!CheckACK(pAST))
3837 {
3838 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check ACK Failed \n");
3839 return (FALSE);
3840 }
3841
3842 for (i=0; i<127; i++)
3843 {
3844 jData = ReceiveI2CDataByte(pAST);
3845 SendACK(pAST);
3846
3847 *pjDstEDID++ = jData;
3848 }
3849
3850 jData = ReceiveI2CDataByte(pAST);
3851 SendNACK(pAST);
3852 *pjDstEDID = jData;
3853
3854 I2CStop(pAST);
3855
3856 return (TRUE);
3857
3858 } /* ASTGetVGAEDID */
3859
bASTInitAST1180(ScrnInfoPtr pScrn)3860 Bool bASTInitAST1180(ScrnInfoPtr pScrn)
3861 {
3862 ASTRecPtr pAST;
3863 uint32_t ulData;
3864
3865 pAST = ASTPTR(pScrn);
3866
3867 /* Enable PCI */
3868 PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04);
3869 ulData |= 0x03;
3870 PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04);
3871
3872 /* init DRAM if no F/W */
3873 /* TODO */
3874
3875 WriteAST1180SOC(AST1180_MMC_BASE+0x00, 0xFC600309); /* unlock */
3876 WriteAST1180SOC(AST1180_SCU_BASE+0x00, 0x1688a8a8); /* unlock */
3877 usleep(100);
3878
3879 WriteAST1180SOC(AST1180_MMC_BASE+0x08, 0x000011e3); /* req. */
3880
3881 /* init SCU */
3882 #if 0
3883 ReadAST1180SOC(AST1180_SCU_BASE+0x08, ulData); /* delay compensation */
3884 ulData &= 0xFFFFE0FF;
3885 ulData |= 0x00000C00;
3886 WriteAST1180SOC(AST1180_SCU_BASE+0x08, ulData);
3887 #endif
3888
3889 ReadAST1180SOC(AST1180_SCU_BASE+0x0c, ulData); /* 2d clk */
3890 ulData &= 0xFFFFFFFD;
3891 WriteAST1180SOC(AST1180_SCU_BASE+0x0c, ulData);
3892
3893 return (TRUE);
3894
3895 } /* bASTInitAST1180 */
3896
ASTGetAST1180DRAMInfo(ScrnInfoPtr pScrn)3897 void ASTGetAST1180DRAMInfo(ScrnInfoPtr pScrn)
3898 {
3899 ASTRecPtr pAST = ASTPTR(pScrn);
3900 ULONG ulData;
3901
3902 WriteAST1180SOC(AST1180_MMC_BASE+0x00, 0xFC600309); /* unlock */
3903 ReadAST1180SOC(AST1180_MMC_BASE+0x04, ulData);
3904 pAST->ulDRAMBusWidth = 32;
3905 if (ulData & 0x40)
3906 pAST->ulDRAMBusWidth = 16;
3907
3908 /* DRAM size */
3909 switch (ulData & 0x0C)
3910 {
3911 case 0x00:
3912 pAST->ulDRAMSize = DRAM_SIZE_032M;
3913 break;
3914 case 0x04:
3915 pAST->ulDRAMSize = DRAM_SIZE_064M;
3916 break;
3917 case 0x08:
3918 pAST->ulDRAMSize = DRAM_SIZE_128M;
3919 break;
3920 case 0x0c:
3921 pAST->ulDRAMSize = DRAM_SIZE_256M;
3922 break;
3923 }
3924
3925 /* Get framebuffer size */
3926 switch (ulData & 0x30)
3927 {
3928 case 0x00:
3929 pAST->ulVRAMSize = DRAM_SIZE_016M;
3930 break;
3931 case 0x10:
3932 pAST->ulVRAMSize = DRAM_SIZE_032M;
3933 break;
3934 case 0x20:
3935 pAST->ulVRAMSize = DRAM_SIZE_064M;
3936 break;
3937 case 0x30:
3938 pAST->ulVRAMSize = DRAM_SIZE_128M;
3939 break;
3940 }
3941
3942 /* VRAM base */
3943 if (pAST->ulVRAMSize >= pAST->ulDRAMSize)
3944 pAST->ulVRAMSize = pAST->ulDRAMSize;
3945 pAST->ulVRAMBase = pAST->ulDRAMSize - pAST->ulVRAMSize;
3946
3947 /* MCLK */
3948 pAST->ulMCLK = 200;
3949
3950 } /* ASTGetAST1180DRAMInfo */
3951
vASTEnableVGAMMIO(ScrnInfoPtr pScrn)3952 void vASTEnableVGAMMIO(ScrnInfoPtr pScrn)
3953 {
3954 ASTRecPtr pAST = ASTPTR(pScrn);
3955 uint32_t ulData;
3956 UCHAR jReg;
3957
3958 jReg = inb(pAST->RelocateIO + 0x43);
3959 if (jReg != 0x01)
3960 {
3961 /* Enable PCI */
3962 PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04);
3963 ulData |= 0x03;
3964 PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04);
3965
3966 outb(pAST->RelocateIO + 0x43, 0x01);
3967 outb(pAST->RelocateIO + 0x42, 0x01);
3968 }
3969
3970 jReg = GetReg(VGA_ENABLE_PORT);
3971 if (jReg == 0xFF) /* MMIO Access is disabled */
3972 {
3973 outw(pAST->RelocateIO + 0x54, 0xa880);
3974 outw(pAST->RelocateIO + 0x54, 0x04a1);
3975 }
3976
3977 } /* vEnableASTVGAMMIO */
3978