vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / graphics / et6x00 / setmode.c
blob9e666da5e8ee321999a1857a81a5a70fadbb8568
1 /*****************************************************************************\
2 * Tseng Labs ET6000, ET6100 and ET6300 graphics driver for BeOS 5.
3 * Copyright (c) 2003-2004, Evgeniy Vladimirovich Bobkov.
4 \*****************************************************************************/
6 #include "setmode.h"
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.
18 /*****************************************************************************/
19 typedef struct {
20 uint32 VisScreenWidth;
21 uint32 VisScreenHeight;
22 uint8 BitsPerPlane;
23 uint8 NumberGreenBits;
24 uint16 Frequency;
25 } VIDEO_MODE_INFORMATION;
26 /*****************************************************************************/
28 * ATTENTION: Don't forget that CRTC indexed register 0x11
29 * bit[7] write-protects some registers.
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}},
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}},
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}},
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}},
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}},
178 #define CLOCK0MN (sizeof(clock0MN) / sizeof(clock0MN[0]))
179 /*****************************************************************************/
180 __inline void et6000EnableLinearMemoryMapping(uint16 pciConfigSpace)
183 * Relocate memory via PCI Base Address 0; don't enable MMU;
184 * enable memory mapped registers; enable system linear memory mapping.
186 ioSet8(pciConfigSpace+0x40, 0xf0, 0x0b);
188 /*****************************************************************************/
189 static void setPCIConfigSpaceRegisters41to5E(uint16 pciConfigSpace,
190 VIDEO_MODE_INFORMATION *mi,
191 uint32 m)
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;
200 pci415e[1] = clock0MN[m].pci42;
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]);
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 */
216 /*****************************************************************************/
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);
229 /* Enable host access to display memory, color mode */
230 ioSet8(0x3c2, 0x00, (ioGet8(0x3cc) & 0xfc) | 0x03);
232 /*****************************************************************************/
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;
239 f = ioGet8(0x3da); /* Set index/data flip-flop to index mode */
240 atcIndexReg = ioGet8(0x3c0) & 0xe0; /* Save bits[7:5] */
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]);
248 switch (bpp) {
249 case 24:
250 atc16 |= 0x20;
251 break;
252 case 16:
253 atc16 |= 0x10;
254 break;
256 f = ioGet8(0x3da); /* Set index/data flip-flop to index mode */
257 ioSet8(0x3c0, 0x00, 0x16 | atcIndexReg);
258 ioSet8(0x3c0, 0x00, atc16);
260 /*****************************************************************************/
261 static void setTS(void) {
262 uint8 ts[7] = {0x02, 0x01, 0x0f, 0x00, 0x0e, 0x00, 0x00};
263 uint8 i;
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]);
271 /*****************************************************************************/
272 static void setGDC(void) {
273 uint8 gdc[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff};
274 uint8 i;
276 for (i = 0; i < 9; i++) {
277 ioSet8(0x3ce, 0xf0, i);
278 ioSet8(0x3cf, 0x00, gdc[i]);
281 /*****************************************************************************/
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));
286 /* Set bit[2] of the selected CLOCK0 PLL parameters register number */
287 ioSet8(0x3d4, 0xc0, 0x34);
288 ioSet8(0x3d5, 0xfd, (regNum & 0x04) << 1);
290 /*****************************************************************************/
291 static void setPLL(uint16 pciConfigSpace,
292 uint32 m) /* mode index */
294 uint8 regNum = 3;
295 uint8 clock0M = 0, clock0N = 0;
297 clock0M = clock0MN[m].clock0M;
298 clock0N = clock0MN[m].clock0N;
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);
306 /*****************************************************************************/
307 static void setCRTC(uint32 m) /* mode index */
309 uint8 i;
311 /* Unlock the write protection of several registers */
312 ioSet8(0x3d4, 0xc0, 0x11);
313 ioSet8(0x3d5, 0x7f, 0x00);
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]);
323 /*****************************************************************************/
324 static uint32 et6000SetGraphicsMode(VIDEO_MODE_INFORMATION *mi,
325 uint16 pciConfigSpace)
327 uint8 m;
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)))
336 break;
339 if (m == CLOCK0MN)
340 return B_BAD_VALUE; /* Found no entry for requested mode */
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);
353 return B_OK;
355 /*****************************************************************************/
356 status_t et6000SetMode(display_mode *mode, uint16 pciConfigSpace) {
357 VIDEO_MODE_INFORMATION mi;
359 mi.VisScreenWidth = mode->virtual_width;
360 mi.VisScreenHeight = mode->virtual_height;
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;
382 mi.Frequency = (uint16) (mode->timing.pixel_clock * 1000
383 / (mode->timing.h_total * mode->timing.v_total));
385 return et6000SetGraphicsMode(&mi, pciConfigSpace);
387 /*****************************************************************************/
388 status_t et6000ProposeMode(display_mode *mode, uint32 memSize) {
389 uint8 m, bpp;
390 uint16 refreshRate;
392 /* Framebuffer must not overlap with the memory mapped registers */
393 if (memSize > 0x3fe000)
394 memSize = 0x3fe000;
396 memSize -= ET6000_ACL_NEEDS_MEMORY;
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;
413 refreshRate = (uint16) (mode->timing.pixel_clock * 1000
414 / (mode->timing.h_total * mode->timing.v_total));
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)))
423 break;
426 if (m == CLOCK0MN)
427 return B_BAD_VALUE; /* Found no entry for requested mode */
429 if (mode->virtual_width * mode->virtual_height * bpp / 8 > memSize)
430 return B_BAD_VALUE; /* Not enough adapter onboard memory */
432 return B_OK;
434 /*****************************************************************************/