From patchwork Fri Jan 17 13:47:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lee Shawn C X-Patchwork-Id: 11338347 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 70042138D for ; Fri, 17 Jan 2020 05:49:05 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5712820748 for ; Fri, 17 Jan 2020 05:49:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5712820748 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 99E9F6F3A2; Fri, 17 Jan 2020 05:49:03 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 12CAD6F3A2 for ; Fri, 17 Jan 2020 05:49:03 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Jan 2020 21:49:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,328,1574150400"; d="scan'208";a="424333033" Received: from shawnle1-build-machine.itwn.intel.com ([10.5.253.9]) by fmsmga005.fm.intel.com with ESMTP; 16 Jan 2020 21:49:00 -0800 From: Lee Shawn C To: intel-gfx@lists.freedesktop.org Date: Fri, 17 Jan 2020 21:47:17 +0800 Message-Id: <20200117134717.2703-1-shawn.c.lee@intel.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH] drm/i915: Check require bandwidth did not exceed LSPCON limitation X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Cooper Chiou , Sam McNally Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" While mode setting, driver would calculate mode rate based on resolution and bpp. And choose the best bpp that did not exceed DP bandwidtd. But LSPCON had more restriction due to it convert DP to HDMI. Driver should respect HDMI's bandwidth limitation if LSPCON was active. This change would ignore the bpp when its required output bandwidth already over HDMI 2.0 or 1.4 spec. Cc: Imre Deak Cc: Ville Syrjälä Cc: Maarten Lankhorst Cc: Jani Nikula Cc: Cooper Chiou Cc: Sam McNally Signed-off-by: Lee Shawn C --- drivers/gpu/drm/i915/display/intel_dp.c | 45 +++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_lspcon.c | 5 +++ drivers/gpu/drm/i915/display/intel_lspcon.h | 1 + 3 files changed, 51 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index c7424e2a04a3..c27d3e7ac219 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1976,6 +1976,47 @@ static int intel_dp_output_bpp(const struct intel_crtc_state *crtc_state, int bp return bpp; } +static bool +intel_dp_lspcon_exceed_bandwidth_limitation(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int bpp) +{ + struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp); + struct intel_connector *connector = intel_dp->attached_connector; + const struct drm_display_info *info = &connector->base.display_info; + enum drm_lspcon_mode lspcon_current_mode = lspcon_get_mode(lspcon); + const int pcon_mode_max_tmds_clock = 600000; + const int ls_mode_max_tmds_clock = 340000; + int mode_rate, max_tmds_clock = pcon_mode_max_tmds_clock; + + if (lspcon->active) { + switch (bpp) { + case 36: + mode_rate = pipe_config->hw.adjusted_mode.crtc_clock * 3 / 2; + break; + case 30: + mode_rate = pipe_config->hw.adjusted_mode.crtc_clock * 5 / 4; + break; + case 24: + default: + mode_rate = pipe_config->hw.adjusted_mode.crtc_clock; + break; + } + + if (lspcon_current_mode == DRM_LSPCON_MODE_LS) + max_tmds_clock = ls_mode_max_tmds_clock; + + if (info->max_tmds_clock) + max_tmds_clock = min(max_tmds_clock, + info->max_tmds_clock); + + if (mode_rate > max_tmds_clock) + return true; + } + + return false; +} + /* Optimize link config in order: max bpp, min clock, min lanes */ static int intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, @@ -1989,6 +2030,10 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { int output_bpp = intel_dp_output_bpp(pipe_config, bpp); + /* Bypass th bpp if require bandwidth over HDMI spec when LSPCON active */ + if (intel_dp_lspcon_exceed_bandwidth_limitation(intel_dp, pipe_config, output_bpp)) + continue; + mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, output_bpp); diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index d807c5648c87..6952c5028fdf 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -550,6 +550,11 @@ void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon) lspcon_wait_mode(lspcon, DRM_LSPCON_MODE_PCON); } +int lspcon_get_mode(struct intel_lspcon *lspcon) +{ + return lspcon_get_current_mode(lspcon); +} + bool lspcon_init(struct intel_digital_port *intel_dig_port) { struct intel_dp *dp = &intel_dig_port->dp; diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h index 37cfddf8a9c5..5ce9daef9708 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.h +++ b/drivers/gpu/drm/i915/display/intel_lspcon.h @@ -18,6 +18,7 @@ struct intel_lspcon; bool lspcon_init(struct intel_digital_port *intel_dig_port); void lspcon_resume(struct intel_lspcon *lspcon); void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); +int lspcon_get_mode(struct intel_lspcon *lspcon); void lspcon_write_infoframe(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, unsigned int type,