nVidia driver: Fixed PLL for C51 chipset. Finally fixes ticket #12955

This commit is contained in:
Rudolf Cornelissen 2021-05-02 16:05:48 +00:00
parent 6cd4da00c0
commit 0516144cf2
5 changed files with 59 additions and 28 deletions

View File

@ -1,6 +1,6 @@
/* program the DAC */
/* Author:
Rudolf Cornelissen 12/2003-10/2009
Rudolf Cornelissen 12/2003-5/2021
*/
#define MODULE_BIT 0x00010000
@ -329,7 +329,7 @@ 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)
{
int m = 0, n = 0, p = 0/*, m_max*/;
int m = 0, n = 0, p = 0, m_min = 7, p_max = 0x10;
float error, error_best = INFINITY;
int best[3] = {0, 0, 0};
float f_vco, max_pclk;
@ -358,17 +358,22 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find(
max_pclk = si->ps.max_dac1_clock_32;
break;
}
/* update PLL divider specs for C51 chipset */
if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) {
m_min = 4;
p_max = 0x20;
}
/* if some dualhead mode is active, an extra restriction might apply */
if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE))
max_pclk = si->ps.max_dac1_clock_32dh;
/* Make sure the requested pixelclock is within the PLL's operational limits */
/* lower limit is min_pixel_vco divided by highest postscaler-factor */
if (req_pclk < (si->ps.min_pixel_vco / 16.0))
if (req_pclk < (si->ps.min_pixel_vco / p_max))
{
LOG(4,("DAC: clamping pixclock: requested %fMHz, set to %fMHz\n",
req_pclk, (float)(si->ps.min_pixel_vco / 16.0)));
req_pclk = (si->ps.min_pixel_vco / 16.0);
req_pclk, (float)(si->ps.min_pixel_vco / p_max)));
req_pclk = (si->ps.min_pixel_vco / p_max);
}
/* upper limit is given by pins in combination with current active mode */
if (req_pclk > max_pclk)
@ -379,7 +384,7 @@ static status_t nv4_nv10_nv20_dac_pix_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_pclk * p;
@ -391,17 +396,19 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find(
if (si->ps.ext_pll) f_vco /= 4;
/* iterate trough all valid reference-frequency postscaler settings */
for (m = 7; m <= 14; m++)
for (m = m_min; 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.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;
} else {
if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) {
/* C51 chipset */
if (((si->ps.f_ref / m) < 1.7) || ((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.. */
@ -464,6 +471,9 @@ static status_t nv4_nv10_nv20_dac_pix_pll_find(
case 16:
p = 0x04;
break;
case 32:
p = 0x05;
break;
}
*p_result = p;

View File

@ -1,6 +1,6 @@
/* program the secondary DAC */
/* Author:
Rudolf Cornelissen 12/2003-9/2009
Rudolf Cornelissen 12/2003-5/2021
*/
#define MODULE_BIT 0x00001000
@ -286,7 +286,7 @@ static status_t nv10_nv20_dac2_pix_pll_find(
display_mode target, float* calc_pclk, 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_min = 7, p_max = 0x10;
float error, error_best = INFINITY;
int best[3] = {0, 0, 0};
float f_vco, max_pclk;
@ -315,17 +315,22 @@ static status_t nv10_nv20_dac2_pix_pll_find(
max_pclk = si->ps.max_dac2_clock_32;
break;
}
/* update PLL divider specs for C51 chipset */
if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) {
m_min = 4;
p_max = 0x20;
}
/* if some dualhead mode is active, an extra restriction might apply */
if ((target.flags & DUALHEAD_BITS) && (target.space == B_RGB32_LITTLE))
max_pclk = si->ps.max_dac2_clock_32dh;
/* Make sure the requested pixelclock is within the PLL's operational limits */
/* lower limit is min_pixel_vco divided by highest postscaler-factor */
if (req_pclk < (si->ps.min_video_vco / 16.0))
if (req_pclk < (si->ps.min_video_vco / p_max))
{
LOG(4,("DAC2: clamping pixclock: requested %fMHz, set to %fMHz\n",
req_pclk, (float)(si->ps.min_video_vco / 16.0)));
req_pclk = (si->ps.min_video_vco / 16.0);
req_pclk, (float)(si->ps.min_video_vco / p_max)));
req_pclk = (si->ps.min_video_vco / p_max);
}
/* upper limit is given by pins in combination with current active mode */
if (req_pclk > max_pclk)
@ -336,7 +341,7 @@ static status_t nv10_nv20_dac2_pix_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_pclk * p;
@ -348,17 +353,19 @@ static status_t nv10_nv20_dac2_pix_pll_find(
if (si->ps.ext_pll) f_vco /= 4;
/* iterate trough all valid reference-frequency postscaler settings */
for (m = 7; m <= 14; m++)
for (m = m_min; 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.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;
} else {
if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) {
/* C51 chipset */
if (((si->ps.f_ref / m) < 1.7) || ((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.. */
@ -420,6 +427,9 @@ static status_t nv10_nv20_dac2_pix_pll_find(
case 16:
p = 0x04;
break;
case 32:
p = 0x05;
break;
}
*p_result = p;

View File

@ -92,7 +92,7 @@ status_t nv_general_powerup()
{
status_t status;
LOG(1,("POWERUP: Haiku nVidia Accelerant 1.12 running.\n"));
LOG(1,("POWERUP: Haiku nVidia Accelerant 1.16 running.\n"));
/* log VBLANK INT usability status */
if (si->ps.int_assigned)

View File

@ -3217,6 +3217,16 @@ static void pinsnv30_arch_fake(void)
/* not used (yet) because no coldstart will be attempted (yet) */
si->ps.std_engine_clock = 190;
si->ps.std_memory_clock = 190;
if ((CFGR(DEVID) & 0xfff0ffff) == 0x024010de) {
/* C51 chipset */
si->ps.max_system_vco = 1000;
si->ps.min_system_vco = 500;
si->ps.max_pixel_vco = 1000;
si->ps.min_pixel_vco = 500;
si->ps.max_video_vco = 1000;
si->ps.min_video_vco = 500;
}
}
static void getRAMsize_arch_nv4(void)

View File

@ -4,10 +4,11 @@
</head>
<body>
<p><h2>Changes done for each driverversion:</h2></p>
<p><h1>head (Haiku repository 1.12, Rudolf)</h1></p>
<p><h1>head (Haiku repository 1.16, Rudolf)</h1></p>
<ul>
<li>Fixed driver trouble on several Geforce 6000-6200 cards and maybe even more where the refreshrate was not properly calculated causing things like only displaying a part of the screen, a wobbly screen, no screen at all or just displaying at a too low rate. In cases where the GPU and/or RAM PLL is programmed on cards (depending on the nvidia.settings file) this might also solve random 'noise' or flickering across the entire screen(s). It turns out some newer supported cards outthere (notably Nforce 4 and 4xx types) use a new crystal frequency base (25 Mhz) for the GPU chip which was not yet detected by the driver.
<li>Fixed I2C buses not working and so screen DDC/EDID fetch failing on C51 chips specifically. This makes default startup resolution, screenprefs panel and widescreen modes available without nvidia.settings file tricks on a number of Geforce 6100(Go) and 6150(Go) graphics outthere. Now there should nolonger be cards without functioning (but implemented) I2C channels in this driver.
<li>Fixed PLL VCO, discriminator and postscaler limits for C51 chips specifically. This fixes (much more) wobbly- or black screens. C51 chips (Geforce 6100(Go) and 6150(Go)) should now work without any problems left.
</ul>
<p><h1>Nvidia driver 1.10 (Rudolf)</h1></p>
<ul>