From patchwork Tue Nov 16 17:09:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 328762 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAGHAqN1003172 for ; Tue, 16 Nov 2010 17:11:13 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CD7C0A0CB2 for ; Tue, 16 Nov 2010 09:10:52 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qw0-f49.google.com (mail-qw0-f49.google.com [209.85.216.49]) by gabe.freedesktop.org (Postfix) with ESMTP id E56D1A0C81 for ; Tue, 16 Nov 2010 09:10:00 -0800 (PST) Received: by mail-qw0-f49.google.com with SMTP id 5so201510qwh.36 for ; Tue, 16 Nov 2010 09:10:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=k5yGWViqHfWck0hMgqXj9rE6daFdYhsAEBzzKPEt7Pc=; b=bajSUIxpJJaCohlgdYfpdoXcy1laWaSTvn6b09s9JCqpOEkQetQRvH8TYXshShtbtb /STge7ggVMD7LqtshVPSXZe3ZVsLSI5W5ozbLVLw3H9GYqYt9E8/IpL8eup/pXJ6WuOo M8PkQV6UFbMo92N2W5lGLyL8wh9Gwt1BOYy60= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=FeUj6+P+kYyJsgQ94HslPKm85i2WNfL/6TQaykjV9LtpGXZW66Fcw6pEQ+F3d3khxH kvSwTHmVsVqCqx9+OpMS+jsIJiL3GHfFNGn5u58O/B8kh+F5OSnu59W2izVKNZIdnosq BjzG2xTyHtO3BlZeLQcUYVDJq5RyvOI0Y1Dt4= Received: by 10.229.87.13 with SMTP id u13mr6430214qcl.202.1289927400437; Tue, 16 Nov 2010 09:10:00 -0800 (PST) Received: from localhost.localdomain (static-74-96-105-7.washdc.fios.verizon.net [74.96.105.7]) by mx.google.com with ESMTPS id t35sm873542qco.42.2010.11.16.09.09.59 (version=SSLv3 cipher=RC4-MD5); Tue, 16 Nov 2010 09:09:59 -0800 (PST) From: Alex Deucher To: airlied@gmail.com, dri-devel@lists.freedesktop.org Subject: [PATCH 2/4] drm/radeon/kms: properly power up/down the eDP panel as needed Date: Tue, 16 Nov 2010 12:09:40 -0500 Message-Id: <1289927382-30882-2-git-send-email-alexdeucher@gmail.com> X-Mailer: git-send-email 1.7.1.1 In-Reply-To: <1289927382-30882-1-git-send-email-alexdeucher@gmail.com> References: <1289927382-30882-1-git-send-email-alexdeucher@gmail.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 16 Nov 2010 17:11:13 +0000 (UTC) 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);