4 Rudolf Cornelissen 10/2002-4/2006
7 #define MODULE_BIT 0x00008000
11 static status_t
test_ram(void);
12 static status_t
engxx_general_powerup (void);
13 static status_t
eng_general_bios_to_powergraphics(void);
15 static void eng_dump_configuration_space (void)
17 #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \
18 uint32 value = CFGR(reg); \
19 MSG(("configuration_space 0x%02x %20s 0x%08x\n", \
20 ENCFG_##reg, #reg, value)); \
23 DUMP_CFG (DEVCTRL
, 0);
26 DUMP_CFG (BASE1REGS
,0);
27 DUMP_CFG (BASE2FB
, 0);
33 DUMP_CFG (SUBSYSID1
,0);
34 DUMP_CFG (ROMBASE
, 0);
37 DUMP_CFG (INTERRUPT
,0);
38 DUMP_CFG (SUBSYSID2
,0);
40 DUMP_CFG (AGPSTAT
, 0);
42 DUMP_CFG (ROMSHADOW
,0);
44 DUMP_CFG (SCHRATCH
, 0);
89 status_t
eng_general_powerup()
93 LOG(1,("POWERUP: Haiku VIA Accelerant 0.16 running.\n"));
95 /* preset no laptop */
96 si
->ps
.laptop
= false;
98 /* detect card type and power it up */
103 si
->ps
.card_type
= CLE3022
;
104 si
->ps
.card_arch
= CLE266
;
105 LOG(4,("POWERUP: Detected VIA CLE266 Unichrome Pro (CLE3022)\n"));
106 status
= engxx_general_powerup();
109 //fixme: card_type unknown..
110 si
->ps
.card_type
= VT3204
;
111 si
->ps
.card_arch
= K8M800
;
112 LOG(4,("POWERUP: Detected VIA K8M800 Unichrome Pro (unknown chiptype)\n"));
113 status
= engxx_general_powerup();
116 si
->ps
.card_type
= CLE3122
;
117 si
->ps
.card_arch
= CLE266
;
118 LOG(4,("POWERUP: Detected VIA CLE266 Unichrome Pro (CLE3122)\n"));
119 status
= engxx_general_powerup();
122 si
->ps
.card_type
= VT3205
;
123 si
->ps
.card_arch
= KM400
;
124 LOG(4,("POWERUP: Detected VIA KM400 Unichrome (VT3205)\n"));
125 status
= engxx_general_powerup();
128 si
->ps
.card_type
= VT7205
;
129 si
->ps
.card_arch
= KM400
;
130 LOG(4,("POWERUP: Detected VIA KM400 Unichrome (VT7205)\n"));
131 status
= engxx_general_powerup();
134 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID
)));
141 static status_t
test_ram()
143 uint32 value
, offset
;
144 status_t result
= B_OK
;
146 /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */
147 if (si
->fbc
.frame_buffer
== NULL
)
149 LOG(8,("INIT: test_ram detected NULL pointer.\n"));
153 for (offset
= 0, value
= 0x55aa55aa; offset
< 256; offset
++)
155 /* write testpattern to cardRAM */
156 ((uint32
*)si
->fbc
.frame_buffer
)[offset
] = value
;
157 /* toggle testpattern */
158 value
= 0xffffffff - value
;
161 for (offset
= 0, value
= 0x55aa55aa; offset
< 256; offset
++)
163 /* readback and verify testpattern from cardRAM */
164 if (((uint32
*)si
->fbc
.frame_buffer
)[offset
] != value
) result
= B_ERROR
;
165 /* toggle testpattern */
166 value
= 0xffffffff - value
;
172 * This routine *has* to be done *after* SetDispplayMode has been executed,
173 * or test results will not be representative!
174 * (CAS latency is dependant on NV setup on some (DRAM) boards) */
175 status_t
eng_set_cas_latency()
177 status_t result
= B_ERROR
;
180 /* check current RAM access to see if we need to change anything */
181 if (test_ram() == B_OK
)
183 LOG(4,("INIT: RAM access OK.\n"));
187 /* check if we read PINS at starttime so we have valid registersettings at our disposal */
188 if (si
->ps
.pins_status
!= B_OK
)
190 LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n"));
194 /* OK. We might have a problem, try to fix it now.. */
195 LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n"));
197 switch(si
->ps
.card_type
)
200 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n"));
205 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency
));
207 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency
));
212 void setup_virtualized_heads(bool cross
)
216 head1_validate_timing
= (crtc_validate_timing
) eng_crtc2_validate_timing
;
217 head1_set_timing
= (crtc_set_timing
) eng_crtc2_set_timing
;
218 head1_depth
= (crtc_depth
) eng_crtc2_depth
;
219 head1_dpms
= (crtc_dpms
) eng_crtc2_dpms
;
220 head1_dpms_fetch
= (crtc_dpms_fetch
) eng_crtc2_dpms_fetch
;
221 head1_set_display_pitch
= (crtc_set_display_pitch
) eng_crtc2_set_display_pitch
;
222 head1_set_display_start
= (crtc_set_display_start
) eng_crtc2_set_display_start
;
223 head1_cursor_init
= (crtc_cursor_init
) eng_crtc2_cursor_init
;
224 head1_cursor_show
= (crtc_cursor_show
) eng_crtc2_cursor_show
;
225 head1_cursor_hide
= (crtc_cursor_hide
) eng_crtc2_cursor_hide
;
226 head1_cursor_define
= (crtc_cursor_define
) eng_crtc2_cursor_define
;
227 head1_cursor_position
= (crtc_cursor_position
) eng_crtc2_cursor_position
;
229 head1_mode
= (dac_mode
) eng_dac2_mode
;
230 head1_palette
= (dac_palette
) eng_dac2_palette
;
231 head1_set_pix_pll
= (dac_set_pix_pll
) eng_dac2_set_pix_pll
;
232 head1_pix_pll_find
= (dac_pix_pll_find
) eng_dac2_pix_pll_find
;
234 head2_validate_timing
= (crtc_validate_timing
) eng_crtc_validate_timing
;
235 head2_set_timing
= (crtc_set_timing
) eng_crtc_set_timing
;
236 head2_depth
= (crtc_depth
) eng_crtc_depth
;
237 head2_dpms
= (crtc_dpms
) eng_crtc_dpms
;
238 head2_dpms_fetch
= (crtc_dpms_fetch
) eng_crtc_dpms_fetch
;
239 head2_set_display_pitch
= (crtc_set_display_pitch
) eng_crtc_set_display_pitch
;
240 head2_set_display_start
= (crtc_set_display_start
) eng_crtc_set_display_start
;
241 head2_cursor_init
= (crtc_cursor_init
) eng_crtc_cursor_init
;
242 head2_cursor_show
= (crtc_cursor_show
) eng_crtc_cursor_show
;
243 head2_cursor_hide
= (crtc_cursor_hide
) eng_crtc_cursor_hide
;
244 head2_cursor_define
= (crtc_cursor_define
) eng_crtc_cursor_define
;
245 head2_cursor_position
= (crtc_cursor_position
) eng_crtc_cursor_position
;
247 head2_mode
= (dac_mode
) eng_dac_mode
;
248 head2_palette
= (dac_palette
) eng_dac_palette
;
249 head2_set_pix_pll
= (dac_set_pix_pll
) eng_dac_set_pix_pll
;
250 head2_pix_pll_find
= (dac_pix_pll_find
) eng_dac_pix_pll_find
;
254 head1_validate_timing
= (crtc_validate_timing
) eng_crtc_validate_timing
;
255 head1_set_timing
= (crtc_set_timing
) eng_crtc_set_timing
;
256 head1_depth
= (crtc_depth
) eng_crtc_depth
;
257 head1_dpms
= (crtc_dpms
) eng_crtc_dpms
;
258 head1_dpms_fetch
= (crtc_dpms_fetch
) eng_crtc_dpms_fetch
;
259 head1_set_display_pitch
= (crtc_set_display_pitch
) eng_crtc_set_display_pitch
;
260 head1_set_display_start
= (crtc_set_display_start
) eng_crtc_set_display_start
;
261 head1_cursor_init
= (crtc_cursor_init
) eng_crtc_cursor_init
;
262 head1_cursor_show
= (crtc_cursor_show
) eng_crtc_cursor_show
;
263 head1_cursor_hide
= (crtc_cursor_hide
) eng_crtc_cursor_hide
;
264 head1_cursor_define
= (crtc_cursor_define
) eng_crtc_cursor_define
;
265 head1_cursor_position
= (crtc_cursor_position
) eng_crtc_cursor_position
;
267 head1_mode
= (dac_mode
) eng_dac_mode
;
268 head1_palette
= (dac_palette
) eng_dac_palette
;
269 head1_set_pix_pll
= (dac_set_pix_pll
) eng_dac_set_pix_pll
;
270 head1_pix_pll_find
= (dac_pix_pll_find
) eng_dac_pix_pll_find
;
272 head2_validate_timing
= (crtc_validate_timing
) eng_crtc2_validate_timing
;
273 head2_set_timing
= (crtc_set_timing
) eng_crtc2_set_timing
;
274 head2_depth
= (crtc_depth
) eng_crtc2_depth
;
275 head2_dpms
= (crtc_dpms
) eng_crtc2_dpms
;
276 head2_dpms_fetch
= (crtc_dpms_fetch
) eng_crtc2_dpms_fetch
;
277 head2_set_display_pitch
= (crtc_set_display_pitch
) eng_crtc2_set_display_pitch
;
278 head2_set_display_start
= (crtc_set_display_start
) eng_crtc2_set_display_start
;
279 head2_cursor_init
= (crtc_cursor_init
) eng_crtc2_cursor_init
;
280 head2_cursor_show
= (crtc_cursor_show
) eng_crtc2_cursor_show
;
281 head2_cursor_hide
= (crtc_cursor_hide
) eng_crtc2_cursor_hide
;
282 head2_cursor_define
= (crtc_cursor_define
) eng_crtc2_cursor_define
;
283 head2_cursor_position
= (crtc_cursor_position
) eng_crtc2_cursor_position
;
285 head2_mode
= (dac_mode
) eng_dac2_mode
;
286 head2_palette
= (dac_palette
) eng_dac2_palette
;
287 head2_set_pix_pll
= (dac_set_pix_pll
) eng_dac2_set_pix_pll
;
288 head2_pix_pll_find
= (dac_pix_pll_find
) eng_dac2_pix_pll_find
;
292 void set_crtc_owner(bool head
)
294 if (si
->ps
.secondary_head
)
298 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's,
299 * while non-NV11 cards behave normally.
301 * Double-write action needed on those strange NV11 cards: */
302 /* RESET: needed on NV11 */
304 /* enable access to CRTC1, SEQ1, GRPH1, ATB1, ??? */
309 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's,
310 * while non-NV11 cards behave normally.
312 * Double-write action needed on those strange NV11 cards: */
313 /* RESET: needed on NV11 */
315 /* enable access to CRTC2, SEQ2, GRPH2, ATB2, ??? */
321 static status_t
engxx_general_powerup()
323 LOG(4,("POWERUP: Chip revision is $%02x\n", si
->ps
.chip_rev
));
324 LOG(4, ("INIT: card powerup\n"));
326 /* setup cardspecs */
328 * this MUST be done before the driver attempts a card coldstart */
331 /* only process BIOS for finetuning specs and coldstarting card if requested
334 * this in fact frees the driver from relying on the BIOS to be executed
335 * at system power-up POST time. */
336 if (!si
->settings
.usebios
)
338 LOG(2, ("INIT: Attempting card coldstart!\n"));
339 /* update the cardspecs in the shared_info PINS struct according to reported
340 * specs as much as is possible;
341 * this also coldstarts the card if possible (executes BIOS CMD script(s)) */
346 LOG(2, ("INIT: Skipping card coldstart!\n"));
349 /* get RAM size and fake panel startup (panel init code is still missing) */
352 /* log the final card specifications */
355 /* dump config space as it is after a possible coldstart attempt */
356 if (si
->settings
.logmask
& 0x80000000) eng_dump_configuration_space();
358 /* setup CRTC and DAC functions access: determined in fake_panel_start */
359 setup_virtualized_heads(si
->ps
.crtc2_prim
);
361 /* do powerup needed from pre-inited card state as done by system POST cardBIOS
362 * execution or driver coldstart above */
363 return eng_general_bios_to_powergraphics();
366 /* this routine switches the CRTC/DAC sets to 'connectors', but only for analog
367 * outputs. We need this to make sure the analog 'switch' is set in the same way the
368 * digital 'switch' is set by the BIOS or we might not be able to use dualhead. */
369 status_t
eng_general_output_select(bool cross
)
371 /* make sure this call is warranted */
372 if (si
->ps
.secondary_head
)
374 /* NV11 cards can't switch heads (confirmed) */
375 if (si
->ps
.card_type
!= NV11
)
379 LOG(4,("INIT: switching analog outputs to be cross-connected\n"));
381 /* enable head 2 on connector 1 */
382 /* (b8 = select CRTC (head) for output,
383 * b4 = ??? (confirmed not to be a FP switch),
384 * b0 = enable CRT) */
385 DACW(OUTPUT
, 0x00000101);
386 /* enable head 1 on connector 2 */
387 DAC2W(OUTPUT
, 0x00000001);
391 LOG(4,("INIT: switching analog outputs to be straight-through\n"));
393 /* enable head 1 on connector 1 */
394 DACW(OUTPUT
, 0x00000001);
395 /* enable head 2 on connector 2 */
396 DAC2W(OUTPUT
, 0x00000101);
401 LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n"));
411 /* this routine switches CRTC/DAC set use. We need this because it's unknown howto
412 * switch digital panels to/from a specific CRTC/DAC set. */
413 status_t
eng_general_head_select(bool cross
)
415 /* make sure this call is warranted */
416 if (si
->ps
.secondary_head
)
418 /* invert CRTC/DAC use to do switching */
421 LOG(4,("INIT: switching CRTC/DAC use to be cross-connected\n"));
422 si
->crtc_switch_mode
= !si
->ps
.crtc2_prim
;
426 LOG(4,("INIT: switching CRTC/DAC use to be straight-through\n"));
427 si
->crtc_switch_mode
= si
->ps
.crtc2_prim
;
429 /* update CRTC and DAC functions access */
430 setup_virtualized_heads(si
->crtc_switch_mode
);
440 /* basic change of card state from VGA to enhanced mode:
441 * Should work from VGA BIOS POST init state. */
442 static status_t
eng_general_bios_to_powergraphics()
444 /* let acc engine make power off/power on cycle to start 'fresh' */
445 // ENG_REG32(RG32_PWRUPCTRL) = 0x13110011;
448 /* power-up all hardware function blocks */
449 // ENG_REG32(RG32_PWRUPCTRL) = 0x13111111;
451 /* select colormode CRTC registers base adresses,
452 * but don't touch the current selected pixelclock source yet */
453 ENG_REG8(RG8_MISCW
) = (((ENG_REG8(RG8_MISCR
)) & 0x0c) | 0xc3);
455 /* unlock (extended) registers for R/W access */
457 CRTCW(VSYNCE
,(CRTCR(VSYNCE
) & 0x7f));
459 /* turn off both displays and the hardcursors (also disables transfers) */
460 head1_dpms(false, false, false);
462 if (si
->ps
.secondary_head
)
464 // head2_dpms(false, false, false);
465 // head2_cursor_hide();
468 // if (si->ps.secondary_head)
471 /* switch overlay engine to CRTC1 */
472 /* bit 17: GPU FP port #1 (confirmed NV25, NV28, confirmed not on NV34),
473 * bit 16: GPU FP port #2 (confirmed NV25, NV28, NV34),
474 * bit 12: overlay engine (all cards),
475 * bit 9: TVout chip #2 (confirmed on NV18, NV25, NV28),
476 * bit 8: TVout chip #1 (all cards),
477 * bit 4: both I2C busses (all cards) */
478 ENG_REG32(RG32_2FUNCSEL
) &= ~0x00001000;
479 ENG_REG32(RG32_FUNCSEL
) |= 0x00001000;
481 si
->overlay
.crtc
= false;
483 /* set card to 'enhanced' mode: (only VGA standard registers used here) */
484 /* (keep) card enabled, set plain normal memory usage, no old VGA 'tricks' ... */
485 CRTCW(MODECTL
, 0xc3);
486 /* ... plain sequential memory use, more than 64Kb RAM installed,
487 * switch to graphics mode ... */
489 /* ... disable bitplane tweaking ... */
490 GRPHW(ENSETRESET
, 0x00);
491 /* ... no logical function tweaking with display data, no data rotation ... */
492 GRPHW(DATAROTATE
, 0x00);
493 /* ... reset read map select to plane 0 ... */
494 GRPHW(READMAPSEL
, 0x00);
495 /* ... set standard mode ... */
497 /* ... ISA framebuffer mapping is 64Kb window, switch to graphics mode (again),
498 * select standard adressing ... */
500 /* ... disable bit masking ... */
501 GRPHW(BITMASK
, 0xff);
502 /* ... attributes are in color, switch to graphics mode (again) ... */
504 /* ... set overscan color to black ... */
505 ATBW(OSCANCOLOR
, 0x00);
506 /* ... enable all color planes ... */
507 ATBW(COLPLANE_EN
, 0x0f);
508 /* ... reset horizontal pixelpanning ... */
509 ATBW(HORPIXPAN
, 0x00);
510 /* ... reset colorpalette groupselect bits ... */
512 /* ... do unknown standard VGA register ... */
514 /* ... and enable all four byteplanes. */
516 /* setup sequencer clocking mode */
521 * This may only be done when no transfers are in progress on the bus, so now
522 * is probably a good time.. */
525 /* turn screen one on */
526 head1_dpms(true, true, true);
531 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify
532 * virtual_size to the nearest valid maximum for the mode on the card if not so.
533 * Also: check if virtual_width adheres to the cards granularity constraints, and
534 * create mode slopspace if not so.
535 * We use acc or crtc granularity constraints based on the 'worst case' scenario.
537 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */
538 status_t
eng_general_validate_pic_size (display_mode
*target
, uint32
*bytes_per_row
, bool *acc_mode
)
541 uint32 acc_mask
, crtc_mask
;
542 uint32 max_crtc_width
, max_acc_width
;
545 /* determine pixel multiple based on 2D/3D engine constraints */
547 switch (si
->ps
.card_arch
)
551 * TNT1, TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */
552 switch (target
->space
)
554 case B_CMAP8
: acc_mask
= 0x0f; depth
= 8; break;
555 case B_RGB15
: acc_mask
= 0x07; depth
= 16; break;
556 case B_RGB16
: acc_mask
= 0x07; depth
= 16; break;
557 case B_RGB24
: acc_mask
= 0x0f; depth
= 24; break;
558 case B_RGB32
: acc_mask
= 0x03; depth
= 32; break;
560 LOG(8,("INIT: unknown color space: 0x%08x\n", target
->space
));
567 /* determine pixel multiple based on CRTC memory pitch constraints.
568 * (Note: Don't mix this up with CRTC timing contraints! Those are
569 * multiples of 8 for horizontal, 1 for vertical timing.) */
570 switch (si
->ps
.card_type
)
573 switch (target
->space
)
575 case B_CMAP8
: crtc_mask
= 0x07; break;
576 case B_RGB15
: crtc_mask
= 0x03; break;
577 case B_RGB16
: crtc_mask
= 0x03; break;
578 case B_RGB24
: crtc_mask
= 0x07; break;
579 case B_RGB32
: crtc_mask
= 0x01; break;
581 LOG(8,("INIT: unknown color space: 0x%08x\n", target
->space
));
587 /* set virtual_width limit for accelerated modes */
589 switch (si
->ps
.card_arch
)
593 * TNT1, TNT2, TNT2-M64 */
594 switch(target
->space
)
596 case B_CMAP8
: max_acc_width
= 8176; break;
597 case B_RGB15
: max_acc_width
= 4088; break;
598 case B_RGB16
: max_acc_width
= 4088; break;
599 case B_RGB24
: max_acc_width
= 2720; break;
600 case B_RGB32
: max_acc_width
= 2044; break;
602 LOG(8,("INIT: unknown color space: 0x%08x\n", target
->space
));
608 * GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */
609 switch(target
->space
)
611 case B_CMAP8
: max_acc_width
= 16368; break;
612 case B_RGB15
: max_acc_width
= 8184; break;
613 case B_RGB16
: max_acc_width
= 8184; break;
614 case B_RGB24
: max_acc_width
= 5456; break;
615 case B_RGB32
: max_acc_width
= 4092; break;
617 LOG(8,("INIT: unknown color space: 0x%08x\n", target
->space
));
620 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity!
621 * So let it fall through... */
622 if (si
->ps
.card_type
!= NV31
) break;
626 switch(target
->space
)
628 case B_CMAP8
: max_acc_width
= 16320; break;
629 case B_RGB15
: max_acc_width
= 8160; break;
630 case B_RGB16
: max_acc_width
= 8160; break;
631 case B_RGB24
: max_acc_width
= 5440; break;
632 case B_RGB32
: max_acc_width
= 4080; break;
634 LOG(8,("INIT: unknown color space: 0x%08x\n", target
->space
));
641 /* set virtual_width limit for unaccelerated modes */
642 switch (si
->ps
.card_type
)
645 switch(target
->space
)
647 case B_CMAP8
: max_crtc_width
= 16376; break;
648 case B_RGB15
: max_crtc_width
= 8188; break;
649 case B_RGB16
: max_crtc_width
= 8188; break;
650 case B_RGB24
: max_crtc_width
= 5456; break;
651 case B_RGB32
: max_crtc_width
= 4094; break;
653 LOG(8,("INIT: unknown color space: 0x%08x\n", target
->space
));
659 /* check for acc capability, and adjust mode to adhere to hardware constraints */
660 if (max_acc_width
<= max_crtc_width
)
662 /* check if we can setup this mode with acceleration */
664 //blocking acc totally:
667 if (target
->virtual_width
> max_acc_width
) *acc_mode
= false;
669 /* (NV cards can even do more than this(?)...
670 * but 4096 is confirmed on all cards at max. accelerated width.) */
671 if (target
->virtual_height
> 4096) *acc_mode
= false;
673 /* now check virtual_size based on CRTC constraints */
674 if (target
->virtual_width
> max_crtc_width
) target
->virtual_width
= max_crtc_width
;
675 /* virtual_height: The only constraint here is the cards memory size which is
676 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
677 * 'Limiting here' to the variable size that's at least available (uint16). */
678 if (target
->virtual_height
> 65535) target
->virtual_height
= 65535;
680 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if
681 * it was confined above, so we can finally calculate safely if we need slopspace
682 * for this mode... */
685 /* the mode needs to adhere to the largest granularity imposed... */
686 if (acc_mask
< crtc_mask
)
687 video_pitch
= ((target
->virtual_width
+ crtc_mask
) & ~crtc_mask
);
689 video_pitch
= ((target
->virtual_width
+ acc_mask
) & ~acc_mask
);
691 else /* unaccelerated mode */
692 video_pitch
= ((target
->virtual_width
+ crtc_mask
) & ~crtc_mask
);
694 else /* max_acc_width > max_crtc_width */
696 /* check if we can setup this mode with acceleration */
698 //blocking acc totally:
700 /* (we already know virtual_width will be no problem) */
702 /* (NV cards can even do more than this(?)...
703 * but 4096 is confirmed on all cards at max. accelerated width.) */
704 if (target
->virtual_height
> 4096) *acc_mode
= false;
706 /* now check virtual_size based on CRTC constraints */
709 /* note that max_crtc_width already adheres to crtc_mask */
710 if (target
->virtual_width
> (max_crtc_width
& ~acc_mask
))
711 target
->virtual_width
= (max_crtc_width
& ~acc_mask
);
713 else /* unaccelerated mode */
715 if (target
->virtual_width
> max_crtc_width
)
716 target
->virtual_width
= max_crtc_width
;
718 /* virtual_height: The only constraint here is the cards memory size which is
719 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
720 * 'Limiting here' to the variable size that's at least available (uint16). */
721 if (target
->virtual_height
> 65535) target
->virtual_height
= 65535;
723 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if
724 * it was confined above, so we can finally calculate safely if we need slopspace
725 * for this mode... */
728 /* the mode needs to adhere to the largest granularity imposed... */
729 if (acc_mask
< crtc_mask
)
730 video_pitch
= ((target
->virtual_width
+ crtc_mask
) & ~crtc_mask
);
732 video_pitch
= ((target
->virtual_width
+ acc_mask
) & ~acc_mask
);
734 else /* unaccelerated mode */
735 video_pitch
= ((target
->virtual_width
+ crtc_mask
) & ~crtc_mask
);
738 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n",
739 video_pitch
, target
->space
));
740 if (target
->virtual_width
!= video_pitch
)
741 LOG(2,("INIT: effective mode slopspace is %d pixels\n",
742 (video_pitch
- target
->virtual_width
)));
744 /* now calculate bytes_per_row for this mode */
745 *bytes_per_row
= video_pitch
* (depth
>> 3);