On 07/03/2015 06:09 PM, Paulo Zanoni wrote: > 2015-07-03 8:28 GMT-03:00 Antti Koskipaa <antti.koskipaa@xxxxxxxxxxxxxxx>: >> 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 <antti.koskipaa@xxxxxxxxxxxxxxx> >> --- >> 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 1dbd957..6aa8083 100644 >> --- a/drivers/gpu/drm/i915/i915_drv.h >> +++ b/drivers/gpu/drm/i915/i915_drv.h >> @@ -1410,6 +1410,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 2ff9eb0..76e12f5 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; > > In the old VBT spec I have, each child_dev_config is supposed to have > only 33 bytes. But in this patch you're increasing it to 38. I believe > this is what's causing the errors I see when I boot my BDW. > > Are you sure they increased the VBT's ChildDevInfo to more than 33 > bytes? I don't have access to your VBT spec right now, so I can't do a > proper review or a suggestion on how to fix the problem. The VBT spec I coded for does increase the size. You need to look at version >= 196 of the spec. >> } __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 15fc66a..c83f15f 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; >> @@ -465,6 +466,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; >> @@ -525,7 +530,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; >> @@ -540,7 +545,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; >> @@ -2083,18 +2088,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; >> } >> -- >> 1.8.1.5 >> >> _______________________________________________ >> Intel-gfx mailing list >> Intel-gfx@xxxxxxxxxxxxxxxxxxxxx >> http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx