From patchwork Tue Mar 31 05:58:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: sonika.jindal@intel.com X-Patchwork-Id: 6127561 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5F0E89F2EC for ; Tue, 31 Mar 2015 06:06:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4ECB6201BC for ; Tue, 31 Mar 2015 06:06:56 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 3318E20172 for ; Tue, 31 Mar 2015 06:06:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 16B696E66B; Mon, 30 Mar 2015 23:06:54 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTP id 522586E66B for ; Mon, 30 Mar 2015 23:06:52 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 30 Mar 2015 23:06:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,499,1422950400"; d="scan'208";a="548748971" Received: from sonikaji-desktop.iind.intel.com ([10.223.25.81]) by orsmga003.jf.intel.com with ESMTP; 30 Mar 2015 23:06:50 -0700 From: Sonika Jindal To: intel-gfx@lists.freedesktop.org Date: Tue, 31 Mar 2015 11:28:33 +0530 Message-Id: <1427781513-7810-1-git-send-email-sonika.jindal@intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <551934B4.5060700@intel.com> References: <551934B4.5060700@intel.com> Cc: Rodrigo Vivi Subject: [Intel-gfx] [PATCH] drm/i915/skl: Enabling PSR2 SU with frame sync X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We make use of HW tracking for Selective update region and enable frame sync on sink. We use hardware's hardcoded data values for frame sync and GTC. v2: Add 3200x2000 resolution restriction with PSR2, move psr2_support to i915_psr struct, add aux_frame_sync to independently control aux frame sync, rename the TP2 TIME macro for 2500us (Rodrigo, Siva) v3: Moving the resolution restriction to intel_psr_enable so that we check it only once(Durga) Cc: Durgadoss R Cc: Rodrigo Vivi Signed-off-by: Sonika Jindal Reviewed-by: Durgadoss R Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com) --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 14 ++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 15 +++++++++++++++ drivers/gpu/drm/i915/intel_psr.c | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eb38cd1..65d3dae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -879,6 +879,8 @@ struct i915_psr { struct delayed_work work; unsigned busy_frontbuffer_bits; bool link_standby; + bool psr2_support; + bool aux_frame_sync; }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5b84ee6..0b42ef3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2745,6 +2745,20 @@ enum skl_disp_power_wells { #define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) #define EDP_PSR_DEBUG_MASK_HPD (1<<25) +#define EDP_PSR2_CTL 0x6f900 +#define EDP_PSR2_ENABLE (1<<31) +#define EDP_SU_TRACK_ENABLE (1<<30) +#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20) +#define EDP_PSR2_TP2_TIME_500 (0<<8) +#define EDP_PSR2_TP2_TIME_100 (1<<8) +#define EDP_PSR2_TP2_TIME_2500 (2<<8) +#define EDP_PSR2_TP2_TIME_50 (3<<8) +#define EDP_PSR2_TP2_TIME_MASK (3<<8) +#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 +#define EDP_PSR2_FRAME_BEFORE_SU_MASK (0xf<<4) +#define EDP_PSR2_IDLE_MASK 0xf + /* 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 3967af1..b0ae45e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3786,6 +3786,21 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) dev_priv->psr.sink_support = true; DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); } + + if (INTEL_INFO(dev)->gen >= 9 && + (intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) { + uint8_t frame_sync_cap; + + dev_priv->psr.sink_support = true; + intel_dp_dpcd_read_wake(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP, + &frame_sync_cap, 1); + dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : false; + /* PSR2 needs frame sync as well */ + dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync; + DRM_DEBUG_KMS("PSR2 %s on sink", + dev_priv->psr.psr2_support ? "supported" : "not supported"); + } } /* Training Pattern 3 support, both source and sink */ diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b9f40c2..8d9ae0b 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -117,6 +117,19 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp) I915_WRITE(VLV_VSCSDP(pipe), val); } +static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp) +{ + struct edp_vsc_psr psr_vsc; + + /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x3; + psr_vsc.sdp_header.HB3 = 0xb; + intel_psr_write_vsc(intel_dp, &psr_vsc); +} + static void hsw_psr_setup_vsc(struct intel_dp *intel_dp) { struct edp_vsc_psr psr_vsc; @@ -165,6 +178,12 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE); + /* Enable AUX frame sync at sink */ + if (dev_priv->psr.aux_frame_sync) + drm_dp_dpcd_writeb(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF, + DP_AUX_FRAME_SYNC_ENABLE); + aux_data_reg = (INTEL_INFO(dev)->gen >= 9) ? DPA_AUX_CH_DATA1 : EDP_PSR_AUX_DATA1(dev); aux_ctl_reg = (INTEL_INFO(dev)->gen >= 9) ? @@ -183,8 +202,10 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) val |= DP_AUX_CH_CTL_TIME_OUT_1600us; val &= ~DP_AUX_CH_CTL_MESSAGE_SIZE_MASK; val |= (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); - /* Use hardcoded data values for PSR */ + /* Use hardcoded data values for PSR, frame sync and GTC */ val &= ~DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL; + val &= ~DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL; + val &= ~DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL; I915_WRITE(aux_ctl_reg, val); } else { I915_WRITE(aux_ctl_reg, @@ -232,6 +253,7 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t max_sleep_time = 0x1f; /* Lately it was identified that depending on panel idle frame count * calculated at HW can be off by 1. So let's use what came @@ -255,6 +277,10 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | EDP_PSR_ENABLE); + + if (dev_priv->psr.psr2_support) + I915_WRITE(EDP_PSR2_CTL, EDP_PSR2_ENABLE | + EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100); } static bool intel_psr_match_conditions(struct intel_dp *intel_dp) @@ -332,6 +358,7 @@ void intel_psr_enable(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; + struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc); if (!HAS_PSR(dev)) { DRM_DEBUG_KMS("PSR not supported on this platform\n"); @@ -364,6 +391,15 @@ void intel_psr_enable(struct intel_dp *intel_dp) if (HAS_DDI(dev)) { hsw_psr_setup_vsc(intel_dp); + if (dev_priv->psr.psr2_support) { + /* PSR2 is restricted to work with panel resolutions upto 3200x2000 */ + if (crtc->config->pipe_src_w > 3200 || + crtc->config->pipe_src_h > 2000) + dev_priv->psr.psr2_support = false; + else + skl_psr_setup_su_vsc(intel_dp); + } + /* Avoid continuous PSR exit by masking memup and hpd */ I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);