diff options
author | Stuart Bennett <sb476@cam.ac.uk> | 2008-04-07 23:20:12 +0100 |
---|---|---|
committer | Stuart Bennett <stuart@freedesktop.org> | 2009-04-29 18:59:32 +0100 |
commit | 2915926702b7ae9ccb1e900c07ca14a2f32e4512 (patch) | |
tree | 4041f01d02a52d8d1f3da8ddbc168b7702e3983b /src/nv_bios.c | |
parent | 47bb00fee8b9906adc03b372efa1ae813bc9ca9a (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.c | 19 |
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); |