From patchwork Tue Jun 30 16:23:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ville Syrjala X-Patchwork-Id: 6697301 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D872CC05AC for ; Tue, 30 Jun 2015 16:24:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E9DF720622 for ; Tue, 30 Jun 2015 16:24:13 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id DB242201EC for ; Tue, 30 Jun 2015 16:24:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5FC826E9AE; Tue, 30 Jun 2015 09:24:12 -0700 (PDT) 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 AA8F56E9AE for ; Tue, 30 Jun 2015 09:24:11 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 30 Jun 2015 09:24:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,378,1432623600"; d="scan'208";a="737800353" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.88]) by fmsmga001.fm.intel.com with SMTP; 30 Jun 2015 09:24:09 -0700 Received: by stinkbox (sSMTP sendmail emulation); Tue, 30 Jun 2015 19:23:59 +0300 From: ville.syrjala@linux.intel.com To: intel-gfx@lists.freedesktop.org Date: Tue, 30 Jun 2015 19:23:59 +0300 Message-Id: <1435681439-26097-1-git-send-email-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.3.6 In-Reply-To: <1435667634-4574-4-git-send-email-ville.syrjala@linux.intel.com> References: <1435667634-4574-4-git-send-email-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 3/4] drm/i915: Account for CHV/BXT DPLL clock limitations 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.8 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: Ville Syrjälä CHV/BXT DPLL can't generate frequencies in the 216-240 MHz range. Account for that when checking whether the HDMI port clock is valid. This is particularly important for BXT since it can otherwise do 12bpc, and standard 1920x1080p60 CEA modes land right in the middle of that range when the clock gets multiplied to account for 12bpc. With the extra checks we will now filter out any mode where both 8bpc and 12bpc clock are within the gap. During modeset we then pick whichever mode works, favoring 12bpc if both are possible. 12bpc isn't supported on CHV so we simply end up filtering out any mode where the 8bpc port clock is in the gap. v2: Fix crtc_clock vs. port_clock fumble in compute_config() (Imre) Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_hdmi.c | 58 +++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 69244ed..f5c60d6 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1151,7 +1151,7 @@ static void pch_post_disable_hdmi(struct intel_encoder *encoder) intel_disable_hdmi(encoder); } -static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) +static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) { struct drm_device *dev = intel_hdmi_to_dev(hdmi); @@ -1164,24 +1164,48 @@ static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) } static enum drm_mode_status +hdmi_port_clock_valid(struct intel_hdmi *hdmi, + int clock, bool respect_dvi_limit) +{ + struct drm_device *dev = intel_hdmi_to_dev(hdmi); + + if (clock < 25000) + return MODE_CLOCK_LOW; + if (clock > hdmi_port_clock_limit(hdmi, respect_dvi_limit)) + return MODE_CLOCK_HIGH; + + /* CHV/BXT DPLL can't generate 216-240 MHz */ + if ((IS_CHERRYVIEW(dev) || IS_BROXTON(dev)) && + clock > 216000 && clock < 240000) + return MODE_CLOCK_RANGE; + + return MODE_OK; +} + +static enum drm_mode_status intel_hdmi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - int clock = mode->clock; + struct intel_hdmi *hdmi = intel_attached_hdmi(connector); + struct drm_device *dev = intel_hdmi_to_dev(hdmi); + enum drm_mode_status status; + int clock; + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + clock = mode->clock; if (mode->flags & DRM_MODE_FLAG_DBLCLK) clock *= 2; - if (clock > hdmi_portclock_limit(intel_attached_hdmi(connector), - true)) - return MODE_CLOCK_HIGH; - if (clock < 25000) - return MODE_CLOCK_LOW; + /* check if we can do 8bpc */ + status = hdmi_port_clock_valid(hdmi, clock, true); - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; + /* if we can't do 8bpc we may still be able to do 12bpc */ + if (!HAS_GMCH_DISPLAY(dev) && status != MODE_OK) + status = hdmi_port_clock_valid(hdmi, clock * 3 / 2, true); - return MODE_OK; + return status; } static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state) @@ -1222,8 +1246,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); struct drm_device *dev = encoder->base.dev; struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; - int clock_12bpc = pipe_config->base.adjusted_mode.crtc_clock * 3 / 2; - int portclock_limit = hdmi_portclock_limit(intel_hdmi, false); + int clock_8bpc = pipe_config->base.adjusted_mode.crtc_clock; + int clock_12bpc = clock_8bpc * 3 / 2; int desired_bpp; pipe_config->has_hdmi_sink = intel_hdmi->has_hdmi_sink; @@ -1242,6 +1266,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) { pipe_config->pixel_multiplier = 2; + clock_8bpc *= 2; clock_12bpc *= 2; } @@ -1261,7 +1286,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, * within limits. */ if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink && - clock_12bpc <= portclock_limit && + hdmi_port_clock_valid(intel_hdmi, clock_12bpc, false) == MODE_OK && hdmi_12bpc_possible(pipe_config) && 0 /* FIXME 12bpc support totally broken */) { DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); @@ -1272,6 +1297,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, } else { DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n"); desired_bpp = 8*3; + + pipe_config->port_clock = clock_8bpc; } if (!pipe_config->bw_constrained) { @@ -1279,8 +1306,9 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, pipe_config->pipe_bpp = desired_bpp; } - if (adjusted_mode->crtc_clock > portclock_limit) { - DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n"); + if (hdmi_port_clock_valid(intel_hdmi, pipe_config->port_clock, + false) != MODE_OK) { + DRM_DEBUG_KMS("unsupported HDMI clock, rejecting mode\n"); return false; }