On Tue, Jun 18, 2019 at 07:08:55PM +0300, Ville Syrjälä wrote:
> On Mon, Jun 17, 2019 at 04:48:10PM -0700, Matt Roper wrote:
> > EHL has a mux on combo PHY A that allows it to be driven either by an
> > internal display (DDI-A or DSI DPHY) or by an external display (DDI-D).
> > This is a motherboard design decision that can not be changed on the
> > fly.  Unfortunately there are no strap registers that allow us to detect
> > the board configuration directly, so let's use the VBT to try to figure
> > it out and program the mux accordingly.
> > 
> > v2:
> >  - Confirmed that VBT's dvo port refers to the DDI and not the PHY.
> >    Thus we can check more explicitly for (ddi_d && !(ddi_a || dsi)).  If
> >    a bad VBT contradicts itself, let internal display win.  (Ville)
> > 
> > Cc: Clint Taylor <clinton.a.tay...@intel.com>
> > Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> > Signed-off-by: Matt Roper <matthew.d.ro...@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_bios.c     |  3 ++
> >  .../gpu/drm/i915/display/intel_combo_phy.c    | 36 +++++++++++++++++++
> >  drivers/gpu/drm/i915/i915_reg.h               |  1 +
> >  3 files changed, 40 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
> > b/drivers/gpu/drm/i915/display/intel_bios.c
> > index c4710889cb32..0c9808132d67 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bios.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bios.c
> > @@ -1668,6 +1668,9 @@ parse_general_definitions(struct drm_i915_private 
> > *dev_priv,
> >             if (!child->device_type)
> >                     continue;
> >  
> > +           DRM_DEBUG_KMS("Found VBT child device with type 0x%x\n",
> > +                         child->device_type);
> > +
> 
> Was this hunk intentional?
> 

Yeah, I figured that having a little more detail on the child device
details will probably be useful for debugging any cases where the VBT
seems to contradict itself.  I'll add a note about the debug message to
the commit message to make it clear it's intentional.


> >             /*
> >              * Copy as much as we know (sizeof) and is available
> >              * (child_dev_size) of the child device. Accessing the data must
> > diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
> > b/drivers/gpu/drm/i915/display/intel_combo_phy.c
> > index 841708da5a56..c18079a09a2e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
> > +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
> > @@ -260,6 +260,32 @@ void intel_combo_phy_power_up_lanes(struct 
> > drm_i915_private *dev_priv,
> >     I915_WRITE(ICL_PORT_CL_DW10(port), val);
> >  }
> >  
> > +static u32 ehl_combo_phy_a_mux(struct drm_i915_private *i915, u32 val)
> > +{
> > +   bool ddi_a_present = i915->vbt.ddi_port_info[PORT_A].child != NULL;
> > +   bool ddi_d_present = i915->vbt.ddi_port_info[PORT_D].child != NULL;
> > +   bool dsi_present = intel_bios_is_dsi_present(i915, NULL);
> > +
> > +   /*
> > +    * VBT's 'dvo port' field for child devices references the DDI, not
> > +    * the PHY.  So if combo PHY A is wired up to drive an external
> > +    * display, we should see a child device present on PORT_D and
> > +    * nothing on PORT_A and no DSI.
> > +    */
> > +   if (ddi_d_present && !ddi_a_present && !dsi_present)
> > +           return val | ICL_PHY_MISC_MUX_DDID;
> > +
> > +   /*
> > +    * If we encounter a VBT that claims to have an external display on
> > +    * DDI-D _and_ an internal display on DDI-A/DSI leave an error message
> > +    * in the log and let the internal display win.
> > +    */
> > +   if (ddi_d_present)
> > +           DRM_ERROR("VBT claims to have both internal and external 
> > displays on PHY A.  Configuring for internal.\n");
> > +
> > +   return val & ~ICL_PHY_MISC_MUX_DDID;
> > +}
> > +
> >  static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
> >  {
> >     enum port port;
> > @@ -273,7 +299,17 @@ static void icl_combo_phys_init(struct 
> > drm_i915_private *dev_priv)
> >                     continue;
> >             }
> >  
> > +           /*
> > +            * EHL's combo PHY A can be hooked up to either an external
> > +            * display (via DDI-D) or an internal display (via DDI-A or
> > +            * the DSI DPHY).  This is a motherboard design decision that
> > +            * can't be changed on the fly, so initialize the PHY's mux
> > +            * based on whether our VBT indicates the presence of any
> > +            * "internal" child devices.
> > +            */
> >             val = I915_READ(ICL_PHY_MISC(port));
> > +           if (!IS_ICELAKE(dev_priv) && port == PORT_A)
> 
> Maybe IS_EHL instead?

That's how I was originally going to write it, but I switched it to !icl
to follow the general convention of "assume future platforms inherit all
behavior of current platform."


Matt

> 
> Patch is
> Reviewed-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
> 
> > +                   val = ehl_combo_phy_a_mux(dev_priv, val);
> >             val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
> >             I915_WRITE(ICL_PHY_MISC(port), val);
> >  
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h 
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 1ae36b9efc85..68afafafd312 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -11138,6 +11138,7 @@ enum skl_power_gate {
> >  #define _ICL_PHY_MISC_B            0x64C04
> >  #define ICL_PHY_MISC(port) _MMIO_PORT(port, _ICL_PHY_MISC_A, \
> >                                              _ICL_PHY_MISC_B)
> > +#define  ICL_PHY_MISC_MUX_DDID                     (1 << 28)
> >  #define  ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN  (1 << 23)
> >  
> >  /* Icelake Display Stream Compression Registers */
> > -- 
> > 2.17.2
> 
> -- 
> Ville Syrjälä
> Intel

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to