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