aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-03-17 22:05:43 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-04-08 20:12:07 -0400
commitf3bbb9ccbf2a0362363ce6d7e4e57dbf34a5cef1 (patch)
tree301098e335ac3d39574381e36124f7ab7a76baae /drivers
parenta76fb4e8ffe42144529e21fe1e609b762e8eb5cc (diff)
drm/nv40: rework lvds table parsing
All indications seem to be that the version 0x30 table should be handled the same way as 0x40 (as used on G80), at least for the parts that we currently try use. This commit cleans up the parsing to make it clearer about what we're actually trying to achieve, and unifies the 0x30/0x40 parsing. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c44
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h1
2 files changed, 17 insertions, 28 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index b5a9336a2e88..075eb894648f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -3198,7 +3198,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
3198 struct nvbios *bios = &dev_priv->vbios; 3198 struct nvbios *bios = &dev_priv->vbios;
3199 unsigned int outputset = (dcbent->or == 4) ? 1 : 0; 3199 unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
3200 uint16_t scriptptr = 0, clktable; 3200 uint16_t scriptptr = 0, clktable;
3201 uint8_t clktableptr = 0;
3202 3201
3203 /* 3202 /*
3204 * For now we assume version 3.0 table - g80 support will need some 3203 * For now we assume version 3.0 table - g80 support will need some
@@ -3217,26 +3216,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
3217 scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]); 3216 scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
3218 break; 3217 break;
3219 case LVDS_RESET: 3218 case LVDS_RESET:
3219 clktable = bios->fp.lvdsmanufacturerpointer + 15;
3220 if (dcbent->or == 4)
3221 clktable += 8;
3222
3220 if (dcbent->lvdsconf.use_straps_for_mode) { 3223 if (dcbent->lvdsconf.use_straps_for_mode) {
3221 if (bios->fp.dual_link) 3224 if (bios->fp.dual_link)
3222 clktableptr += 2; 3225 clktable += 4;
3223 if (bios->fp.BITbit1) 3226 if (bios->fp.if_is_24bit)
3224 clktableptr++; 3227 clktable += 2;
3225 } else { 3228 } else {
3226 /* using EDID */ 3229 /* using EDID */
3227 uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; 3230 int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;
3228 int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
3229 3231
3230 if (bios->fp.dual_link) { 3232 if (bios->fp.dual_link) {
3231 clktableptr += 2; 3233 clktable += 4;
3232 fallbackcmpval *= 2; 3234 cmpval_24bit <<= 1;
3233 } 3235 }
3234 if (fallbackcmpval & fallback) 3236
3235 clktableptr++; 3237 if (bios->fp.strapless_is_24bit & cmpval_24bit)
3238 clktable += 2;
3236 } 3239 }
3237 3240
3238 /* adding outputset * 8 may not be correct */ 3241 clktable = ROM16(bios->data[clktable]);
3239 clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
3240 if (!clktable) { 3242 if (!clktable) {
3241 NV_ERROR(dev, "Pixel clock comparison table not found\n"); 3243 NV_ERROR(dev, "Pixel clock comparison table not found\n");
3242 return -ENOENT; 3244 return -ENOENT;
@@ -3638,31 +3640,19 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
3638 *if_is_24bit = bios->data[lvdsofs] & 16; 3640 *if_is_24bit = bios->data[lvdsofs] & 16;
3639 break; 3641 break;
3640 case 0x30: 3642 case 0x30:
3641 /* 3643 case 0x40:
3642 * My money would be on there being a 24 bit interface bit in
3643 * this table, but I have no example of a laptop bios with a
3644 * 24 bit panel to confirm that. Hence we shout loudly if any
3645 * bit other than bit 0 is set (I've not even seen bit 1)
3646 */
3647 if (bios->data[lvdsofs] > 1)
3648 NV_ERROR(dev,
3649 "You have a very unusual laptop display; please report it\n");
3650 /* 3644 /*
3651 * No sign of the "power off for reset" or "reset for panel 3645 * No sign of the "power off for reset" or "reset for panel
3652 * on" bits, but it's safer to assume we should 3646 * on" bits, but it's safer to assume we should
3653 */ 3647 */
3654 bios->fp.power_off_for_reset = true; 3648 bios->fp.power_off_for_reset = true;
3655 bios->fp.reset_after_pclk_change = true; 3649 bios->fp.reset_after_pclk_change = true;
3650
3656 /* 3651 /*
3657 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is 3652 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
3658 * over-written, and BITbit1 isn't used 3653 * over-written, and if_is_24bit isn't used
3659 */ 3654 */
3660 bios->fp.dual_link = bios->data[lvdsofs] & 1; 3655 bios->fp.dual_link = bios->data[lvdsofs] & 1;
3661 bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
3662 bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
3663 break;
3664 case 0x40:
3665 bios->fp.dual_link = bios->data[lvdsofs] & 1;
3666 bios->fp.if_is_24bit = bios->data[lvdsofs] & 2; 3656 bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
3667 bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; 3657 bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
3668 bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; 3658 bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 4f88e6924d27..fd6274a90148 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -267,7 +267,6 @@ struct nvbios {
267 bool reset_after_pclk_change; 267 bool reset_after_pclk_change;
268 bool dual_link; 268 bool dual_link;
269 bool link_c_increment; 269 bool link_c_increment;
270 bool BITbit1;
271 bool if_is_24bit; 270 bool if_is_24bit;
272 int duallink_transition_clk; 271 int duallink_transition_clk;
273 uint8_t strapless_is_24bit; 272 uint8_t strapless_is_24bit;