1/* 2 Copyright 2008 Haiku, Inc. All rights reserved. 3 Distributed under the terms of the MIT license. 4 5 Authors: 6 Gerald Zajac 2008 7*/ 8 9#include "accel.h" 10 11#include <unistd.h> 12 13 14// Macros for memory mapped I/O. 15//============================== 16 17#define INREG8(addr) *((vuint8*)(gInfo.regs + addr)) 18#define INREG16(addr) *((vuint16*)(gInfo.regs + addr)) 19#define INREG32(addr) *((vuint32*)(gInfo.regs + addr)) 20 21#define OUTREG8(addr, val) *((vuint8*)(gInfo.regs + addr)) = val 22#define OUTREG16(addr, val) *((vuint16*)(gInfo.regs + addr)) = val 23#define OUTREG32(addr, val) *((vuint32*)(gInfo.regs + addr)) = val 24 25 26// Functions for PIO. 27//=================== 28 29uint32 ReadPIO(uint32 addr, uint8 numBytes) 30{ 31 S3GetSetPIO gsp; 32 gsp.magic = S3_PRIVATE_DATA_MAGIC; 33 gsp.offset = addr; 34 gsp.size = numBytes; 35 gsp.value = 0; 36 37 status_t result = ioctl(gInfo.deviceFileDesc, S3_GET_PIO, &gsp, sizeof(gsp)); 38 if (result != B_OK) 39 TRACE("ReadPIO() failed, result = 0x%x\n", result); 40 41 return gsp.value; 42} 43 44 45void WritePIO(uint32 addr, uint8 numBytes, uint32 value) 46{ 47 S3GetSetPIO gsp; 48 gsp.magic = S3_PRIVATE_DATA_MAGIC; 49 gsp.offset = addr; 50 gsp.size = numBytes; 51 gsp.value = value; 52 53 status_t result = ioctl(gInfo.deviceFileDesc, S3_SET_PIO, &gsp, sizeof(gsp)); 54 if (result != B_OK) 55 TRACE("WritePIO() failed, result = 0x%x\n", result); 56} 57 58 59// Functions to read 8/16/32 bit registers. 60//========================================= 61 62uint8 ReadReg8(uint32 addr) 63{ 64 if (gInfo.sharedInfo->chipType == S3_TRIO64) 65 return ReadPIO(addr, 1); 66 67 return INREG8(addr); 68} 69 70 71uint16 ReadReg16(uint32 addr) 72{ 73 if (gInfo.sharedInfo->chipType == S3_TRIO64) 74 return ReadPIO(addr, 2); 75 76 return INREG16(addr); 77} 78 79 80uint32 ReadReg32(uint32 addr) 81{ 82 if (gInfo.sharedInfo->chipType == S3_TRIO64) 83 return ReadPIO(addr, 4); 84 85 return INREG32(addr); 86} 87 88 89// Functions to write 8/16/32 bit registers. 90//========================================= 91 92void WriteReg8(uint32 addr, uint8 value) 93{ 94 if (gInfo.sharedInfo->chipType == S3_TRIO64) 95 WritePIO(addr, 1, value); 96 else 97 OUTREG8(addr, value); 98} 99 100 101void WriteReg16(uint32 addr, uint16 value) 102{ 103 if (gInfo.sharedInfo->chipType == S3_TRIO64) 104 WritePIO(addr, 2, value); 105 else 106 OUTREG16(addr, value); 107} 108 109 110void WriteReg32(uint32 addr, uint32 value) 111{ 112 if (gInfo.sharedInfo->chipType == S3_TRIO64) 113 WritePIO(addr, 4, value); 114 else 115 OUTREG32(addr, value); 116} 117 118 119// Functions to read/write CRTC registers. 120//======================================== 121 122uint8 ReadCrtcReg(uint8 index) 123{ 124 if (gInfo.sharedInfo->chipType == S3_TRIO64) { 125 WritePIO_8(0x3d4, index); 126 return ReadPIO_8(0x3d5); 127 } 128 129 OUTREG8(0x83d4, index); 130 return INREG8(0x83d5); 131} 132 133 134void WriteCrtcReg(uint8 index, uint8 value) 135{ 136 if (gInfo.sharedInfo->chipType == S3_TRIO64) { 137 WritePIO_8(0x3d4, index); 138 WritePIO_8(0x3d5, value); 139 } else { 140 OUTREG8(0x83d4, index); 141 OUTREG8(0x83d5, value); 142 } 143} 144 145 146void WriteCrtcReg(uint8 index, uint8 value, uint8 mask) 147{ 148 // Write a value to a CRTC reg using a mask. The mask selects the 149 // bits to be modified. 150 151 if (gInfo.sharedInfo->chipType == S3_TRIO64) { 152 WritePIO_8(0x3d4, index); 153 WritePIO_8(0x3d5, (ReadPIO_8(0x3d5) & ~mask) | (value & mask)); 154 } else { 155 OUTREG8(0x83d4, index); 156 OUTREG8(0x83d5, (INREG8(0x83d5) & ~mask) | (value & mask)); 157 } 158} 159 160 161// Functions to read/write Sequence registers. 162//============================================ 163 164uint8 ReadSeqReg(uint8 index) 165{ 166 if (gInfo.sharedInfo->chipType == S3_TRIO64) { 167 WritePIO_8(0x3c4, index); 168 return ReadPIO_8(0x3c5); 169 } 170 171 OUTREG8(0x83c4, index); 172 return INREG8(0x83c5); 173} 174 175 176void WriteSeqReg(uint8 index, uint8 value) 177{ 178 if (gInfo.sharedInfo->chipType == S3_TRIO64) { 179 WritePIO_8(0x3c4, index); 180 WritePIO_8(0x3c5, value); 181 } else { 182 OUTREG8(0x83c4, index); 183 OUTREG8(0x83c5, value); 184 } 185} 186 187 188void WriteSeqReg(uint8 index, uint8 value, uint8 mask) 189{ 190 // Write a value to a Sequencer reg using a mask. The mask selects the 191 // bits to be modified. 192 193 if (gInfo.sharedInfo->chipType == S3_TRIO64) { 194 WritePIO_8(0x3c4, index); 195 WritePIO_8(0x3c5, (ReadPIO_8(0x3c5) & ~mask) | (value & mask)); 196 } else { 197 OUTREG8(0x83c4, index); 198 OUTREG8(0x83c5, (INREG8(0x83c5) & ~mask) | (value & mask)); 199 } 200} 201 202 203// Functions to read/write the misc output register. 204//================================================== 205 206uint8 ReadMiscOutReg() 207{ 208 if (gInfo.sharedInfo->chipType == S3_TRIO64) 209 return ReadPIO_8(0x3cc); 210 211 return INREG8(0x83cc); 212} 213 214 215void WriteMiscOutReg(uint8 value) 216{ 217 if (gInfo.sharedInfo->chipType == S3_TRIO64) 218 WritePIO_8(0x3c2, value); 219 else 220 OUTREG8(0x83c2, value); 221} 222 223 224void WriteIndexedColor(uint8 index, uint8 red, uint8 green, uint8 blue) 225{ 226 // Write an indexed color. Argument index is the index (0-255) of the 227 // color, and arguments red, green, & blue are the components of the color. 228 229 // Note that although the Trio64V+ chip supports MMIO in nearly all areas, 230 // it does not support MMIO for setting indexed colors; thus, use PIO to 231 // set the indexed color. 232 233 if (gInfo.sharedInfo->chipType == S3_TRIO64 234 || gInfo.sharedInfo->chipType == S3_TRIO64_VP) { 235 WritePIO_8(0x3c8, index); // color index 236 WritePIO_8(0x3c9, red); 237 WritePIO_8(0x3c9, green); 238 WritePIO_8(0x3c9, blue); 239 } else { 240 OUTREG8(0x83c8, index); // color index 241 OUTREG8(0x83c9, red); 242 OUTREG8(0x83c9, green); 243 OUTREG8(0x83c9, blue); 244 } 245} 246