From patchwork Fri Jul 10 11:10:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Antti_Koskip=C3=A4=C3=A4?= X-Patchwork-Id: 6765091 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E01419F319 for ; Fri, 10 Jul 2015 11:10:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DA93020604 for ; Fri, 10 Jul 2015 11:10:50 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 795DF20619 for ; Fri, 10 Jul 2015 11:10:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D1EE47A120; Fri, 10 Jul 2015 04:10:48 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 7DE216E37A for ; Fri, 10 Jul 2015 04:10:47 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP; 10 Jul 2015 04:10:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,446,1432623600"; d="scan'208";a="726379887" Received: from sahapukki.fi.intel.com ([10.237.72.154]) by orsmga001.jf.intel.com with ESMTP; 10 Jul 2015 04:10:46 -0700 From: Antti Koskipaa To: intel-gfx@lists.freedesktop.org Date: Fri, 10 Jul 2015 14:10:55 +0300 Message-Id: <1436526655-2965-3-git-send-email-antti.koskipaa@linux.intel.com> X-Mailer: git-send-email 2.3.6 In-Reply-To: <1436526655-2965-1-git-send-email-antti.koskipaa@linux.intel.com> References: <1436526655-2965-1-git-send-email-antti.koskipaa@linux.intel.com> Subject: [Intel-gfx] [PATCH 2/2] drm/i915: Per-DDI I_boost override 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-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 An OEM may request increased I_boost beyond the recommended values by specifying an I_boost value to be applied to all swing entries for a port. These override values are specified in VBT. v2: rebase and remove unused iboost_bit variable Issue: VIZ-5676 Signed-off-by: Antti Koskipaa Reviewed-by: David Weinehall --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/intel_bios.c | 21 +++++++++++++++++++++ drivers/gpu/drm/i915/intel_bios.h | 9 +++++++++ drivers/gpu/drm/i915/intel_ddi.c | 38 ++++++++++++++++++++++++++++++-------- 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 768d1db..9a22a4d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1420,6 +1420,9 @@ struct ddi_vbt_port_info { uint8_t supports_dvi:1; uint8_t supports_hdmi:1; uint8_t supports_dp:1; + + uint8_t dp_boost_level; + uint8_t hdmi_boost_level; }; enum psr_lines_to_wait { diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 763a636..e9ced16 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -886,6 +886,17 @@ err: memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence)); } +static u8 translate_iboost(u8 val) +{ + static const u8 mapping[] = { 1, 3, 7 }; /* See VBT spec */ + + if (val >= ARRAY_SIZE(mapping)) { + DRM_DEBUG_KMS("Unsupported I_boost value found in VBT (%d), display may not work properly\n", val); + return 0; + } + return mapping[val]; +} + static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, const struct bdb_header *bdb) { @@ -986,6 +997,16 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, hdmi_level_shift); info->hdmi_level_shift = hdmi_level_shift; } + + /* Parse the I_boost config for SKL and above */ + if (bdb->version >= 196 && (child->common.flags_1 & IBOOST_ENABLE)) { + info->dp_boost_level = translate_iboost(child->common.iboost_level & 0xF); + DRM_DEBUG_KMS("VBT (e)DP boost level for port %c: %d\n", + port_name(port), info->dp_boost_level); + info->hdmi_boost_level = translate_iboost(child->common.iboost_level >> 4); + DRM_DEBUG_KMS("VBT HDMI boost level for port %c: %d\n", + port_name(port), info->hdmi_boost_level); + } } static void parse_ddi_ports(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index af0b476..8edd75c 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -231,6 +231,10 @@ struct old_child_dev_config { /* This one contains field offsets that are known to be common for all BDB * versions. Notice that the meaning of the contents contents may still change, * but at least the offsets are consistent. */ + +/* Definitions for flags_1 */ +#define IBOOST_ENABLE (1<<3) + struct common_child_dev_config { u16 handle; u16 device_type; @@ -239,8 +243,13 @@ struct common_child_dev_config { u8 not_common2[2]; u8 ddc_pin; u16 edid_ptr; + u8 obsolete; + u8 flags_1; + u8 not_common3[13]; + u8 iboost_level; } __packed; + /* This field changes depending on the BDB version, so the most reliable way to * read it is by checking the BDB version and reading the raw pointer. */ union child_device_config { diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9a40bfb..0446084 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -440,6 +440,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg; + u32 iboost_bit = 0; int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, size; int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; @@ -466,6 +467,10 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev, &n_hdmi_entries); hdmi_default_entry = 8; + /* If we're boosting the current, set bit 31 of trans1 */ + if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || + dev_priv->vbt.ddi_port_info[port].dp_boost_level) + iboost_bit = 1<<31; } else if (IS_BROADWELL(dev)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; @@ -526,7 +531,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, } for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) { - I915_WRITE(reg, ddi_translations[i].trans1); + I915_WRITE(reg, ddi_translations[i].trans1 | iboost_bit); reg += 4; I915_WRITE(reg, ddi_translations[i].trans2); reg += 4; @@ -541,7 +546,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, hdmi_level = hdmi_default_entry; /* Entry 9 is for HDMI: */ - I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1); + I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); reg += 4; I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2); reg += 4; @@ -2078,18 +2083,35 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level, struct drm_i915_private *dev_priv = dev->dev_private; const struct ddi_buf_trans *ddi_translations; uint8_t iboost; + uint8_t dp_iboost, hdmi_iboost; int n_entries; u32 reg; + /* VBT may override standard boost values */ + dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level; + hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level; + if (type == INTEL_OUTPUT_DISPLAYPORT) { - ddi_translations = skl_get_buf_trans_dp(dev, &n_entries); - iboost = ddi_translations[port].i_boost; + if (dp_iboost) { + iboost = dp_iboost; + } else { + ddi_translations = skl_get_buf_trans_dp(dev, &n_entries); + iboost = ddi_translations[port].i_boost; + } } else if (type == INTEL_OUTPUT_EDP) { - ddi_translations = skl_get_buf_trans_edp(dev, &n_entries); - iboost = ddi_translations[port].i_boost; + if (dp_iboost) { + iboost = dp_iboost; + } else { + ddi_translations = skl_get_buf_trans_edp(dev, &n_entries); + iboost = ddi_translations[port].i_boost; + } } else if (type == INTEL_OUTPUT_HDMI) { - ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries); - iboost = ddi_translations[port].i_boost; + if (hdmi_iboost) { + iboost = hdmi_iboost; + } else { + ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries); + iboost = ddi_translations[port].i_boost; + } } else { return; }