diff options
| author | Michel Dänzer <daenzer@vmware.com> | 2009-09-15 11:09:27 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@linux.ie> | 2009-09-16 02:10:19 -0400 |
| commit | 8dfaa8a7779ad2667d539aca6ae11cd87f562db6 (patch) | |
| tree | e7decd381bde41c6322b867c75482f9898ecdbfa | |
| parent | f657c2a7310ad56e2b67f35f4c5c6106a7146b9c (diff) | |
drm/radeon/kms: Get LVDS native mode details from EDID if necessary.
Fixes RMX problems on older Apple laptops which don't have an x86 BIOS ROM.
Signed-off-by: Michel Dänzer <daenzer@vmware.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_combios.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 34 |
2 files changed, 41 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 2a027e00762a..cb60f5532334 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -863,8 +863,10 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
| 863 | int tmp, i; | 863 | int tmp, i; |
| 864 | struct radeon_encoder_lvds *lvds = NULL; | 864 | struct radeon_encoder_lvds *lvds = NULL; |
| 865 | 865 | ||
| 866 | if (rdev->bios == NULL) | 866 | if (rdev->bios == NULL) { |
| 867 | return radeon_legacy_get_lvds_info_from_regs(rdev); | 867 | lvds = radeon_legacy_get_lvds_info_from_regs(rdev); |
| 868 | goto out; | ||
| 869 | } | ||
| 868 | 870 | ||
| 869 | lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); | 871 | lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); |
| 870 | 872 | ||
| @@ -965,11 +967,13 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
| 965 | lvds->native_mode.flags = 0; | 967 | lvds->native_mode.flags = 0; |
| 966 | } | 968 | } |
| 967 | } | 969 | } |
| 968 | encoder->native_mode = lvds->native_mode; | ||
| 969 | } else { | 970 | } else { |
| 970 | DRM_INFO("No panel info found in BIOS\n"); | 971 | DRM_INFO("No panel info found in BIOS\n"); |
| 971 | return radeon_legacy_get_lvds_info_from_regs(rdev); | 972 | lvds = radeon_legacy_get_lvds_info_from_regs(rdev); |
| 972 | } | 973 | } |
| 974 | out: | ||
| 975 | if (lvds) | ||
| 976 | encoder->native_mode = lvds->native_mode; | ||
| 973 | return lvds; | 977 | return lvds; |
| 974 | } | 978 | } |
| 975 | 979 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index d2842da8c8b0..5ee81b6a8799 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -227,6 +227,36 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
| 227 | return 0; | 227 | return 0; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | ||
| 231 | struct drm_connector *connector) | ||
| 232 | { | ||
| 233 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 234 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | ||
| 235 | |||
| 236 | /* Try to get native mode details from EDID if necessary */ | ||
| 237 | if (!native_mode->dotclock) { | ||
| 238 | struct drm_display_mode *t, *mode; | ||
| 239 | |||
| 240 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { | ||
| 241 | if (mode->hdisplay == native_mode->panel_xres && | ||
| 242 | mode->vdisplay == native_mode->panel_yres) { | ||
| 243 | native_mode->hblank = mode->htotal - mode->hdisplay; | ||
| 244 | native_mode->hoverplus = mode->hsync_start - mode->hdisplay; | ||
| 245 | native_mode->hsync_width = mode->hsync_end - mode->hsync_start; | ||
| 246 | native_mode->vblank = mode->vtotal - mode->vdisplay; | ||
| 247 | native_mode->voverplus = mode->vsync_start - mode->vdisplay; | ||
| 248 | native_mode->vsync_width = mode->vsync_end - mode->vsync_start; | ||
| 249 | native_mode->dotclock = mode->clock; | ||
| 250 | DRM_INFO("Determined LVDS native mode details from EDID\n"); | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | } | ||
| 255 | if (!native_mode->dotclock) { | ||
| 256 | DRM_INFO("No LVDS native mode details, disabling RMX\n"); | ||
| 257 | radeon_encoder->rmx_type = RMX_OFF; | ||
| 258 | } | ||
| 259 | } | ||
| 230 | 260 | ||
| 231 | static int radeon_lvds_get_modes(struct drm_connector *connector) | 261 | static int radeon_lvds_get_modes(struct drm_connector *connector) |
| 232 | { | 262 | { |
| @@ -239,9 +269,11 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) | |||
| 239 | ret = radeon_ddc_get_modes(radeon_connector); | 269 | ret = radeon_ddc_get_modes(radeon_connector); |
| 240 | if (ret > 0) { | 270 | if (ret > 0) { |
| 241 | encoder = radeon_best_single_encoder(connector); | 271 | encoder = radeon_best_single_encoder(connector); |
| 242 | if (encoder) | 272 | if (encoder) { |
| 273 | radeon_fixup_lvds_native_mode(encoder, connector); | ||
| 243 | /* add scaled modes */ | 274 | /* add scaled modes */ |
| 244 | radeon_add_common_modes(encoder, connector); | 275 | radeon_add_common_modes(encoder, connector); |
| 276 | } | ||
| 245 | return ret; | 277 | return ret; |
| 246 | } | 278 | } |
| 247 | } | 279 | } |
