diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-03-17 22:05:43 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-04-08 20:12:07 -0400 |
commit | f3bbb9ccbf2a0362363ce6d7e4e57dbf34a5cef1 (patch) | |
tree | 301098e335ac3d39574381e36124f7ab7a76baae /drivers | |
parent | a76fb4e8ffe42144529e21fe1e609b762e8eb5cc (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.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.h | 1 |
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; |