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(&param, 16);		/* 16bits */
1571             else
1572                 CBRDLLI_AST2150(&param, 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(&param);
2924             DDR3_Init(&param);
2925         }
2926         else
2927         {
2928             GetDDR2Info(&param);
2929             DDR2_Init(&param);
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