1 /* Authors:
2 Mark Watson 12/1999,
3 Apsed,
4 Rudolf Cornelissen 10/2002-10/2009
5 */
6
7 #define MODULE_BIT 0x00008000
8
9 #include "mga_std.h"
10
11 static status_t test_ram(void);
12 static status_t mil_general_powerup (void);
13 static status_t g100_general_powerup (void);
14 static status_t g200_general_powerup (void);
15 static status_t g400_general_powerup (void);
16 static status_t g450_general_powerup (void);
17 static status_t gx00_general_bios_to_powergraphics(void);
18
mga_dump_configuration_space(void)19 static void mga_dump_configuration_space (void)
20 {
21 #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \
22 uint32 value = CFGR(reg); \
23 MSG(("configuration_space 0x%02x %20s 0x%08x\n", \
24 MGACFG_##reg, #reg, value)); \
25 } while (0)
26 DUMP_CFG (DEVID, 0);
27 DUMP_CFG (DEVCTRL, 0);
28 DUMP_CFG (CLASS, 0);
29 DUMP_CFG (HEADER, 0);
30 DUMP_CFG (MGABASE2, 0);
31 DUMP_CFG (MGABASE1, 0);
32 DUMP_CFG (MGABASE3, MYST);
33 DUMP_CFG (SUBSYSIDR, MYST);
34 DUMP_CFG (ROMBASE, 0);
35 DUMP_CFG (CAP_PTR, MIL2);
36 DUMP_CFG (INTCTRL, 0);
37 DUMP_CFG (OPTION, 0);
38 DUMP_CFG (MGA_INDEX, 0);
39 DUMP_CFG (MGA_DATA, 0);
40 DUMP_CFG (SUBSYSIDW, MYST);
41 DUMP_CFG (OPTION2, G100);
42 DUMP_CFG (OPTION3, G400);
43 DUMP_CFG (OPTION4, G400);
44 DUMP_CFG (PM_IDENT, G100);
45 DUMP_CFG (PM_CSR, G100);
46 DUMP_CFG (AGP_IDENT, MIL2);
47 DUMP_CFG (AGP_STS, MIL2);
48 DUMP_CFG (AGP_CMD, MIL2);
49 #undef DUMP_CFG
50 }
51
gx00_general_powerup()52 status_t gx00_general_powerup()
53 {
54 status_t status;
55 uint8 card_class;
56
57 LOG(1,("POWERUP: Haiku Matrox Accelerant 0.33 running.\n"));
58
59 /* log VBLANK INT usability status */
60 if (si->ps.int_assigned)
61 LOG(4,("POWERUP: Usable INT assigned to HW; Vblank semaphore enabled\n"));
62 else
63 LOG(4,("POWERUP: No (usable) INT assigned to HW; Vblank semaphore disabled\n"));
64
65 /* WARNING:
66 * _adi.name_ and _adi.chipset_ can contain 31 readable characters max.!!! */
67
68 /* detect card type and power it up */
69 switch(CFGR(DEVID))
70 {
71 case 0x051a102b: //MGA-1064 Mystique PCI
72 sprintf(si->adi.name, "Matrox Mystique PCI");
73 sprintf(si->adi.chipset, "MGA-1064");
74 LOG(8,("POWERUP: Unimplemented Matrox device %08x\n",CFGR(DEVID)));
75 return B_ERROR;
76 case 0x0519102b: //MGA-2064 Millenium PCI
77 si->ps.card_type = MIL1;
78 sprintf(si->adi.name, "Matrox Millennium I");
79 sprintf(si->adi.chipset, "MGA-2064");
80 status = mil_general_powerup();
81 break;
82 case 0x051b102b:case 0x051f102b: //MGA-2164 Millenium II PCI/AGP
83 si->ps.card_type = MIL2;
84 sprintf(si->adi.name, "Matrox Millennium II");
85 sprintf(si->adi.chipset, "MGA-2164");
86 status = mil_general_powerup();
87 break;
88 case 0x1000102b:case 0x1001102b: //G100
89 si->ps.card_type = G100;
90 sprintf(si->adi.name, "Matrox MGA G100");
91 sprintf(si->adi.chipset, "G100");
92 status = g100_general_powerup();
93 break;
94 case 0x0520102b:case 0x0521102b: //G200
95 si->ps.card_type = G200;
96 sprintf(si->adi.name, "Matrox MGA G200");
97 sprintf(si->adi.chipset, "G200");
98 status = g200_general_powerup();
99 break;
100 case 0x0525102b: //G400, G400MAX or G450
101 /* get classinfo to distinguish different types */
102 card_class = CFGR(CLASS) & 0xff;
103 if (card_class & 0x80)
104 {
105 /* G450 */
106 si->ps.card_type = G450;
107 sprintf(si->adi.name, "Matrox MGA G450");
108 sprintf(si->adi.chipset, "G450 revision %x", (card_class & 0x7f));
109 LOG(4, ("50 revision %x\n", card_class & 0x7f));
110 status = g450_general_powerup();
111 }
112 else
113 {
114 /* standard G400, G400MAX */
115 /* the only difference is the max RAMDAC speed, accounted for via pins. */
116 si->ps.card_type = G400;
117 sprintf(si->adi.name, "Matrox MGA G400");
118 sprintf(si->adi.chipset, "G400 revision %x", (card_class & 0x7f));
119 status = g400_general_powerup();
120 }
121 break;
122 case 0x2527102b://G550 patch from Jean-Michel Batto
123 si->ps.card_type = G450;
124 sprintf(si->adi.name, "Matrox MGA G550");
125 sprintf(si->adi.chipset, "G550");
126 status = g450_general_powerup();
127 break;
128 default:
129 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID)));
130 return B_ERROR;
131 }
132
133 /* override memory detection if requested by user */
134 if (si->settings.memory != 0)
135 si->ps.memory_size = si->settings.memory;
136
137 return status;
138 }
139
test_ram()140 static status_t test_ram()
141 {
142 uint32 value, offset;
143 status_t result = B_OK;
144
145 /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */
146 if (si->fbc.frame_buffer == NULL)
147 {
148 LOG(8,("INIT: test_ram detected NULL pointer.\n"));
149 return B_ERROR;
150 }
151
152 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++)
153 {
154 /* write testpattern to cardRAM */
155 ((vuint32 *)si->fbc.frame_buffer)[offset] = value;
156 /* toggle testpattern */
157 value = 0xffffffff - value;
158 }
159
160 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++)
161 {
162 /* readback and verify testpattern from cardRAM */
163 if (((vuint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR;
164 /* toggle testpattern */
165 value = 0xffffffff - value;
166 }
167 return result;
168 }
169
170 /* NOTE:
171 * This routine *has* to be done *after* SetDispplayMode has been executed,
172 * or test results will not be representative!
173 * (CAS latency is dependant on MGA setup on some (DRAM) boards) */
mga_set_cas_latency()174 status_t mga_set_cas_latency()
175 {
176 status_t result = B_ERROR;
177 uint8 latency = 0;
178
179 /* check current RAM access to see if we need to change anything */
180 if (test_ram() == B_OK)
181 {
182 LOG(4,("INIT: RAM access OK.\n"));
183 return B_OK;
184 }
185
186 /* check if we read PINS at starttime so we have valid registersettings at our disposal */
187 if (si->ps.pins_status != B_OK)
188 {
189 LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n"));
190 return B_ERROR;
191 }
192
193 /* OK. We might have a problem, try to fix it now.. */
194 LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n"));
195
196 switch(si->ps.card_type)
197 {
198 case G100:
199 if (!si->ps.sdram)
200 {
201 LOG(4,("INIT: G100 SGRAM CAS tuning not permitted, aborting.\n"));
202 return B_OK;
203 }
204 /* SDRAM card */
205 for (latency = 4; latency >= 2; latency-- )
206 {
207 /* MCTLWTST is a write-only register! */
208 ACCW(MCTLWTST, ((si->ps.mctlwtst_reg & 0xfffffffc) | (latency - 2)));
209 result = test_ram();
210 if (result == B_OK) break;
211 }
212 break;
213 case G200:
214 /* fixme: implement this */
215 LOG(4,("INIT: G200 RAM CAS tuning not implemented, aborting.\n"));
216 return B_OK;
217 break;
218 case G400:
219 case G400MAX:
220 /* fixme: implement this if needed */
221 LOG(4,("INIT: G400/G400MAX RAM CAS tuning not implemented, aborting.\n"));
222 return B_OK;
223 break;
224 case G450:
225 case G550:
226 /* fixme: implement this if needed */
227 LOG(4,("INIT: G450/G550 RAM CAS tuning not implemented, aborting.\n"));
228 return B_OK;
229 break;
230 default:
231 /* fixme: Millenium2 and others if needed */
232 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n"));
233 return B_OK;
234 break;
235 }
236 if (result == B_OK)
237 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency));
238 else
239 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency));
240
241 return result;
242 }
243
244 static
mil_general_powerup()245 status_t mil_general_powerup()
246 {
247 status_t result;
248
249 LOG(4, ("INIT: Millenium I/II powerup\n"));
250 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset));
251 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space();
252
253 /* initialize the shared_info PINS struct */
254 result = parse_pins();
255 if (result != B_OK) fake_pins();
256
257 /* log the PINS struct settings */
258 dump_pins();
259
260 //remove this:
261 fake_pins();
262 LOG(2, ("INIT: Using faked PINS for now:\n"));
263 dump_pins();
264 //end remove this.
265
266 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
267 //restore this line:
268 // if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics();
269
270 //set to powergraphics etc.
271 LOG(2, ("INIT: Skipping card coldstart!\n"));
272 mil2_dac_init();
273
274 //ok:
275 /* disable overscan, select 0 IRE, select straight-through sync signals from CRTC */
276 DXIW (GENCTRL, (DXIR (GENCTRL) & 0x0c));
277 /* fixme: checkout if we need this sync inverting stuff: already done via CRTC!?!
278 | (vsync_pos? 0x00:0x02)
279 | (hsync_pos? 0x00:0x01)); */
280
281 /* 8-bit DAC, enable DAC */
282 DXIW(MISCCTRL, 0x0c);
283 //
284
285 VGAW_I(SEQ,1,0x00);
286 /*enable screen*/
287
288 return B_OK;
289 }
290
291 static
g100_general_powerup()292 status_t g100_general_powerup()
293 {
294 status_t result;
295
296 LOG(4, ("INIT: G100 powerup\n"));
297 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset));
298 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space();
299
300 /* initialize the shared_info PINS struct */
301 result = parse_pins();
302 if (result != B_OK) fake_pins();
303
304 /* log the PINS struct settings */
305 dump_pins();
306
307 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
308 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics();
309
310 /*power up the PLLs,LUT,DAC*/
311 LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
312 /* turn off both displays and the hardcursor (also disables transfers) */
313 gx00_crtc_dpms(false, false, false);
314 /* on singlehead cards with TVout program the MAVEN as well */
315 if (si->ps.tvout) gx00_maven_dpms(false, false, false);
316 gx00_crtc_cursor_hide();
317 /* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
318 * (this would create electrical shortcuts,
319 * resulting in extra chip heat and distortions visible on screen */
320 /* set voltage reference - using DAC reference block partly */
321 DXIW(VREFCTRL,0x03);
322 /* wait for 100ms for voltage reference to stabilize */
323 delay(100000);
324 /* power up the SYSPLL */
325 CFGW(OPTION,CFGR(OPTION)|0x20);
326 /* power up the PIXPLL */
327 DXIW(PIXCLKCTRL,0x08);
328
329 /* disable pixelclock oscillations before switching on CLUT */
330 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04));
331 /* disable 15bit mode CLUT-overlay function */
332 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd));
333 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */
334 DXIW(MISCCTRL,0x1b);
335 snooze(250);
336 /* re-enable pixelclock oscillations */
337 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb));
338
339 /* setup i2c bus */
340 i2c_init();
341
342 /*make sure card is in powergraphics mode*/
343 VGAW_I(CRTCEXT,3,0x80);
344
345 /*set the system clocks to powergraphics speed*/
346 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n"));
347 g100_dac_set_sys_pll();
348
349 /* 'official' RAM initialisation */
350 LOG(2,("INIT: RAM init\n"));
351 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */
352 ACCW(PLNWT,0x00000000);
353 ACCW(PLNWT,0xffffffff);
354 /* program memory control waitstates */
355 ACCW(MCTLWTST,si->ps.mctlwtst_reg);
356 /* set memory configuration including:
357 * - no split framebuffer.
358 * - Mark says b14 (G200) should be done also though not defined for G100 in spec,
359 * - b3 v3_mem_type was included by Mark for memconfig setup: but looks like not defined */
360 CFGW(OPTION,(CFGR(OPTION)&0xFFFF8FFF) | ((si->ps.v3_mem_type & 0x04) << 10));
361 /* set memory buffer type:
362 * - Mark says: if((v3_mem_type & 0x03) == 0x03) then do not or-in bits in option2;
363 * but looks like v3_mem_type b1 is not defined,
364 * - Mark also says: place v3_mem_type b1 in option2 bit13 (if not 0x03) but b13 = reserved. */
365 CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_mem_type & 0x01) << 12));
366 /* set RAM read tap delay */
367 CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFFFF0) | ((si->ps.v3_mem_type & 0xf0) >> 4));
368 /* wait 200uS minimum */
369 snooze(250);
370
371 /* reset memory (MACCESS is a write only register!) */
372 ACCW(MACCESS, 0x00000000);
373 /* select JEDEC reset method */
374 ACCW(MACCESS, 0x00004000);
375 /* perform actual RAM reset */
376 ACCW(MACCESS, 0x0000c000);
377 snooze(250);
378 /* start memory refresh */
379 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000));
380 /* set memory control waitstate again AFTER the RAM reset */
381 ACCW(MCTLWTST,si->ps.mctlwtst_reg);
382 /* end 'official' RAM initialisation. */
383
384 /* Bus parameters: enable retries, use advanced read */
385 CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29)));
386
387 /*enable writing to crtc registers*/
388 VGAW_I(CRTC,0x11,0);
389
390 return B_OK;
391 }
392
393 static
g200_general_powerup()394 status_t g200_general_powerup()
395 {
396 status_t result;
397
398 LOG(4, ("INIT: G200 powerup\n"));
399 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset));
400 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space();
401
402 /* initialize the shared_info PINS struct */
403 result = parse_pins();
404 if (result != B_OK) fake_pins();
405
406 /* log the PINS struct settings */
407 dump_pins();
408
409 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
410 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics();
411
412 /*power up the PLLs,LUT,DAC*/
413 LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
414 /* turn off both displays and the hardcursor (also disables transfers) */
415 gx00_crtc_dpms(false, false, false);
416 /* on singlehead cards with TVout program the MAVEN as well */
417 if (si->ps.tvout) gx00_maven_dpms(false, false, false);
418 gx00_crtc_cursor_hide();
419 /* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
420 * (this would create electrical shortcuts,
421 * resulting in extra chip heat and distortions visible on screen */
422 /* set voltage reference - using DAC reference block partly */
423 DXIW(VREFCTRL,0x03);
424 /* wait for 100ms for voltage reference to stabilize */
425 delay(100000);
426 /* power up the SYSPLL */
427 CFGW(OPTION,CFGR(OPTION)|0x20);
428 /* power up the PIXPLL */
429 DXIW(PIXCLKCTRL,0x08);
430
431 /* disable pixelclock oscillations before switching on CLUT */
432 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04));
433 /* disable 15bit mode CLUT-overlay function */
434 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd));
435 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */
436 DXIW(MISCCTRL,0x1b);
437 snooze(250);
438 /* re-enable pixelclock oscillations */
439 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb));
440
441 /* setup i2c bus */
442 i2c_init();
443
444 /*make sure card is in powergraphics mode*/
445 VGAW_I(CRTCEXT,3,0x80);
446
447 /*set the system clocks to powergraphics speed*/
448 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n"));
449 g200_dac_set_sys_pll();
450
451 /* 'official' RAM initialisation */
452 LOG(2,("INIT: RAM init\n"));
453 /* disable hardware plane write mask if SDRAM card */
454 if (si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) & 0xffffbfff));
455 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */
456 ACCW(PLNWT,0x00000000);
457 ACCW(PLNWT,0xffffffff);
458 /* program memory control waitstates */
459 ACCW(MCTLWTST,si->ps.mctlwtst_reg);
460 /* set memory configuration including:
461 * - SDRAM / SGRAM special functions select. */
462 CFGW(OPTION,(CFGR(OPTION)&0xFFFF83FF) | ((si->ps.v3_mem_type & 0x07) << 10));
463 if (!si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) | (0x01 << 14)));
464 /* set memory buffer type */
465 CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_option2_reg & 0x03) << 12));
466 /* set mode register opcode and streamer flow control */
467 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0x0000FFFF)|(si->ps.memrdbk_reg & 0xffff0000));
468 /* set RAM read tap delays */
469 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0xFFFF0000)|(si->ps.memrdbk_reg & 0x0000ffff));
470 /* wait 200uS minimum */
471 snooze(250);
472
473 /* reset memory (MACCESS is a write only register!) */
474 ACCW(MACCESS, 0x00000000);
475 /* perform actual RAM reset */
476 ACCW(MACCESS, 0x00008000);
477 snooze(250);
478 /* start memory refresh */
479 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000));
480 /* set memory control waitstate again AFTER the RAM reset */
481 ACCW(MCTLWTST,si->ps.mctlwtst_reg);
482 /* end 'official' RAM initialisation. */
483
484 /* Bus parameters: enable retries, use advanced read */
485 CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29)));
486
487 /*enable writing to crtc registers*/
488 VGAW_I(CRTC,0x11,0);
489
490 return B_OK;
491 }
492
493 static
g400_general_powerup()494 status_t g400_general_powerup()
495 {
496 status_t result;
497
498 LOG(4, ("INIT: G400/G400MAX powerup\n"));
499 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset));
500 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space();
501
502 /* initialize the shared_info PINS struct */
503 result = parse_pins();
504 if (result != B_OK) fake_pins();
505
506 /* log the PINS struct settings */
507 dump_pins();
508
509 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
510 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics();
511
512 /* reset MAVEN so we know the sync polarity is at reset situation (Hpos, Vpos) */
513 if (si->ps.tvout)
514 {
515 ACCW(RST, 0x00000002);
516 snooze(1000);
517 ACCW(RST, 0x00000000);
518 }
519
520 /*power up the PLLs,LUT,DAC*/
521 LOG(4,("INIT: PLL/LUT/DAC powerup\n"));
522 /* turn off both displays and the hardcursor (also disables transfers) */
523 gx00_crtc_dpms(false, false, false);
524 g400_crtc2_dpms(false, false, false);
525 gx00_crtc_cursor_hide();
526
527 /* set voltage reference - not using DAC reference block */
528 DXIW(VREFCTRL,0x00);
529 /* wait for 100ms for voltage reference to stabilize */
530 delay(100000);
531 /* power up the SYSPLL */
532 CFGW(OPTION,CFGR(OPTION)|0x20);
533 /* power up the PIXPLL */
534 DXIW(PIXCLKCTRL,0x08);
535
536 /* disable pixelclock oscillations before switching on CLUT */
537 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04));
538 /* disable 15bit mode CLUT-overlay function */
539 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd));
540 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */
541 DXIW(MISCCTRL,0x9b);
542 snooze(250);
543 /* re-enable pixelclock oscillations */
544 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb));
545
546 DXIW(MAFCDEL,0x02); /*makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr!*/
547 DXIW(PANELMODE,0x00); /*eclipse panellink*/
548
549 /* setup i2c bus */
550 i2c_init();
551
552 /* make sure card is in powergraphics mode */
553 VGAW_I(CRTCEXT,3,0x80);
554
555 /* set the system clocks to powergraphics speed */
556 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n"));
557 g400_dac_set_sys_pll();
558
559 /* 'official' RAM initialisation */
560 LOG(2,("INIT: RAM init\n"));
561 /* disable hardware plane write mask if SDRAM card */
562 if (si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) & 0xffffbfff));
563 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */
564 ACCW(PLNWT,0x00000000);
565 ACCW(PLNWT,0xffffffff);
566 /* program memory control waitstates */
567 ACCW(MCTLWTST, si->ps.mctlwtst_reg);
568 /* set memory configuration including:
569 * - SDRAM / SGRAM special functions select. */
570 CFGW(OPTION,(CFGR(OPTION)&0xFFFF83FF) | (si->ps.option_reg & 0x00001c00));
571 if (!si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) | (0x01 << 14)));
572 /* set mode register opcode and streamer flow control */
573 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0x0000FFFF)|(si->ps.memrdbk_reg & 0xffff0000));
574 /* set RAM read tap delays */
575 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0xFFFF0000)|(si->ps.memrdbk_reg & 0x0000ffff));
576 /* wait 200uS minimum */
577 snooze(250);
578
579 /* reset memory (MACCESS is a write only register!) */
580 ACCW(MACCESS, 0x00000000);
581 /* perform actual RAM reset */
582 ACCW(MACCESS, 0x00008000);
583 snooze(250);
584 /* start memory refresh */
585 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000));
586 /* set memory control waitstate again AFTER the RAM reset */
587 ACCW(MCTLWTST,si->ps.mctlwtst_reg);
588 /* end 'official' RAM initialisation. */
589
590 /* 'advance read' busparameter and 'memory priority' enable/disable setup */
591 CFGW(OPTION, ((CFGR(OPTION) & 0xefbfffff) | (si->ps.option_reg & 0x10400000)));
592
593 /*enable writing to crtc registers*/
594 VGAW_I(CRTC,0x11,0);
595 if (si->ps.secondary_head)
596 {
597 MAVW(LOCK,0x01);
598 CR2W(DATACTL,0x00000000);
599 }
600
601 return B_OK;
602 }
603
604 static
g450_general_powerup()605 status_t g450_general_powerup()
606 {
607 status_t result;
608 uint32 pwr_cas[] = {0, 1, 5, 6, 7, 5, 2, 3};
609
610 /* used for convenience: MACCESS is a write only register! */
611 uint32 maccess = 0x00000000;
612
613 LOG(4, ("INIT: G450/G550 powerup\n"));
614 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset));
615 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space();
616
617 /* initialize the shared_info PINS struct */
618 result = parse_pins();
619 if (result != B_OK) fake_pins();
620
621 /* log the PINS struct settings */
622 dump_pins();
623
624 /* check output connector setup */
625 if (si->ps.primary_dvi && si->ps.secondary_head &&
626 si->ps.tvout && (i2c_sec_tv_adapter() != B_OK))
627 {
628 /* signal CRTC2 DPMS which connector to program or readout */
629 si->crossed_conns = true;
630 }
631
632 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
633 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics();
634
635 /* power up the PLLs,LUT,DAC */
636 LOG(4,("INIT: PLL/LUT/DAC powerup\n"));
637 /* disable outputs */
638 DXIW(OUTPUTCONN,0x00);
639 /* turn off both displays and the hardcursor (also disables transfers) */
640 gx00_crtc_dpms(false, false, false);
641 g400_crtc2_dpms(false, false, false);
642 gx00_crtc_cursor_hide();
643
644 /* power up everything except DVI electronics (for now) */
645 DXIW(PWRCTRL,0x1b);
646 /* set voltage reference - not using DAC reference block */
647 DXIW(VREFCTRL,0x00);
648 /* wait for 100ms for voltage reference to stabilize */
649 delay(100000);
650 /* power up the SYSPLL */
651 CFGW(OPTION,CFGR(OPTION)|0x20);
652 /* power up the PIXPLL */
653 DXIW(PIXCLKCTRL,0x08);
654
655 /* disable pixelclock oscillations before switching on CLUT */
656 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04));
657 /* disable 15bit mode CLUT-overlay function */
658 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd));
659 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */
660 DXIW(MISCCTRL,0x9b);
661 snooze(250);
662
663 /* re-enable pixelclock oscillations */
664 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb));
665
666 //fixme:
667 DXIW(MAFCDEL,0x02); /*makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr!*/
668 DXIW(PANELMODE,0x00); /*eclipse panellink*/
669
670 /* setup i2c bus */
671 i2c_init();
672
673 /* make sure card is in powergraphics mode */
674 VGAW_I(CRTCEXT,3,0x80);
675
676 /* set the system clocks to powergraphics speed */
677 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n"));
678 g450_dac_set_sys_pll();
679
680 /* 'official' RAM initialisation */
681 LOG(2,("INIT: RAM init\n"));
682 /* stop memory refresh, and setup b9, memconfig, b13, sgram planemask function, b21 fields,
683 * and don't touch the rest */
684 CFGW(OPTION, ((CFGR(OPTION) & 0xf8400164) | (si->ps.option_reg & 0x00207e00)));
685 /* setup b10-b15 unknown field */
686 CFGW(OPTION2, ((CFGR(OPTION2) & 0xffff0200) | (si->ps.option2_reg & 0x0000fc00)));
687
688 /* program memory control waitstates */
689 ACCW(MCTLWTST, si->ps.mctlwtst_reg);
690 /* program option4 b0-3 and b29-30 fields, reset the rest: stop memory clock */
691 CFGW(OPTION4, (si->ps.option4_reg & 0x6000000f));
692 /* set RAM read tap delays and mode register opcode / streamer flow control */
693 ACCW(MEMRDBK, si->ps.memrdbk_reg);
694 /* b7 v5_mem_type = done by Mark Watson. fixme: still confirm! (unknown bits) */
695 maccess = ((((uint32)si->ps.v5_mem_type) & 0x80) >> 1);
696 ACCW(MACCESS, maccess);
697 /* clear b0-1 and 3, and set b31 in option4: re-enable memory clock */
698 CFGW(OPTION4, ((si->ps.option4_reg & 0x60000004) | 0x80000000));
699 snooze(250);
700
701 /* if DDR RAM */
702 if ((si->ps.v5_mem_type & 0x0060) == 0x0020)
703 {
704 /* if not 'EMRSW RAM-option' available */
705 if (!(si->ps.v5_mem_type & 0x0100))
706 {
707 /* clear unknown bits */
708 maccess = 0x00000000;
709 ACCW(MACCESS, maccess);
710 /* clear b12: unknown bit */
711 ACCW(MEMRDBK, (si->ps.memrdbk_reg & 0xffffefff));
712 }
713 else
714 /* if not 'DLL RAM-option' available */
715 if (!(si->ps.v5_mem_type & 0x0200))
716 {
717 /* clear b12: unknown bit */
718 ACCW(MEMRDBK, (si->ps.memrdbk_reg & 0xffffefff));
719 }
720 }
721
722 /* create positive flank to generate memory reset */
723 //fixme: G550 is still noted as a G450, fix upon trouble..
724 if (si->ps.card_type == G450) {
725 ACCW(MACCESS, (maccess & 0xffff3fff));
726 ACCW(MACCESS, (maccess | 0x0000c000));
727 } else { //G550
728 ACCW(MACCESS, (maccess & 0xffff7fff));
729 ACCW(MACCESS, (maccess | 0x00008000));
730 }
731 snooze(250);
732
733 /* start memory refresh */
734 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000));
735
736 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */
737 ACCW(PLNWT,0x00000000);
738 ACCW(PLNWT,0xffffffff);
739
740 /* if not 'MEMCASLT RAM-option' available */
741 if (!(si->ps.v5_mem_type & 0x0400))
742 {
743 /* calculate powergraphics CAS-latency from pins CAS-latency, and update register setting */
744 ACCW(MCTLWTST,
745 ((si->ps.mctlwtst_reg & 0xfffffff8) | pwr_cas[(si->ps.mctlwtst_reg & 0x07)]));
746
747 }
748
749 /*enable writing to crtc registers*/
750 VGAW_I(CRTC,0x11,0);
751 //fixme..
752 if (si->ps.secondary_head)
753 {
754 //MAVW(LOCK,0x01);
755 CR2W(DATACTL,0x00000000);
756 }
757
758 /* enable primary analog output */
759 gx50_general_output_select();
760
761 /* enable 'straight-through' sync outputs on both analog output connectors and
762 * make sure CRTC1 sync outputs are patched through! */
763 DXIW(SYNCCTRL,0x00);
764
765 return B_OK;
766 }
767
gx50_general_output_select()768 status_t gx50_general_output_select()
769 {
770 /* make sure this call is warranted */
771 if ((si->ps.card_type != G450) && (si->ps.card_type != G550)) return B_ERROR;
772
773 /* choose primary analog outputconnector */
774 if (si->ps.primary_dvi && si->ps.secondary_head && si->ps.tvout)
775 {
776 if (i2c_sec_tv_adapter() == B_OK)
777 {
778 LOG(4,("INIT: secondary TV-adapter detected, using primary connector\n"));
779 DXIW(OUTPUTCONN,0x01);
780 /* signal CRTC2 DPMS which connector to program */
781 si->crossed_conns = false;
782 }
783 else
784 {
785 LOG(4,("INIT: no secondary TV-adapter detected, using secondary connector\n"));
786 DXIW(OUTPUTCONN,0x04);
787 /* signal CRTC2 DPMS which connector to program */
788 si->crossed_conns = true;
789 }
790 }
791 else
792 {
793 LOG(4,("INIT: using primary connector\n"));
794 DXIW(OUTPUTCONN,0x01);
795 /* signal CRTC2 DPMS which connector to program */
796 si->crossed_conns = false;
797 }
798 return B_OK;
799 }
800
801 /* connect CRTC(s) to the specified DAC(s) */
gx00_general_dac_select(int dac)802 status_t gx00_general_dac_select(int dac)
803 {
804 /*MISCCTRL, clock src,...*/
805 switch(dac)
806 {
807 /* G100 - G400 */
808 case DS_CRTC1DAC:
809 case DS_CRTC1DAC_CRTC2MAVEN:
810 /* connect CRTC1 to pixPLL */
811 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x1);
812 /* connect CRTC2 to vidPLL, connect CRTC1 to internal DAC and
813 * enable CRTC2 external video timing reset signal.
814 * (Setting for MAVEN 'master mode' TVout signal generation.) */
815 if (si->ps.secondary_head) CR2W(CTL,(CR2R(CTL)&0xffe00779)|0xD0000002);
816 /* disable CRTC1 external video timing reset signal */
817 VGAW_I(CRTCEXT,1,(VGAR_I(CRTCEXT,1)&0x77));
818 /* select CRTC2 RGB24 MAFC mode: connects CRTC2 to MAVEN DAC */
819 DXIW(MISCCTRL,(DXIR(MISCCTRL)&0x19)|0x82);
820 break;
821 case DS_CRTC1MAVEN:
822 case DS_CRTC1MAVEN_CRTC2DAC:
823 /* connect CRTC1 to vidPLL */
824 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x2);
825 /* connect CRTC2 to pixPLL and internal DAC and
826 * disable CRTC2 external video timing reset signal */
827 if (si->ps.secondary_head) CR2W(CTL,(CR2R(CTL)&0x2fe00779)|0x4|(0x1<<20));
828 /* enable CRTC1 external video timing reset signal.
829 * note: this is nolonger used as G450/G550 cannot do TVout on CRTC1 */
830 VGAW_I(CRTCEXT,1,(VGAR_I(CRTCEXT,1)|0x88));
831 /* select CRTC1 RGB24 MAFC mode: connects CRTC1 to MAVEN DAC */
832 DXIW(MISCCTRL,(DXIR(MISCCTRL)&0x19)|0x02);
833 break;
834 /* G450/G550 */
835 case DS_CRTC1CON1_CRTC2CON2:
836 if (si->ps.card_type < G450) return B_ERROR;
837 /* connect CRTC1 to pixPLL */
838 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x1);
839 /* connect CRTC2 to vidPLL, connect CRTC1 to DAC1, disable CRTC2
840 * external video timing reset signal, set CRTC2 progressive scan mode
841 * and disable TVout mode (b12).
842 * (Setting for MAVEN 'slave mode' TVout signal generation.) */
843 //fixme: enable timing resets if TVout is used in master mode!
844 //otherwise keep it disabled.
845 CR2W(CTL,(CR2R(CTL)&0x2de00779)|0x6|(0x0<<20));
846 /* connect DAC1 to CON1, CRTC2/'DAC2' to CON2 (monitor mode) */
847 DXIW(OUTPUTCONN,0x09);
848 /* Select 1.5 Volt MAVEN DAC ref. for monitor mode */
849 DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40);
850 DXIW(GENIODATA, 0x00);
851 /* signal CRTC2 DPMS which connector to program */
852 si->crossed_conns = false;
853 break;
854 //fixme: toggle PLL's below if possible:
855 // otherwise toggle PLL's for G400 2nd case?
856 case DS_CRTC1CON2_CRTC2CON1:
857 if (si->ps.card_type < G450) return B_ERROR;
858 /* connect CRTC1 to pixPLL */
859 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x1);
860 /* connect CRTC2 to vidPLL and DAC1, disable CRTC2 external
861 * video timing reset signal, and set CRTC2 progressive scan mode and
862 * disable TVout mode (b12). */
863 CR2W(CTL,(CR2R(CTL)&0x2de00779)|0x6|(0x1<<20));
864 /* connect DAC1 to CON2 (monitor mode), CRTC2/'DAC2' to CON1 */
865 DXIW(OUTPUTCONN,0x05);
866 /* Select 1.5 Volt MAVEN DAC ref. for monitor mode */
867 DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40);
868 DXIW(GENIODATA, 0x00);
869 /* signal CRTC2 DPMS which connector to program */
870 si->crossed_conns = true;
871 break;
872 default:
873 return B_ERROR;
874 }
875 return B_OK;
876 }
877
878 /* basic change of card state from VGA to powergraphics -> should work from BIOS init state*/
879 static
gx00_general_bios_to_powergraphics()880 status_t gx00_general_bios_to_powergraphics()
881 {
882 LOG(2, ("INIT: Skipping card coldstart!\n"));
883
884 //set to powergraphics etc.
885 CFGW(DEVCTRL,(2|CFGR(DEVCTRL)));
886 /*enable device response (already enabled here!)*/
887
888 VGAW_I(CRTC,0x11,0);
889 /*allow me to change CRTC*/
890
891 VGAW_I(CRTCEXT,3,0x80);
892 /*use powergraphix (+ trash other bits, they are set later)*/
893
894 VGAW(MISCW,0x08);
895 /*set only MGA pixel clock in MISC - I don't want to map VGA stuff under this OS*/
896
897 switch (si->ps.card_type)
898 {
899 case G400:
900 case G400MAX:
901 /* reset MAVEN so we know the sync polarity is at reset situation (Hpos, Vpos) */
902 if (si->ps.tvout)
903 {
904 ACCW(RST, 0x00000002);
905 snooze(1000);
906 ACCW(RST, 0x00000000);
907 }
908 /* makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr! */
909 DXIW(MAFCDEL,0x02);
910 break;
911 case G450:
912 case G550:
913 /* power up everything except DVI electronics (for now) */
914 DXIW(PWRCTRL,0x1b);
915 /* enable 'straight-through' sync outputs on both analog output
916 * connectors and make sure CRTC1 sync outputs are patched through! */
917 DXIW(SYNCCTRL,0x00);
918 break;
919 default:
920 break;
921 }
922
923 if (si->ps.card_type >= G100)
924 {
925 DXIW(MISCCTRL,0x9b);
926 /*CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC*/
927
928 DXIW(MULCTRL,0x4);
929 /*RGBA direct mode*/
930 }
931 else
932 {
933 LOG(8, ("INIT: < G100 DAC powerup badly implemented, MISC 0x%02x\n", VGAR(MISCR)));
934 } // apsed TODO MIL2
935
936 VGAW_I(SEQ,1,0x00);
937 /*enable screen*/
938
939 return B_OK;
940 }
941
942 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify
943 * virtual_size to the nearest valid maximum for the mode on the card if not so.
944 * Then: check if virtual_width adheres to the cards _multiple_ constraints, and
945 * create mode slopspace if not so.
946 * We use acc multiple constraints here if we expect we can use acceleration, because
947 * acc constraints are worse than CRTC constraints.
948 *
949 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */
950 //fixme: seperate heads for real dualhead modes:
951 //CRTC1 and 2 constraints differ!
gx00_general_validate_pic_size(display_mode * target,uint32 * bytes_per_row,bool * acc_mode)952 status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode)
953 {
954 /* Note:
955 * This routine assumes that the CRTC memory pitch granularity is 'smaller than',
956 * or 'equals' the acceleration engine memory pitch granularity! */
957
958 uint32 video_pitch;
959 uint32 acc_mask, crtc_mask;
960 uint8 depth = 8;
961
962 /* determine pixel multiple based on 2D/3D engine constraints */
963 switch (si->ps.card_type)
964 {
965 case MIL1:
966 case MIL2:
967 /* see MIL1/2 specs:
968 * these cards always use a 64bit RAMDAC (TVP3026) and interleaved memory */
969 switch (target->space)
970 {
971 case B_CMAP8: acc_mask = 0x7f; depth = 8; break;
972 case B_RGB15: acc_mask = 0x3f; depth = 16; break;
973 case B_RGB16: acc_mask = 0x3f; depth = 16; break;
974 case B_RGB24: acc_mask = 0x7f; depth = 24; break;
975 case B_RGB32: acc_mask = 0x1f; depth = 32; break;
976 default:
977 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
978 return B_ERROR;
979 }
980 break;
981 default:
982 /* see G100 and up specs:
983 * these cards can do 2D as long as multiples of 32 are used.
984 * (Note: don't mix this up with adress linearisation!) */
985 switch (target->space)
986 {
987 case B_CMAP8: depth = 8; break;
988 case B_RGB15: depth = 16; break;
989 case B_RGB16: depth = 16; break;
990 case B_RGB24: depth = 24; break;
991 case B_RGB32: depth = 32; break;
992 default:
993 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
994 return B_ERROR;
995 }
996 acc_mask = 0x1f;
997 break;
998 }
999
1000 /* determine pixel multiple based on CRTC memory pitch constraints.
1001 * (Note: Don't mix this up with CRTC timing contraints! Those are
1002 * multiples of 8 for horizontal, 1 for vertical timing.) */
1003 switch (si->ps.card_type)
1004 {
1005 case MIL1:
1006 case MIL2:
1007 /* see MIL1/2 specs:
1008 * these cards always use a 64bit RAMDAC and interleaved memory */
1009 switch (target->space)
1010 {
1011 case B_CMAP8: crtc_mask = 0x7f; break;
1012 case B_RGB15: crtc_mask = 0x3f; break;
1013 case B_RGB16: crtc_mask = 0x3f; break;
1014 /* for B_RGB24 crtc_mask 0x7f is worst case scenario (MIL2 constraint) */
1015 case B_RGB24: crtc_mask = 0x7f; break;
1016 case B_RGB32: crtc_mask = 0x1f; break;
1017 default:
1018 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1019 return B_ERROR;
1020 }
1021 break;
1022 default:
1023 /* see G100 and up specs */
1024 switch (target->space)
1025 {
1026 case B_CMAP8: crtc_mask = 0x0f; break;
1027 case B_RGB15: crtc_mask = 0x07; break;
1028 case B_RGB16: crtc_mask = 0x07; break;
1029 case B_RGB24: crtc_mask = 0x0f; break;
1030 case B_RGB32: crtc_mask = 0x03; break;
1031 default:
1032 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1033 return B_ERROR;
1034 }
1035 /* see G400 specs: CRTC2 has different constraints */
1036 /* Note:
1037 * set for RGB and B_YCbCr422 modes. Other modes need larger multiples! */
1038 if (target->flags & DUALHEAD_BITS)
1039 {
1040 switch (target->space)
1041 {
1042 case B_RGB16: crtc_mask = 0x1f; break;
1043 case B_RGB32: crtc_mask = 0x0f; break;
1044 default:
1045 LOG(8,("INIT: illegal DH color space: 0x%08x\n", target->space));
1046 return B_ERROR;
1047 }
1048 }
1049 break;
1050 }
1051
1052 /* check if we can setup this mode with acceleration:
1053 * Max sizes need to adhere to both the acceleration engine _and_ the CRTC constraints! */
1054 *acc_mode = true;
1055 /* check virtual_width */
1056 switch (si->ps.card_type)
1057 {
1058 case MIL1:
1059 case MIL2:
1060 case G100:
1061 /* acc constraint: */
1062 if (target->virtual_width > 2048) *acc_mode = false;
1063 break;
1064 default:
1065 /* G200-G550 */
1066 /* acc constraint: */
1067 if (target->virtual_width > 4096) *acc_mode = false;
1068 /* for 32bit mode a lower CRTC1 restriction applies! */
1069 if ((target->space == B_RGB32_LITTLE) && (target->virtual_width > (4092 & ~acc_mask)))
1070 *acc_mode = false;
1071 break;
1072 }
1073 /* virtual_height */
1074 if (target->virtual_height > 2048) *acc_mode = false;
1075
1076 /* now check virtual_size based on CRTC constraints,
1077 * making sure virtual_width stays within the 'mask' constraint: which is only
1078 * nessesary because of an extra constraint in MIL1/2 cards that exists here. */
1079 {
1080 /* virtual_width */
1081 //fixme for CRTC2 (identical on all G400+ cards):
1082 //16bit mode: max. virtual_width == 16352 (no extra mask needed);
1083 //32bit mode: max. virtual_width == 8176 (no extra mask needed);
1084 //other colordepths are unsupported on CRTC2.
1085 switch(target->space)
1086 {
1087 case B_CMAP8:
1088 if (target->virtual_width > (16368 & ~crtc_mask))
1089 target->virtual_width = (16368 & ~crtc_mask);
1090 break;
1091 case B_RGB15_LITTLE:
1092 case B_RGB16_LITTLE:
1093 if (target->virtual_width > (8184 & ~crtc_mask))
1094 target->virtual_width = (8184 & ~crtc_mask);
1095 break;
1096 case B_RGB24_LITTLE:
1097 if (target->virtual_width > (5456 & ~crtc_mask))
1098 target->virtual_width = (5456 & ~crtc_mask);
1099 break;
1100 case B_RGB32_LITTLE:
1101 if (target->virtual_width > (4092 & ~crtc_mask))
1102 target->virtual_width = (4092 & ~crtc_mask);
1103 break;
1104 }
1105
1106 /* virtual_height: The only constraint here is the cards memory size which is
1107 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
1108 * 'Limiting here' to the variable size that's at least available (uint16). */
1109 if (target->virtual_height > 65535) target->virtual_height = 65535;
1110 }
1111
1112 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if
1113 * it was confined above, so we can finally calculate safely if we need slopspace
1114 * for this mode... */
1115 if (*acc_mode)
1116 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
1117 else
1118 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
1119
1120 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n",
1121 video_pitch, target->space));
1122 if (target->virtual_width != video_pitch)
1123 LOG(2,("INIT: effective mode slopspace is %d pixels\n",
1124 (video_pitch - target->virtual_width)));
1125
1126 /* now calculate bytes_per_row for this mode */
1127 *bytes_per_row = video_pitch * (depth >> 3);
1128
1129 return B_OK;
1130 }
1131