xref: /haiku/src/add-ons/accelerants/s3/register_io.cpp (revision 35db13ea5a14c9f6fee81f3de4d54a2fe42502b8)
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 
ReadPIO(uint32 addr,uint8 numBytes)29 uint32 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 
WritePIO(uint32 addr,uint8 numBytes,uint32 value)45 void 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 
ReadReg8(uint32 addr)62 uint8 ReadReg8(uint32 addr)
63 {
64 	if (gInfo.sharedInfo->chipType == S3_TRIO64)
65 		return ReadPIO(addr, 1);
66 
67 	return INREG8(addr);
68 }
69 
70 
ReadReg16(uint32 addr)71 uint16 ReadReg16(uint32 addr)
72 {
73 	if (gInfo.sharedInfo->chipType == S3_TRIO64)
74 		return ReadPIO(addr, 2);
75 
76 	return INREG16(addr);
77 }
78 
79 
ReadReg32(uint32 addr)80 uint32 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 
WriteReg8(uint32 addr,uint8 value)92 void 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 
WriteReg16(uint32 addr,uint16 value)101 void 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 
WriteReg32(uint32 addr,uint32 value)110 void 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 
ReadCrtcReg(uint8 index)122 uint8 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 
WriteCrtcReg(uint8 index,uint8 value)134 void 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 
WriteCrtcReg(uint8 index,uint8 value,uint8 mask)146 void 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 
ReadSeqReg(uint8 index)164 uint8 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 
WriteSeqReg(uint8 index,uint8 value)176 void 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 
WriteSeqReg(uint8 index,uint8 value,uint8 mask)188 void 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 
ReadMiscOutReg()206 uint8 ReadMiscOutReg()
207 {
208 	if (gInfo.sharedInfo->chipType == S3_TRIO64)
209 		return ReadPIO_8(0x3cc);
210 
211 	return INREG8(0x83cc);
212 }
213 
214 
WriteMiscOutReg(uint8 value)215 void 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 
WriteIndexedColor(uint8 index,uint8 red,uint8 green,uint8 blue)224 void 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