Message ID | 1458047634-29790-2-git-send-email-shubhangi.shrivastava@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Mar 15, 2016 at 06:43:54PM +0530, Shubhangi Shrivastava wrote: > This patch sets the invert bit for hpd detection for each port > based on VBT configuration. Since each AOB can be designed to > depend on invert bit or not, it is expected if an AOB requires > invert bit, the user will set respective bit in VBT. > > v2: Separated VBT parsing from the rest of the logic. (Jani) > > v3: Moved setting invert bit logic to bxt_hpd_irq_setup() > and changed its logic to avoid looping twice. (Ville) > > v4: Changed the logic to mask out the bits first and then > set them to remove need of temporary variable. (Ville) > > Signed-off-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com> > Signed-off-by: Durgadoss R <durgadoss.r@intel.com> > Signed-off-by: Shubhangi Shrivastava <shubhangi.shrivastava@intel.com> > --- > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > drivers/gpu/drm/i915/i915_irq.c | 20 ++++++++++++++++++++ > drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++ > drivers/gpu/drm/i915/intel_bios.c | 35 +++++++++++++++++++++++++++++++++++ > 4 files changed, 65 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 1557d65..7a00966 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -3334,6 +3334,8 @@ extern void intel_i2c_reset(struct drm_device *dev); > /* intel_bios.c */ > int intel_bios_init(struct drm_i915_private *dev_priv); > bool intel_bios_is_valid_vbt(const void *buf, size_t size); > +bool intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv, > + enum port port); > > /* intel_opregion.c */ > #ifdef CONFIG_ACPI > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 53e5104..0a1e378 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -3503,6 +3503,26 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) > hotplug = I915_READ(PCH_PORT_HOTPLUG); > hotplug |= PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | > PORTA_HOTPLUG_ENABLE; > + > + DRM_DEBUG_KMS("Invert bit setting: hp_ctl:%x hp_port:%x\n", > + hotplug, enabled_irqs); > + hotplug &= ~BXT_DDI_HPD_INVERT_MASK; > + > + /* > + * For BXT invert bit has to be set based on AOB design > + * for HPD detection logic, update it based on VBT fields. > + */ > + > + if ((enabled_irqs & BXT_DE_PORT_HP_DDIA) && > + intel_bios_is_port_hpd_inverted(dev_priv, PORT_A)) > + hotplug |= BXT_DDIA_HPD_INVERT; > + if ((enabled_irqs & BXT_DE_PORT_HP_DDIB) && > + intel_bios_is_port_hpd_inverted(dev_priv, PORT_B)) > + hotplug |= BXT_DDIB_HPD_INVERT; > + if ((enabled_irqs & BXT_DE_PORT_HP_DDIC) && > + intel_bios_is_port_hpd_inverted(dev_priv, PORT_C)) > + hotplug |= BXT_DDIC_HPD_INVERT; > + > I915_WRITE(PCH_PORT_HOTPLUG, hotplug); > } > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 7dfc400..f80b870 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -6213,6 +6213,14 @@ enum skl_disp_power_wells { > #define PORTB_HOTPLUG_SHORT_DETECT (1 << 0) > #define PORTB_HOTPLUG_LONG_DETECT (2 << 0) > > +/* BXT hotplug control */ > +#define BXT_DDIA_HPD_INVERT (1 << 27) > +#define BXT_DDIC_HPD_INVERT (1 << 11) > +#define BXT_DDIB_HPD_INVERT (1 << 3) > +#define BXT_DDI_HPD_INVERT_MASK (BXT_DDIA_HPD_INVERT | \ > + BXT_DDIB_HPD_INVERT | \ > + BXT_DDIC_HPD_INVERT) The bits defines should be inserted to the proper place in the already existing set of defines for this register. > + > #define PCH_PORT_HOTPLUG2 _MMIO(0xc403C) /* SHOTPLUG_CTL2 SPT+ */ > #define PORTE_HOTPLUG_ENABLE (1 << 4) > #define PORTE_HOTPLUG_STATUS_MASK (3 << 0) > diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c > index a26d4b4..71d62f8 100644 > --- a/drivers/gpu/drm/i915/intel_bios.c > +++ b/drivers/gpu/drm/i915/intel_bios.c > @@ -105,6 +105,41 @@ find_section(const void *_bdb, int section_id) > return NULL; > } > > +bool > +intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv, > + enum port port) > +{ > + int i; > + > + if (WARN_ON_ONCE(!IS_BROXTON(dev_priv))) > + return false; > + > + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { > + > + if (!dev_priv->vbt.child_dev[i].common.hpd_invert) > + continue; > + > + switch (dev_priv->vbt.child_dev[i].common.dvo_port) { > + case DVO_PORT_DPA: > + case DVO_PORT_HDMIA: > + if (port == PORT_A) > + return true; break; > + case DVO_PORT_DPB: > + case DVO_PORT_HDMIB: > + if (port == PORT_B) > + return true; break; > + case DVO_PORT_DPC: > + case DVO_PORT_HDMIC: > + if (port == PORT_C) > + return true; break; With the missing breaks added and the defines moved to the right place this is Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > + default: > + break; > + } > + } > + > + return false; > +} > + > static void > fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, > const struct lvds_dvo_timing *dvo_timing) > -- > 2.6.1
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1557d65..7a00966 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3334,6 +3334,8 @@ extern void intel_i2c_reset(struct drm_device *dev); /* intel_bios.c */ int intel_bios_init(struct drm_i915_private *dev_priv); bool intel_bios_is_valid_vbt(const void *buf, size_t size); +bool intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv, + enum port port); /* intel_opregion.c */ #ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 53e5104..0a1e378 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3503,6 +3503,26 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) hotplug = I915_READ(PCH_PORT_HOTPLUG); hotplug |= PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE | PORTA_HOTPLUG_ENABLE; + + DRM_DEBUG_KMS("Invert bit setting: hp_ctl:%x hp_port:%x\n", + hotplug, enabled_irqs); + hotplug &= ~BXT_DDI_HPD_INVERT_MASK; + + /* + * For BXT invert bit has to be set based on AOB design + * for HPD detection logic, update it based on VBT fields. + */ + + if ((enabled_irqs & BXT_DE_PORT_HP_DDIA) && + intel_bios_is_port_hpd_inverted(dev_priv, PORT_A)) + hotplug |= BXT_DDIA_HPD_INVERT; + if ((enabled_irqs & BXT_DE_PORT_HP_DDIB) && + intel_bios_is_port_hpd_inverted(dev_priv, PORT_B)) + hotplug |= BXT_DDIB_HPD_INVERT; + if ((enabled_irqs & BXT_DE_PORT_HP_DDIC) && + intel_bios_is_port_hpd_inverted(dev_priv, PORT_C)) + hotplug |= BXT_DDIC_HPD_INVERT; + I915_WRITE(PCH_PORT_HOTPLUG, hotplug); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7dfc400..f80b870 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6213,6 +6213,14 @@ enum skl_disp_power_wells { #define PORTB_HOTPLUG_SHORT_DETECT (1 << 0) #define PORTB_HOTPLUG_LONG_DETECT (2 << 0) +/* BXT hotplug control */ +#define BXT_DDIA_HPD_INVERT (1 << 27) +#define BXT_DDIC_HPD_INVERT (1 << 11) +#define BXT_DDIB_HPD_INVERT (1 << 3) +#define BXT_DDI_HPD_INVERT_MASK (BXT_DDIA_HPD_INVERT | \ + BXT_DDIB_HPD_INVERT | \ + BXT_DDIC_HPD_INVERT) + #define PCH_PORT_HOTPLUG2 _MMIO(0xc403C) /* SHOTPLUG_CTL2 SPT+ */ #define PORTE_HOTPLUG_ENABLE (1 << 4) #define PORTE_HOTPLUG_STATUS_MASK (3 << 0) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index a26d4b4..71d62f8 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -105,6 +105,41 @@ find_section(const void *_bdb, int section_id) return NULL; } +bool +intel_bios_is_port_hpd_inverted(struct drm_i915_private *dev_priv, + enum port port) +{ + int i; + + if (WARN_ON_ONCE(!IS_BROXTON(dev_priv))) + return false; + + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { + + if (!dev_priv->vbt.child_dev[i].common.hpd_invert) + continue; + + switch (dev_priv->vbt.child_dev[i].common.dvo_port) { + case DVO_PORT_DPA: + case DVO_PORT_HDMIA: + if (port == PORT_A) + return true; + case DVO_PORT_DPB: + case DVO_PORT_HDMIB: + if (port == PORT_B) + return true; + case DVO_PORT_DPC: + case DVO_PORT_HDMIC: + if (port == PORT_C) + return true; + default: + break; + } + } + + return false; +} + static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, const struct lvds_dvo_timing *dvo_timing)