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