From patchwork Fri Jul 28 19:22:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jim.bride@linux.intel.com X-Patchwork-Id: 9869281 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 8DCE86038F for ; Fri, 28 Jul 2017 19:25:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 761AD288C6 for ; Fri, 28 Jul 2017 19:25:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6AA6B288CD; Fri, 28 Jul 2017 19:25:13 +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=-4.2 required=2.0 tests=BAYES_00, 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 C0665288C6 for ; Fri, 28 Jul 2017 19:25:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4FD4D6F4D4; Fri, 28 Jul 2017 19:25:11 +0000 (UTC) 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 ESMTPS id 1F3016F4D4 for ; Fri, 28 Jul 2017 19:25:10 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jul 2017 12:25:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,427,1496127600"; d="scan'208";a="292855444" Received: from shiv.jf.intel.com ([10.54.75.141]) by fmsmga004.fm.intel.com with ESMTP; 28 Jul 2017 12:25:08 -0700 From: Jim Bride To: intel-gfx@lists.freedesktop.org Date: Fri, 28 Jul 2017 12:22:29 -0700 Message-Id: <1501269749-10909-1-git-send-email-jim.bride@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501001291-2708-5-git-send-email-jim.bride@linux.intel.com> References: <1501001291-2708-5-git-send-email-jim.bride@linux.intel.com> Cc: Paulo Zanoni , Jani Nikula , Rodrigo Vivi Subject: [Intel-gfx] [PATCH v5] drm/i915/edp: Allow alternate fixed mode for eDP if available. 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-Virus-Scanned: ClamAV using ClamSMTP Some fixed resolution panels actually support more than one mode, with the only thing different being the refresh rate. Having this alternate mode available to us is desirable, because it allows us to test PSR on panels whose setup time at the preferred mode is too long. With this patch we allow the use of the alternate mode if it's available and it was specifically requested. v2 and v3: Rebase v4: * Fix up some leaky mode stuff (Chris) * Rebase v5: * Fix a NULL pointer derefreence (David Weinehall) Cc: David Weinehall Cc: Rodrigo Vivi Cc: Paulo Zanoni Cc: Jani Nikula Cc: Chris Wilson Signed-off-by: Jim Bride Reviewed-by: David Weinehall --- drivers/gpu/drm/i915/intel_dp.c | 38 +++++++++++++++++++++++++++++++++----- drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_dsi.c | 2 +- drivers/gpu/drm/i915/intel_dvo.c | 2 +- drivers/gpu/drm/i915/intel_lvds.c | 3 ++- drivers/gpu/drm/i915/intel_panel.c | 6 ++++++ 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7c0e530..60c4642 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1606,6 +1606,23 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp, return bpp; } +static bool intel_edp_compare_alt_mode(struct drm_display_mode *m1, + struct drm_display_mode *m2) +{ + bool bres = false; + + if (m1 && m2) + bres = (m1->hdisplay == m2->hdisplay && + m1->hsync_start == m2->hsync_start && + m1->hsync_end == m2->hsync_end && + m1->htotal == m2->htotal && + m1->vdisplay == m2->vdisplay && + m1->vsync_start == m2->vsync_start && + m1->vsync_end == m2->vsync_end && + m1->vtotal == m2->vtotal); + return bres; +} + bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, @@ -1652,8 +1669,16 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON; if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { - intel_fixed_panel_mode(intel_connector->panel.fixed_mode, - adjusted_mode); + struct drm_display_mode *panel_mode = + intel_connector->panel.alt_fixed_mode; + struct drm_display_mode *req_mode = &pipe_config->base.mode; + + if (!intel_edp_compare_alt_mode(req_mode, panel_mode)) + panel_mode = intel_connector->panel.fixed_mode; + + drm_mode_debug_printmodeline(panel_mode); + + intel_fixed_panel_mode(panel_mode, adjusted_mode); if (INTEL_GEN(dev_priv) >= 9) { int ret; @@ -5810,6 +5835,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); struct drm_display_mode *fixed_mode = NULL; + struct drm_display_mode *alt_fixed_mode = NULL; struct drm_display_mode *downclock_mode = NULL; bool has_dpcd; struct drm_display_mode *scan; @@ -5865,13 +5891,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } intel_connector->edid = edid; - /* prefer fixed mode from EDID if available */ + /* prefer fixed mode from EDID if available, save an alt mode also */ 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_connector, fixed_mode); - break; + } else if (!alt_fixed_mode) { + alt_fixed_mode = drm_mode_duplicate(dev, scan); } } @@ -5908,7 +5935,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, pipe_name(pipe)); } - intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); + intel_panel_init(&intel_connector->panel, fixed_mode, alt_fixed_mode, + downclock_mode); intel_connector->panel.backlight.power = intel_edp_backlight_power; intel_panel_setup_backlight(connector, pipe); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 046d358..00bde65 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -265,6 +265,7 @@ struct intel_encoder { struct intel_panel { struct drm_display_mode *fixed_mode; + struct drm_display_mode *alt_fixed_mode; struct drm_display_mode *downclock_mode; /* backlight */ @@ -1682,6 +1683,7 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv); /* intel_panel.c */ int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode, + struct drm_display_mode *alt_fixed_mode, struct drm_display_mode *downclock_mode); void intel_panel_fini(struct intel_panel *panel); void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 50ec836..d3a6608 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1851,7 +1851,7 @@ void intel_dsi_init(struct drm_i915_private *dev_priv) connector->display_info.width_mm = fixed_mode->width_mm; connector->display_info.height_mm = fixed_mode->height_mm; - intel_panel_init(&intel_connector->panel, fixed_mode, NULL); + intel_panel_init(&intel_connector->panel, fixed_mode, NULL, NULL); intel_panel_setup_backlight(connector, INVALID_PIPE); intel_dsi_add_properties(intel_connector); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index c1544a5..39fd4f3 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -554,7 +554,7 @@ void intel_dvo_init(struct drm_i915_private *dev_priv) */ intel_panel_init(&intel_connector->panel, intel_dvo_get_current_mode(connector), - NULL); + NULL, NULL); intel_dvo->panel_wants_dither = true; } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6fe5d7c..a995ccb 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1140,7 +1140,8 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) out: mutex_unlock(&dev->mode_config.mutex); - intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); + intel_panel_init(&intel_connector->panel, fixed_mode, NULL, + downclock_mode); intel_panel_setup_backlight(connector, INVALID_PIPE); lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index fd2e081..e7df774 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1920,11 +1920,13 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel) int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode, + struct drm_display_mode *alt_fixed_mode, struct drm_display_mode *downclock_mode) { intel_panel_init_backlight_funcs(panel); panel->fixed_mode = fixed_mode; + panel->alt_fixed_mode = alt_fixed_mode; panel->downclock_mode = downclock_mode; return 0; @@ -1938,6 +1940,10 @@ void intel_panel_fini(struct intel_panel *panel) if (panel->fixed_mode) drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); + if (panel->alt_fixed_mode) + drm_mode_destroy(intel_connector->base.dev, + panel->alt_fixed_mode); + if (panel->downclock_mode) drm_mode_destroy(intel_connector->base.dev, panel->downclock_mode);