diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index 3c65881e79..5f7a96c950 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -110,6 +110,10 @@ status_t nv_dac_set_pix_pll(display_mode target) /* program new frequency */ DACW(PIXPLLC, ((p << 16) | (n << 8) | m)); + /* program MSByte N and M scalers if they exist (b31=1 enables them) */ + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) + DACW(PIXPLLC2, 0x80000401); + /* Wait for the PIXPLL frequency to lock until timeout occurs */ //fixme: do NV cards have a LOCK indication bit?? /* while((!(DXIR(PIXPLLSTAT)&0x40)) & (time <= 2000)) @@ -223,8 +227,8 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find( /* check if this is within range of the VCO specs */ if ((f_vco >= si->ps.min_pixel_vco) && (f_vco <= si->ps.max_pixel_vco)) { - /* NV31 (FX5600) tweak (missing register for 2nd VCO postscaler) */ - f_vco /= si->pixpll_vco_div2; + /* FX5600 and FX5700 tweak for MSbytes N and M scalers */ + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) f_vco /= 4; /* iterate trough all valid reference-frequency postscaler settings */ for (m = 7; m <= 14; m++) @@ -234,13 +238,18 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find( /* calculate VCO postscaler setting for current setup.. */ n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); + /* ..and check for validity */ if ((n < 1) || (n > 255)) continue; /* find error in frequency this setting gives */ - /* si->pixpll_vco_div2 below is NV31 (FX5600) tweak (missing register) */ - error = - fabs((req_pclk / si->pixpll_vco_div2) - (((si->ps.f_ref / m) * n) / p)); + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) + { + /* FX5600 and FX5700 tweak for MSbytes N and M scalers */ + error = fabs((req_pclk / 4) - (((si->ps.f_ref / m) * n) / p)); + } + else + error = fabs(req_pclk - (((si->ps.f_ref / m) * n) / p)); /* note the setting if best yet */ if (error < error_best) @@ -261,8 +270,8 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find( /* log the VCO frequency found */ f_vco = ((si->ps.f_ref / m) * n); - /* NV31 (FX5600) tweak (missing register for 2nd VCO postscaler) */ - f_vco *= si->pixpll_vco_div2; + /* FX5600 and FX5700 tweak for MSbytes N and M scalers */ + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) f_vco *= 4; LOG(2,("DAC: pix VCO frequency found %fMhz\n", f_vco)); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c index 21cf27d3a0..96111d8359 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c @@ -100,7 +100,7 @@ status_t nv_dac2_set_pix_pll(display_mode target) { return result; } - + /*reprogram (disable,select,wait for stability,enable)*/ // DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0F)|0x04); /*disable the PIXPLL*/ // DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0C)|0x01); /*select the PIXPLL*/ @@ -108,6 +108,10 @@ status_t nv_dac2_set_pix_pll(display_mode target) /* program new frequency */ DAC2W(PIXPLLC, ((p << 16) | (n << 8) | m)); + /* program MSByte N and M scalers if they exist (b31=1 enables them) */ + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) + DAC2W(PIXPLLC2, 0x80000401); + /* Wait for the PIXPLL frequency to lock until timeout occurs */ //fixme: do NV cards have a LOCK indication bit?? /* while((!(DXIR(PIXPLLSTAT)&0x40)) & (time <= 2000)) @@ -221,8 +225,8 @@ static status_t nv10_nv20_dac2_pix_pll_find( /* check if this is within range of the VCO specs */ if ((f_vco >= si->ps.min_video_vco) && (f_vco <= si->ps.max_video_vco)) { - /* NV31 (FX5600) tweak (missing register for 2nd VCO postscaler) */ - f_vco /= si->pixpll_vco_div2; + /* FX5600 and FX5700 tweak for MSbytes N and M scalers */ + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) f_vco /= 4; /* iterate trough all valid reference-frequency postscaler settings */ for (m = 7; m <= 14; m++) @@ -236,9 +240,13 @@ static status_t nv10_nv20_dac2_pix_pll_find( if ((n < 1) || (n > 255)) continue; /* find error in frequency this setting gives */ - /* si->pixpll_vco_div2 below is NV31 (FX5600) tweak (missing register) */ - error = - fabs((req_pclk / si->pixpll_vco_div2) - (((si->ps.f_ref / m) * n) / p)); + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) + { + /* FX5600 and FX5700 tweak for MSbytes N and M scalers */ + error = fabs((req_pclk / 4) - (((si->ps.f_ref / m) * n) / p)); + } + else + error = fabs(req_pclk - (((si->ps.f_ref / m) * n) / p)); /* note the setting if best yet */ if (error < error_best) @@ -259,8 +267,8 @@ static status_t nv10_nv20_dac2_pix_pll_find( /* log the VCO frequency found */ f_vco = ((si->ps.f_ref / m) * n); - /* NV31 (FX5600) tweak (missing register for 2nd VCO postscaler) */ - f_vco *= si->pixpll_vco_div2; + /* FX5600 and FX5700 tweak for MSbytes N and M scalers */ + if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) f_vco *= 4; LOG(2,("DAC2: pix VCO frequency found %fMhz\n", f_vco)); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index 44667930d2..c9cb1f8c18 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -80,7 +80,7 @@ status_t nv_general_powerup() { status_t status; - LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.08-5 running.\n")); + LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.08-6 running.\n")); /* preset no laptop */ si->ps.laptop = false; @@ -911,6 +911,9 @@ status_t nv_general_bios_to_powergraphics() * bit 0: TVOUT. (> NV04A) */ NV_REG32(NV32_PWRUPCTRL) = 0x13111111; + /* select colormode CRTC registers base adresses */ + NV_REG8(NV8_MISCW) = 0xcb; + /* unlock card registers for R/W access */ if (si->ps.secondary_head) CRTCW(OWNER, 0x00); CRTCW(LOCK, 0x57); @@ -939,42 +942,50 @@ status_t nv_general_bios_to_powergraphics() NV_REG32(NV32_2FUNCSEL) &= ~0x00001000; } - //fixme: FX5600 cards have a second postdivider for the pixel PLL VCO. - //find it and program it, instead of relying on the cards BIOS... - //BIOS tested: FX5600 BIOS V4.31.20.38.00 - - //UPDATE: create new pllsetup (all 4 PLL's) for NV31(FX5600) and NV36(FX5700) - //these cards have extra N and M dividers at offset $70 above primary dividers. - - /* non-NV31/NV36 cards have no second postdivider */ - si->pixpll_vco_div2 = 1; - if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36)) - { - /* only reading b0-7, as the rest seems to be write-only */ - uint16 v_display = CRTCR(VDISPE) + 1; - if ((!(CRTCR(REPAINT1) & 0x01)) && - ((v_display == (600 & 0xff)) || (v_display == (1200 & 0xff)))) - { - /* if a VESA mode was already set, and the mode was 800x600 or 1600x1200 - * the BIOS programs the second VCO postdivider to 5 */ - si->pixpll_vco_div2 = 5; - LOG(2, ("INIT: assuming NV31 pixPLL second VCO postdivider is set to 5!\n")); - } - else - { - /* else the BIOS programs the second VCO postdivider to 4 */ - si->pixpll_vco_div2 = 4; - LOG(2, ("INIT: assuming NV31 pixPLL second VCO postdiviver is set to 4!\n")); - } - } - + /* enable 'enhanced' mode on primary head: */ + /* enable access to primary head */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + /* don't doublebuffer CRTC access: set programmed values immediately */ + CRTCW(BUFFER, 0xff); + /* select VGA mode (old VGA register) */ + CRTCW(MODECTL, 0xc3); + /* select graphics mode (old VGA register) */ + SEQW(MEMMODE, 0x0e); + /* select 8 dots character clocks (old VGA register) */ + SEQW(CLKMODE, 0x21); + /* select VGA mode (old VGA register) */ + GRPHW(MODE, 0x00); + /* select graphics mode (old VGA register) */ + GRPHW(MISC, 0x01); + /* select graphics mode (old VGA register) */ + ATBW(MODECTL, 0x01); /* enable 'enhanced mode', enable Vsync & Hsync, * set DAC palette to 8-bit width, disable large screen */ - if (si->ps.secondary_head) CRTCW(OWNER, 0x00); CRTCW(REPAINT1, 0x04); + + /* enable 'enhanced' mode on secondary head: */ if (si->ps.secondary_head) { + /* enable access to secondary head (is SEQ2, GRPH2, CRTC2, ATB2, etc!!) */ CRTC2W(OWNER, 0x03); + /* select colormode CRTC2 registers base adresses */ + NV_REG8(NV8_MISCW) = 0xcb; + /* don't doublebuffer CRTC2 access: set programmed values immediately */ + CRTC2W(BUFFER, 0xff); + /* select VGA mode (old VGA register) */ + CRTC2W(MODECTL, 0xc3); + /* select graphics mode (old VGA register) */ + SEQW(MEMMODE, 0x0e); + /* select 8 dots character clocks (old VGA register) */ + SEQW(CLKMODE, 0x21); + /* select VGA mode (old VGA register) */ + GRPHW(MODE, 0x00); + /* select graphics mode (old VGA register) */ + GRPHW(MISC, 0x01); + /* select graphics mode (old VGA register) */ + ATB2W(MODECTL, 0x01); + /* enable 'enhanced mode', enable Vsync & Hsync, + * set DAC palette to 8-bit width, disable large screen */ CRTC2W(REPAINT1, 0x04); }