From ffd67465bf930d0cfb4833cdfc4ecc70b855faf0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 13 Dec 2010 00:25:26 -0500 Subject: [PATCH] drm/radeon/kms: don't mess with backlight if the gpu does not control it The on chip backlight control is not used by all OEMs. Check to see if the GPU controller is used (via firmware info table) and only touch the backlight if it uses the internal controller. Might fix: https://bugs.freedesktop.org/show_bug.cgi?id=32319 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_atombios.c | 13 ++++++++++++- drivers/gpu/drm/radeon/radeon_encoders.c | 11 +++++++---- drivers/gpu/drm/radeon/radeon_mode.h | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index a3b4d68..c587077 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1505,8 +1505,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct struct radeon_device *rdev = dev->dev_private; struct radeon_mode_info *mode_info = &rdev->mode_info; int index = GetIndexIntoMasterTable(DATA, LVDS_Info); - uint16_t data_offset, misc; + int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); + uint16_t data_offset, fw_data_offset, misc; union lvds_info *lvds_info; + union firmware_info *firmware_info; uint8_t frev, crev; struct radeon_encoder_atom_dig *lvds = NULL; int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; @@ -1521,6 +1523,15 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct if (!lvds) return NULL; + if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, + NULL, NULL, &fw_data_offset)) { + firmware_info = + (union firmware_info *)(mode_info->atom_context->bios + + fw_data_offset); + if (firmware_info->info.usFirmwareCapability.sbfAccess.GPUControlsBL) + lvds->gpu_controls_backlight = true; + } + lvds->native_mode.clock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; lvds->native_mode.hdisplay = diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 0f02b54..6d09102 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1230,6 +1230,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; int index = 0; bool is_dig = false; @@ -1317,7 +1318,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) && dig->gpu_controls_backlight) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); break; case DRM_MODE_DPMS_STANDBY: @@ -1339,7 +1340,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) radeon_dig_connector->edp_on = false; } } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) && dig->gpu_controls_backlight) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); break; } @@ -1370,7 +1371,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_ON: args.ucAction = ATOM_ENABLE; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + && dig->gpu_controls_backlight) { args.ucAction = ATOM_LCD_BLON; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } @@ -1380,7 +1382,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_OFF: args.ucAction = ATOM_DISABLE; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + && dig->gpu_controls_backlight) { args.ucAction = ATOM_LCD_BLOFF; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 12bdeab..15dee27 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -351,6 +351,7 @@ struct radeon_encoder_atom_dig { uint32_t lcd_misc; uint16_t panel_pwr_delay; uint32_t lcd_ss_id; + bool gpu_controls_backlight; /* panel mode */ struct drm_display_mode native_mode; }; -- 1.7.1.1