vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / skeleton / engine / general.c
blobc825c8eb9108c137aa4bf25c5d89c4ef268e5127
1 /* Authors:
2 Mark Watson 12/1999,
3 Apsed,
4 Rudolf Cornelissen 10/2002-11/2004
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 skeleton Accelerant 0.01 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 0x31221106:
103 si->ps.card_type = NV04;
104 si->ps.card_arch = NV04A;
105 LOG(4,("POWERUP: Detected Nvidia TNT1 (NV04)\n"));
106 status = engxx_general_powerup();
107 break;
108 */ default:
109 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID)));
110 return B_ERROR;
113 return status;
116 static status_t test_ram()
118 uint32 value, offset;
119 status_t result = B_OK;
121 /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */
122 if (si->fbc.frame_buffer == NULL)
124 LOG(8,("INIT: test_ram detected NULL pointer.\n"));
125 return B_ERROR;
128 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++)
130 /* write testpattern to cardRAM */
131 ((uint32 *)si->fbc.frame_buffer)[offset] = value;
132 /* toggle testpattern */
133 value = 0xffffffff - value;
136 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++)
138 /* readback and verify testpattern from cardRAM */
139 if (((uint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR;
140 /* toggle testpattern */
141 value = 0xffffffff - value;
143 return result;
146 /* NOTE:
147 * This routine *has* to be done *after* SetDispplayMode has been executed,
148 * or test results will not be representative!
149 * (CAS latency is dependant on NV setup on some (DRAM) boards) */
150 status_t eng_set_cas_latency()
152 status_t result = B_ERROR;
153 uint8 latency = 0;
155 /* check current RAM access to see if we need to change anything */
156 if (test_ram() == B_OK)
158 LOG(4,("INIT: RAM access OK.\n"));
159 return B_OK;
162 /* check if we read PINS at starttime so we have valid registersettings at our disposal */
163 if (si->ps.pins_status != B_OK)
165 LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n"));
166 return B_ERROR;
169 /* OK. We might have a problem, try to fix it now.. */
170 LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n"));
172 switch(si->ps.card_type)
174 default:
175 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n"));
176 return B_OK;
177 break;
179 if (result == B_OK)
180 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency));
181 else
182 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency));
184 return result;
187 void setup_virtualized_heads(bool cross)
189 if (cross)
191 head1_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing;
192 head1_set_timing = (crtc_set_timing) eng_crtc2_set_timing;
193 head1_depth = (crtc_depth) eng_crtc2_depth;
194 head1_dpms = (crtc_dpms) eng_crtc2_dpms;
195 head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch;
196 head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch;
197 head1_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start;
198 head1_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init;
199 head1_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show;
200 head1_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide;
201 head1_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define;
202 head1_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position;
204 head1_mode = (dac_mode) eng_dac2_mode;
205 head1_palette = (dac_palette) eng_dac2_palette;
206 head1_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll;
207 head1_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find;
209 head2_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing;
210 head2_set_timing = (crtc_set_timing) eng_crtc_set_timing;
211 head2_depth = (crtc_depth) eng_crtc_depth;
212 head2_dpms = (crtc_dpms) eng_crtc_dpms;
213 head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch;
214 head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch;
215 head2_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start;
216 head2_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init;
217 head2_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show;
218 head2_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide;
219 head2_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define;
220 head2_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position;
222 head2_mode = (dac_mode) eng_dac_mode;
223 head2_palette = (dac_palette) eng_dac_palette;
224 head2_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll;
225 head2_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find;
227 else
229 head1_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing;
230 head1_set_timing = (crtc_set_timing) eng_crtc_set_timing;
231 head1_depth = (crtc_depth) eng_crtc_depth;
232 head1_dpms = (crtc_dpms) eng_crtc_dpms;
233 head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch;
234 head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch;
235 head1_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start;
236 head1_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init;
237 head1_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show;
238 head1_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide;
239 head1_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define;
240 head1_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position;
242 head1_mode = (dac_mode) eng_dac_mode;
243 head1_palette = (dac_palette) eng_dac_palette;
244 head1_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll;
245 head1_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find;
247 head2_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing;
248 head2_set_timing = (crtc_set_timing) eng_crtc2_set_timing;
249 head2_depth = (crtc_depth) eng_crtc2_depth;
250 head2_dpms = (crtc_dpms) eng_crtc2_dpms;
251 head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch;
252 head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch;
253 head2_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start;
254 head2_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init;
255 head2_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show;
256 head2_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide;
257 head2_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define;
258 head2_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position;
260 head2_mode = (dac_mode) eng_dac2_mode;
261 head2_palette = (dac_palette) eng_dac2_palette;
262 head2_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll;
263 head2_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find;
267 void set_crtc_owner(bool head)
269 if (si->ps.secondary_head)
271 if (!head)
273 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's,
274 * while non-NV11 cards behave normally.
276 * Double-write action needed on those strange NV11 cards: */
277 /* RESET: needed on NV11 */
278 CRTCW(OWNER, 0xff);
279 /* enable access to CRTC1, SEQ1, GRPH1, ATB1, ??? */
280 CRTCW(OWNER, 0x00);
282 else
284 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's,
285 * while non-NV11 cards behave normally.
287 * Double-write action needed on those strange NV11 cards: */
288 /* RESET: needed on NV11 */
289 CRTC2W(OWNER, 0xff);
290 /* enable access to CRTC2, SEQ2, GRPH2, ATB2, ??? */
291 CRTC2W(OWNER, 0x03);
296 static status_t engxx_general_powerup()
298 LOG(4, ("INIT: card powerup\n"));
300 /* setup cardspecs */
301 /* note:
302 * this MUST be done before the driver attempts a card coldstart */
303 set_specs();
305 /* only process BIOS for finetuning specs and coldstarting card if requested
306 * by the user;
307 * note:
308 * this in fact frees the driver from relying on the BIOS to be executed
309 * at system power-up POST time. */
310 if (!si->settings.usebios)
312 LOG(2, ("INIT: Attempting card coldstart!\n"));
313 /* update the cardspecs in the shared_info PINS struct according to reported
314 * specs as much as is possible;
315 * this also coldstarts the card if possible (executes BIOS CMD script(s)) */
316 // parse_pins();
318 else
320 LOG(2, ("INIT: Skipping card coldstart!\n"));
323 /* get RAM size and fake panel startup (panel init code is still missing) */
324 fake_panel_start();
326 /* log the final card specifications */
327 dump_pins();
329 /* dump config space as it is after a possible coldstart attempt */
330 if (si->settings.logmask & 0x80000000) eng_dump_configuration_space();
332 /* setup CRTC and DAC functions access: determined in fake_panel_start */
333 setup_virtualized_heads(si->ps.crtc2_prim);
335 /* do powerup needed from pre-inited card state as done by system POST cardBIOS
336 * execution or driver coldstart above */
337 return eng_general_bios_to_powergraphics();
340 /* this routine switches the CRTC/DAC sets to 'connectors', but only for analog
341 * outputs. We need this to make sure the analog 'switch' is set in the same way the
342 * digital 'switch' is set by the BIOS or we might not be able to use dualhead. */
343 status_t eng_general_output_select(bool cross)
345 /* make sure this call is warranted */
346 if (si->ps.secondary_head)
348 /* NV11 cards can't switch heads (confirmed) */
349 if (si->ps.card_type != NV11)
351 if (cross)
353 LOG(4,("INIT: switching analog outputs to be cross-connected\n"));
355 /* enable head 2 on connector 1 */
356 /* (b8 = select CRTC (head) for output,
357 * b4 = ??? (confirmed not to be a FP switch),
358 * b0 = enable CRT) */
359 DACW(OUTPUT, 0x00000101);
360 /* enable head 1 on connector 2 */
361 DAC2W(OUTPUT, 0x00000001);
363 else
365 LOG(4,("INIT: switching analog outputs to be straight-through\n"));
367 /* enable head 1 on connector 1 */
368 DACW(OUTPUT, 0x00000001);
369 /* enable head 2 on connector 2 */
370 DAC2W(OUTPUT, 0x00000101);
373 else
375 LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n"));
377 return B_OK;
379 else
381 return B_ERROR;
385 /* this routine switches CRTC/DAC set use. We need this because it's unknown howto
386 * switch digital panels to/from a specific CRTC/DAC set. */
387 status_t eng_general_head_select(bool cross)
389 /* make sure this call is warranted */
390 if (si->ps.secondary_head)
392 /* invert CRTC/DAC use to do switching */
393 if (cross)
395 LOG(4,("INIT: switching CRTC/DAC use to be cross-connected\n"));
396 si->crtc_switch_mode = !si->ps.crtc2_prim;
398 else
400 LOG(4,("INIT: switching CRTC/DAC use to be straight-through\n"));
401 si->crtc_switch_mode = si->ps.crtc2_prim;
403 /* update CRTC and DAC functions access */
404 setup_virtualized_heads(si->crtc_switch_mode);
406 return B_OK;
408 else
410 return B_ERROR;
414 /* basic change of card state from VGA to enhanced mode:
415 * Should work from VGA BIOS POST init state. */
416 static status_t eng_general_bios_to_powergraphics()
418 /* let acc engine make power off/power on cycle to start 'fresh' */
419 // ENG_RG32(RG32_PWRUPCTRL) = 0x13110011;
420 snooze(1000);
422 /* power-up all hardware function blocks */
423 /* bit 28: OVERLAY ENGINE (BES),
424 * bit 25: CRTC2, (> NV04A)
425 * bit 24: CRTC1,
426 * bit 20: framebuffer,
427 * bit 16: PPMI,
428 * bit 12: PGRAPH,
429 * bit 8: PFIFO,
430 * bit 4: PMEDIA,
431 * bit 0: TVOUT. (> NV04A) */
432 // ENG_RG32(RG32_PWRUPCTRL) = 0x13111111;
434 /* select colormode CRTC registers base adresses */
435 // ENG_REG8(RG8_MISCW) = 0xcb;
437 /* enable access to primary head */
438 // set_crtc_owner(0);
439 /* unlock head's registers for R/W access */
440 // CRTCW(LOCK, 0x57);
441 // CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
442 // if (si->ps.secondary_head)
443 if (0)
445 /* enable access to secondary head */
446 set_crtc_owner(1);
447 /* unlock head's registers for R/W access */
448 CRTC2W(LOCK, 0x57);
449 CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
452 /* turn off both displays and the hardcursors (also disables transfers) */
453 // head1_dpms(false, false, false);
454 // head1_cursor_hide();
455 // if (si->ps.secondary_head)
456 if (0)
458 // head2_dpms(false, false, false);
459 // head2_cursor_hide();
462 // if (si->ps.secondary_head)
463 if (0)
465 /* switch overlay engine to CRTC1 */
466 /* bit 17: GPU FP port #1 (confirmed NV25, NV28, confirmed not on NV34),
467 * bit 16: GPU FP port #2 (confirmed NV25, NV28, NV34),
468 * bit 12: overlay engine (all cards),
469 * bit 9: TVout chip #2 (confirmed on NV18, NV25, NV28),
470 * bit 8: TVout chip #1 (all cards),
471 * bit 4: both I2C busses (all cards) */
472 ENG_RG32(RG32_2FUNCSEL) &= ~0x00001000;
473 ENG_RG32(RG32_FUNCSEL) |= 0x00001000;
475 si->overlay.crtc = false;
477 /* enable 'enhanced' mode on primary head: */
478 /* enable access to primary head */
479 // set_crtc_owner(0);
480 /* note: 'BUFFER' is a non-standard register in behaviour(!) on most
481 * NV11's like the GeForce2 MX200, while the MX400 and non-NV11 cards
482 * behave normally.
483 * Also readback is not nessesarily what was written before!
485 * Double-write action needed on those strange NV11 cards: */
486 /* RESET: don't doublebuffer CRTC access: set programmed values immediately... */
487 // CRTCW(BUFFER, 0xff);
488 /* ... and use fine pitched CRTC granularity on > NV4 cards (b2 = 0) */
489 /* note: this has no effect on possible bandwidth issues. */
490 // CRTCW(BUFFER, 0xfb);
491 /* select VGA mode (old VGA register) */
492 // CRTCW(MODECTL, 0xc3);
493 /* select graphics mode (old VGA register) */
494 // SEQW(MEMMODE, 0x0e);
495 /* select 8 dots character clocks (old VGA register) */
496 // SEQW(CLKMODE, 0x21);
497 /* select VGA mode (old VGA register) */
498 // GRPHW(MODE, 0x00);
499 /* select graphics mode (old VGA register) */
500 // GRPHW(MISC, 0x01);
501 /* select graphics mode (old VGA register) */
502 // ATBW(MODECTL, 0x01);
503 /* enable 'enhanced mode', enable Vsync & Hsync,
504 * set DAC palette to 8-bit width, disable large screen */
505 // CRTCW(REPAINT1, 0x04);
507 /* enable 'enhanced' mode on secondary head: */
508 // if (si->ps.secondary_head)
509 if (0)
511 /* enable access to secondary head */
512 set_crtc_owner(1);
513 /* select colormode CRTC2 registers base adresses */
514 ENG_REG8(RG8_MISCW) = 0xcb;
515 /* note: 'BUFFER' is a non-standard register in behaviour(!) on most
516 * NV11's like the GeForce2 MX200, while the MX400 and non-NV11 cards
517 * behave normally.
518 * Also readback is not nessesarily what was written before!
520 * Double-write action needed on those strange NV11 cards: */
521 /* RESET: don't doublebuffer CRTC2 access: set programmed values immediately... */
522 CRTC2W(BUFFER, 0xff);
523 /* ... and use fine pitched CRTC granularity on > NV4 cards (b2 = 0) */
524 /* note: this has no effect on possible bandwidth issues. */
525 CRTC2W(BUFFER, 0xfb);
526 /* select VGA mode (old VGA register) */
527 CRTC2W(MODECTL, 0xc3);
528 /* select graphics mode (old VGA register) */
529 SEQW(MEMMODE, 0x0e);
530 /* select 8 dots character clocks (old VGA register) */
531 SEQW(CLKMODE, 0x21);
532 /* select VGA mode (old VGA register) */
533 GRPHW(MODE, 0x00);
534 /* select graphics mode (old VGA register) */
535 GRPHW(MISC, 0x01);
536 /* select graphics mode (old VGA register) */
537 ATB2W(MODECTL, 0x01);
538 /* enable 'enhanced mode', enable Vsync & Hsync,
539 * set DAC palette to 8-bit width, disable large screen */
540 CRTC2W(REPAINT1, 0x04);
543 /* enable palettes */
544 // DACW(GENCTRL, 0x00100100);
545 // if (si->ps.secondary_head) DAC2W(GENCTRL, 0x00100100);
547 /* enable programmable PLLs */
548 // DACW(PLLSEL, 0x10000700);
549 // if (si->ps.secondary_head) DACW(PLLSEL, (DACR(PLLSEL) | 0x20000800));
551 /* turn on DAC and make sure detection testsignal routing is disabled
552 * (b16 = disable DAC,
553 * b12 = enable testsignal output */
554 // DACW(TSTCTRL, (DACR(TSTCTRL) & 0xfffeefff));
555 /* turn on DAC2 if it exists
556 * (NOTE: testsignal function block resides in DAC1 only (!)) */
557 // if (si->ps.secondary_head) DAC2W(TSTCTRL, (DAC2R(TSTCTRL) & 0xfffeefff));
559 /* setup AGP:
560 * Note:
561 * This may only be done when no transfers are in progress on the bus, so now
562 * is probably a good time.. */
563 eng_agp_setup();
565 /* turn screen one on */
566 // head1_dpms(true, true, true);
568 return B_OK;
571 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify
572 * virtual_size to the nearest valid maximum for the mode on the card if not so.
573 * Also: check if virtual_width adheres to the cards granularity constraints, and
574 * create mode slopspace if not so.
575 * We use acc or crtc granularity constraints based on the 'worst case' scenario.
577 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */
578 status_t eng_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode)
580 uint32 video_pitch;
581 uint32 acc_mask, crtc_mask;
582 uint32 max_crtc_width, max_acc_width;
583 uint8 depth = 8;
585 /* determine pixel multiple based on 2D/3D engine constraints */
586 switch (si->ps.card_arch)
588 default:
589 /* confirmed for:
590 * TNT1, TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */
591 switch (target->space)
593 case B_CMAP8: acc_mask = 0x0f; depth = 8; break;
594 case B_RGB15: acc_mask = 0x07; depth = 16; break;
595 case B_RGB16: acc_mask = 0x07; depth = 16; break;
596 case B_RGB24: acc_mask = 0x0f; depth = 24; break;
597 case B_RGB32: acc_mask = 0x03; depth = 32; break;
598 default:
599 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
600 return B_ERROR;
602 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity!
603 * So let it fall through... */
604 if (si->ps.card_type != NV31) break;
605 case NV20A:
606 /* confirmed for:
607 * GeForce4 Ti4200 */
608 switch (target->space)
610 case B_CMAP8: acc_mask = 0x3f; depth = 8; break;
611 case B_RGB15: acc_mask = 0x1f; depth = 16; break;
612 case B_RGB16: acc_mask = 0x1f; depth = 16; break;
613 case B_RGB24: acc_mask = 0x3f; depth = 24; break;
614 case B_RGB32: acc_mask = 0x0f; depth = 32; break;
615 default:
616 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
617 return B_ERROR;
619 break;
622 /* determine pixel multiple based on CRTC memory pitch constraints:
623 * -> all NV cards have same granularity constraints on CRTC1 and CRTC2,
624 * provided that the CRTC1 and CRTC2 BUFFER register b2 = 0;
626 * (Note: Don't mix this up with CRTC timing contraints! Those are
627 * multiples of 8 for horizontal, 1 for vertical timing.) */
628 switch (si->ps.card_type)
630 default:
631 // case NV04:
632 /* confirmed for:
633 * TNT1 always;
634 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
635 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 0 */
636 /* NOTE:
637 * Unfortunately older cards have a hardware fault that prevents use.
638 * We need doubled granularity on those to prevent the single top line
639 * from shifting to the left!
640 * This is confirmed for TNT2, GeForce2 MX200, GeForce2 MX400.
641 * Confirmed OK are:
642 * GeForce4 MX440, GeForce4 Ti4200, GeForceFX 5200. */
643 switch (target->space)
645 case B_CMAP8: crtc_mask = 0x0f; break; /* 0x07 */
646 case B_RGB15: crtc_mask = 0x07; break; /* 0x03 */
647 case B_RGB16: crtc_mask = 0x07; break; /* 0x03 */
648 case B_RGB24: crtc_mask = 0x0f; break; /* 0x07 */
649 case B_RGB32: crtc_mask = 0x03; break; /* 0x01 */
650 default:
651 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
652 return B_ERROR;
654 break;
655 // default:
656 /* confirmed for:
657 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
658 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 1 */
659 /* switch (target->space)
661 case B_CMAP8: crtc_mask = 0x1f; break;
662 case B_RGB15: crtc_mask = 0x0f; break;
663 case B_RGB16: crtc_mask = 0x0f; break;
664 case B_RGB24: crtc_mask = 0x1f; break;
665 case B_RGB32: crtc_mask = 0x07; break;
666 default:
667 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
668 return B_ERROR;
670 break;
671 */ }
673 /* set virtual_width limit for accelerated modes */
674 switch (si->ps.card_arch)
676 case NV04A:
677 /* confirmed for:
678 * TNT1, TNT2, TNT2-M64 */
679 switch(target->space)
681 case B_CMAP8: max_acc_width = 8176; break;
682 case B_RGB15: max_acc_width = 4088; break;
683 case B_RGB16: max_acc_width = 4088; break;
684 case B_RGB24: max_acc_width = 2720; break;
685 case B_RGB32: max_acc_width = 2044; break;
686 default:
687 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
688 return B_ERROR;
690 break;
691 default:
692 /* confirmed for:
693 * GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */
694 switch(target->space)
696 case B_CMAP8: max_acc_width = 16368; break;
697 case B_RGB15: max_acc_width = 8184; break;
698 case B_RGB16: max_acc_width = 8184; break;
699 case B_RGB24: max_acc_width = 5456; break;
700 case B_RGB32: max_acc_width = 4092; break;
701 default:
702 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
703 return B_ERROR;
705 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity!
706 * So let it fall through... */
707 if (si->ps.card_type != NV31) break;
708 case NV20A:
709 /* confirmed for:
710 * GeForce4 Ti4200 */
711 switch(target->space)
713 case B_CMAP8: max_acc_width = 16320; break;
714 case B_RGB15: max_acc_width = 8160; break;
715 case B_RGB16: max_acc_width = 8160; break;
716 case B_RGB24: max_acc_width = 5440; break;
717 case B_RGB32: max_acc_width = 4080; break;
718 default:
719 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
720 return B_ERROR;
722 break;
725 /* set virtual_width limit for unaccelerated modes */
726 switch (si->ps.card_type)
728 default:
729 // case NV04:
730 /* confirmed for:
731 * TNT1 always;
732 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
733 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 0 */
734 /* NOTE:
735 * Unfortunately older cards have a hardware fault that prevents use.
736 * We need doubled granularity on those to prevent the single top line
737 * from shifting to the left!
738 * This is confirmed for TNT2, GeForce2 MX200, GeForce2 MX400.
739 * Confirmed OK are:
740 * GeForce4 MX440, GeForce4 Ti4200, GeForceFX 5200. */
741 switch(target->space)
743 case B_CMAP8: max_crtc_width = 16368; break; /* 16376 */
744 case B_RGB15: max_crtc_width = 8184; break; /* 8188 */
745 case B_RGB16: max_crtc_width = 8184; break; /* 8188 */
746 case B_RGB24: max_crtc_width = 5456; break; /* 5456 */
747 case B_RGB32: max_crtc_width = 4092; break; /* 4094 */
748 default:
749 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
750 return B_ERROR;
752 break;
753 // default:
754 /* confirmed for:
755 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
756 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 1 */
757 /* switch(target->space)
759 case B_CMAP8: max_crtc_width = 16352; break;
760 case B_RGB15: max_crtc_width = 8176; break;
761 case B_RGB16: max_crtc_width = 8176; break;
762 case B_RGB24: max_crtc_width = 5440; break;
763 case B_RGB32: max_crtc_width = 4088; break;
764 default:
765 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
766 return B_ERROR;
768 break;
769 */ }
771 /* check for acc capability, and adjust mode to adhere to hardware constraints */
772 if (max_acc_width <= max_crtc_width)
774 /* check if we can setup this mode with acceleration */
775 // *acc_mode = true;
776 //blocking acc totally:
777 *acc_mode = false;
778 /* virtual_width */
779 if (target->virtual_width > max_acc_width) *acc_mode = false;
780 /* virtual_height */
781 /* (NV cards can even do more than this(?)...
782 * but 4096 is confirmed on all cards at max. accelerated width.) */
783 if (target->virtual_height > 4096) *acc_mode = false;
785 /* now check virtual_size based on CRTC constraints */
786 if (target->virtual_width > max_crtc_width) target->virtual_width = max_crtc_width;
787 /* virtual_height: The only constraint here is the cards memory size which is
788 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
789 * 'Limiting here' to the variable size that's at least available (uint16). */
790 if (target->virtual_height > 65535) target->virtual_height = 65535;
792 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if
793 * it was confined above, so we can finally calculate safely if we need slopspace
794 * for this mode... */
795 if (*acc_mode)
797 /* the mode needs to adhere to the largest granularity imposed... */
798 if (acc_mask < crtc_mask)
799 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
800 else
801 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
803 else /* unaccelerated mode */
804 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
806 else /* max_acc_width > max_crtc_width */
808 /* check if we can setup this mode with acceleration */
809 *acc_mode = true;
810 /* (we already know virtual_width will be no problem) */
811 /* virtual_height */
812 /* (NV cards can even do more than this(?)...
813 * but 4096 is confirmed on all cards at max. accelerated width.) */
814 if (target->virtual_height > 4096) *acc_mode = false;
816 /* now check virtual_size based on CRTC constraints */
817 if (*acc_mode)
819 /* note that max_crtc_width already adheres to crtc_mask */
820 if (target->virtual_width > (max_crtc_width & ~acc_mask))
821 target->virtual_width = (max_crtc_width & ~acc_mask);
823 else /* unaccelerated mode */
825 if (target->virtual_width > max_crtc_width)
826 target->virtual_width = max_crtc_width;
828 /* virtual_height: The only constraint here is the cards memory size which is
829 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
830 * 'Limiting here' to the variable size that's at least available (uint16). */
831 if (target->virtual_height > 65535) target->virtual_height = 65535;
833 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if
834 * it was confined above, so we can finally calculate safely if we need slopspace
835 * for this mode... */
836 if (*acc_mode)
838 /* the mode needs to adhere to the largest granularity imposed... */
839 if (acc_mask < crtc_mask)
840 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
841 else
842 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
844 else /* unaccelerated mode */
845 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
848 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n",
849 video_pitch, target->space));
850 if (target->virtual_width != video_pitch)
851 LOG(2,("INIT: effective mode slopspace is %d pixels\n",
852 (video_pitch - target->virtual_width)));
854 /* now calculate bytes_per_row for this mode */
855 *bytes_per_row = video_pitch * (depth >> 3);
857 return B_OK;