From patchwork Wed Jan 30 18:24:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Vivi X-Patchwork-Id: 2069381 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 7C1A43FD1A for ; Wed, 30 Jan 2013 18:37:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5D729E63CE for ; Wed, 30 Jan 2013 10:37:50 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-yh0-f41.google.com (mail-yh0-f41.google.com [209.85.213.41]) by gabe.freedesktop.org (Postfix) with ESMTP id 030D0E6218; Wed, 30 Jan 2013 10:30:29 -0800 (PST) Received: by mail-yh0-f41.google.com with SMTP id 47so313483yhr.28 for ; Wed, 30 Jan 2013 10:30:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=4GIf4FkMbrf0FsVLHCTOogzdqVUXMgHNP/DGR/XYJsA=; b=fTyIPvHccRccFB3x2xdBUEJq3aufw0yEeq9QxkCzjMFK1a/WL8E7FFOUQ/FR1NQBrJ fX4KlJbk8AhV7s3EMOcaV84S5Z1wau5BisFjcqZnbJi6z7jL8OQM+nKHXu4U89AKPok2 mEFOot7GPTEYZOcqB4bgYqT5+hoJj4b0ojsm7coKKxRCnYEVDA9lZWCgxeBhWijX9Bqn B+MTqZYMsjF4ieG00xy/pvChcDn4BMKEkwtAriJ85SjvyWxQoE+Xb11t1/rw6WAovurB 0l94EdRxNEA46DJRM1/43hbjvXX+ODtEVe/4MGBCf2fgXnT6CKKPQ/Sp3CQDZwkzBgpw uuGA== X-Received: by 10.236.152.40 with SMTP id c28mr6683754yhk.79.1359570629371; Wed, 30 Jan 2013 10:30:29 -0800 (PST) Received: from localhost.localdomain (200.188.217.18.dedicated.neoviatelecom.com.br. [200.188.217.18]) by mx.google.com with ESMTPS id c16sm1873528ann.15.2013.01.30.10.30.27 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 30 Jan 2013 10:30:28 -0800 (PST) From: Rodrigo Vivi To: intel-gfx@lists.freedesktop.org Date: Wed, 30 Jan 2013 16:24:47 -0200 Message-Id: <1359570291-2170-6-git-send-email-rodrigo.vivi@gmail.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1359570291-2170-1-git-send-email-rodrigo.vivi@gmail.com> References: <1359570291-2170-1-git-send-email-rodrigo.vivi@gmail.com> Cc: dri-devel@lists.freedesktop.org Subject: [Intel-gfx] [PATCH 5/9] drm/i915: Setup EDP PSR AUX Registers X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org From: Shobhit Kumar Signed-off-by: Shobhit Kumar v2: Created aux_clock_divider function to avoid duplicated code. Unfortunatelly dp_aux_ch and psr_aux_ch aren't so similar to reuse full code. Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_reg.h | 13 ++++++ drivers/gpu/drm/i915/intel_dp.c | 89 +++++++++++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_drv.h | 1 + 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7bb3134..10732dc 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1563,6 +1563,19 @@ #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B) +#define EDP_PSR_AUX_CTL 0x64810 +#define EDP_PSR_AUX_DATA1 0x64814 +#define EDP_PSR_AUX_DATA2 0x64818 +#define EDP_PSR_AUX_DATA3 0x6481c +#define EDP_PSR_AUX_DATA4 0x64820 +#define EDP_PSR_AUX_DATA5 0x64824 +#define EDP_PSR_STATUS_CTL 0x64840 +#define EDP_PSR_STATUS_MASK (7<<29) +#define EDP_PSR_PERF_CNT 0x64844 +#define EDP_PSR_DEBUG_CTL 0x64860 +#define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) +#define EDP_PSR_DEBUG_MASK_HPD (1<<25) + /* VGA port control */ #define ADPA 0x61100 #define PCH_ADPA 0xe1100 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index aeb0ef1..fe83e05 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -364,6 +364,34 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) return status; } +static uint32_t get_aux_clock_divider(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + /* The clock divider is based off the hrawclk, + * and would like to run at 2MHz. So, take the + * hrawclk value and divide by 2 and use that + * + * Note that PCH attached eDP panels should use a 125MHz input + * clock divider. + */ + if (is_cpu_edp(intel_dp)) { + if (HAS_DDI(dev)) + return intel_ddi_get_cdclk_freq(dev_priv) >> 1; + else if (IS_VALLEYVIEW(dev)) + return 100; + else if (IS_GEN6(dev) || IS_GEN7(dev)) + return 200; /* SNB & IVB eDP input clock at 400Mhz */ + else + return 225; /* eDP input clock at 450Mhz */ + } else if (HAS_PCH_SPLIT(dev)) + return DIV_ROUND_UP(intel_pch_rawclk(dev), 2); + else + return intel_hrawclk(dev) / 2; +} + static int intel_dp_aux_ch(struct intel_dp *intel_dp, uint8_t *send, int send_bytes, @@ -411,26 +439,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, } intel_dp_check_edp(intel_dp); - /* The clock divider is based off the hrawclk, - * and would like to run at 2MHz. So, take the - * hrawclk value and divide by 2 and use that - * - * Note that PCH attached eDP panels should use a 125MHz input - * clock divider. - */ - if (is_cpu_edp(intel_dp)) { - if (HAS_DDI(dev)) - aux_clock_divider = intel_ddi_get_cdclk_freq(dev_priv) >> 1; - else if (IS_VALLEYVIEW(dev)) - aux_clock_divider = 100; - else if (IS_GEN6(dev) || IS_GEN7(dev)) - aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ - else - aux_clock_divider = 225; /* eDP input clock at 450Mhz */ - } else if (HAS_PCH_SPLIT(dev)) - aux_clock_divider = DIV_ROUND_UP(intel_pch_rawclk(dev), 2); - else - aux_clock_divider = intel_hrawclk(dev) / 2; + aux_clock_divider = get_aux_clock_divider(intel_dp); if (IS_GEN6(dev)) precharge = 3; @@ -1440,6 +1449,46 @@ static bool is_edp_psr(struct intel_dp *intel_dp) return (is_edp(intel_dp) && (intel_dp->psr_dpcd[0] & 0x1)); } +static void intel_edp_psr_setup(struct intel_dp *intel_dp) +{ + struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t aux_clock_divider; + int precharge = 0x3; + int msg_size = 5; /* Header(4) + Message(1) */ + + /* No need to setup if already done as these setting are persistent + * until power states are entered */ + if (intel_dp->psr_setup) + return; + + /* Setup AUX registers */ + /* Write command on DPCD 0x0600 */ + I915_WRITE(EDP_PSR_AUX_DATA1, 0x80060000); + + /* Set the state to normal operation D0 in DPCD 0x0600 */ + I915_WRITE(EDP_PSR_AUX_DATA2, 0x01000000); + + aux_clock_divider = get_aux_clock_divider(intel_dp); + + I915_WRITE(EDP_PSR_AUX_CTL, + DP_AUX_CH_CTL_TIME_OUT_400us | + (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | + (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | + (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); + + /* Setup the debug register */ + I915_WRITE(EDP_PSR_DEBUG_CTL, I915_READ(EDP_PSR_DEBUG_CTL) | + EDP_PSR_DEBUG_MASK_MEMUP | + EDP_PSR_DEBUG_MASK_HPD); + + /* This flag can be made to 0 from pm code so as to reinitialize the + * AUX register in case of power states, returning from which will not + * maintain the AUX register settings + */ + intel_dp->psr_setup = 1; +} + static void intel_enable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d4b3bac..3fa2dd0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -383,6 +383,7 @@ struct intel_dp { int backlight_on_delay; int backlight_off_delay; struct delayed_work panel_vdd_work; + uint8_t psr_setup; bool want_panel_vdd; struct intel_connector *attached_connector; };