From patchwork Tue Nov 19 06:07:00 2013 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: 3200151 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A6967C045B for ; Tue, 19 Nov 2013 06:00:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 81FF920347 for ; Tue, 19 Nov 2013 06:00:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 36B3A202F7 for ; Tue, 19 Nov 2013 06:00:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2A6DFFD48A; Mon, 18 Nov 2013 22:00:35 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id DDF82FD48A for ; Mon, 18 Nov 2013 22:00:27 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 18 Nov 2013 22:00:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.93,535,1378882800"; d="scan'208";a="437577545" Received: from vkannan-desktop.iind.intel.com ([10.223.25.35]) by orsmga002.jf.intel.com with ESMTP; 18 Nov 2013 22:00:22 -0800 From: Vandana Kannan To: intel-gfx@lists.freedesktop.org Date: Tue, 19 Nov 2013 11:37:00 +0530 Message-Id: <1384841225-4688-3-git-send-email-vandana.kannan@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1384841225-4688-1-git-send-email-vandana.kannan@intel.com> References: <1384841225-4688-1-git-send-email-vandana.kannan@intel.com> Subject: [Intel-gfx] [PATCH 2/6] drm/i915: Parse EDID probed modes for DRRS support 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@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 From: Pradeep Bhat This patch parses the eDP EDID probed_mode list 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. This feature is for PV2 and not PV1. Signed-off-by: Pradeep Bhat Signed-off-by: Vandana Kannan --- drivers/gpu/drm/i915/intel_dp.c | 91 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 35 +++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7619eae..46f202b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3481,6 +3481,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct drm_display_mode *scan; struct edid *edid; + intel_dp->drrs_state.is_drrs_supported = DRRS_NOT_SUPPORTED; if (!is_edp(intel_dp)) return true; @@ -3529,6 +3530,15 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } } + /** + * Do the eDP DRRS support check here as we have valid EDID. + * Parse the list of probed modes and find out if we can get + * a mode with low refresh rate for resolution same as fixed_mode. + */ + if (fixed_mode && INTEL_INFO(dev)->gen >= 5) + intel_dp_find_drrs_lowclk(intel_dig_port, + intel_connector, fixed_mode); + /* fallback to VBT if available for eDP */ if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { fixed_mode = drm_mode_duplicate(dev, @@ -3738,3 +3748,84 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) kfree(intel_connector); } } + +static void +intel_dp_drrs_modelist_create(struct intel_digital_port *intel_dig_port, + struct drm_display_mode *fixed_mode, + struct drm_display_mode *lowest_mode) +{ + struct intel_dp *intel_dp = &intel_dig_port->dp; + + intel_dp->drrs_state.refresh_rate_array[DRRS_HIGH_RR] = + fixed_mode->vrefresh; + intel_dp->drrs_state.pixel_clock[DRRS_HIGH_RR] = fixed_mode->clock; + + intel_dp->drrs_state.refresh_rate_array[DRRS_LOW_RR] = + lowest_mode->vrefresh; + intel_dp->drrs_state.pixel_clock[DRRS_LOW_RR] = lowest_mode->clock; +} + +void +intel_dp_find_drrs_lowclk(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 intel_encoder *intel_encoder = &intel_dig_port->base; + struct drm_device *dev = intel_encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_display_mode *scan, *temp_mode; + int downclock; + + intel_dp->drrs_state.is_drrs_supported = DRRS_NOT_SUPPORTED; + /** + * Check if PSR is supported by panel and enabled + * if so then DRRS is reported as not supported for Haswell. + */ + + if (INTEL_INFO(dev)->gen < 8 && intel_edp_is_psr_enabled(dev)) { + DRM_INFO("eDP panel is PSR enabled. Cannot support DRRS.\n"); + return; + } + + /* First check if DRRS is enabled from VBT struct */ + if (!dev_priv->vbt.intel_drrs_enabled) { + DRM_INFO("VBT doesn't support DRRS.\n"); + return; + } + + /* Iterate the EDID probed_modes to get the Lowest refresh rate */ + downclock = fixed_mode->clock; + temp_mode = fixed_mode; + + list_for_each_entry(scan, &connector->probed_modes, head) { + if (scan->hdisplay == fixed_mode->hdisplay && + scan->hsync_start == fixed_mode->hsync_start && + scan->hsync_end == fixed_mode->hsync_end && + scan->htotal == fixed_mode->htotal && + scan->vdisplay == fixed_mode->vdisplay && + scan->vsync_start == fixed_mode->vsync_start && + scan->vsync_end == fixed_mode->vsync_end && + scan->vtotal == fixed_mode->vtotal) { + if (scan->clock < downclock) { + downclock = scan->clock; + temp_mode = scan; + } + } + } + + /* Create a list of different DRRS Refresh rates for use later */ + if (downclock < fixed_mode->clock && + dev_priv->vbt.drrs_mode == SEAMLESS_DRRS_SUPPORT) { + intel_dp_drrs_modelist_create(intel_dig_port, fixed_mode, + temp_mode); + intel_dp->drrs_state.is_drrs_supported = + dev_priv->vbt.drrs_mode; + intel_dp->drrs_state.drrs_refresh_rate_type = DRRS_HIGH_RR; + DRM_INFO("SEAMLESS DRRS supported for eDP panel.\n"); + } + + return; +} + diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9d2624f..bd7964d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -450,6 +450,36 @@ struct intel_hdmi { #define DP_MAX_DOWNSTREAM_PORTS 0x10 +/** + * This enum is used to indicate the DRRS support type. + * The values of the enum map 1-to-1 with the values from VBT. + */ +enum edp_panel_type { + DRRS_NOT_SUPPORTED = -1, + STATIC_DRRS_SUPPORT = 0, + SEAMLESS_DRRS_SUPPORT = 2 +}; +/** + * 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 */ +}; +/** + * The drrs_info struct will represent the DRRS feature for eDP + * panel. + */ +struct drrs_info { + int is_drrs_supported; + int drrs_refresh_rate_type; + int refresh_rate_array[DRRS_MAX_RR]; + int pixel_clock[DRRS_MAX_RR]; +}; + struct intel_dp { uint32_t output_reg; uint32_t aux_ch_ctl_reg; @@ -475,6 +505,7 @@ struct intel_dp { bool want_panel_vdd; bool psr_setup_done; struct intel_connector *attached_connector; + struct drrs_info drrs_state; }; struct intel_digital_port { @@ -789,6 +820,10 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, int intel_overlay_attrs(struct drm_device *dev, void *data, struct drm_file *file_priv); +/* drrs */ +extern void intel_dp_find_drrs_lowclk(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector, + struct drm_display_mode *fixed_mode); /* intel_panel.c */ int intel_panel_init(struct intel_panel *panel,