vboard.c revision 72313efb
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 */
26static char MICROCODE_DIR [PATH_MAX] = MODULEDIR;
27
28/*
29 * local function prototypes
30 */
31
32
33/*
34 * functions
35 */
36int
37verite_initboard(ScrnInfoPtr pScreenInfo)
38{
39    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
40
41    IOADDRESS 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
119int
120verite_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
134int
135verite_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
206void
207verite_check_csucode(ScrnInfoPtr pScreenInfo)
208{
209  renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
210  IOADDRESS 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