The eDP panel must be powered up for aux transactions, so power it
up for detect and mode probe functions, otherwise power it up or
down based on dpms.

Signed-off-by: Alex Deucher <alexdeuc...@gmail.com>
---
 drivers/gpu/drm/radeon/radeon_connectors.c |   13 +++++++++
 drivers/gpu/drm/radeon/radeon_encoders.c   |   41 ++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_mode.h       |    2 +
 3 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c 
b/drivers/gpu/drm/radeon/radeon_connectors.c
index fe6c747..76008a5 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1008,9 +1008,16 @@ static void radeon_dp_connector_destroy(struct 
drm_connector *connector)
 static int radeon_dp_get_modes(struct drm_connector *connector)
 {
        struct radeon_connector *radeon_connector = 
to_radeon_connector(connector);
+       struct radeon_connector_atom_dig *radeon_dig_connector = 
radeon_connector->con_priv;
        int ret;
 
+       if (!radeon_dig_connector->edp_on)
+               atombios_set_edp_panel_power(radeon_connector,
+                                            ATOM_TRANSMITTER_ACTION_POWER_ON);
        ret = radeon_ddc_get_modes(radeon_connector);
+       if (!radeon_dig_connector->edp_on)
+               atombios_set_edp_panel_power(radeon_connector,
+                                            ATOM_TRANSMITTER_ACTION_POWER_OFF);
        return ret;
 }
 
@@ -1029,8 +1036,14 @@ radeon_dp_detect(struct drm_connector *connector, bool 
force)
        if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
                /* eDP is always DP */
                radeon_dig_connector->dp_sink_type = 
CONNECTOR_OBJECT_ID_DISPLAYPORT;
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(radeon_connector,
+                                                    
ATOM_TRANSMITTER_ACTION_POWER_ON);
                if (radeon_dp_getdpcd(radeon_connector))
                        ret = connector_status_connected;
+               if (!radeon_dig_connector->edp_on)
+                       atombios_set_edp_panel_power(radeon_connector,
+                                                    
ATOM_TRANSMITTER_ACTION_POWER_OFF);
        } else {
                radeon_dig_connector->dp_sink_type = 
radeon_dp_getsinktype(radeon_connector);
                if (radeon_dig_connector->dp_sink_type == 
CONNECTOR_OBJECT_ID_DISPLAYPORT) {
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c 
b/drivers/gpu/drm/radeon/radeon_encoders.c
index d55cb58..701103c 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -978,6 +978,29 @@ atombios_dig_transmitter_setup(struct drm_encoder 
*encoder, int action, uint8_t
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t 
*)&args);
 }
 
+void
+atombios_set_edp_panel_power(struct radeon_connector *radeon_connector, int 
action)
+{
+       struct drm_device *dev = radeon_connector->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       union dig_transmitter_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
+       uint8_t frev, crev;
+
+       if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) ||
+           (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
+               return;
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 
&crev))
+               return;
+
+       memset(&args, 0, sizeof(args));
+
+       args.v1.ucAction = action;
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t 
*)&args);
+}
+
 static void
 atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
 {
@@ -1082,6 +1105,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, 
int mode)
                        if (atombios_get_encoder_mode(encoder) == 
ATOM_ENCODER_MODE_DP) {
                                struct drm_connector *connector = 
radeon_get_connector_for_encoder(encoder);
 
+                               if (radeon_encoder->devices & 
(ATOM_DEVICE_LCD_SUPPORT)) {
+                                       struct radeon_connector 
*radeon_connector = to_radeon_connector(connector);
+                                       struct radeon_connector_atom_dig 
*radeon_dig_connector =
+                                               radeon_connector->con_priv;
+                                       
atombios_set_edp_panel_power(radeon_connector,
+                                                                    
ATOM_TRANSMITTER_ACTION_POWER_ON);
+                                       radeon_dig_connector->edp_on = true;
+                               }
                                dp_link_train(encoder, connector);
                                if (ASIC_IS_DCE4(rdev))
                                        atombios_dig_encoder_setup(encoder, 
ATOM_ENCODER_CMD_DP_VIDEO_ON);
@@ -1096,6 +1127,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, 
int mode)
                        if (atombios_get_encoder_mode(encoder) == 
ATOM_ENCODER_MODE_DP) {
                                if (ASIC_IS_DCE4(rdev))
                                        atombios_dig_encoder_setup(encoder, 
ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+                               if (radeon_encoder->devices & 
(ATOM_DEVICE_LCD_SUPPORT)) {
+                                       struct drm_connector *connector =
+                                               
radeon_get_connector_for_encoder(encoder);
+                                       struct radeon_connector 
*radeon_connector = to_radeon_connector(connector);
+                                       struct radeon_connector_atom_dig 
*radeon_dig_connector =
+                                               radeon_connector->con_priv;
+                                       
atombios_set_edp_panel_power(radeon_connector,
+                                                                    
ATOM_TRANSMITTER_ACTION_POWER_OFF);
+                                       radeon_dig_connector->edp_on = false;
+                               }
                        }
                        if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
                                atombios_dig_transmitter_setup(encoder, 
ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h 
b/drivers/gpu/drm/radeon/radeon_mode.h
index 680f576..76c0778 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -385,6 +385,7 @@ struct radeon_connector_atom_dig {
        u8 dp_sink_type;
        int dp_clock;
        int dp_lane_count;
+       bool edp_on;
 };
 
 struct radeon_gpio_rec {
@@ -526,6 +527,7 @@ struct drm_encoder 
*radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, i
 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int 
action);
 extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
+extern void atombios_set_edp_panel_power(struct radeon_connector 
*radeon_connector, int action);
 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
-- 
1.7.1.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to