BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / accelerants / via / engine / general.c
blobe79c6fd9b690b009e31014a136eefa41ad3905a9
1 /* Authors:
2 Mark Watson 12/1999,
3 Apsed,
4 Rudolf Cornelissen 10/2002-4/2006
5 */
7 #define MODULE_BIT 0x00008000
9 #include "std.h"
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)); \
21 } while (0)
22 DUMP_CFG (DEVID, 0);
23 DUMP_CFG (DEVCTRL, 0);
24 DUMP_CFG (CLASS, 0);
25 DUMP_CFG (HEADER, 0);
26 DUMP_CFG (BASE1REGS,0);
27 DUMP_CFG (BASE2FB, 0);
28 DUMP_CFG (BASE3, 0);
29 DUMP_CFG (BASE4, 0);
30 DUMP_CFG (BASE5, 0);
31 DUMP_CFG (BASE6, 0);
32 DUMP_CFG (BASE7, 0);
33 DUMP_CFG (SUBSYSID1,0);
34 DUMP_CFG (ROMBASE, 0);
35 DUMP_CFG (CAPPTR, 0);
36 DUMP_CFG (CFG_1, 0);
37 DUMP_CFG (INTERRUPT,0);
38 DUMP_CFG (SUBSYSID2,0);
39 DUMP_CFG (AGPREF, 0);
40 DUMP_CFG (AGPSTAT, 0);
41 DUMP_CFG (AGPCMD, 0);
42 DUMP_CFG (ROMSHADOW,0);
43 DUMP_CFG (VGA, 0);
44 DUMP_CFG (SCHRATCH, 0);
45 DUMP_CFG (CFG_10, 0);
46 DUMP_CFG (CFG_11, 0);
47 DUMP_CFG (CFG_12, 0);
48 DUMP_CFG (CFG_13, 0);
49 DUMP_CFG (CFG_14, 0);
50 DUMP_CFG (CFG_15, 0);
51 DUMP_CFG (CFG_16, 0);
52 DUMP_CFG (CFG_17, 0);
53 DUMP_CFG (CFG_18, 0);
54 DUMP_CFG (CFG_19, 0);
55 DUMP_CFG (CFG_20, 0);
56 DUMP_CFG (CFG_21, 0);
57 DUMP_CFG (CFG_22, 0);
58 DUMP_CFG (CFG_23, 0);
59 DUMP_CFG (CFG_24, 0);
60 DUMP_CFG (CFG_25, 0);
61 DUMP_CFG (CFG_26, 0);
62 DUMP_CFG (CFG_27, 0);
63 DUMP_CFG (CFG_28, 0);
64 DUMP_CFG (CFG_29, 0);
65 DUMP_CFG (CFG_30, 0);
66 DUMP_CFG (CFG_31, 0);
67 DUMP_CFG (CFG_32, 0);
68 DUMP_CFG (CFG_33, 0);
69 DUMP_CFG (CFG_34, 0);
70 DUMP_CFG (CFG_35, 0);
71 DUMP_CFG (CFG_36, 0);
72 DUMP_CFG (CFG_37, 0);
73 DUMP_CFG (CFG_38, 0);
74 DUMP_CFG (CFG_39, 0);
75 DUMP_CFG (CFG_40, 0);
76 DUMP_CFG (CFG_41, 0);
77 DUMP_CFG (CFG_42, 0);
78 DUMP_CFG (CFG_43, 0);
79 DUMP_CFG (CFG_44, 0);
80 DUMP_CFG (CFG_45, 0);
81 DUMP_CFG (CFG_46, 0);
82 DUMP_CFG (CFG_47, 0);
83 DUMP_CFG (CFG_48, 0);
84 DUMP_CFG (CFG_49, 0);
85 DUMP_CFG (CFG_50, 0);
86 #undef DUMP_CFG
89 status_t eng_general_powerup()
91 status_t status;
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 */
99 switch(CFGR(DEVID))
101 /* Vendor Via */
102 case 0x30221106:
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();
107 break;
108 case 0x31081106:
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();
114 break;
115 case 0x31221106:
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();
120 break;
121 case 0x32051106:
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();
126 break;
127 case 0x72051106:
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();
132 break;
133 default:
134 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID)));
135 return B_ERROR;
138 return status;
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"));
150 return B_ERROR;
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;
168 return result;
171 /* NOTE:
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;
178 uint8 latency = 0;
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"));
184 return B_OK;
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"));
191 return B_ERROR;
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)
199 default:
200 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n"));
201 return B_OK;
202 break;
204 if (result == B_OK)
205 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency));
206 else
207 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency));
209 return result;
212 void setup_virtualized_heads(bool cross)
214 if (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;
252 else
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)
296 if (!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 */
303 CRTCW(OWNER, 0xff);
304 /* enable access to CRTC1, SEQ1, GRPH1, ATB1, ??? */
305 CRTCW(OWNER, 0x00);
307 else
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 */
314 CRTC2W(OWNER, 0xff);
315 /* enable access to CRTC2, SEQ2, GRPH2, ATB2, ??? */
316 CRTC2W(OWNER, 0x03);
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 */
327 /* note:
328 * this MUST be done before the driver attempts a card coldstart */
329 set_specs();
331 /* only process BIOS for finetuning specs and coldstarting card if requested
332 * by the user;
333 * note:
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)) */
342 // parse_pins();
344 else
346 LOG(2, ("INIT: Skipping card coldstart!\n"));
349 /* get RAM size and fake panel startup (panel init code is still missing) */
350 fake_panel_start();
352 /* log the final card specifications */
353 dump_pins();
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)
377 if (cross)
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);
389 else
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);
399 else
401 LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n"));
403 return B_OK;
405 else
407 return B_ERROR;
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 */
419 if (cross)
421 LOG(4,("INIT: switching CRTC/DAC use to be cross-connected\n"));
422 si->crtc_switch_mode = !si->ps.crtc2_prim;
424 else
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);
432 return B_OK;
434 else
436 return B_ERROR;
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;
446 snooze(1000);
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 */
456 SEQW(LOCK, 0x01);
457 CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
459 /* turn off both displays and the hardcursors (also disables transfers) */
460 head1_dpms(false, false, false);
461 head1_cursor_hide();
462 if (si->ps.secondary_head)
464 // head2_dpms(false, false, false);
465 // head2_cursor_hide();
468 // if (si->ps.secondary_head)
469 if (0)
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 ... */
488 SEQW(MEMMODE, 0x0e);
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 ... */
496 GRPHW(MODE, 0x00);
497 /* ... ISA framebuffer mapping is 64Kb window, switch to graphics mode (again),
498 * select standard adressing ... */
499 GRPHW(MISC, 0x05);
500 /* ... disable bit masking ... */
501 GRPHW(BITMASK, 0xff);
502 /* ... attributes are in color, switch to graphics mode (again) ... */
503 ATBW(MODECTL, 0x01);
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 ... */
511 ATBW(COLSEL, 0x00);
512 /* ... do unknown standard VGA register ... */
513 ATBW(0x16, 0x01);
514 /* ... and enable all four byteplanes. */
515 SEQW(MAPMASK, 0x0f);
516 /* setup sequencer clocking mode */
517 SEQW(CLKMODE, 0x21);
519 /* setup AGP:
520 * Note:
521 * This may only be done when no transfers are in progress on the bus, so now
522 * is probably a good time.. */
523 eng_agp_setup();
525 /* turn screen one on */
526 head1_dpms(true, true, true);
528 return B_OK;
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)
540 uint32 video_pitch;
541 uint32 acc_mask, crtc_mask;
542 uint32 max_crtc_width, max_acc_width;
543 uint8 depth = 8;
545 /* determine pixel multiple based on 2D/3D engine constraints */
546 //via fixme.
547 switch (si->ps.card_arch)
549 default:
550 /* confirmed for:
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;
559 default:
560 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
561 return B_ERROR;
563 break;
566 //via ok:
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)
572 default:
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;
580 default:
581 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
582 return B_ERROR;
584 break;
587 /* set virtual_width limit for accelerated modes */
588 //via fixme:
589 switch (si->ps.card_arch)
591 case NV04A:
592 /* confirmed for:
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;
601 default:
602 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
603 return B_ERROR;
605 break;
606 default:
607 /* confirmed for:
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;
616 default:
617 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
618 return B_ERROR;
620 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity!
621 * So let it fall through... */
622 if (si->ps.card_type != NV31) break;
623 case NV20A:
624 /* confirmed for:
625 * GeForce4 Ti4200 */
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;
633 default:
634 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
635 return B_ERROR;
637 break;
640 //via ok:
641 /* set virtual_width limit for unaccelerated modes */
642 switch (si->ps.card_type)
644 default:
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;
652 default:
653 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
654 return B_ERROR;
656 break;
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 */
663 // *acc_mode = true;
664 //blocking acc totally:
665 *acc_mode = false;
666 /* virtual_width */
667 if (target->virtual_width > max_acc_width) *acc_mode = false;
668 /* virtual_height */
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... */
683 if (*acc_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);
688 else
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 */
697 // *acc_mode = true;
698 //blocking acc totally:
699 *acc_mode = false;
700 /* (we already know virtual_width will be no problem) */
701 /* virtual_height */
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 */
707 if (*acc_mode)
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... */
726 if (*acc_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);
731 else
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);
747 return B_OK;