From patchwork Fri May 25 03:30:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dhinakaran Pandiyan X-Patchwork-Id: 10426009 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 20DD3601D5 for ; Fri, 25 May 2018 03:31:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0DD9129588 for ; Fri, 25 May 2018 03:31:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 000FA2958D; Fri, 25 May 2018 03:31:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F4A929588 for ; Fri, 25 May 2018 03:31:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8C2E76E139; Fri, 25 May 2018 03:31:02 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-qt0-x243.google.com (mail-qt0-x243.google.com [IPv6:2607:f8b0:400d:c0d::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 83E756E14F for ; Fri, 25 May 2018 03:31:00 +0000 (UTC) Received: by mail-qt0-x243.google.com with SMTP id h2-v6so4889640qtp.7 for ; Thu, 24 May 2018 20:31:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=MZuLQw5s0xephJmwcKiTw2fSMvKneSIwxIw0ybkOHOg=; b=EQbGaVGPuEoiMDSemEitD1SDCsDU1nclDj6M0wMTMb74hv+24mc5G2GkS6WE94amD7 65QLEyRpl+DUzH9Fwco1YM6FWvLjwM8be6X0p17TvjjKYg9aVzuEy/9+wLIJFAtjo/A+ mNefnfUC3b6GBtFeWNRXmsG4FKdiy31f2J7VcWZIfFjBbCHNMsAEc/y3nSuDbwbn27iU ELKeNFjUf8uAngvdp5BKKm2//lIAUpITpeYlKxqJ9Hb/Axt0dZQvmYQKzIR+T3kDzQ8y INuCiGB7Eu+/7FvsVGuass6FD0ooXURleN1ybUdGTdtWd8CfNUg2RtGDLSGhJOjq2rbn CmTw== X-Gm-Message-State: ALKqPwdFdYK5EOwcm7yalzxjgkbEgy68bTwsT2yDSWWXQeuzkSJAzjU/ EYa6ABMaf0H0miaYtJwYnDhJkA== X-Google-Smtp-Source: ADUXVKKtl+g2Ro/CsdiGTuL4H9QN7xPpBnRhHqNugHEe3fjE9OWy661zSIT4nWFtTg6XwFy0o209AQ== X-Received: by 2002:ac8:302a:: with SMTP id f39-v6mr575480qte.257.1527219059239; Thu, 24 May 2018 20:30:59 -0700 (PDT) Received: from dk-ThinkPad-X260.fios-router.home (50-39-164-98.bvtn.or.frontiernet.net. [50.39.164.98]) by smtp.gmail.com with ESMTPSA id s16-v6sm18032617qks.78.2018.05.24.20.30.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 May 2018 20:30:58 -0700 (PDT) From: Dhinakaran Pandiyan X-Google-Original-From: Dhinakaran Pandiyan To: intel-gfx@lists.freedesktop.org Date: Thu, 24 May 2018 20:30:47 -0700 Message-Id: <20180525033047.7596-1-dhinakaran.pandiyan@intel.com> X-Mailer: git-send-email 2.14.1 Subject: [Intel-gfx] [PATCH] drm/i915/psr: Set idle frame count based on sink synchronization latency X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jani Nikula , Dhinakaran Pandiyan , Rodrigo Vivi MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP DPCD 2009h "Synchronization latency in sink" has bits that tell us the maximum number of frames sink can take to resynchronize to source timing when exiting PSR. More importantly, as per eDP 1.4b, this is the "Minimum number of frames following PSR exit that the Source device needs to wait for PSR entry." We currently use this value only to setup the number frames to wait before PSR2 selective update. But, based on the above description it makes more sense to use this to configure idle frames for both PSR1 and and PSR2. This will ensure we wait the required number of frames before activation whether it is PSR1 or PSR2. The minimum number of idle frames remains 6, while allowing sink synchronization latency and VBT to increase this value. This also solves the flip-flop between sink and source frames that I noticed on my Thinkpad X260 during PSR exit. This specific panel has a value of 8h, which according to the spec means the "Source device must wait for more than eight active frames after PSR exit before initiating PSR entry. (In this case, should be provided by the panel supplier.)" VBT however has a value of 0. Cc: Jani Nikula Cc: Jose Roberto de Souza Cc: Rodrigo Vivi Signed-off-by: Dhinakaran Pandiyan Reviewed-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_psr.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index ebc483f06c6f..71dfe541740f 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -247,6 +247,8 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) return; } dev_priv->psr.sink_support = true; + dev_priv->psr.sink_sync_latency = + intel_dp_get_sink_sync_latency(intel_dp); if (INTEL_GEN(dev_priv) >= 9 && (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) { @@ -272,8 +274,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) if (dev_priv->psr.sink_psr2_support) { dev_priv->psr.colorimetry_support = intel_dp_get_colorimetry_status(intel_dp); - dev_priv->psr.sink_sync_latency = - intel_dp_get_sink_sync_latency(intel_dp); } } } @@ -370,21 +370,21 @@ static void hsw_activate_psr1(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 = to_i915(dev); + u32 max_sleep_time = 0x1f; + u32 val = EDP_PSR_ENABLE; - uint32_t max_sleep_time = 0x1f; - /* - * Let's respect VBT in case VBT asks a higher idle_frame value. - * Let's use 6 as the minimum to cover all known cases including - * the off-by-one issue that HW has in some cases. Also there are - * cases where sink should be able to train - * with the 5 or 6 idle patterns. + /* Let's use 6 as the minimum to cover all known cases including the + * off-by-one issue that HW has in some cases. */ - uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - uint32_t val = EDP_PSR_ENABLE; + int idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT; + /* sink_sync_latency of 8 means source has to wait for more than 8 + * frames, we'll go with 9 frames for now + */ + idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT; + val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT; if (IS_HASWELL(dev_priv)) val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; @@ -424,15 +424,15 @@ static void hsw_activate_psr2(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 = to_i915(dev); - /* - * Let's respect VBT in case VBT asks a higher idle_frame value. - * Let's use 6 as the minimum to cover all known cases including - * the off-by-one issue that HW has in some cases. Also there are - * cases where sink should be able to train - * with the 5 or 6 idle patterns. + u32 val; + + /* Let's use 6 as the minimum to cover all known cases including the + * off-by-one issue that HW has in some cases. */ - uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - u32 val = idle_frames << EDP_PSR2_IDLE_FRAME_SHIFT; + int idle_frames = max(6, dev_priv->vbt.psr.idle_frames); + + idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); + val = idle_frames << EDP_PSR2_IDLE_FRAME_SHIFT; /* FIXME: selective update is probably totally broken because it doesn't * mesh at all with our frontbuffer tracking. And the hw alone isn't