1 /*
2  * includes
3  */
4 
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8 
9 #include "rendition.h"
10 #include "v1krisc.h"
11 #include "vboard.h"
12 #include "vloaduc.h"
13 #include "vos.h"
14 
15 #if !defined(PATH_MAX)
16 #define PATH_MAX 1024
17 #endif
18 
19 /*
20  * global data
21  */
22 
23 #include "cscode.h"
24 
25 /* Global imported during compile-time */
26 static char MICROCODE_DIR [PATH_MAX] = MODULEDIR;
27 
28 /*
29  * local function prototypes
30  */
31 
32 
33 /*
34  * functions
35  */
36 int
verite_initboard(ScrnInfoPtr pScreenInfo)37 verite_initboard(ScrnInfoPtr pScreenInfo)
38 {
39     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
40 
41     unsigned long iob=pRendition->board.io_base;
42     vu8 *vmb;
43     vu32 offset;
44     vu8 memendian;
45     int c,pc;
46 
47     /* write "monitor" program to memory */
48     v1k_stop(pScreenInfo);
49     pRendition->board.csucode_base=0x800;
50     memendian=verite_in8(iob+MEMENDIAN);
51     verite_out8(iob+MEMENDIAN, MEMENDIAN_NO);
52 
53     /* Note that CS ucode must wait on address in csucode_base
54      * when initialized for later context switch code to work. */
55 
56     ErrorF("Loading csucode @ %p + 0x800\n", pRendition->board.vmem_base);
57     vmb=pRendition->board.vmem_base;
58     offset=pRendition->board.csucode_base;
59     for (c=0; c<sizeof(csrisc)/sizeof(vu32); c++, offset+=sizeof(vu32))
60 	verite_write_memory32(vmb, offset, csrisc[c]);
61 
62     /* Initialize the CS flip semaphore */
63     verite_write_memory32(vmb, 0x7f8, 0);
64     verite_write_memory32(vmb, 0x7fc, 0);
65 
66     /* Run the code we just transfered to the boards memory */
67     /* ... and start accelerator */
68     v1k_flushicache(pScreenInfo);
69 
70     verite_out8(iob + STATEINDEX, STATEINDEX_PC);
71     pc = verite_in32(iob + STATEDATA);
72     v1k_start(pScreenInfo, pRendition->board.csucode_base);
73 
74     /* Get on loading the ucode */
75     verite_out8(iob + STATEINDEX, STATEINDEX_PC);
76 
77     for (c = 0; c < 0xffffffL; c++){
78 	v1k_stop(pScreenInfo);
79 	pc = verite_in32(iob + STATEDATA);
80 	v1k_continue(pScreenInfo);
81 	if (pc == pRendition->board.csucode_base)
82 	    break;
83     }
84     if (pc != pRendition->board.csucode_base){
85 	xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
86 		   ("VERITE_INITBOARD -- PC != CSUCODEBASE\n"));
87 	ErrorF ("RENDITION: PC == 0x%x   --  CSU == 0x%lx\n",
88 		pc,(unsigned long)pRendition->board.csucode_base);
89     }
90 
91     /* reset memory endian */
92     verite_out8(iob+MEMENDIAN, memendian);
93 
94     if (V1000_DEVICE == pRendition->board.chip){
95 	c=verite_load_ucfile(pScreenInfo, strcat ((char *)MICROCODE_DIR,"v10002d.uc"));
96     }
97     else {
98 	/* V2x00 chip */
99 	c=verite_load_ucfile(pScreenInfo, strcat ((char *)MICROCODE_DIR,"v20002d.uc"));
100     }
101 
102     if (c == -1) {
103 	xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
104 		   ("Microcode loading failed !!!\n"));
105 	return 1;
106     }
107 
108     pRendition->board.ucode_entry=c;
109 
110 #ifdef DEBUG
111     ErrorF("UCode_Entry == 0x%x\n",pRendition->board.ucode_entry);
112 #endif
113 
114     /* Everything's OK */
115     return 0;
116 }
117 
118 
119 int
verite_resetboard(ScrnInfoPtr pScreenInfo)120 verite_resetboard(ScrnInfoPtr pScreenInfo)
121 {
122     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
123     vu16 iob=pRendition->board.io_base;
124     vu8 memendian=verite_in8(iob+MEMENDIAN);
125     vu32 crtcctl = verite_in32(iob+CRTCCTL);
126 
127     v1k_softreset(pScreenInfo);
128     verite_out8(iob+MEMENDIAN, memendian);
129     verite_out32(iob+CRTCCTL, crtcctl);
130 
131     return 0;
132 }
133 
134 int
verite_getmemorysize(ScrnInfoPtr pScreenInfo)135 verite_getmemorysize(ScrnInfoPtr pScreenInfo)
136 {
137     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
138 
139 #define PATTERN  0xf5faaf5f
140 #define START    0x12345678
141 #define ONEMEG   (1024L*1024L)
142     vu32 offset;
143     vu32 pattern;
144     vu32 start;
145     vu8 memendian;
146 #ifdef XSERVER
147     vu8 modereg;
148 
149     modereg=verite_in8(pRendition->board.io_base+MODEREG);
150     verite_out8(pRendition->board.io_base+MODEREG, NATIVE_MODE);
151 #endif
152 
153     /* no byte swapping */
154     memendian=verite_in8(pRendition->board.io_base+MEMENDIAN);
155     verite_out8(pRendition->board.io_base+MEMENDIAN, MEMENDIAN_NO);
156 
157     /* it looks like the v1000 wraps the memory; but for I'm not sure,
158      * let's test also for non-writable offsets */
159     start=verite_read_memory32(pRendition->board.vmem_base, 0);
160     verite_write_memory32(pRendition->board.vmem_base, 0, START);
161     for (offset=ONEMEG; offset<16*ONEMEG; offset+=ONEMEG) {
162 #ifdef DEBUG
163         ErrorF( "Testing %d MB: ", offset/ONEMEG);
164 #endif
165         pattern=verite_read_memory32(pRendition->board.vmem_base, offset);
166         if (START == pattern) {
167 #ifdef DEBUG
168             ErrorF( "Back at the beginning\n");
169 #endif
170             break;
171         }
172 
173         pattern^=PATTERN;
174         verite_write_memory32(pRendition->board.vmem_base, offset, pattern);
175 
176 #ifdef DEBUG
177         ErrorF( "%x <-> %x\n", (int)pattern,
178                     (int)verite_read_memory32(pRendition->board.vmem_base, offset));
179 #endif
180 
181         if (pattern != verite_read_memory32(pRendition->board.vmem_base, offset)) {
182             offset-=ONEMEG;
183             break;
184         }
185         verite_write_memory32(pRendition->board.vmem_base, offset, pattern^PATTERN);
186     }
187     verite_write_memory32(pRendition->board.vmem_base, 0, start);
188 
189     if (16*ONEMEG <= offset)
190         pRendition->board.mem_size=4*ONEMEG;
191     else
192 	    pRendition->board.mem_size=offset;
193 
194     /* restore default byte swapping */
195     verite_out8(pRendition->board.io_base+MEMENDIAN, memendian);
196 
197 #ifdef XSERVER
198     verite_out8(pRendition->board.io_base+MODEREG, modereg);
199 #endif
200 
201     return pRendition->board.mem_size;
202 #undef PATTERN
203 #undef ONEMEG
204 }
205 
206 void
verite_check_csucode(ScrnInfoPtr pScreenInfo)207 verite_check_csucode(ScrnInfoPtr pScreenInfo)
208 {
209   renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
210   unsigned long iob=pRendition->board.io_base;
211   vu8 *vmb;
212   vu32 offset;
213   int c;
214   int memend;
215   int mismatches=0;
216 
217   memend=verite_in8(iob+MEMENDIAN);
218   verite_out8(iob+MEMENDIAN, MEMENDIAN_NO);
219 
220 #ifdef DEBUG
221   ErrorF("Checking presence of csucode @ 0x%x + 0x800\n",
222 	 pRendition->board.vmem_base);
223 
224   if (0x800 != pRendition->board.csucode_base)
225     ErrorF("pRendition->board.csucode_base == 0x%x\n",
226 	   pRendition->board.csucode_base);
227 #endif
228 
229   /* compare word by word */
230   vmb=pRendition->board.vmem_base;
231   offset=pRendition->board.csucode_base;
232   for (c=0; c<sizeof(csrisc)/sizeof(vu32); c++, offset+=sizeof(vu32))
233     if (csrisc[c] != verite_read_memory32(vmb, offset)) {
234       ErrorF("csucode mismatch in word %02d: 0x%08lx should be 0x%08lx\n",
235 	     c,
236 	     (unsigned long)verite_read_memory32(vmb, offset),
237 	     (unsigned long)csrisc[c]);
238       mismatches++;
239     }
240 #ifdef DEBUG
241   ErrorF("Encountered %d out of %d possible mismatches\n",
242 	 mismatches,
243 	 sizeof(csrisc)/sizeof(vu32));
244 #endif
245 
246   verite_out8(iob+MEMENDIAN, memend);
247 }
248 
249 /*
250  * end of file vboard.c
251  */
252