[Intel-gfx] [PATCH 06/11] drm/i915: Introduce spt_irq_handler()

Ville Syrjälä ville.syrjala at linux.intel.com
Thu Aug 27 10:52:41 PDT 2015


On Thu, Aug 27, 2015 at 07:13:49PM +0300, Ville Syrjälä wrote:
> On Thu, Aug 27, 2015 at 10:38:25AM +0300, Jani Nikula wrote:
> > On Thu, 27 Aug 2015, Paulo Zanoni <przanoni at gmail.com> wrote:
> > > 2015-08-12 12:44 GMT-03:00  <ville.syrjala at linux.intel.com>:
> > >> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> > >>
> > >> Starting from SPT the only interrupts living in the south are GMBUS and
> > >> HPD. What's worse some of the SPT specific new bits conflict with some
> > >> other bits on earlier PCH generations. So better not use the
> > >> cpt_irq_handler() for SPT+ anymore.
> > >>
> > >> Also kill the hand rolled port E handling with something more
> > >> standardish. This also avoids accidentally confusing port B and port E
> > >> long pulses since the bits occupy the same positions, just in different
> > >> registers.
> > >>
> > >> Also add a comment noting that the short pulse duration bits are
> > >> reserved on LPT+. The 2ms value we program is 0, so no issue wrt. the
> > >> MBZ in the spec.
> > >>
> > >> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> > >> ---
> > >>  drivers/gpu/drm/i915/i915_irq.c | 123 +++++++++++++++++++++++++++-------------
> > >>  1 file changed, 83 insertions(+), 40 deletions(-)
> > >>
> > >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > >> index d12106c..e2485bd 100644
> > >> --- a/drivers/gpu/drm/i915/i915_irq.c
> > >> +++ b/drivers/gpu/drm/i915/i915_irq.c
> > >> @@ -1260,6 +1260,16 @@ static bool bxt_port_hotplug_long_detect(enum port port, u32 val)
> > >>         }
> > >>  }
> > >>
> > >> +static bool spt_port_hotplug2_long_detect(enum port port, u32 val)
> > >> +{
> > >> +       switch (port) {
> > >> +       case PORT_E:
> > >> +               return val & PORTE_HOTPLUG_LONG_DETECT;
> > >> +       default:
> > >> +               return false;
> > >> +       }
> > >> +}
> > >> +
> > >>  static bool pch_port_hotplug_long_detect(enum port port, u32 val)
> > >>  {
> > >>         switch (port) {
> > >> @@ -1269,8 +1279,6 @@ static bool pch_port_hotplug_long_detect(enum port port, u32 val)
> > >>                 return val & PORTC_HOTPLUG_LONG_DETECT;
> > >>         case PORT_D:
> > >>                 return val & PORTD_HOTPLUG_LONG_DETECT;
> > >> -       case PORT_E:
> > >> -               return val & PORTE_HOTPLUG_LONG_DETECT;
> > >>         default:
> > >>                 return false;
> > >>         }
> > >> @@ -1771,12 +1779,7 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
> > >>  {
> > >>         struct drm_i915_private *dev_priv = dev->dev_private;
> > >>         int pipe;
> > >> -       u32 hotplug_trigger;
> > >> -
> > >> -       if (HAS_PCH_SPT(dev))
> > >> -               hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT;
> > >> -       else
> > >> -               hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
> > >> +       u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
> > >>
> > >>         if (hotplug_trigger) {
> > >>                 u32 dig_hotplug_reg, pin_mask, long_mask;
> > >> @@ -1784,22 +1787,10 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
> > >>                 dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
> > >>                 I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
> > >>
> > >> -               if (HAS_PCH_SPT(dev)) {
> > >> -                       intel_get_hpd_pins(&pin_mask, &long_mask,
> > >> -                                          hotplug_trigger,
> > >> -                                          dig_hotplug_reg, hpd_spt,
> > >> -                                          pch_port_hotplug_long_detect);
> > >> -
> > >> -                       /* detect PORTE HP event */
> > >> -                       dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
> > >> -                       if (pch_port_hotplug_long_detect(PORT_E,
> > >> -                                                        dig_hotplug_reg))
> > >> -                               long_mask |= 1 << HPD_PORT_E;
> > >> -               } else
> > >> -                       intel_get_hpd_pins(&pin_mask, &long_mask,
> > >> -                                          hotplug_trigger,
> > >> -                                          dig_hotplug_reg, hpd_cpt,
> > >> -                                          pch_port_hotplug_long_detect);
> > >> +               intel_get_hpd_pins(&pin_mask, &long_mask,
> > >> +                                  hotplug_trigger,
> > >> +                                  dig_hotplug_reg, hpd_cpt,
> > >> +                                  pch_port_hotplug_long_detect);
> > >>
> > >>                 intel_hpd_irq_handler(dev, pin_mask, long_mask);
> > >>         }
> > >> @@ -1833,6 +1824,42 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
> > >>                 cpt_serr_int_handler(dev);
> > >>  }
> > >>
> > >> +static void spt_irq_handler(struct drm_device *dev, u32 pch_iir)
> > >> +{
> > >> +       struct drm_i915_private *dev_priv = dev->dev_private;
> > >> +       u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT &
> > >> +               ~SDE_PORTE_HOTPLUG_SPT;
> > >> +       u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT;
> > >> +
> > >> +       if (hotplug_trigger) {
> > >> +               u32 dig_hotplug_reg, pin_mask, long_mask;
> > >> +
> > >> +               dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
> > >> +               I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
> > >> +
> > >> +               intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
> > >> +                                  dig_hotplug_reg, hpd_spt,
> > >> +                                  pch_port_hotplug_long_detect);
> > >> +               intel_hpd_irq_handler(dev, pin_mask, long_mask);
> > >> +       }
> > >> +
> > >> +       if (hotplug2_trigger) {
> > >> +               u32 dig_hotplug_reg, pin_mask, long_mask;
> > >> +
> > >> +               dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
> > >> +               I915_WRITE(PCH_PORT_HOTPLUG2, dig_hotplug_reg);
> > >> +
> > >> +               intel_get_hpd_pins(&pin_mask, &long_mask, hotplug2_trigger,
> > >> +                                  dig_hotplug_reg, hpd_spt,
> > >> +                                  spt_port_hotplug2_long_detect);
> > >> +
> > >> +               intel_hpd_irq_handler(dev, pin_mask, long_mask);
> > >> +       }
> > >
> > > Instead of calling intel_hpd_irq_handler() twice, can't you just do
> > > something like:
> > > intel_hpd_irq_hanlder(dev, pin_mask1 | pin_mask2, long_mask1 | long_mask2) ?
> > 
> > 
> > And if you reverted
> > 
> > commit fd63e2a972c670887e5e8a08440111d3812c0996
> > Author: Imre Deak <imre.deak at intel.com>
> > Date:   Tue Jul 21 15:32:44 2015 -0700
> > 
> >     drm/i915: combine i9xx_get_hpd_pins and pch_get_hpd_pins
> > 
> > and added another version for spt, this would all be pretty and each of
> > the functions would do exactly what is required and you could have
> > meaningful, platform specific debug logging in each of the functions.
> > 
> > By focusing on deduplicating a few lines in get_hpd_pins, the callers
> > (which are platform specific code to begin with) get more complicated.
> 
> OK, let me have a look at this mess in a bit more detail and see what can
> be done. Paulo's idea at least is simple enough to do, so I'll do at
> least that.

I think what I'll do is leave intel_get_hpd_pins() mostly intact, except
I'll move the pin_mask/long_mask 0 initialization out into the callers.
That way anyone can call it multiple times and accumulate all the bits to
the same two masks, and then call intel_hpd_irq_handler just once.

Going back to platform specific variants of the function didn't seem too
nice as I'd probably then need to add more variants for port A HPD etc.

-- 
Ville Syrjälä
Intel OTC


More information about the Intel-gfx mailing list