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