1 /*****************************************************************************\
2 * Tseng Labs ET6000, ET6100 and ET6300 graphics driver for BeOS 5.
3 * Copyright (c) 2003-2004, Evgeniy Vladimirovich Bobkov.
4 \*****************************************************************************/
5
6 #include "setmode.h"
7
8
9 /*
10 * ATTENTION: Currently we set the graphics modes by setting the registers
11 * with the beforehand dumped values of the corresponding registers. So not
12 * all graphics modes ET6x00 chips are capable of are accessible. So it would
13 * be great to implement the normal algorithm of run-time computing of the
14 * values to set the register.
15 */
16
17
18 /*****************************************************************************/
19 typedef struct {
20 uint32 VisScreenWidth;
21 uint32 VisScreenHeight;
22 uint8 BitsPerPlane;
23 uint8 NumberGreenBits;
24 uint16 Frequency;
25 } VIDEO_MODE_INFORMATION;
26 /*****************************************************************************/
27 /*
28 * ATTENTION: Don't forget that CRTC indexed register 0x11
29 * bit[7] write-protects some registers.
30 */
31 struct {
32 uint16 width, height, bpp, refreshRate;
33 uint8 clock0M, clock0N;
34 uint8 pci42; /* contains MCLK divider (MDIV) */
35 uint8 crtc[64];
36 } clock0MN[] = {
37 {640, 480, 24, 75, 0x28, 0x22, 0x02,
38 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
39 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0xea, 0x0c, 0xdf, 0xf0, 0x60, 0xe7, 0x04, 0xab,
41 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
42 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
43 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
44 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
45 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
46 {640, 480, 24, 72, 0x56, 0x63, 0x00,
47 {0x63, 0x4f, 0x50, 0x86, 0x55, 0x9a, 0x06, 0x3e,
48 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0xe8, 0x0b, 0xdf, 0xf0, 0x60, 0xe7, 0xff, 0xab,
50 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
51 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
52 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
53 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
54 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
55 {640, 480, 24, 60, 0x28, 0x22, 0x02,
56 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
57 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0xea, 0x0c, 0xdf, 0xf0, 0x60, 0xe7, 0x04, 0xab,
59 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
60 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
61 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
62 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
63 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
64
65 {640, 480, 16, 75, 0x56, 0x43, 0x01,
66 {0x64, 0x4f, 0x4f, 0x88, 0x54, 0x9c, 0xf2, 0x1f,
67 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0xe0, 0x03, 0xdf, 0xa0, 0x60, 0xdf, 0xf3, 0xab,
69 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
70 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
71 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
72 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
73 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
74 {640, 480, 16, 72, 0x56, 0x43, 0x01,
75 {0x63, 0x4f, 0x50, 0x86, 0x55, 0x9a, 0x06, 0x3e,
76 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0xe8, 0x0b, 0xdf, 0xa0, 0x60, 0xe7, 0xff, 0xab,
78 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
79 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
80 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
81 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
82 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
83 {640, 480, 16, 60, 0x28, 0x41, 0x01,
84 {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
85 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0xea, 0x0c, 0xdf, 0xa0, 0x60, 0xe7, 0x04, 0xab,
87 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
88 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
89 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
90 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
91 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
92
93 {800, 600, 24, 75, 0x79, 0x49, 0x00,
94 {0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
95 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x58, 0x0c, 0x57, 0x2c, 0x60, 0x57, 0x73, 0xab,
97 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
98 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
99 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
100 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
101 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x80}},
102 {800, 600, 24, 72, 0x28, 0x41, 0x00,
103 {0x7d, 0x63, 0x63, 0x81, 0x6d, 0x1c, 0x98, 0xf0,
104 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x7c, 0x02, 0x57, 0x2c, 0x60, 0x57, 0x99, 0xab,
106 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
107 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
108 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
109 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
110 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x80}},
111 {800, 600, 24, 60, 0x79, 0x49, 0x00,
112 {0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
113 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x58, 0x0c, 0x57, 0x2c, 0x60, 0x57, 0x73, 0xab,
115 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
116 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
117 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
118 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
119 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x80}},
120
121 {800, 600, 16, 75, 0x51, 0x44, 0x00,
122 {0x7f, 0x63, 0x63, 0x83, 0x68, 0x12, 0x6f, 0xf0,
123 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x58, 0x0b, 0x57, 0xc8, 0x60, 0x57, 0x70, 0xab,
125 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
126 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
127 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
128 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
129 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
130 {800, 600, 16, 72, 0x28, 0x41, 0x00,
131 {0x7d, 0x63, 0x63, 0x81, 0x6d, 0x1c, 0x98, 0xf0,
132 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x7c, 0x02, 0x57, 0xc8, 0x60, 0x57, 0x99, 0xab,
134 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
135 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
136 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
137 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
138 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
139 {800, 600, 16, 60, 0x79, 0x49, 0x00,
140 {0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0,
141 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x58, 0x0c, 0x57, 0xc8, 0x60, 0x57, 0x73, 0xab,
143 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
144 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
145 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
146 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
147 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}},
148
149 {1024, 768, 16, 75, 0x1f, 0x21, 0x00,
150 {0x9f, 0x7f, 0x7f, 0x83, 0x84, 0x90, 0x1e, 0xf5,
151 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x83, 0xff, 0x00, 0x60, 0xff, 0x1f, 0xab,
153 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
154 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
155 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
156 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
157 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x80}},
158 {1024, 768, 16, 70, 0x28, 0x22, 0x00,
159 {0x9f, 0x7f, 0x7f, 0x83, 0x84, 0x90, 0x1e, 0xf5,
160 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x83, 0xff, 0x00, 0x60, 0xff, 0x1f, 0xab,
162 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
163 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
164 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
165 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
166 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x80}},
167 {1024, 768, 16, 60, 0x6b, 0x44, 0x00,
168 {0xa1, 0x7f, 0x80, 0x84, 0x88, 0x99, 0x26, 0xfd,
169 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x08, 0x0a, 0xff, 0x00, 0x60, 0x04, 0x22, 0xab,
171 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
172 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
173 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
174 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x11, 0x11,
175 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x80}},
176 };
177
178 #define CLOCK0MN (sizeof(clock0MN) / sizeof(clock0MN[0]))
179 /*****************************************************************************/
et6000EnableLinearMemoryMapping(uint16 pciConfigSpace)180 __inline void et6000EnableLinearMemoryMapping(uint16 pciConfigSpace)
181 {
182 /*
183 * Relocate memory via PCI Base Address 0; don't enable MMU;
184 * enable memory mapped registers; enable system linear memory mapping.
185 */
186 ioSet8(pciConfigSpace+0x40, 0xf0, 0x0b);
187 }
188 /*****************************************************************************/
setPCIConfigSpaceRegisters41to5E(uint16 pciConfigSpace,VIDEO_MODE_INFORMATION * mi,uint32 m)189 static void setPCIConfigSpaceRegisters41to5E(uint16 pciConfigSpace,
190 VIDEO_MODE_INFORMATION *mi,
191 uint32 m)
192 {
193 uint8 pci415e[30] = {
194 0x3a, 0x00, 0x02, 0x15, 0x04, 0x40, 0x13, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x04, 0x00, 0x00, 0x00, 0x00, 0x00};
198 uint8 i;
199
200 pci415e[1] = clock0MN[m].pci42;
201
202 for (i=0x41; i<0x5f; i++) {
203 if ((i==0x45) || ((i>0x47)&&(i<0x4e)) ||
204 (i==0x4e) || ((i>0x59)&&(i<0x5c)))
205 continue; /* Skip absent or read-only registers */
206 ioSet8(pciConfigSpace+i, 0x00, pci415e[i-0x41]);
207 }
208
209 if (mi->BitsPerPlane == 16) {
210 if (mi->NumberGreenBits == 5)
211 ioSet8(pciConfigSpace+0x58, 0xfd, 0x00); /* 16bpp is 5:5:5 */
212 else
213 ioSet8(pciConfigSpace+0x58, 0xfd, 0x02); /* 16bpp is 5:6:5 */
214 }
215 }
216 /*****************************************************************************/
setMiscOutputRegister(VIDEO_MODE_INFORMATION * mi)217 static void setMiscOutputRegister(VIDEO_MODE_INFORMATION *mi) {
218 uint8 MiscOutputReg;
219 if (mi->VisScreenHeight < 400)
220 MiscOutputReg = 0x80; /* -vsync, +hsync */
221 else if (mi->VisScreenHeight < 480)
222 MiscOutputReg = 0x40; /* +vsync, -hsync */
223 else if (mi->VisScreenHeight < 768)
224 MiscOutputReg = 0xc0; /* -vsync, -hsync */
225 else
226 MiscOutputReg = 0x00; /* +vsync, +hsync */
227 ioSet8(0x3c2, 0x00, (ioGet8(0x3cc) & 0x3f) | MiscOutputReg);
228
229 /* Enable host access to display memory, color mode */
230 ioSet8(0x3c2, 0x00, (ioGet8(0x3cc) & 0xfc) | 0x03);
231 }
232 /*****************************************************************************/
setATC(uint8 bpp)233 static void setATC(uint8 bpp) {
234 uint8 atc[7] = {0x21, 0x00, 0x30, 0x00, 0x00}, atc16 = 0x80;///
235 ///uint8 atc[7] = {0x01, 0x00, 0x0f, 0x00, 0x00}, atc16 = 0x80;///zzz
236 uint8 i, atcIndexReg;
237 volatile uint8 f;
238
239 f = ioGet8(0x3da); /* Set index/data flip-flop to index mode */
240 atcIndexReg = ioGet8(0x3c0) & 0xe0; /* Save bits[7:5] */
241
242 for (i = 0x10; i < 0x15; i++) {
243 f = ioGet8(0x3da); /* Set index/data flip-flop to index mode */
244 ioSet8(0x3c0, 0x00, i | atcIndexReg);
245 ioSet8(0x3c0, 0x00, atc[i-0x10]);
246 }
247
248 switch (bpp) {
249 case 24:
250 atc16 |= 0x20;
251 break;
252 case 16:
253 atc16 |= 0x10;
254 break;
255 }
256 f = ioGet8(0x3da); /* Set index/data flip-flop to index mode */
257 ioSet8(0x3c0, 0x00, 0x16 | atcIndexReg);
258 ioSet8(0x3c0, 0x00, atc16);
259 }
260 /*****************************************************************************/
setTS(void)261 static void setTS(void) {
262 uint8 ts[7] = {0x02, 0x01, 0x0f, 0x00, 0x0e, 0x00, 0x00};
263 uint8 i;
264
265 for (i = 0; i < 7; i++) {
266 if (i == 5) continue; /* Skip absent register */
267 ioSet8(0x3c4, 0xf8, i);
268 ioSet8(0x3c5, 0x00, ts[i]);
269 }
270 }
271 /*****************************************************************************/
setGDC(void)272 static void setGDC(void) {
273 uint8 gdc[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff};
274 uint8 i;
275
276 for (i = 0; i < 9; i++) {
277 ioSet8(0x3ce, 0xf0, i);
278 ioSet8(0x3cf, 0x00, gdc[i]);
279 }
280 }
281 /*****************************************************************************/
setClock0RegNum(uint8 regNum)282 static void setClock0RegNum(uint8 regNum) {
283 /* Set bits[1:0] of the selected CLOCK0 PLL parameters register number */
284 ioSet8(0x3c2, 0x00, (ioGet8(0x3cc) & 0xf3) | ((regNum & 0x03) << 2));
285
286 /* Set bit[2] of the selected CLOCK0 PLL parameters register number */
287 ioSet8(0x3d4, 0xc0, 0x34);
288 ioSet8(0x3d5, 0xfd, (regNum & 0x04) << 1);
289 }
290 /*****************************************************************************/
setPLL(uint16 pciConfigSpace,uint32 m)291 static void setPLL(uint16 pciConfigSpace,
292 uint32 m) /* mode index */
293 {
294 uint8 regNum = 3;
295 uint8 clock0M = 0, clock0N = 0;
296
297 clock0M = clock0MN[m].clock0M;
298 clock0N = clock0MN[m].clock0N;
299
300 setClock0RegNum(regNum);
301 ioSet8(pciConfigSpace+0x67, 0x00, regNum);
302 ioSet8(pciConfigSpace+0x68, 0x00, regNum);
303 ioSet8(pciConfigSpace+0x69, 0x00, clock0M);
304 ioSet8(pciConfigSpace+0x69, 0x00, clock0N);
305 }
306 /*****************************************************************************/
setCRTC(uint32 m)307 static void setCRTC(uint32 m) /* mode index */
308 {
309 uint8 i;
310
311 /* Unlock the write protection of several registers */
312 ioSet8(0x3d4, 0xc0, 0x11);
313 ioSet8(0x3d5, 0x7f, 0x00);
314
315 for (i = 0; i < 64; i++) {
316 if (((i > 0x18) && (i < 0x33)) ||
317 ((i > 0x35) && (i < 0x3f)))
318 continue; /* Skip absent or read-only registers */
319 ioSet8(0x3d4, 0xc0, i);
320 ioSet8(0x3d5, 0x00, clock0MN[m].crtc[i]);
321 }
322 }
323 /*****************************************************************************/
et6000SetGraphicsMode(VIDEO_MODE_INFORMATION * mi,uint16 pciConfigSpace)324 static uint32 et6000SetGraphicsMode(VIDEO_MODE_INFORMATION *mi,
325 uint16 pciConfigSpace)
326 {
327 uint8 m;
328
329 for(m = 0; m < CLOCK0MN; m++) {
330 if ((clock0MN[m].width == mi->VisScreenWidth) &&
331 (clock0MN[m].height == mi->VisScreenHeight) &&
332 (clock0MN[m].bpp == mi->BitsPerPlane) &&
333 ((clock0MN[m].refreshRate-1 <= mi->Frequency) &&
334 (clock0MN[m].refreshRate+1 >= mi->Frequency)))
335 {
336 break;
337 }
338 }
339 if (m == CLOCK0MN)
340 return B_BAD_VALUE; /* Found no entry for requested mode */
341
342 et6000EnableLinearMemoryMapping(pciConfigSpace);
343 setMiscOutputRegister(mi);
344 ioSet8(0x3d8, 0x00, 0xa0); /* Set the KEY for color modes */
345 setPCIConfigSpaceRegisters41to5E(pciConfigSpace, mi, m);
346 ioSet8(0x3c6, 0x00, 0xff); /* Set pixel mask */
347 setATC(mi->BitsPerPlane);
348 setTS();
349 setGDC();
350 setCRTC(m);
351 setPLL(pciConfigSpace, m);
352
353 return B_OK;
354 }
355 /*****************************************************************************/
et6000SetMode(display_mode * mode,uint16 pciConfigSpace)356 status_t et6000SetMode(display_mode *mode, uint16 pciConfigSpace) {
357 VIDEO_MODE_INFORMATION mi;
358
359 mi.VisScreenWidth = mode->virtual_width;
360 mi.VisScreenHeight = mode->virtual_height;
361
362 switch (mode->space) {
363 case B_RGB24_LITTLE:
364 case B_RGB24_BIG:
365 mi.BitsPerPlane = 24;
366 mi.NumberGreenBits = 8;
367 break;
368 case B_RGB16_LITTLE:
369 case B_RGB16_BIG:
370 mi.BitsPerPlane = 16;
371 mi.NumberGreenBits = 6;
372 break;
373 case B_RGB15_LITTLE:
374 case B_RGB15_BIG:
375 mi.BitsPerPlane = 16;
376 mi.NumberGreenBits = 5;
377 break;
378 default:
379 return B_BAD_VALUE;
380 }
381
382 mi.Frequency = (uint16) (mode->timing.pixel_clock * 1000
383 / (mode->timing.h_total * mode->timing.v_total));
384
385 return et6000SetGraphicsMode(&mi, pciConfigSpace);
386 }
387 /*****************************************************************************/
et6000ProposeMode(display_mode * mode,uint32 memSize)388 status_t et6000ProposeMode(display_mode *mode, uint32 memSize) {
389 uint8 m, bpp;
390 uint16 refreshRate;
391
392 /* Framebuffer must not overlap with the memory mapped registers */
393 if (memSize > 0x3fe000)
394 memSize = 0x3fe000;
395
396 memSize -= ET6000_ACL_NEEDS_MEMORY;
397
398 switch (mode->space) {
399 case B_RGB24_LITTLE:
400 case B_RGB24_BIG:
401 bpp = 24;
402 break;
403 case B_RGB16_LITTLE:
404 case B_RGB16_BIG:
405 case B_RGB15_LITTLE:
406 case B_RGB15_BIG:
407 bpp = 16;
408 break;
409 default:
410 return B_BAD_VALUE;
411 }
412
413 refreshRate = (uint16) (mode->timing.pixel_clock * 1000
414 / (mode->timing.h_total * mode->timing.v_total));
415
416 for(m = 0; m < CLOCK0MN; m++) {
417 if ((clock0MN[m].width == mode->virtual_width) &&
418 (clock0MN[m].height == mode->virtual_height) &&
419 (clock0MN[m].bpp == bpp) &&
420 ((clock0MN[m].refreshRate-1 <= refreshRate) &&
421 (clock0MN[m].refreshRate+1 >= refreshRate)))
422 {
423 break;
424 }
425 }
426 if (m == CLOCK0MN)
427 return B_BAD_VALUE; /* Found no entry for requested mode */
428
429 if (mode->virtual_width * mode->virtual_height * bpp / 8 > memSize)
430 return B_BAD_VALUE; /* Not enough adapter onboard memory */
431
432 return B_OK;
433 }
434 /*****************************************************************************/
435