On Thu, 2020-07-16 at 15:05 -0700, Matt Roper wrote: > If HTI (also sometimes called HDPORT) is enabled at startup, it may be > using some of the PHYs and DPLLs making them unavailable for general > usage. Let's read out the HDPORT_STATE register and avoid making use of > resources that HTI is already using. > > v2: > - Fix minor checkpatch warnings > > v3: > - Just readout HDPORT_STATE register once during init and then parse it > later as needed. > - Add a 'has_hti' device info flag to track whether we should readout > HDPORT_STATE or not. We can skip the platform/flag tests later since > the hti_state in dev_priv will remain 0 for platforms it does not > apply to. > - Move PLL masking into icl_get_combo_phy_dpll() since at the moment > RKL is the only platform that has HTI. (Jose) > Reviewed-by: José Roberto de Souza <jose.souza@xxxxxxxxx> > Bspec: 49189 > Bspec: 53707 > Cc: Lucas De Marchi <lucas.demarchi@xxxxxxxxx> > Cc: José Roberto de Souza <jose.souza@xxxxxxxxx> > Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_ddi.c | 19 +++++++++++++++++++ > drivers/gpu/drm/i915/display/intel_display.c | 8 ++++++++ > drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 11 +++++++++++ > drivers/gpu/drm/i915/i915_drv.h | 8 ++++++++ > drivers/gpu/drm/i915/i915_pci.c | 1 + > drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ > drivers/gpu/drm/i915/intel_device_info.h | 1 + > 7 files changed, 54 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c > index 1ca70f9abc8d..714b2bc96f23 100644 > --- a/drivers/gpu/drm/i915/display/intel_ddi.c > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c > @@ -4923,6 +4923,13 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port) > return max_lanes; > } > > +static bool hti_uses_phy(struct drm_i915_private *i915, enum phy phy) > +{ > + return i915->hti_state & HDPORT_ENABLED && > + (i915->hti_state & HDPORT_PHY_USED_DP(phy) || > + i915->hti_state & HDPORT_PHY_USED_HDMI(phy)); > +} > + > void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > { > struct intel_digital_port *dig_port; > @@ -4930,6 +4937,18 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > bool init_hdmi, init_dp, init_lspcon = false; > enum phy phy = intel_port_to_phy(dev_priv, port); > > + /* > + * On platforms with HTI (aka HDPORT), if it's enabled at boot it may > + * have taken over some of the PHYs and made them unavailable to the > + * driver. In that case we should skip initializing the corresponding > + * outputs. > + */ > + if (hti_uses_phy(dev_priv, phy)) { > + drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n", > + port_name(port), phy_name(phy)); > + return; > + } > + > init_hdmi = intel_bios_port_supports_dvi(dev_priv, port) || > intel_bios_port_supports_hdmi(dev_priv, port); > init_dp = intel_bios_port_supports_dp(dev_priv, port); > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c > index 6cb66580ad2c..db2a5a1a9b35 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.c > +++ b/drivers/gpu/drm/i915/display/intel_display.c > @@ -47,6 +47,7 @@ > #include "display/intel_ddi.h" > #include "display/intel_dp.h" > #include "display/intel_dp_mst.h" > +#include "display/intel_dpll_mgr.h" > #include "display/intel_dsi.h" > #include "display/intel_dvo.h" > #include "display/intel_gmbus.h" > @@ -17903,6 +17904,13 @@ int intel_modeset_init(struct drm_i915_private *i915) > if (i915->max_cdclk_freq == 0) > intel_update_max_cdclk(i915); > > + /* > + * If the platform has HTI, we need to find out whether it has reserved > + * any display resources before we create our display outputs. > + */ > + if (INTEL_INFO(i915)->display.has_hti) > + i915->hti_state = intel_de_read(i915, HDPORT_STATE); > + > /* Just disable it once at startup */ > intel_vga_disable(i915); > intel_setup_outputs(i915); > diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c > index 134c2ecf4c80..81ab975fe4f0 100644 > --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c > +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c > @@ -3475,6 +3475,14 @@ static void icl_update_active_dpll(struct intel_atomic_state *state, > icl_set_active_port_dpll(crtc_state, port_dpll_id); > } > > +static u32 intel_get_hti_plls(struct drm_i915_private *i915) > +{ > + if (!(i915->hti_state & HDPORT_ENABLED)) > + return 0; > + > + return REG_FIELD_GET(HDPORT_DPLL_USED_MASK, i915->hti_state); > +} > + > static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state, > struct intel_crtc *crtc, > struct intel_encoder *encoder) > @@ -3518,6 +3526,9 @@ static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state, > dpll_mask = BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0); > } > > + /* Eliminate DPLLs from consideration if reserved by HTI */ > + dpll_mask &= ~intel_get_hti_plls(dev_priv); > + > port_dpll->pll = intel_find_shared_dpll(state, crtc, > &port_dpll->hw_state, > dpll_mask); > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index e4f7f6518945..56dfc6d98caa 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1044,6 +1044,14 @@ struct drm_i915_private { > > struct intel_l3_parity l3_parity; > > + /* > + * HTI (aka HDPORT) state read during initial hw readout. Most > + * platforms don't have HTI, so this will just stay 0. Those that do > + * will use this later to figure out which PLLs and PHYs are unavailable > + * for driver usage. > + */ > + u32 hti_state; > + > /* > * edram size in MB. > * Cannot be determined by PCIID. You must always read a register. > diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c > index 2338f92ce490..366ddfc8df6b 100644 > --- a/drivers/gpu/drm/i915/i915_pci.c > +++ b/drivers/gpu/drm/i915/i915_pci.c > @@ -890,6 +890,7 @@ static const struct intel_device_info rkl_info = { > .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | > BIT(TRANSCODER_C), > .require_force_probe = 1, > + .display.has_hti = 1, > .display.has_psr_hw_tracking = 0, > .platform_engine_mask = > BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0), > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index bfdb6d23b5d8..89a9f2d8110e 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -2921,6 +2921,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) > #define MBUS_BBOX_CTL_S1 _MMIO(0x45040) > #define MBUS_BBOX_CTL_S2 _MMIO(0x45044) > > +#define HDPORT_STATE _MMIO(0x45050) > +#define HDPORT_DPLL_USED_MASK REG_GENMASK(14, 12) > +#define HDPORT_PHY_USED_DP(phy) REG_BIT(2 * (phy) + 2) > +#define HDPORT_PHY_USED_HDMI(phy) REG_BIT(2 * (phy) + 1) > +#define HDPORT_ENABLED REG_BIT(0) > + > /* Make render/texture TLB fetches lower priorty than associated data > * fetches. This is not turned on by default > */ > diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h > index fd2385457ab6..6a3d607218aa 100644 > --- a/drivers/gpu/drm/i915/intel_device_info.h > +++ b/drivers/gpu/drm/i915/intel_device_info.h > @@ -146,6 +146,7 @@ enum intel_ppgtt_type { > func(has_gmch); \ > func(has_hdcp); \ > func(has_hotplug); \ > + func(has_hti); \ > func(has_ipc); \ > func(has_modular_fia); \ > func(has_overlay); \ _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx