1 /*
2  * includes
3  */
4 
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8 
9 #include "rendition.h"
10 #include "vramdac.h"
11 #include "vos.h"
12 #include "v1kregs.h"
13 #include "v2kregs.h"
14 
15 /*
16  * defines
17  */
18 
19 #undef DEBUG
20 
21 /* directly accessable RAMDAC registers */
22 #define BT485_WRITE_ADDR        0x00
23 #define BT485_RAMDAC_DATA       0x01
24 #define BT485_PIXEL_MASK        0x02
25 #define BT485_READ_ADDR         0x03
26 #define BT485_CURS_WR_ADDR      0x04
27 #define BT485_CURS_DATA         0x05
28 #define BT485_COMMAND_REG_0     0x06
29 #define BT485_CURS_RD_ADDR      0x07
30 #define BT485_COMMAND_REG_1     0x08
31 #define BT485_COMMAND_REG_2     0x09
32 #define BT485_STATUS_REG        0x0a
33 #define BT485_CURS_RAM_DATA     0x0b
34 #define BT485_CURS_X_LOW        0x0c
35 #define BT485_CURS_X_HIGH       0x0d
36 #define BT485_CURS_Y_LOW        0x0e
37 #define BT485_CURS_Y_HIGH       0x0f
38 
39 /* indirectly accessable ramdac registers */
40 #define BT485_COMMAND_REG_3     0x01
41 
42 /* bits in command register 0 */
43 #define BT485_CR0_EXTENDED_REG_ACCESS   0x80
44 #define BT485_CR0_SCLK_SLEEP_DISABLE    0x40
45 #define BT485_CR0_BLANK_PEDESTAL        0x20
46 #define BT485_CR0_SYNC_ON_BLUE          0x10
47 #define BT485_CR0_SYNC_ON_GREEN         0x08
48 #define BT485_CR0_SYNC_ON_RED           0x04
49 #define BT485_CR0_8_BIT_DAC             0x02
50 #define BT485_CR0_SLEEP_ENABLE          0x01
51 
52 /* bits in command register 1 */
53 #define BT485_CR1_24BPP             0x00
54 #define BT485_CR1_16BPP             0x20
55 #define BT485_CR1_8BPP              0x40
56 #define BT485_CR1_4BPP              0x60
57 #define BT485_CR1_1BPP              0x80
58 #define BT485_CR1_BYPASS_CLUT       0x10
59 #define BT485_CR1_565_16BPP         0x08
60 #define BT485_CR1_555_16BPP         0x00
61 #define BT485_CR1_1_TO_1_16BPP      0x04
62 #define BT485_CR1_2_TO_1_16BPP      0x00
63 #define BT485_CR1_PD7_PIXEL_SWITCH  0x02
64 #define BT485_CR1_PIXEL_PORT_CD     0x01
65 #define BT485_CR1_PIXEL_PORT_AB     0x00
66 
67 /* bits in command register 2 */
68 #define BT485_CR2_SCLK_DISABLE      0x80
69 #define BT485_TEST_PATH_SELECT      0x40
70 #define BT485_PIXEL_INPUT_GATE      0x20
71 #define BT485_PIXEL_CLK_SELECT      0x10
72 #define BT485_INTERLACE_SELECT      0x08
73 #define BT485_16BPP_CLUT_PACKED     0x04
74 #define BT485_X_WINDOW_CURSOR       0x03
75 #define BT485_2_COLOR_CURSOR        0x02
76 #define BT485_3_COLOR_CURSOR        0x01
77 #define BT485_DISABLE_CURSOR        0x00
78 #define BT485_CURSOR_MASK           0x03
79 
80 /* bits in command register 3 */
81 #define BT485_4BPP_NIBBLE_SWAP      0x10
82 #define BT485_CLOCK_DOUBLER         0x08
83 #define BT485_64_BY_64_CURSOR       0x04
84 #define BT485_32_BY_32_CURSOR       0x00
85 #define BT485_SIZE_MASK             0x04
86 
87 /* special constants for the Brooktree BT485 RAMDAC */
88 #define BT485_INPUT_LIMIT           110000000
89 
90 
91 
92 /*
93  * local function prototypes
94  */
95 
96 static void Bt485_write_masked(unsigned long port, vu8 reg, vu8 mask, vu8 data);
97 static void Bt485_write_cmd3_masked(unsigned long port, vu8 mask, vu8 data);
98 #if 0
99 static vu8 Bt485_read_masked(unsigned long port, vu8 reg, vu8 mask);
100 static vu8 Bt485_read_cmd3_masked(unsigned long port, vu8 mask);
101 #endif
102 
103 /*
104  * local data
105  */
106 
107 static int Cursor_size=0;
108 
109 
110 
111 /*
112  * functions
113  */
114 
115 /*
116  * int verite_initdac(ScrnInfoPtr pScreenInfo, vu8 bpp, vu8 doubleclock)
117  *
118  * Used to initialize the ramdac. Palette-bypass is dis-/enabled with respect
119  * to the color depth, the cursor is disabled by default. If needed (i.e. if
120  * the corresponding field in the verite_board_t struct is set), the clock doubling
121  * is turned on.
122  */
123 
124 void
verite_savedac(ScrnInfoPtr pScreenInfo)125 verite_savedac (ScrnInfoPtr pScreenInfo)
126 {
127     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
128     int iob=pRendition->board.io_base + RAMDACBASEADDR;
129     RenditionRegPtr reg = &pRendition->saveRegs;
130 
131     reg->daccmd0 = verite_in8(iob+BT485_COMMAND_REG_0);
132     reg->daccmd1 = verite_in8(iob+BT485_COMMAND_REG_1);
133     reg->daccmd2 = verite_in8(iob+BT485_COMMAND_REG_2);
134     verite_out8(iob+BT485_COMMAND_REG_0,reg->daccmd0
135 		| BT485_CR0_EXTENDED_REG_ACCESS);
136     verite_out8(iob+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
137     reg->daccmd3 = verite_in8(iob+BT485_STATUS_REG);
138     verite_out8(iob+BT485_COMMAND_REG_0,reg->daccmd0);
139 }
140 
141 
142 void
verite_restoredac(ScrnInfoPtr pScreenInfo,RenditionRegPtr reg)143 verite_restoredac (ScrnInfoPtr pScreenInfo, RenditionRegPtr reg)
144 {
145     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
146     int iob=pRendition->board.io_base + RAMDACBASEADDR;
147 
148     verite_out8(iob+BT485_COMMAND_REG_0, reg->daccmd0
149 		| BT485_CR0_EXTENDED_REG_ACCESS);
150     verite_out8(iob+BT485_COMMAND_REG_1, reg->daccmd1);
151     verite_out8(iob+BT485_COMMAND_REG_2, reg->daccmd2);
152     verite_out8(iob+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
153     verite_out8(iob+BT485_STATUS_REG, reg->daccmd3);
154     verite_out8(iob+BT485_COMMAND_REG_0, reg->daccmd0);
155 
156 }
157 
158 int
verite_initdac(ScrnInfoPtr pScreenInfo,vu8 bpp,vu8 doubleclock)159 verite_initdac(ScrnInfoPtr pScreenInfo, vu8 bpp, vu8 doubleclock)
160 {
161     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
162     unsigned long iob=pRendition->board.io_base+RAMDACBASEADDR;
163     vu8 cmd0,cmd1,cmd2;
164     vu8 cmd3_data=0;
165 
166 #ifdef DEBUG
167     ErrorF ("Rendition: Debug verite_initdac called\n");
168 #endif
169 
170     if (doubleclock)
171         cmd3_data|=BT485_CLOCK_DOUBLER;
172 
173     switch (bpp) {
174         case 1:
175         case 4:
176 			xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
177 				   "color depth %d not (yet ?) supported\n",
178 				   bpp);
179 			return -1;
180 
181         case 8:
182 	    cmd0 = BT485_CR0_EXTENDED_REG_ACCESS |
183 	           BT485_CR0_8_BIT_DAC;
184 
185 	    cmd1 = BT485_CR1_8BPP |
186 	           BT485_CR1_PIXEL_PORT_AB;
187 
188 	    cmd2 = BT485_PIXEL_INPUT_GATE |
189 	           BT485_DISABLE_CURSOR;
190 
191             verite_out8(iob+BT485_COMMAND_REG_0, cmd0);
192             verite_out8(iob+BT485_COMMAND_REG_1, cmd1);
193             verite_out8(iob+BT485_COMMAND_REG_2, cmd2);
194             break;
195 
196         case 16:
197 	    cmd0 = BT485_CR0_EXTENDED_REG_ACCESS |
198 	           BT485_CR0_8_BIT_DAC;
199 
200 	    cmd1 = BT485_CR1_16BPP |
201 	           BT485_CR1_2_TO_1_16BPP |
202 	           BT485_CR1_PIXEL_PORT_AB;
203 
204 	    cmd2 = BT485_PIXEL_INPUT_GATE |
205 	           BT485_DISABLE_CURSOR;
206 
207 	    if (pScreenInfo->defaultVisual == TrueColor)
208 	      cmd1 |= BT485_CR1_BYPASS_CLUT;
209 
210             if (pScreenInfo->weight.green == 5)
211 	      cmd1 |= BT485_CR1_555_16BPP;
212 	    else
213 	      cmd1 |= BT485_CR1_565_16BPP;
214 
215             verite_out8(iob+BT485_COMMAND_REG_0,cmd0);
216             verite_out8(iob+BT485_COMMAND_REG_1,cmd1);
217             verite_out8(iob+BT485_COMMAND_REG_2,cmd2);
218             break;
219 
220         case 32:
221 	    cmd0 = BT485_CR0_EXTENDED_REG_ACCESS |
222 	           BT485_CR0_8_BIT_DAC;
223 
224 	    cmd1 = BT485_CR1_24BPP |
225 	           BT485_CR1_PIXEL_PORT_AB;
226 
227 	    cmd2 = BT485_PIXEL_INPUT_GATE |
228 	           BT485_DISABLE_CURSOR;
229 
230 	    if (pScreenInfo->defaultVisual == TrueColor)
231 	      cmd1 |= BT485_CR1_BYPASS_CLUT;
232 
233             verite_out8(iob+BT485_COMMAND_REG_0,cmd0);
234             verite_out8(iob+BT485_COMMAND_REG_1,cmd1);
235             verite_out8(iob+BT485_COMMAND_REG_2,cmd2);
236             break;
237 
238         default:
239             xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
240 			"Color depth not supported (%d bpp)\n", bpp);
241             return -1;
242             break;
243     }
244 
245     verite_out8(iob+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
246     verite_out8(iob+BT485_STATUS_REG, cmd3_data);
247 /*
248     Bt485_write_masked(iob, BT485_COMMAND_REG_0, 0x7f, 0x00);
249 */
250     verite_out8(iob+BT485_PIXEL_MASK, 0xff);
251 
252     return 0;
253 }
254 
255 
256 
257 /*
258  * void verite_enablecursor(ScrnInfoPtr pScreenInfo, int type, int size)
259  *
260  * Used to enable the hardware cursor. Size indicates, whether to use no cursor
261  * at all, a 32x32 or a 64x64 cursor. The type selects a two-color, three-color
262  * or X-window-like cursor. Valid values are defined in vramdac.h.
263  *
264  */
265 void
verite_enablecursor(ScrnInfoPtr pScreenInfo,int type,int size)266 verite_enablecursor(ScrnInfoPtr pScreenInfo, int type, int size)
267 {
268     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
269 
270     static vu8 ctypes[]={ BT485_DISABLE_CURSOR, BT485_2_COLOR_CURSOR,
271                       BT485_3_COLOR_CURSOR, BT485_X_WINDOW_CURSOR };
272     static vu8 csizes[]={ BT485_32_BY_32_CURSOR, BT485_64_BY_64_CURSOR };
273 
274     unsigned long iob=pRendition->board.io_base+RAMDACBASEADDR;
275 
276 #ifdef DEBUG
277     ErrorF ("Rendition: Debug verite_enablecursor called type=0x%x\n",type);
278 #endif
279 
280     /* type goes to command register 2 */
281     Bt485_write_masked(iob, BT485_COMMAND_REG_2, ~BT485_CURSOR_MASK,
282                       ctypes[type]);
283 
284     /* size is in command register 3 */
285     Bt485_write_cmd3_masked(iob, ~BT485_SIZE_MASK, csizes[size]);
286 
287     if (type)
288       Cursor_size=(size ? 64 : 32);
289 
290 #ifdef DEBUG
291     ErrorF ("Rendition: Debug verite_enablecursor Exit\n");
292 #endif
293 
294 }
295 
296 /*
297  * void verite_movecursor(ScrnInfoPtr pScreenInfo, vu16 x, vu16 y, vu8 xo, vu8 yo)
298  *
299  * Moves the cursor to the specified location. To hide the cursor, call
300  * this routine with x=0x0 and y=0x0.
301  *
302  */
303 void
verite_movecursor(ScrnInfoPtr pScreenInfo,vu16 x,vu16 y,vu8 xo,vu8 yo)304 verite_movecursor(ScrnInfoPtr pScreenInfo, vu16 x, vu16 y, vu8 xo, vu8 yo)
305 {
306     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
307     unsigned long iob=pRendition->board.io_base+RAMDACBASEADDR;
308 
309     x+=Cursor_size-xo;
310     y+=Cursor_size-yo;
311 
312     verite_out8(iob+BT485_CURS_X_LOW, x&0xff);
313     verite_out8(iob+BT485_CURS_X_HIGH, (x>>8)&0x0f);
314     verite_out8(iob+BT485_CURS_Y_LOW, y&0xff);
315     verite_out8(iob+BT485_CURS_Y_HIGH, (y>>8)&0x0f);
316 }
317 
318 
319 
320 /*
321  * void verite_setcursorcolor(ScrnInfoPtr pScreenInfo, vu32 bg, vu32 fg)
322  *
323  * Sets the color of the cursor -- should be revised for use with 3 colors!
324  *
325  */
326 void
verite_setcursorcolor(ScrnInfoPtr pScreenInfo,vu32 fg,vu32 bg)327 verite_setcursorcolor(ScrnInfoPtr pScreenInfo, vu32 fg, vu32 bg)
328 {
329     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
330     unsigned long iob=pRendition->board.io_base+RAMDACBASEADDR;
331 
332 #ifdef DEBUG
333     ErrorF ("Rendition: Debug verite_setcursorcolor called FG=0x%x BG=0x%x\n",
334 	    fg,bg);
335 #endif
336 
337     verite_out8(iob+BT485_CURS_WR_ADDR, 0x00);
338 
339     /* load the cursor color 0 */
340     verite_out8(iob+BT485_CURS_DATA, 0x00);
341     verite_out8(iob+BT485_CURS_DATA, 0x00);
342     verite_out8(iob+BT485_CURS_DATA, 0x00);
343 
344     /* load the cursor color 1 */
345     verite_out8(iob+BT485_CURS_DATA, (fg>>16) & 0xff);
346     verite_out8(iob+BT485_CURS_DATA, (fg>>8) & 0xff);
347     verite_out8(iob+BT485_CURS_DATA,  fg&0xff );
348 
349     /*
350      *  The V2xxx and the V1xxx with external BT485 behave differently.
351      *  If we set color 2 to fg both work correctly.
352      */
353     /* load the cursor color 2 */
354     verite_out8(iob+BT485_CURS_DATA, (fg>>16) & 0xff);
355     verite_out8(iob+BT485_CURS_DATA, (fg>>8) & 0xff);
356     verite_out8(iob+BT485_CURS_DATA,  fg & 0xff);
357 
358     /* load the cursor color 3 */
359     verite_out8(iob+BT485_CURS_DATA, (bg>>16)&0xff );
360     verite_out8(iob+BT485_CURS_DATA, (bg>>8)&0xff );
361     verite_out8(iob+BT485_CURS_DATA, bg&0xff );
362 }
363 
364 
365 
366 /*
367  * Oh god, this code is quite a mess ... should be re-written soon.
368  * But for now I'm happy it works ;) <ml>
369  *
370  */
371 void
verite_loadcursor(ScrnInfoPtr pScreenInfo,vu8 size,vu8 * cursorimage)372 verite_loadcursor(ScrnInfoPtr pScreenInfo, vu8 size, vu8 *cursorimage)
373 {
374     int c, bytes, row;
375     vu8 *src = cursorimage;
376     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
377     unsigned long iob=pRendition->board.io_base+RAMDACBASEADDR;
378     vu8 tmp;
379     vu8 memend; /* Added for byte-swap fix */
380 
381 #ifdef DEBUG
382     ErrorF ("Rendition: Debug verite_loadcursor called\n");
383 #endif
384 
385     if (NULL == cursorimage)
386         return;
387 
388     /* Following two lines added for the byte-swap fix */
389     memend = verite_in8(pRendition->board.io_base + MEMENDIAN);
390     verite_out8(pRendition->board.io_base + MEMENDIAN, MEMENDIAN_HW);
391 
392     size&=1;
393     if (size)
394         bytes=64;
395     else
396         bytes=32;
397     bytes=(bytes*bytes)>>3;
398 
399     if (pRendition->board.chip == V1000_DEVICE) {
400       /* now load the cursor data into the cursor ram */
401 
402       tmp=verite_in8(iob+BT485_COMMAND_REG_0)&0x7f;
403       verite_out8(iob+BT485_COMMAND_REG_0, tmp|0x80);
404 
405       verite_out8(iob+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
406 
407       tmp=verite_in8(iob+BT485_STATUS_REG)&0xf8;
408       verite_out8(iob+BT485_STATUS_REG, tmp|(size<<2));
409       verite_out8(iob+BT485_WRITE_ADDR, 0x00);
410 
411       /* output cursor image */
412       src=cursorimage;
413 
414       /* First plane data */
415       for (c=0; c<bytes; c++)  {
416         verite_out8(iob+BT485_CURS_RAM_DATA, *src);
417         src+=2;
418       }
419 
420       /* Second plane data */
421       src=cursorimage+1;
422       for (c=0; c<bytes; c++)  {
423         verite_out8(iob+BT485_CURS_RAM_DATA, *src);
424         src+=2;
425       }
426     }
427     else {
428       /* V2x00 HW-Cursor, supports only 64x64x2 size */
429 
430       verite_out32(iob+CURSORBASE, pRendition->board.hwcursor_membase);
431 
432       /* First plane data */
433       for (row=0; row<64; row++)
434 	for (c=0, src=cursorimage+1+16*row; c<8; c++, src+=2)
435 	  verite_write_memory8(pRendition->board.vmem_base, 16*(63-row)+c,
436      			  (c&1)?(*(src-2)):(*(src+2)));
437       /* Second plane data */
438       for (row=0; row<64; row++)
439 	for (c=0, src=cursorimage+16*row; c<8; c++, src+=2)
440 	  verite_write_memory8(pRendition->board.vmem_base, 8+16*(63-row)+c,
441 			  (c&1)?(*(src-2)):(*(src+2)));
442 
443     }
444     /* Following line added for the byte-swap fix */
445     verite_out8(pRendition->board.io_base + MEMENDIAN, memend);
446 }
447 
448 
449 
450 /* NOTE: count is the actual number of colors decremented by 1 */
451 
452 void
verite_setpalette(ScrnInfoPtr pScreenInfo,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)453 verite_setpalette(ScrnInfoPtr pScreenInfo, int numColors, int *indices,
454 		LOCO *colors, VisualPtr pVisual)
455 {
456     renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
457     unsigned long iob=pRendition->board.io_base;
458     vu32 crtc_status;
459     int i, index;
460 
461 #ifdef DEBUG
462     ErrorF ("Rendition: Debug verite_setpalette called\n");
463 #endif
464 
465     while (1) {
466         crtc_status=verite_in32(iob+CRTCSTATUS);
467         if (crtc_status & CRTCSTATUS_VERT_SYNC)
468             break;
469     };
470 
471     iob+=RAMDACBASEADDR;
472 
473     for (i = 0; i < numColors; i++) {
474         index = indices[i];
475 	verite_out8(iob+BT485_WRITE_ADDR, index);
476 
477         verite_out8(iob+BT485_RAMDAC_DATA, colors[index].red);
478         verite_out8(iob+BT485_RAMDAC_DATA, colors[index].green);
479         verite_out8(iob+BT485_RAMDAC_DATA, colors[index].blue);
480     }
481 }
482 
483 /*
484  * local functions
485  */
486 
487 /*
488  * static void Bt485_write_masked(unsigned long port, vu8 reg, vu8 mask, vu8 data)
489  *
490  *
491  */
492 static void
Bt485_write_masked(unsigned long port,vu8 reg,vu8 mask,vu8 data)493 Bt485_write_masked(unsigned long port, vu8 reg, vu8 mask, vu8 data)
494 {
495     vu8 tmp;
496 
497     tmp=verite_in8(port+reg)&mask;
498     verite_out8(port+reg, tmp|data);
499 }
500 
501 
502 
503 /*
504  * static void Bt485_write_cmd3_masked(unsigned long port, vu8 mask, vu8 data)
505  *
506  *
507  */
508 static void
Bt485_write_cmd3_masked(unsigned long port,vu8 mask,vu8 data)509 Bt485_write_cmd3_masked(unsigned long port, vu8 mask, vu8 data)
510 {
511 /*
512  *   Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x80);
513  */
514     verite_out8(port+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
515     Bt485_write_masked(port, BT485_STATUS_REG, mask, data);
516 /*
517  *    Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x00);
518  */
519 }
520 
521 
522 
523 #if 0
524 /*
525  * static vu8 Bt485_read_masked(unsigned long port, vu8 reg, vu8 mask)
526  *
527  *
528  */
529 static vu8
530 Bt485_read_masked(unsigned long port, vu8 reg, vu8 mask)
531 {
532     return verite_in8(port+reg)&mask;
533 }
534 
535 
536 /*
537  * static vu8 Bt485_read_cmd3_masked(unsigned long port, vu8 mask)
538  *
539  *
540  */
541 static vu8
542 Bt485_read_cmd3_masked(unsigned long port, vu8 mask)
543 {
544     vu8 value;
545 
546     Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x80);
547     verite_out8(port+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
548     value=Bt485_read_masked(port, BT485_STATUS_REG, mask);
549     Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x00);
550 
551     return value;
552 }
553 #endif
554 
555 
556 /*
557  * end of file vramdac.c
558  */
559