diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index 12f8e97534..2c94d8a8e7 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -1,6 +1,6 @@ /* program the DAC */ /* Author: - Rudolf Cornelissen 12/2003-9/2004 + Rudolf Cornelissen 12/2003-10/2004 */ #define MODULE_BIT 0x00010000 @@ -9,8 +9,6 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find( display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test); -static status_t g100_g400max_dac_sys_pll_find( - float req_sclk,float * calc_sclk,uint8 * m_result,uint8 * n_result,uint8 * p_result); /* see if an analog VGA monitor is connected to connector #1 */ bool nv_dac_crt_connected(void) @@ -386,19 +384,19 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find( } /* find nearest valid system PLL setting */ -static status_t g100_g400max_dac_sys_pll_find( - float req_sclk,float * calc_sclk,uint8 * m_result,uint8 * n_result,uint8 * p_result) +status_t nv_dac_sys_pll_find( + float req_sclk, float* calc_sclk, uint8* m_result, uint8* n_result, uint8* p_result, uint8 test) { - int m = 0, n = 0, p = 0, m_max; + int m = 0, n = 0, p = 0/*, m_max*/; float error, error_best = 999999999; int best[3]; float f_vco; /* determine the max. reference-frequency postscaler setting for the * current card (see G100, G200 and G400 specs). */ - switch(si->ps.card_type) +/* switch(si->ps.card_type) { -/* case G100: + case G100: LOG(4,("DAC: G100 restrictions apply\n")); m_max = 7; break; @@ -406,30 +404,32 @@ static status_t g100_g400max_dac_sys_pll_find( LOG(4,("DAC: G200 restrictions apply\n")); m_max = 7; break; -*/ default: + default: LOG(4,("DAC: G400/G400MAX restrictions apply\n")); m_max = 32; break; } +*/ + LOG(4,("DAC: NV4/NV10/NV20 restrictions apply\n")); - /* Make sure the requested systemclock is within the PLL's operational limits */ + /* Make sure the requested clock is within the PLL's operational limits */ /* lower limit is min_system_vco divided by highest postscaler-factor */ - if (req_sclk < (si->ps.min_system_vco / 8.0)) + if (req_sclk < (si->ps.min_system_vco / 16.0)) { LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", - req_sclk, (float)(si->ps.min_system_vco / 8.0))); - req_sclk = (si->ps.min_system_vco / 8.0); + req_sclk, (float)(si->ps.min_system_vco / 16.0))); + req_sclk = (si->ps.min_system_vco / 16.0); } - /* upper limit is max_system_vco */ + /* upper limit is given by pins */ if (req_sclk > si->ps.max_system_vco) { LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", - req_sclk, (float)si->ps.max_system_vco)); + req_sclk, (float)si->ps.max_system_vco)); req_sclk = si->ps.max_system_vco; } /* iterate through all valid PLL postscaler settings */ - for (p=0x01; p < 0x10; p = p<<1) + for (p=0x01; p < 0x20; p = p<<1) { /* calculate the needed VCO frequency for this postscaler setting */ f_vco = req_sclk * p; @@ -437,16 +437,37 @@ static status_t g100_g400max_dac_sys_pll_find( /* check if this is within range of the VCO specs */ if ((f_vco >= si->ps.min_system_vco) && (f_vco <= si->ps.max_system_vco)) { + /* FX5600 and FX5700 tweak for 2nd set N and M scalers */ + if (si->ps.ext_pll) f_vco /= 4; + /* iterate trough all valid reference-frequency postscaler settings */ - for (m = 2; m <= m_max; m++) + for (m = 7; m <= 14; m++) { + /* check if phase-discriminator will be within operational limits */ + //fixme: PLL calcs will be resetup/splitup/updated... + if (si->ps.card_type == NV36) + { + if (((si->ps.f_ref / m) < 3.2) || ((si->ps.f_ref / m) > 6.4)) continue; + } + else + { + if (((si->ps.f_ref / m) < 1.0) || ((si->ps.f_ref / m) > 2.0)) continue; + } + /* calculate VCO postscaler setting for current setup.. */ n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); + /* ..and check for validity */ - if ((n < 8) || (n > 128)) continue; + if ((n < 1) || (n > 255)) continue; /* find error in frequency this setting gives */ - error = fabs(req_sclk - (((si->ps.f_ref / m) * n) / p)); + if (si->ps.ext_pll) + { + /* FX5600 and FX5700 tweak for 2nd set N and M scalers */ + error = fabs((req_sclk / 4) - (((si->ps.f_ref / m) * n) / p)); + } + else + error = fabs(req_sclk - (((si->ps.f_ref / m) * n) / p)); /* note the setting if best yet */ if (error < error_best) @@ -461,32 +482,39 @@ static status_t g100_g400max_dac_sys_pll_find( } /* setup the scalers programming values for found optimum setting */ - m=best[0] - 1; - n=best[1] - 1; - p=best[2] - 1; + m = best[0]; + n = best[1]; + p = best[2]; + + /* log the VCO frequency found */ + f_vco = ((si->ps.f_ref / m) * n); + /* FX5600 and FX5700 tweak for 2nd set N and M scalers */ + if (si->ps.ext_pll) f_vco *= 4; - /* calc the needed PLL loopbackfilter setting belonging to current VCO speed, - * for the current card (see G100, G200 and G400 specs). */ - f_vco = (si->ps.f_ref / (m + 1)) * (n + 1); LOG(2,("DAC: sys VCO frequency found %fMhz\n", f_vco)); - switch(si->ps.card_type) - { - default: - for(;;) - { - if (f_vco >= 240) {p |= (0x03 << 3); break;}; - if (f_vco >= 170) {p |= (0x02 << 3); break;}; - if (f_vco >= 110) {p |= (0x01 << 3); break;}; - break; - } - break; - } - /* return the results */ - *calc_sclk = f_vco / ((p & 0x07) + 1); + *calc_sclk = (f_vco / p); *m_result = m; *n_result = n; + switch(p) + { + case 1: + p = 0x00; + break; + case 2: + p = 0x01; + break; + case 4: + p = 0x02; + break; + case 8: + p = 0x03; + break; + case 16: + p = 0x04; + break; + } *p_result = p; /* display the found pixelclock values */ @@ -495,53 +523,3 @@ static status_t g100_g400max_dac_sys_pll_find( return B_OK; } - -/*set up system pll - NB mclk is memory clock */ -status_t g400_dac_set_sys_pll() -{ - /* values for DAC sys pll registers */ - uint8 m, n, p; -// uint time = 0; - float calc_sclk; - - LOG(1,("DAC: Setting up G400/G400MAX system clock\n")); - g100_g400max_dac_sys_pll_find((float)si->ps.std_engine_clock, &calc_sclk, &m, &n, &p); - - /* reprogram the clock - set PCI/AGP, program, set to programmed */ - /* clear, so don't o/clock addons */ -// CFGW(OPTION2, 0); - /* disable the SYSPLL */ -// CFGW(OPTION, CFGR(OPTION) | 0x04); - /* select the PCI/AGP clock */ -// CFGW(OPTION3, 0); - /* enable the SYSPLL */ -// CFGW(OPTION, CFGR(OPTION) & 0xfffffffb); - - /* program the new clock */ -// DXIW(SYSPLLM, m); -// DXIW(SYSPLLN, n); -// DXIW(SYSPLLP, p); - - /* Wait for the SYSPLL frequency to lock until timeout occurs */ -/* while((!(DXIR(SYSPLLSTAT)&0x40)) & (time <= 2000)) - { - time++; - snooze(1); - } - - if (time > 2000) - LOG(2,("DAC: sys PLL frequency not locked!\n")); - else - LOG(2,("DAC: sys PLL frequency locked\n")); -*/ - /* disable the SYSPLL */ -// CFGW(OPTION, CFGR(OPTION) | 0x04); - /* setup Gclk, Mclk and Wclk divs via PINS and select SYSPLL as system clock source */ -// CFGW(OPTION3, si->ps.option3_reg); - /* make sure the PLLs are not swapped (set default config) */ -// CFGW(OPTION, CFGR(OPTION) & 0xffffffbf); - /* enable the SYSPLL (and make sure the SYSPLL is indeed powered up) */ -// CFGW(OPTION, (CFGR(OPTION) & 0xfffffffb) | 0x20); - - return B_OK; -} diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index 4e416c7ea1..6ed077113b 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -182,9 +182,9 @@ static status_t pins3_5_read(uint8 *rom, uint32 offset) LOG(8,("INFO: PLL VCO range is %dkHz - %dkHz\n", fvco_min, fvco_max)); /* modify presets to reflect card capability */ + si->ps.min_system_vco = fvco_min / 1000; + si->ps.max_system_vco = fvco_max / 1000; //fixme: enable and modify PLL code... - //si->ps.min_system_vco = fvco_min / 1000; - //si->ps.max_system_vco = fvco_max / 1000; //si->ps.min_pixel_vco = fvco_min / 1000; //si->ps.max_pixel_vco = fvco_max / 1000; //si->ps.min_video_vco = fvco_min / 1000; @@ -412,13 +412,9 @@ static status_t exec_type1_script(uint8* rom, uint16 adress, int16* size, uint16 reg, ((float)data2))); if (exec) { - //fixme: setup core and RAM PLL calc routine(s), now (mis)using DAC's... - display_mode target; float calced_clk; uint8 m, n, p; - target.space = B_CMAP8; - target.timing.pixel_clock = (data2 * 1000); - nv_dac_pix_pll_find(target, &calced_clk, &m, &n, &p, 0); + nv_dac_sys_pll_find(((float)data2), &calced_clk, &m, &n, &p, 0); NV_REG32(reg) = ((p << 16) | (n << 8) | m); } log_pll(reg); @@ -718,13 +714,9 @@ static status_t exec_type1_script(uint8* rom, uint16 adress, int16* size, uint16 LOG(8,("cmd 'calculate and set PLL 32bit reg $%08x for %.3fMHz'\n", reg, (data / 100.0))); if (exec) { - //fixme: setup core and RAM PLL calc routine(s), now (mis)using DAC's... - display_mode target; float calced_clk; uint8 m, n, p; - target.space = B_CMAP8; - target.timing.pixel_clock = (data * 10); - nv_dac_pix_pll_find(target, &calced_clk, &m, &n, &p, 0); + nv_dac_sys_pll_find((data / 100.0), &calced_clk, &m, &n, &p, 0); NV_REG32(reg) = ((p << 16) | (n << 8) | m); } log_pll(reg); @@ -1035,13 +1027,9 @@ static status_t exec_type2_script_mode(uint8* rom, uint16* adress, int16* size, reg2, (data2 / 100.0))); if (*exec && reg2) { - //fixme: setup core and RAM PLL calc routine(s), now (mis)using DAC's... - display_mode target; float calced_clk; uint8 m, n, p; - target.space = B_CMAP8; - target.timing.pixel_clock = (data2 * 10); - nv_dac_pix_pll_find(target, &calced_clk, &m, &n, &p, 0); + nv_dac_sys_pll_find((data2 / 100.0), &calced_clk, &m, &n, &p, 0); NV_REG32(reg2) = ((p << 16) | (n << 8) | m); //fixme? /* program 2nd set N and M scalers if they exist (b31=1 enables them) */ @@ -1542,7 +1530,6 @@ static status_t exec_type2_script_mode(uint8* rom, uint16* adress, int16* size, } /* execute */ - //fixme: setup new PLL routines that adhere to pins speeds for VCO, etc... *adress += 1; reg = *((uint32*)(&(rom[*adress]))); *adress += 4; @@ -1551,13 +1538,9 @@ static status_t exec_type2_script_mode(uint8* rom, uint16* adress, int16* size, LOG(8,("cmd 'calculate and set PLL 32bit reg $%08x for %.3fMHz'\n", reg, (data / 100.0))); if (*exec) { - //fixme: setup core and RAM PLL calc routine(s), now (mis)using DAC's... - display_mode target; float calced_clk; uint8 m, n, p; - target.space = B_CMAP8; - target.timing.pixel_clock = (data * 10); - nv_dac_pix_pll_find(target, &calced_clk, &m, &n, &p, 0); + nv_dac_sys_pll_find((data / 100.0), &calced_clk, &m, &n, &p, 0); NV_REG32(reg) = ((p << 16) | (n << 8) | m); //fixme? /* program 2nd set N and M scalers if they exist (b31=1 enables them) */ diff --git a/src/add-ons/accelerants/nvidia/engine/nv_proto.h b/src/add-ons/accelerants/nvidia/engine/nv_proto.h index 2ef36fc3be..eb15c98490 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_proto.h +++ b/src/add-ons/accelerants/nvidia/engine/nv_proto.h @@ -44,7 +44,7 @@ status_t nv_dac_mode(int,float); status_t nv_dac_palette(uint8*,uint8*,uint8*); status_t nv_dac_pix_pll_find(display_mode target,float * result,uint8 *,uint8 *,uint8 *, uint8); status_t nv_dac_set_pix_pll(display_mode target); -status_t g400_dac_set_sys_pll(void); +status_t nv_dac_sys_pll_find(float, float*, uint8*, uint8*, uint8*, uint8); /* DAC2 functions */ bool nv_dac2_crt_connected(void);