From 7340b4612e23a3c96f9f720ab70e2d59892e6dab Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Thu, 14 Oct 2004 09:42:21 +0000 Subject: [PATCH] more PLL calc routine finetuning. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9340 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/nvidia/engine/nv_dac.c | 87 +++++++++++-------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index c0e84b0137..d19b25d4e1 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -387,7 +387,7 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find( 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; + int m = 0, n = 0, p = 0, m_max, p_max; float error, error_best = 999999999; int best[3]; float f_vco, discr_low, discr_high; @@ -398,53 +398,67 @@ status_t nv_dac_sys_pll_find( { case NV04A: LOG(4,("DAC: NV04 restrictions apply\n")); - /* set phase-discriminator frequency range (Mhz) */ - /* (verified) */ + /* set phase-discriminator frequency range (Mhz) (verified) */ discr_low = 1.0; discr_high = 2.0; + /* set max. useable reference frequency postscaler divider factor */ + m_max = 14; + /* set max. useable VCO output postscaler divider factor */ + p_max = 16; break; default: - LOG(4,("DAC: NV10/NV20/NV30 restrictions apply\n")); - /* apparantly we would get distortions on high PLL output frequencies if - * we use the phase-discriminator at low frequencies */ - /* (low discriminator specs are verified) */ - if (req_sclk > 340.0) + switch (si->ps.card_type) { - /* Fpll > 340Mhz */ - discr_low = 6.74; + case NV28: + //fixme: how about some other cards??? + LOG(4,("DAC: NV28 restrictions apply\n")); + /* set max. useable reference frequency postscaler divider factor; + * apparantly we would get distortions on high PLL output frequencies if + * we use the phase-discriminator at low frequencies */ + if (req_sclk > 340.0) m_max = 2; /* Fpll > 340Mhz */ + else if (req_sclk > 200.0) m_max = 4; /* 200Mhz < Fpll <= 340Mhz */ + else if (req_sclk > 150.0) m_max = 6; /* 150Mhz < Fpll <= 200Mhz */ + else m_max = 14; /* Fpll < 150Mhz */ + + /* set max. useable VCO output postscaler divider factor */ + p_max = 32; + /* set phase-discriminator frequency range (Mhz) (verified) */ + discr_low = 1.0; + discr_high = 27.0; + break; + default: + LOG(4,("DAC: NV10/NV20/NV30 restrictions apply\n")); + /* set max. useable reference frequency postscaler divider factor; + * apparantly we would get distortions on high PLL output frequencies if + * we use the phase-discriminator at low frequencies */ + if (req_sclk > 340.0) m_max = 2; /* Fpll > 340Mhz */ + else if (req_sclk > 250.0) m_max = 6; /* 250Mhz < Fpll <= 340Mhz */ + else m_max = 14; /* Fpll < 250Mhz */ + + /* set max. useable VCO output postscaler divider factor */ + p_max = 16; + /* set phase-discriminator frequency range (Mhz) (verified) */ + if (si->ps.card_type == NV36) discr_low = 3.2; + else discr_low = 1.0; + /* (high discriminator spec is failsafe) */ + discr_high = 14.0; + break; } - else - { - if (req_sclk > 250.0) - { - /* 250Mhz < Fpll <= 340Mhz */ - discr_low = 2.24; - } - else - { - /* Fpll < 250Mhz */ - discr_low = 1.0; - } - } - /* (additional verified restriction on NV36) */ - if (si->ps.card_type == NV36) - { - if (discr_low < 3.2) discr_low = 3.2; - } - /* (high discriminator spec is failsafe) */ - discr_high = 14.0; break; } + + LOG(4,("DAC: PLL reference frequency postscaler divider range is 1 - %d\n", m_max)); + LOG(4,("DAC: PLL VCO output postscaler divider range is 1 - %d\n", p_max)); LOG(4,("DAC: PLL discriminator input frequency range is %2.2fMhz - %2.2fMhz\n", discr_low, discr_high)); /* 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 / 16.0)) + if (req_sclk < (si->ps.min_system_vco / ((float)p_max))) { LOG(4,("DAC: clamping sysclock: requested %fMHz, set to %fMHz\n", - req_sclk, (float)(si->ps.min_system_vco / 16.0))); - req_sclk = (si->ps.min_system_vco / 16.0); + req_sclk, (si->ps.min_system_vco / ((float)p_max)))); + req_sclk = (si->ps.min_system_vco / ((float)p_max)); } /* upper limit is given by pins */ if (req_sclk > si->ps.max_system_vco) @@ -455,7 +469,7 @@ status_t nv_dac_sys_pll_find( } /* iterate through all valid PLL postscaler settings */ - for (p=0x01; p < 0x20; p = p<<1) + for (p=0x01; p <= p_max; p = p<<1) { /* calculate the needed VCO frequency for this postscaler setting */ f_vco = req_sclk * p; @@ -467,7 +481,7 @@ status_t nv_dac_sys_pll_find( if (si->ps.ext_pll) f_vco /= 4; /* iterate trough all valid reference-frequency postscaler settings */ - for (m = 1; m <= 14; m++) + for (m = 1; m <= m_max; m++) { /* check if phase-discriminator will be within operational limits */ if (((si->ps.f_ref / m) < discr_low) || ((si->ps.f_ref / m) > discr_high)) @@ -533,6 +547,9 @@ status_t nv_dac_sys_pll_find( case 16: p = 0x04; break; + case 32: + p = 0x05; + break; } *p_result = p;