From patchwork Thu Apr 3 11:10:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: vandana.kannan@intel.com X-Patchwork-Id: 3932391 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 843379F38C for ; Thu, 3 Apr 2014 10:59:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 97F7D20225 for ; Thu, 3 Apr 2014 10:59:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 676AA2018E for ; Thu, 3 Apr 2014 10:59:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D514A6E8F4; Thu, 3 Apr 2014 03:59:16 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 6187A6E8F4 for ; Thu, 3 Apr 2014 03:59:15 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 03 Apr 2014 03:54:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,786,1389772800"; d="scan'208";a="514015093" Received: from vkannan-desktop.iind.intel.com ([10.223.25.35]) by orsmga002.jf.intel.com with ESMTP; 03 Apr 2014 03:58:21 -0700 From: Vandana Kannan To: intel-gfx@lists.freedesktop.org Date: Thu, 3 Apr 2014 16:40:23 +0530 Message-Id: <1396523423-19389-1-git-send-email-vandana.kannan@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <87k3b9chpm.fsf@intel.com> References: <87k3b9chpm.fsf@intel.com> Subject: [Intel-gfx] [PATCH v8 2/6] drm/i915: Parse EDID probed modes for DRRS support X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 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=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY, URIBL_JP_SURBL, URIBL_WS_SURBL autolearn=no 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 From: Pradeep Bhat This patch and finds out the lowest refresh rate supported for the resolution same as the fixed_mode. It also checks the VBT fields to see if panel supports seamless DRRS or not. Based on above data it marks whether eDP panel supports seamless DRRS or not. This information is needed for supporting seamless DRRS switch for certain power saving usecases. This patch is tested by enabling the DRM logs and user should see whether Seamless DRRS is supported or not. v2: Daniel's review comments Modified downclock deduction based on intel_find_panel_downclock v3: Chris's review comments Moved edp_downclock_avail and edp_downclock to intel_panel v4: Jani's review comments. Changed name of the enum edp_panel_type to drrs_support type. Change is_drrs_supported to drrs_support of type enum drrs_support_type. v5: Incorporated Jani's review comments Modify intel_dp_drrs_initialize to return downclock mode. Support for Gen7 and above. v6: Incorporated Chris's review comments. Changed initialize to init in intel_drrs_initialize v7: Incorporated Jani's review comments. Removed edp_downclock and edp_downclock_avail. Return NULL explicitly. Make drrs_state and unnamed struct. Move Gen based check inside drrs_init. v8: Made changes to track PSR enable/disable throughout system use (instead of just in the init sequence) for disabling/enabling DRRS. Jani's review comments. Signed-off-by: Pradeep Bhat Signed-off-by: Vandana Kannan Cc: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 5 ++++ drivers/gpu/drm/i915/intel_dp.c | 55 +++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_drv.h | 16 ++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cd73a33..b6ea225 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -794,6 +794,10 @@ struct i915_fbc { } no_fbc_reason; }; +struct i915_drrs { + bool is_psr_enabled; +}; + struct i915_psr { bool sink_support; bool source_ok; @@ -1497,6 +1501,7 @@ typedef struct drm_i915_private { struct timer_list hotplug_reenable_timer; struct i915_fbc fbc; + struct i915_drrs drrs; struct intel_opregion opregion; struct intel_vbt_data vbt; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 59ee4dc..ce588d1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1697,6 +1697,7 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) static void intel_edp_psr_do_enable(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct drm_i915_private *dev_priv = dev->dev_private; if (!intel_edp_psr_match_conditions(intel_dp) || intel_edp_is_psr_enabled(dev)) @@ -1710,6 +1711,11 @@ static void intel_edp_psr_do_enable(struct intel_dp *intel_dp) /* Enable PSR on the host */ intel_edp_psr_enable_source(intel_dp); + + if (INTEL_INFO(dev)->gen < 8) { + dev_priv->drrs.is_psr_enabled = true; + DRM_DEBUG_KMS("eDP panel PSR enabled. Can't support DRRS\n"); + } } void intel_edp_psr_enable(struct intel_dp *intel_dp) @@ -1736,6 +1742,9 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp) if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) & EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) DRM_ERROR("Timed out waiting for PSR Idle State\n"); + + if (INTEL_INFO(dev)->gen < 8) + dev_priv->drrs.is_psr_enabled = false; } void intel_edp_psr_update(struct drm_device *dev) @@ -3611,6 +3620,44 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, I915_READ(pp_div_reg)); } +static struct drm_display_mode * +intel_dp_drrs_init(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector, + struct drm_display_mode *fixed_mode) +{ + struct drm_connector *connector = &intel_connector->base; + struct intel_dp *intel_dp = &intel_dig_port->dp; + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_display_mode *downclock_mode = NULL; + + if (INTEL_INFO(dev)->gen <= 6) { + DRM_DEBUG_KMS("DRRS supported for Gen7 and above\n"); + return NULL; + } + + if (INTEL_INFO(dev)->gen < 8 && intel_edp_is_psr_enabled(dev)) + dev_priv->drrs.is_psr_enabled = true; + + if (dev_priv->vbt.drrs_type == DRRS_NOT_SUPPORTED) { + DRM_INFO("VBT doesn't support DRRS\n"); + return NULL; + } + + downclock_mode = intel_find_panel_downclock + (dev, fixed_mode, connector); + + if (downclock_mode != NULL && + dev_priv->vbt.drrs_type == SEAMLESS_DRRS_SUPPORT) { + intel_dp->drrs_state.type = dev_priv->vbt.drrs_type; + + intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR; + DRM_INFO("seamless DRRS supported for eDP panel.\n"); + } + + return downclock_mode; +} + static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct intel_connector *intel_connector, struct edp_power_seq *power_seq) @@ -3620,10 +3667,13 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *fixed_mode = NULL; + struct drm_display_mode *downclock_mode = NULL; bool has_dpcd; struct drm_display_mode *scan; struct edid *edid; + intel_dp->drrs_state.type = DRRS_NOT_SUPPORTED; + if (!is_edp(intel_dp)) return true; @@ -3665,6 +3715,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, list_for_each_entry(scan, &connector->probed_modes, head) { if ((scan->type & DRM_MODE_TYPE_PREFERRED)) { fixed_mode = drm_mode_duplicate(dev, scan); + downclock_mode = intel_dp_drrs_init( + intel_dig_port, + intel_connector, fixed_mode); break; } } @@ -3677,7 +3730,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; } - intel_panel_init(&intel_connector->panel, fixed_mode, NULL); + intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); intel_panel_setup_backlight(connector); return true; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index fa99104..d781165 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -483,6 +483,17 @@ struct intel_hdmi { #define DP_MAX_DOWNSTREAM_PORTS 0x10 +/** + * HIGH_RR is the highest eDP panel refresh rate read from EDID + * LOW_RR is the lowest eDP panel refresh rate found from EDID + * parsing for same resolution. + */ +enum edp_drrs_refresh_rate_type { + DRRS_HIGH_RR, + DRRS_LOW_RR, + DRRS_MAX_RR, /* RR count */ +}; + struct intel_dp { uint32_t output_reg; uint32_t aux_ch_ctl_reg; @@ -521,6 +532,11 @@ struct intel_dp { bool has_aux_irq, int send_bytes, uint32_t aux_clock_divider); + struct { + enum drrs_support_type type; + enum edp_drrs_refresh_rate_type refresh_rate_type; + } drrs_state; + }; struct intel_digital_port {