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
96static void Bt485_write_masked(unsigned long port, vu8 reg, vu8 mask, vu8 data);
97static void Bt485_write_cmd3_masked(unsigned long port, vu8 mask, vu8 data);
98#if 0
99static vu8 Bt485_read_masked(unsigned long port, vu8 reg, vu8 mask);
100static vu8 Bt485_read_cmd3_masked(unsigned long port, vu8 mask);
101#endif
102
103/*
104 * local data
105 */
106
107static 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
124void
125verite_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
142void
143verite_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
158int
159verite_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 */
265void
266verite_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 */
303void
304verite_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 */
326void
327verite_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 */
371void
372verite_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
452void
453verite_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 */
492static void
493Bt485_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 */
508static void
509Bt485_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 */
529static vu8
530Bt485_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 */
541static vu8
542Bt485_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