/* Authors: Mark Watson 12/1999, Apsed, Rudolf Cornelissen 10/2002-2/2016 */ #define MODULE_BIT 0x00008000 #include "std.h" static status_t test_ram(void); static status_t engxx_general_powerup (void); static status_t eng_general_bios_to_powergraphics(void); static void eng_dump_configuration_space (void) { #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \ uint32 value = CFGR(reg); \ MSG(("configuration_space 0x%02x %20s 0x%08x\n", \ ENCFG_##reg, #reg, value)); \ } while (0) DUMP_CFG (DEVID, 0); DUMP_CFG (DEVCTRL, 0); DUMP_CFG (CLASS, 0); DUMP_CFG (HEADER, 0); DUMP_CFG (BASE1REGS,0); DUMP_CFG (BASE2FB, 0); DUMP_CFG (BASE3, 0); DUMP_CFG (BASE4, 0); DUMP_CFG (BASE5, 0); DUMP_CFG (BASE6, 0); DUMP_CFG (BASE7, 0); DUMP_CFG (SUBSYSID1,0); DUMP_CFG (ROMBASE, 0); DUMP_CFG (CAPPTR, 0); DUMP_CFG (CFG_1, 0); DUMP_CFG (INTERRUPT,0); DUMP_CFG (SUBSYSID2,0); DUMP_CFG (AGPREF, 0); DUMP_CFG (AGPSTAT, 0); DUMP_CFG (AGPCMD, 0); DUMP_CFG (ROMSHADOW,0); DUMP_CFG (VGA, 0); DUMP_CFG (SCHRATCH, 0); DUMP_CFG (CFG_10, 0); DUMP_CFG (CFG_11, 0); DUMP_CFG (CFG_12, 0); DUMP_CFG (CFG_13, 0); DUMP_CFG (CFG_14, 0); DUMP_CFG (CFG_15, 0); DUMP_CFG (CFG_16, 0); DUMP_CFG (CFG_17, 0); DUMP_CFG (CFG_18, 0); DUMP_CFG (CFG_19, 0); DUMP_CFG (CFG_20, 0); DUMP_CFG (CFG_21, 0); DUMP_CFG (CFG_22, 0); DUMP_CFG (CFG_23, 0); DUMP_CFG (CFG_24, 0); DUMP_CFG (CFG_25, 0); DUMP_CFG (CFG_26, 0); DUMP_CFG (CFG_27, 0); DUMP_CFG (CFG_28, 0); DUMP_CFG (CFG_29, 0); DUMP_CFG (CFG_30, 0); DUMP_CFG (CFG_31, 0); DUMP_CFG (CFG_32, 0); DUMP_CFG (CFG_33, 0); DUMP_CFG (CFG_34, 0); DUMP_CFG (CFG_35, 0); DUMP_CFG (CFG_36, 0); DUMP_CFG (CFG_37, 0); DUMP_CFG (CFG_38, 0); DUMP_CFG (CFG_39, 0); DUMP_CFG (CFG_40, 0); DUMP_CFG (CFG_41, 0); DUMP_CFG (CFG_42, 0); DUMP_CFG (CFG_43, 0); DUMP_CFG (CFG_44, 0); DUMP_CFG (CFG_45, 0); DUMP_CFG (CFG_46, 0); DUMP_CFG (CFG_47, 0); DUMP_CFG (CFG_48, 0); DUMP_CFG (CFG_49, 0); DUMP_CFG (CFG_50, 0); #undef DUMP_CFG } status_t eng_general_powerup() { status_t status; LOG(1,("POWERUP: Haiku VIA Accelerant 0.19 running.\n")); /* preset no laptop */ si->ps.laptop = false; /* detect card type and power it up */ switch(CFGR(DEVID)) { /* Vendor Via */ case 0x30221106: si->ps.card_type = VT3022; si->ps.card_arch = CLE266; LOG(4,("POWERUP: Detected VIA CLE266 Unichrome Pro (VT3022)\n")); status = engxx_general_powerup(); break; case 0x31081106: si->ps.card_type = VT3108; si->ps.card_arch = K8M800; LOG(4,("POWERUP: Detected VIA K8M800 Unichrome Pro (VT3108)\n")); status = engxx_general_powerup(); break; case 0x31221106: si->ps.card_type = VT3122; si->ps.card_arch = CLE266; LOG(4,("POWERUP: Detected VIA CLE266 Unichrome Pro (VT3122)\n")); status = engxx_general_powerup(); break; case 0x32051106: si->ps.card_type = VT3205; si->ps.card_arch = KM400; LOG(4,("POWERUP: Detected VIA KM400 Unichrome (VT3205)\n")); status = engxx_general_powerup(); break; case 0x72051106: si->ps.card_type = VT7205; si->ps.card_arch = KM400; LOG(4,("POWERUP: Detected VIA KM400 Unichrome (VT7205)\n")); status = engxx_general_powerup(); break; default: LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID))); return B_ERROR; } return status; } static status_t test_ram() { uint32 value, offset; status_t result = B_OK; /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */ if (si->fbc.frame_buffer == NULL) { LOG(8,("INIT: test_ram detected NULL pointer.\n")); return B_ERROR; } for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) { /* write testpattern to cardRAM */ ((uint32 *)si->fbc.frame_buffer)[offset] = value; /* toggle testpattern */ value = 0xffffffff - value; } for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) { /* readback and verify testpattern from cardRAM */ if (((uint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR; /* toggle testpattern */ value = 0xffffffff - value; } return result; } /* NOTE: * This routine *has* to be done *after* SetDispplayMode has been executed, * or test results will not be representative! * (CAS latency is dependant on NV setup on some (DRAM) boards) */ status_t eng_set_cas_latency() { status_t result = B_ERROR; uint8 latency = 0; /* check current RAM access to see if we need to change anything */ if (test_ram() == B_OK) { LOG(4,("INIT: RAM access OK.\n")); return B_OK; } /* check if we read PINS at starttime so we have valid registersettings at our disposal */ if (si->ps.pins_status != B_OK) { LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n")); return B_ERROR; } /* OK. We might have a problem, try to fix it now.. */ LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n")); switch(si->ps.card_type) { default: LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n")); return B_OK; break; } if (result == B_OK) LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency)); else LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency)); return result; } void setup_virtualized_heads(bool cross) { if (cross) { head1_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing; head1_set_timing = (crtc_set_timing) eng_crtc2_set_timing; head1_depth = (crtc_depth) eng_crtc2_depth; head1_dpms = (crtc_dpms) eng_crtc2_dpms; head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch; head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch; head1_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start; head1_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init; head1_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show; head1_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide; head1_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define; head1_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position; head1_mode = (dac_mode) eng_dac2_mode; head1_palette = (dac_palette) eng_dac2_palette; head1_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll; head1_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find; head2_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing; head2_set_timing = (crtc_set_timing) eng_crtc_set_timing; head2_depth = (crtc_depth) eng_crtc_depth; head2_dpms = (crtc_dpms) eng_crtc_dpms; head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch; head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch; head2_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start; head2_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init; head2_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show; head2_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide; head2_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define; head2_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position; head2_mode = (dac_mode) eng_dac_mode; head2_palette = (dac_palette) eng_dac_palette; head2_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll; head2_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find; } else { head1_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing; head1_set_timing = (crtc_set_timing) eng_crtc_set_timing; head1_depth = (crtc_depth) eng_crtc_depth; head1_dpms = (crtc_dpms) eng_crtc_dpms; head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch; head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch; head1_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start; head1_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init; head1_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show; head1_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide; head1_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define; head1_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position; head1_mode = (dac_mode) eng_dac_mode; head1_palette = (dac_palette) eng_dac_palette; head1_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll; head1_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find; head2_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing; head2_set_timing = (crtc_set_timing) eng_crtc2_set_timing; head2_depth = (crtc_depth) eng_crtc2_depth; head2_dpms = (crtc_dpms) eng_crtc2_dpms; head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch; head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch; head2_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start; head2_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init; head2_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show; head2_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide; head2_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define; head2_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position; head2_mode = (dac_mode) eng_dac2_mode; head2_palette = (dac_palette) eng_dac2_palette; head2_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll; head2_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find; } } void set_crtc_owner(bool head) { if (si->ps.secondary_head) { if (!head) { /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's, * while non-NV11 cards behave normally. * * Double-write action needed on those strange NV11 cards: */ /* RESET: needed on NV11 */ CRTCW(OWNER, 0xff); /* enable access to CRTC1, SEQ1, GRPH1, ATB1, ??? */ CRTCW(OWNER, 0x00); } else { /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's, * while non-NV11 cards behave normally. * * Double-write action needed on those strange NV11 cards: */ /* RESET: needed on NV11 */ CRTC2W(OWNER, 0xff); /* enable access to CRTC2, SEQ2, GRPH2, ATB2, ??? */ CRTC2W(OWNER, 0x03); } } } static status_t engxx_general_powerup() { LOG(4,("POWERUP: Chip revision is $%02x\n", si->ps.chip_rev)); LOG(4, ("INIT: card powerup\n")); /* setup cardspecs */ /* note: * this MUST be done before the driver attempts a card coldstart */ set_specs(); /* only process BIOS for finetuning specs and coldstarting card if requested * by the user; * note: * this in fact frees the driver from relying on the BIOS to be executed * at system power-up POST time. */ if (!si->settings.usebios) { LOG(2, ("INIT: Attempting card coldstart!\n")); /* update the cardspecs in the shared_info PINS struct according to reported * specs as much as is possible; * this also coldstarts the card if possible (executes BIOS CMD script(s)) */ // parse_pins(); } else { LOG(2, ("INIT: Skipping card coldstart!\n")); } /* get RAM size and fake panel startup (panel init code is still missing) */ fake_panel_start(); /* log the final card specifications */ dump_pins(); /* dump config space as it is after a possible coldstart attempt */ if (si->settings.logmask & 0x80000000) eng_dump_configuration_space(); /* setup CRTC and DAC functions access: determined in fake_panel_start */ setup_virtualized_heads(si->ps.crtc2_prim); /* do powerup needed from pre-inited card state as done by system POST cardBIOS * execution or driver coldstart above */ return eng_general_bios_to_powergraphics(); } /* this routine switches the CRTC/DAC sets to 'connectors', but only for analog * outputs. We need this to make sure the analog 'switch' is set in the same way the * digital 'switch' is set by the BIOS or we might not be able to use dualhead. */ status_t eng_general_output_select(bool cross) { /* make sure this call is warranted */ if (si->ps.secondary_head) { /* NV11 cards can't switch heads (confirmed) */ if (si->ps.card_type != NV11) { if (cross) { LOG(4,("INIT: switching analog outputs to be cross-connected\n")); /* enable head 2 on connector 1 */ /* (b8 = select CRTC (head) for output, * b4 = ??? (confirmed not to be a FP switch), * b0 = enable CRT) */ DACW(OUTPUT, 0x00000101); /* enable head 1 on connector 2 */ DAC2W(OUTPUT, 0x00000001); } else { LOG(4,("INIT: switching analog outputs to be straight-through\n")); /* enable head 1 on connector 1 */ DACW(OUTPUT, 0x00000001); /* enable head 2 on connector 2 */ DAC2W(OUTPUT, 0x00000101); } } else { LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n")); } return B_OK; } else { return B_ERROR; } } /* this routine switches CRTC/DAC set use. We need this because it's unknown howto * switch digital panels to/from a specific CRTC/DAC set. */ status_t eng_general_head_select(bool cross) { /* make sure this call is warranted */ if (si->ps.secondary_head) { /* invert CRTC/DAC use to do switching */ if (cross) { LOG(4,("INIT: switching CRTC/DAC use to be cross-connected\n")); si->crtc_switch_mode = !si->ps.crtc2_prim; } else { LOG(4,("INIT: switching CRTC/DAC use to be straight-through\n")); si->crtc_switch_mode = si->ps.crtc2_prim; } /* update CRTC and DAC functions access */ setup_virtualized_heads(si->crtc_switch_mode); return B_OK; } else { return B_ERROR; } } /* basic change of card state from VGA to enhanced mode: * Should work from VGA BIOS POST init state. */ static status_t eng_general_bios_to_powergraphics() { /* let acc engine make power off/power on cycle to start 'fresh' */ // ENG_REG32(RG32_PWRUPCTRL) = 0x13110011; snooze(1000); /* power-up all hardware function blocks */ // ENG_REG32(RG32_PWRUPCTRL) = 0x13111111; /* select colormode CRTC registers base adresses, * but don't touch the current selected pixelclock source yet */ ENG_REG8(RG8_MISCW) = (((ENG_REG8(RG8_MISCR)) & 0x0c) | 0xc3); /* unlock (extended) registers for R/W access */ SEQW(LOCK, 0x01); CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); /* turn off both displays and the hardcursors (also disables transfers) */ head1_dpms(false, false, false); head1_cursor_hide(); if (si->ps.secondary_head) { // head2_dpms(false, false, false); // head2_cursor_hide(); } // if (si->ps.secondary_head) if (0) { /* switch overlay engine to CRTC1 */ /* bit 17: GPU FP port #1 (confirmed NV25, NV28, confirmed not on NV34), * bit 16: GPU FP port #2 (confirmed NV25, NV28, NV34), * bit 12: overlay engine (all cards), * bit 9: TVout chip #2 (confirmed on NV18, NV25, NV28), * bit 8: TVout chip #1 (all cards), * bit 4: both I2C busses (all cards) */ ENG_REG32(RG32_2FUNCSEL) &= ~0x00001000; ENG_REG32(RG32_FUNCSEL) |= 0x00001000; } si->overlay.crtc = false; /* set card to 'enhanced' mode: (only VGA standard registers used here) */ /* (keep) card enabled, set plain normal memory usage, no old VGA 'tricks' ... */ CRTCW(MODECTL, 0xc3); /* ... plain sequential memory use, more than 64Kb RAM installed, * switch to graphics mode ... */ SEQW(MEMMODE, 0x0e); /* ... disable bitplane tweaking ... */ GRPHW(ENSETRESET, 0x00); /* ... no logical function tweaking with display data, no data rotation ... */ GRPHW(DATAROTATE, 0x00); /* ... reset read map select to plane 0 ... */ GRPHW(READMAPSEL, 0x00); /* ... set standard mode ... */ GRPHW(MODE, 0x00); /* ... ISA framebuffer mapping is 64Kb window, switch to graphics mode (again), * select standard adressing ... */ GRPHW(MISC, 0x05); /* ... disable bit masking ... */ GRPHW(BITMASK, 0xff); /* ... attributes are in color, switch to graphics mode (again) ... */ ATBW(MODECTL, 0x01); /* ... set overscan color to black ... */ ATBW(OSCANCOLOR, 0x00); /* ... enable all color planes ... */ ATBW(COLPLANE_EN, 0x0f); /* ... reset horizontal pixelpanning ... */ ATBW(HORPIXPAN, 0x00); /* ... reset colorpalette groupselect bits ... */ ATBW(COLSEL, 0x00); /* ... do unknown standard VGA register ... */ ATBW(0x16, 0x01); /* ... and enable all four byteplanes. */ SEQW(MAPMASK, 0x0f); /* setup sequencer clocking mode */ SEQW(CLKMODE, 0x21); /* setup AGP: * Note: * This may only be done when no transfers are in progress on the bus, so now * is probably a good time.. */ eng_agp_setup(); /* turn screen one on */ head1_dpms(true, true, true); return B_OK; } /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify * virtual_size to the nearest valid maximum for the mode on the card if not so. * Also: check if virtual_width adheres to the cards granularity constraints, and * create mode slopspace if not so. * We use acc or crtc granularity constraints based on the 'worst case' scenario. * * Mode slopspace is reflected in fbc->bytes_per_row BTW. */ status_t eng_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode) { uint32 video_pitch; uint32 acc_mask, crtc_mask; uint32 max_crtc_width, max_acc_width; uint8 depth = 8; /* determine pixel multiple based on 2D/3D engine constraints */ //via fixme. switch (si->ps.card_arch) { default: /* confirmed for: * TNT1, TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */ switch (target->space) { case B_CMAP8: acc_mask = 0x0f; depth = 8; break; case B_RGB15: acc_mask = 0x07; depth = 16; break; case B_RGB16: acc_mask = 0x07; depth = 16; break; case B_RGB24: acc_mask = 0x0f; depth = 24; break; case B_RGB32: acc_mask = 0x03; depth = 32; break; default: LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); return B_ERROR; } break; } //via ok: /* determine pixel multiple based on CRTC memory pitch constraints. * (Note: Don't mix this up with CRTC timing contraints! Those are * multiples of 8 for horizontal, 1 for vertical timing.) */ switch (si->ps.card_type) { default: switch (target->space) { case B_CMAP8: crtc_mask = 0x07; break; case B_RGB15: crtc_mask = 0x03; break; case B_RGB16: crtc_mask = 0x03; break; case B_RGB24: crtc_mask = 0x07; break; case B_RGB32: crtc_mask = 0x01; break; default: LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); return B_ERROR; } break; } /* set virtual_width limit for accelerated modes */ //via fixme: switch (si->ps.card_arch) { case NV04A: /* confirmed for: * TNT1, TNT2, TNT2-M64 */ switch(target->space) { case B_CMAP8: max_acc_width = 8176; break; case B_RGB15: max_acc_width = 4088; break; case B_RGB16: max_acc_width = 4088; break; case B_RGB24: max_acc_width = 2720; break; case B_RGB32: max_acc_width = 2044; break; default: LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); return B_ERROR; } break; default: /* confirmed for: * GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */ switch(target->space) { case B_CMAP8: max_acc_width = 16368; break; case B_RGB15: max_acc_width = 8184; break; case B_RGB16: max_acc_width = 8184; break; case B_RGB24: max_acc_width = 5456; break; case B_RGB32: max_acc_width = 4092; break; default: LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); return B_ERROR; } /* NV31 (confirmed GeForceFX 5600) has NV20A granularity! * So let it fall through... */ if (si->ps.card_type != NV31) break; case NV20A: /* confirmed for: * GeForce4 Ti4200 */ switch(target->space) { case B_CMAP8: max_acc_width = 16320; break; case B_RGB15: max_acc_width = 8160; break; case B_RGB16: max_acc_width = 8160; break; case B_RGB24: max_acc_width = 5440; break; case B_RGB32: max_acc_width = 4080; break; default: LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); return B_ERROR; } break; } //via ok: /* set virtual_width limit for unaccelerated modes */ switch (si->ps.card_type) { default: switch(target->space) { case B_CMAP8: max_crtc_width = 16376; break; case B_RGB15: max_crtc_width = 8188; break; case B_RGB16: max_crtc_width = 8188; break; case B_RGB24: max_crtc_width = 5456; break; case B_RGB32: max_crtc_width = 4094; break; default: LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); return B_ERROR; } break; } /* check for acc capability, and adjust mode to adhere to hardware constraints */ if (max_acc_width <= max_crtc_width) { /* check if we can setup this mode with acceleration */ // *acc_mode = true; //blocking acc totally: *acc_mode = false; /* virtual_width */ if (target->virtual_width > max_acc_width) *acc_mode = false; /* virtual_height */ /* (NV cards can even do more than this(?)... * but 4096 is confirmed on all cards at max. accelerated width.) */ if (target->virtual_height > 4096) *acc_mode = false; /* now check virtual_size based on CRTC constraints */ if (target->virtual_width > max_crtc_width) target->virtual_width = max_crtc_width; /* virtual_height: The only constraint here is the cards memory size which is * checked later on in ProposeMode: virtual_height is adjusted then if needed. * 'Limiting here' to the variable size that's at least available (uint16). */ if (target->virtual_height > 65535) target->virtual_height = 65535; /* OK, now we know that virtual_width is valid, and it's needing no slopspace if * it was confined above, so we can finally calculate safely if we need slopspace * for this mode... */ if (*acc_mode) { /* the mode needs to adhere to the largest granularity imposed... */ if (acc_mask < crtc_mask) video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); else video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); } else /* unaccelerated mode */ video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); } else /* max_acc_width > max_crtc_width */ { /* check if we can setup this mode with acceleration */ // *acc_mode = true; //blocking acc totally: *acc_mode = false; /* (we already know virtual_width will be no problem) */ /* virtual_height */ /* (NV cards can even do more than this(?)... * but 4096 is confirmed on all cards at max. accelerated width.) */ if (target->virtual_height > 4096) *acc_mode = false; /* now check virtual_size based on CRTC constraints */ if (*acc_mode) { /* note that max_crtc_width already adheres to crtc_mask */ if (target->virtual_width > (max_crtc_width & ~acc_mask)) target->virtual_width = (max_crtc_width & ~acc_mask); } else /* unaccelerated mode */ { if (target->virtual_width > max_crtc_width) target->virtual_width = max_crtc_width; } /* virtual_height: The only constraint here is the cards memory size which is * checked later on in ProposeMode: virtual_height is adjusted then if needed. * 'Limiting here' to the variable size that's at least available (uint16). */ if (target->virtual_height > 65535) target->virtual_height = 65535; /* OK, now we know that virtual_width is valid, and it's needing no slopspace if * it was confined above, so we can finally calculate safely if we need slopspace * for this mode... */ if (*acc_mode) { /* the mode needs to adhere to the largest granularity imposed... */ if (acc_mask < crtc_mask) video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); else video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); } else /* unaccelerated mode */ video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); } LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n", video_pitch, target->space)); if (target->virtual_width != video_pitch) LOG(2,("INIT: effective mode slopspace is %d pixels\n", (video_pitch - target->virtual_width))); /* now calculate bytes_per_row for this mode */ *bytes_per_row = video_pitch * (depth >> 3); return B_OK; }