1/* 2 * Created 1998 by David Bateman <dbateman@eng.uts.edu.au> 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of the authors not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. The authors makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27/* 28 * The functions in this file are used to read/write the C&T extension register 29 * and supply MMIO replacements of the VGA register access functions in 30 * vgaHW.c for chips that support MMIO access (eg 69000). Unlike the MGA 31 * chips, for instance, the C&T chipsets don't have a direct mapping between 32 * the MMIO mapped vga registers and the PIO versions. 33 * 34 * In General, these are the ONLY supported way of access the video processors 35 * registers. Exception are 36 * 37 * 1) chipsFindIsaDevice, where we don't know the chipset and so we don't know 38 * if the chipset supports MMIO access to its VGA registers, and we don't 39 * know the chips MemBase address and so can't map the VGA registers even 40 * if the chip did support MMIO. This effectively limits the use of non-PCI 41 * MMIO and multihead to a single card accessing 0x3D6/0x3D7. I.E. You can 42 * only have a single C&T card in a non-PCI multihead arrangement. Also as 43 * ISA has no method to disable I/O access to a card ISA multihead will 44 * never be supported. 45 * 46 * 2) ct_Blitter.h, ct_BlitMM.h and ct_BltHiQV.h, where speed is crucial and 47 * we know exactly whether we are using MMIO or PIO. 48 * 49 * 3) The 6554x 32bit DRxx in ct_cursor.c where the choice between MMIO and 50 * PIO is made explicitly 51 */ 52 53 54/* All drivers should typically include these */ 55#include "xf86.h" 56#include "xf86_OSproc.h" 57 58/* Everything using inb/outb, etc needs "compiler.h" */ 59#include "compiler.h" 60 61/* Drivers that need to access the PCI config space directly need this */ 62#include "xf86Pci.h" 63 64/* Driver specific headers */ 65#include "ct_driver.h" 66 67#define CHIPS_MONO_STAT_1 0x3BA 68#define CHIPS_STAT_0 0x3BA 69#define CHIPS_MSS 0x3CB 70#define CHIPS_IOSS 0x3CD 71#define CHIPS_FR_INDEX 0x3D0 72#define CHIPS_FR_DATA 0x3D1 73#define CHIPS_MR_INDEX 0x3D2 74#define CHIPS_MR_DATA 0x3D3 75#define CHIPS_XR_INDEX 0x3D6 76#define CHIPS_XR_DATA 0x3D7 77#define CHIPS_COLOR_STAT_1 0x3DA 78 79#define CHIPS_MMIO_MONO_CRTC_INDEX 0x768 80#define CHIPS_MMIO_MONO_CRTC_DATA 0x769 81#define CHIPS_MMIO_MONO_STAT_1 0x774 82#define CHIPS_MMIO_ATTR_INDEX 0x780 83#define CHIPS_MMIO_ATTR_DATA_W 0x780 84#define CHIPS_MMIO_ATTR_DATA_R 0x781 85#define CHIPS_MMIO_STAT_0 0x784 86#define CHIPS_MMIO_MISC_OUT_W 0x784 87#define CHIPS_MMIO_SEQ_INDEX 0x788 88#define CHIPS_MMIO_SEQ_DATA 0x789 89#define CHIPS_MMIO_DAC_MASK 0x78C 90#define CHIPS_MMIO_DAC_READ_ADDR 0x78D 91#define CHIPS_MMIO_DAC_WRITE_ADDR 0x790 92#define CHIPS_MMIO_DAC_DATA 0x791 93#define CHIPS_MMIO_FEATURE_R 0x794 94#define CHIPS_MMIO_MSS 0x795 95#define CHIPS_MMIO_MISC_OUT_R 0x798 96#define CHIPS_MMIO_IOSS 0x799 97#define CHIPS_MMIO_GRAPH_INDEX 0x79C 98#define CHIPS_MMIO_GRAPH_DATA 0x79D 99#define CHIPS_MMIO_FR_INDEX 0x7A0 100#define CHIPS_MMIO_FR_DATA 0x7A1 101#define CHIPS_MMIO_MR_INDEX 0x7A4 102#define CHIPS_MMIO_MR_DATA 0x7A5 103#define CHIPS_MMIO_COLOR_CRTC_INDEX 0x7A8 104#define CHIPS_MMIO_COLOR_CRTC_DATA 0x7A9 105#define CHIPS_MMIO_XR_INDEX 0x7AC 106#define CHIPS_MMIO_XR_DATA 0x7AD 107#define CHIPS_MMIO_COLOR_STAT_1 0x7B4 108 109/* 110 * PIO Access to the C&T extension registers 111 */ 112static void 113chipsStdWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value) 114{ 115 outb(cPtr->PIOBase + CHIPS_XR_INDEX, index); 116 outb(cPtr->PIOBase + CHIPS_XR_DATA, value); 117} 118 119static CARD8 120chipsStdReadXR(CHIPSPtr cPtr, CARD8 index) 121{ 122 outb(cPtr->PIOBase + CHIPS_XR_INDEX, index); 123 return inb(cPtr->PIOBase + CHIPS_XR_DATA); 124} 125 126static void 127chipsStdWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value) 128{ 129 outb(cPtr->PIOBase + CHIPS_FR_INDEX, index); 130 outb(cPtr->PIOBase + CHIPS_FR_DATA, value); 131} 132 133static CARD8 134chipsStdReadFR(CHIPSPtr cPtr, CARD8 index) 135{ 136 outb(cPtr->PIOBase + CHIPS_FR_INDEX, index); 137 return inb(cPtr->PIOBase + CHIPS_FR_DATA); 138} 139 140static void 141chipsStdWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value) 142{ 143 outb(cPtr->PIOBase + CHIPS_MR_INDEX, index); 144 outb(cPtr->PIOBase + CHIPS_MR_DATA, value); 145} 146 147static CARD8 148chipsStdReadMR(CHIPSPtr cPtr, CARD8 index) 149{ 150 outb(cPtr->PIOBase + CHIPS_MR_INDEX, index); 151 return inb(cPtr->PIOBase + CHIPS_MR_DATA); 152} 153 154static void 155chipsStdWriteMSS(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value) 156{ 157 outb(cPtr->PIOBase + CHIPS_MSS, value); 158} 159 160static CARD8 161chipsStdReadMSS(CHIPSPtr cPtr) 162{ 163 return inb(cPtr->PIOBase + CHIPS_MSS); 164} 165 166static void 167chipsStdWriteIOSS(CHIPSPtr cPtr, CARD8 value) 168{ 169 outb(cPtr->PIOBase + CHIPS_IOSS, value); 170} 171 172static CARD8 173chipsStdReadIOSS(CHIPSPtr cPtr) 174{ 175 return inb(cPtr->PIOBase + CHIPS_IOSS); 176} 177 178void 179CHIPSSetStdExtFuncs(CHIPSPtr cPtr) 180{ 181 cPtr->writeFR = chipsStdWriteFR; 182 cPtr->readFR = chipsStdReadFR; 183 cPtr->writeMR = chipsStdWriteMR; 184 cPtr->readMR = chipsStdReadMR; 185 cPtr->writeXR = chipsStdWriteXR; 186 cPtr->readXR = chipsStdReadXR; 187 cPtr->writeMSS = chipsStdWriteMSS; 188 cPtr->readMSS = chipsStdReadMSS; 189 cPtr->writeIOSS = chipsStdWriteIOSS; 190 cPtr->readIOSS = chipsStdReadIOSS; 191} 192 193/* 194 * MMIO Access to the C&T extension registers 195 */ 196 197#define chipsminb(p) MMIO_IN8(cPtr->MMIOBaseVGA, (p)) 198#define chipsmoutb(p,v) MMIO_OUT8(cPtr->MMIOBaseVGA, (p),(v)) 199 200static void 201chipsMmioWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value) 202{ 203 chipsmoutb(CHIPS_MMIO_XR_INDEX, index); 204 chipsmoutb(CHIPS_MMIO_XR_DATA, value); 205} 206 207static CARD8 208chipsMmioReadXR(CHIPSPtr cPtr, CARD8 index) 209{ 210 chipsmoutb(CHIPS_MMIO_XR_INDEX, index); 211 return chipsminb(CHIPS_MMIO_XR_DATA); 212} 213 214static void 215chipsMmioWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value) 216{ 217 chipsmoutb(CHIPS_MMIO_FR_INDEX, index); 218 chipsmoutb(CHIPS_MMIO_FR_DATA, value); 219} 220 221static CARD8 222chipsMmioReadFR(CHIPSPtr cPtr, CARD8 index) 223{ 224 chipsmoutb(CHIPS_MMIO_FR_INDEX, index); 225 return chipsminb(CHIPS_MMIO_FR_DATA); 226} 227 228static void 229chipsMmioWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value) 230{ 231 chipsmoutb(CHIPS_MMIO_MR_INDEX, index); 232 chipsmoutb(CHIPS_MMIO_MR_DATA, value); 233} 234 235static CARD8 236chipsMmioReadMR(CHIPSPtr cPtr, CARD8 index) 237{ 238 chipsmoutb(CHIPS_MMIO_MR_INDEX, index); 239 return chipsminb(CHIPS_MMIO_MR_DATA); 240} 241 242static void 243chipsMmioWriteMSS(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value) 244{ 245 /* 69030 MMIO Fix. 246 * 247 * <value> determines which MMIOBase to use; either 248 * Pipe A or Pipe B. -GHB 249 */ 250 if ((value & MSS_SHADOW) == MSS_PIPE_B) 251 cPtr->MMIOBaseVGA = cPtr->MMIOBasePipeB; 252 else 253 cPtr->MMIOBaseVGA = cPtr->MMIOBasePipeA; 254 255 hwp->MMIOBase = cPtr->MMIOBaseVGA; 256 257 /* Since our Pipe constants don't set bit 3 of MSS, the value 258 * written here has no effect on the hardware's behavior. It 259 * does allow us to use the value returned by readMSS() to key 260 * the above logic, though. -GHB 261 */ 262 chipsmoutb(CHIPS_MMIO_MSS, value); 263} 264 265static CARD8 266chipsMmioReadMSS(CHIPSPtr cPtr) 267{ 268 return chipsminb(CHIPS_MMIO_MSS); 269} 270 271static void 272chipsMmioWriteIOSS(CHIPSPtr cPtr, CARD8 value) 273{ 274 chipsmoutb(CHIPS_MMIO_IOSS, value); 275} 276 277static CARD8 278chipsMmioReadIOSS(CHIPSPtr cPtr) 279{ 280 return chipsminb(CHIPS_MMIO_IOSS); 281} 282 283void 284CHIPSSetMmioExtFuncs(CHIPSPtr cPtr) 285{ 286 cPtr->writeFR = chipsMmioWriteFR; 287 cPtr->readFR = chipsMmioReadFR; 288 cPtr->writeMR = chipsMmioWriteMR; 289 cPtr->readMR = chipsMmioReadMR; 290 cPtr->writeXR = chipsMmioWriteXR; 291 cPtr->readXR = chipsMmioReadXR; 292 cPtr->writeMSS = chipsMmioWriteMSS; 293 cPtr->readMSS = chipsMmioReadMSS; 294 cPtr->writeIOSS = chipsMmioWriteIOSS; 295 cPtr->readIOSS = chipsMmioReadIOSS; 296} 297 298/* 299 * MMIO versions of the VGA register access functions. 300 */ 301 302#define minb(p) MMIO_IN8(hwp->MMIOBase, (p)) 303#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (p),(v)) 304 305static void 306chipsMmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 307{ 308 if (hwp->IOBase == VGA_IOBASE_MONO) { 309 moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index); 310 moutb(CHIPS_MMIO_MONO_CRTC_DATA, value); 311 } else { 312 moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index); 313 moutb(CHIPS_MMIO_COLOR_CRTC_DATA, value); 314 } 315} 316 317static CARD8 318chipsMmioReadCrtc(vgaHWPtr hwp, CARD8 index) 319{ 320 if (hwp->IOBase == VGA_IOBASE_MONO) { 321 moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index); 322 return minb(CHIPS_MMIO_MONO_CRTC_DATA); 323 } else { 324 moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index); 325 return minb(CHIPS_MMIO_COLOR_CRTC_DATA); 326 } 327} 328 329static void 330chipsMmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value) 331{ 332 moutb(CHIPS_MMIO_GRAPH_INDEX, index); 333 moutb(CHIPS_MMIO_GRAPH_DATA, value); 334} 335 336static CARD8 337chipsMmioReadGr(vgaHWPtr hwp, CARD8 index) 338{ 339 moutb(CHIPS_MMIO_GRAPH_INDEX, index); 340 return minb(CHIPS_MMIO_GRAPH_DATA); 341} 342 343static void 344chipsMmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value) 345{ 346 moutb(CHIPS_MMIO_SEQ_INDEX, index); 347 moutb(CHIPS_MMIO_SEQ_DATA, value); 348} 349 350static CARD8 351chipsMmioReadSeq(vgaHWPtr hwp, CARD8 index) 352{ 353 moutb(CHIPS_MMIO_SEQ_INDEX, index); 354 return minb(CHIPS_MMIO_SEQ_DATA); 355} 356 357static void 358chipsMmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value) 359{ 360 if (hwp->paletteEnabled) 361 index &= ~0x20; 362 else 363 index |= 0x20; 364 365 if (hwp->IOBase == VGA_IOBASE_MONO) 366 (void) minb(CHIPS_MMIO_MONO_STAT_1); 367 else 368 (void) minb(CHIPS_MMIO_COLOR_STAT_1); 369 moutb(CHIPS_MMIO_ATTR_INDEX, index); 370 moutb(CHIPS_MMIO_ATTR_DATA_W, value); 371} 372 373static CARD8 374chipsMmioReadAttr(vgaHWPtr hwp, CARD8 index) 375{ 376 if (hwp->paletteEnabled) 377 index &= ~0x20; 378 else 379 index |= 0x20; 380 381 if (hwp->IOBase == VGA_IOBASE_MONO) 382 (void) minb(CHIPS_MMIO_MONO_STAT_1); 383 else 384 (void) minb(CHIPS_MMIO_COLOR_STAT_1); 385 moutb(CHIPS_MMIO_ATTR_INDEX, index); 386 return minb(CHIPS_MMIO_ATTR_DATA_R); 387} 388 389static void 390chipsMmioWriteMiscOut(vgaHWPtr hwp, CARD8 value) 391{ 392 moutb(CHIPS_MMIO_MISC_OUT_W, value); 393} 394 395static CARD8 396chipsMmioReadMiscOut(vgaHWPtr hwp) 397{ 398 return minb(CHIPS_MMIO_MISC_OUT_R); 399} 400 401static void 402chipsMmioEnablePalette(vgaHWPtr hwp) 403{ 404 if (hwp->IOBase == VGA_IOBASE_MONO) 405 (void) minb(CHIPS_MMIO_MONO_STAT_1); 406 else 407 (void) minb(CHIPS_MMIO_COLOR_STAT_1); 408 moutb(CHIPS_MMIO_ATTR_INDEX, 0x00); 409 hwp->paletteEnabled = TRUE; 410} 411 412static void 413chipsMmioDisablePalette(vgaHWPtr hwp) 414{ 415 if (hwp->IOBase == VGA_IOBASE_MONO) 416 (void) minb(CHIPS_MMIO_MONO_STAT_1); 417 else 418 (void) minb(CHIPS_MMIO_COLOR_STAT_1); 419 moutb(CHIPS_MMIO_ATTR_INDEX, 0x20); 420 hwp->paletteEnabled = FALSE; 421} 422 423static void 424chipsMmioWriteDacMask(vgaHWPtr hwp, CARD8 value) 425{ 426 moutb(CHIPS_MMIO_DAC_MASK, value); 427} 428 429static CARD8 430chipsMmioReadDacMask(vgaHWPtr hwp) 431{ 432 return minb(CHIPS_MMIO_DAC_MASK); 433} 434 435static void 436chipsMmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value) 437{ 438 moutb(CHIPS_MMIO_DAC_READ_ADDR, value); 439} 440 441static void 442chipsMmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value) 443{ 444 moutb(CHIPS_MMIO_DAC_WRITE_ADDR, value); 445} 446 447static void 448chipsMmioWriteDacData(vgaHWPtr hwp, CARD8 value) 449{ 450 moutb(CHIPS_MMIO_DAC_DATA, value); 451} 452 453static CARD8 454chipsMmioReadDacData(vgaHWPtr hwp) 455{ 456 return minb(CHIPS_MMIO_DAC_DATA); 457} 458 459static CARD8 460chipsMmioReadST00(vgaHWPtr hwp) 461{ 462 return minb(CHIPS_MMIO_STAT_0); 463} 464 465static CARD8 466chipsMmioReadST01(vgaHWPtr hwp) 467{ 468 if (hwp->IOBase == VGA_IOBASE_MONO) 469 return minb(CHIPS_MMIO_MONO_STAT_1); 470 else 471 return minb(CHIPS_MMIO_COLOR_STAT_1); 472} 473 474static CARD8 475chipsMmioReadFCR(vgaHWPtr hwp) 476{ 477 return minb(CHIPS_MMIO_FEATURE_R); 478} 479 480static void 481chipsMmioWriteFCR(vgaHWPtr hwp, CARD8 value) 482{ 483 if (hwp->IOBase == VGA_IOBASE_MONO) { 484 moutb(CHIPS_MMIO_MONO_STAT_1, value); 485 } else { 486 moutb(CHIPS_MMIO_COLOR_STAT_1, value); 487 } 488} 489 490void 491CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset) 492{ 493 vgaHWPtr hwp = VGAHWPTR(pScrn); 494 495 hwp->writeCrtc = chipsMmioWriteCrtc; 496 hwp->readCrtc = chipsMmioReadCrtc; 497 hwp->writeGr = chipsMmioWriteGr; 498 hwp->readGr = chipsMmioReadGr; 499 hwp->writeAttr = chipsMmioWriteAttr; 500 hwp->readAttr = chipsMmioReadAttr; 501 hwp->writeSeq = chipsMmioWriteSeq; 502 hwp->readSeq = chipsMmioReadSeq; 503 hwp->writeMiscOut = chipsMmioWriteMiscOut; 504 hwp->readMiscOut = chipsMmioReadMiscOut; 505 hwp->enablePalette = chipsMmioEnablePalette; 506 hwp->disablePalette = chipsMmioDisablePalette; 507 hwp->writeDacMask = chipsMmioWriteDacMask; 508 hwp->readDacMask = chipsMmioReadDacMask; 509 hwp->writeDacWriteAddr = chipsMmioWriteDacWriteAddr; 510 hwp->writeDacReadAddr = chipsMmioWriteDacReadAddr; 511 hwp->writeDacData = chipsMmioWriteDacData; 512 hwp->readDacData = chipsMmioReadDacData; 513 hwp->readST00 = chipsMmioReadST00; 514 hwp->readST01 = chipsMmioReadST01; 515 hwp->readFCR = chipsMmioReadFCR; 516 hwp->writeFCR = chipsMmioWriteFCR; 517 hwp->MMIOBase = base; 518 hwp->MMIOOffset = offset; 519} 520 521 522 523 524