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