summaryrefslogtreecommitdiff
path: root/src/nv_bios.c
diff options
context:
space:
mode:
authorStuart Bennett <sb476@cam.ac.uk>2008-04-07 23:20:12 +0100
committerStuart Bennett <stuart@freedesktop.org>2009-04-29 18:59:32 +0100
commit2915926702b7ae9ccb1e900c07ca14a2f32e4512 (patch)
tree4041f01d02a52d8d1f3da8ddbc168b7702e3983b /src/nv_bios.c
parent47bb00fee8b9906adc03b372efa1ae813bc9ca9a (diff)
plls: max_log2p_bias is likely actually max_log2p
As explained in nouveau_bios.h, a separate max_usable_log2p is needed (lack of change from 6 to 7 tested by setting a stable small mode, say 400x300, then manually tweaking the multiplier up and post divider down). The max_usable_log2p values hardcoded here are unchanged from those previously taken from the bios pll calculation code For reference, the blob will quite happily attempt to set clocks using the raw parsed max_log2p values (and go up to 7 therefore) when setting modes around 200x200 (3MHz pxclk), but at such a low clock my monitor won't agree to give a sensible picture anyway. Reg dumped data using "nvidia" below: nv40: log2P up to 7 (dual pll mode), at very low clocks driver gives up and sets 0x0006ff0d 0x80001f04 nv43: log2P up to 7 (dual pll mode), at very low clocks driver gives up and sets 0x0006ff0d 0x80001f04 nv11: single pll, therefore goes quite happily down to at least 0.25MHz nv31: log2P up to 7 (dual pll mode), at very low clocks card locks up nv34: log2P up to 5 (single pll), goes down to at least 2.25MHz nv4b: log2P up to 6 (single pll mode), at very low clocks driver gives up and sets 0x0006ff0d 0x80001f04
Diffstat (limited to 'src/nv_bios.c')
-rw-r--r--src/nv_bios.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/nv_bios.c b/src/nv_bios.c
index ebf4027..fb6dfe2 100644
--- a/src/nv_bios.c
+++ b/src/nv_bios.c
@@ -3183,6 +3183,8 @@ int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll
pll_lim->vco2.max_n = 0x1f;
pll_lim->vco2.min_m = 0x1;
pll_lim->vco2.max_m = 0x4;
+ pll_lim->max_log2p = 0x7;
+ pll_lim->max_usable_log2p = 0x6;
} else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
uint32_t reg = 0; /* default match */
@@ -3249,7 +3251,13 @@ int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll
pll_lim->vco2.min_m = pll_rec[26];
pll_lim->vco2.max_m = pll_rec[27];
- pll_lim->max_log2p_bias = pll_rec[29];
+ pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29];
+ if (pll_lim->max_log2p > 0x7)
+ /* pll decoding in nv_hw.c assumes never > 7 */
+ NV_WARN(pScrn, "Max log2 P value greater than 7 (%d)\n",
+ pll_lim->max_log2p);
+ if (cv < 0x60)
+ pll_lim->max_usable_log2p = 0x6;
pll_lim->log2p_bias = pll_rec[30];
if (recordlen > 0x22)
@@ -3309,7 +3317,7 @@ int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll
pll_lim->vco2.max_n = record[21];
pll_lim->vco2.min_m = record[22];
pll_lim->vco2.max_m = record[23];
- pll_lim->max_log2p_bias = record[25];
+ pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25];
pll_lim->log2p_bias = record[27];
pll_lim->refclk = ROM32(record[28]);
}
@@ -3336,6 +3344,11 @@ int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll
pll_lim->vco1.min_m = 0x8;
pll_lim->vco1.max_m = 0xe;
}
+ if (cv < 0x17 || cv == 0x1a || cv == 0x20)
+ pll_lim->max_log2p = 4;
+ else
+ pll_lim->max_log2p = 5;
+ pll_lim->max_usable_log2p = pll_lim->max_log2p;
}
if (!pll_lim->refclk)
@@ -3374,7 +3387,7 @@ int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll
ErrorF("pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
ErrorF("pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
- ErrorF("pll.max_log2p_bias: %d\n", pll_lim->max_log2p_bias);
+ ErrorF("pll.max_log2p: %d\n", pll_lim->max_log2p);
ErrorF("pll.log2p_bias: %d\n", pll_lim->log2p_bias);
ErrorF("pll.refclk: %d\n", pll_lim->refclk);