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