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