xref: /haiku/src/add-ons/kernel/drivers/graphics/et6x00/setmode.c (revision 450c95c5c61719040969897f8e582edcc345a1f7)
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