Commit ddff9a60 authored by Matt Roper's avatar Matt Roper Committed by Rodrigo Vivi

drm/i915/rkl: Handle HTI

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)

Bspec: 49189
Bspec: 53707
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200716220551.2730644-5-matthew.d.roper@intel.comReviewed-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent e66f609b
...@@ -4923,6 +4923,13 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port) ...@@ -4923,6 +4923,13 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port)
return max_lanes; 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) void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
{ {
struct intel_digital_port *dig_port; struct intel_digital_port *dig_port;
...@@ -4930,6 +4937,18 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port 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; bool init_hdmi, init_dp, init_lspcon = false;
enum phy phy = intel_port_to_phy(dev_priv, port); 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) || init_hdmi = intel_bios_port_supports_dvi(dev_priv, port) ||
intel_bios_port_supports_hdmi(dev_priv, port); intel_bios_port_supports_hdmi(dev_priv, port);
init_dp = intel_bios_port_supports_dp(dev_priv, port); init_dp = intel_bios_port_supports_dp(dev_priv, port);
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "display/intel_ddi.h" #include "display/intel_ddi.h"
#include "display/intel_dp.h" #include "display/intel_dp.h"
#include "display/intel_dp_mst.h" #include "display/intel_dp_mst.h"
#include "display/intel_dpll_mgr.h"
#include "display/intel_dsi.h" #include "display/intel_dsi.h"
#include "display/intel_dvo.h" #include "display/intel_dvo.h"
#include "display/intel_gmbus.h" #include "display/intel_gmbus.h"
...@@ -17903,6 +17904,13 @@ int intel_modeset_init(struct drm_i915_private *i915) ...@@ -17903,6 +17904,13 @@ int intel_modeset_init(struct drm_i915_private *i915)
if (i915->max_cdclk_freq == 0) if (i915->max_cdclk_freq == 0)
intel_update_max_cdclk(i915); 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 */ /* Just disable it once at startup */
intel_vga_disable(i915); intel_vga_disable(i915);
intel_setup_outputs(i915); intel_setup_outputs(i915);
......
...@@ -3475,6 +3475,14 @@ static void icl_update_active_dpll(struct intel_atomic_state *state, ...@@ -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); 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, static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc, struct intel_crtc *crtc,
struct intel_encoder *encoder) struct intel_encoder *encoder)
...@@ -3518,6 +3526,9 @@ static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state, ...@@ -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); 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->pll = intel_find_shared_dpll(state, crtc,
&port_dpll->hw_state, &port_dpll->hw_state,
dpll_mask); dpll_mask);
......
...@@ -1044,6 +1044,14 @@ struct drm_i915_private { ...@@ -1044,6 +1044,14 @@ struct drm_i915_private {
struct intel_l3_parity l3_parity; 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. * edram size in MB.
* Cannot be determined by PCIID. You must always read a register. * Cannot be determined by PCIID. You must always read a register.
......
...@@ -890,6 +890,7 @@ static const struct intel_device_info rkl_info = { ...@@ -890,6 +890,7 @@ static const struct intel_device_info rkl_info = {
.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C), BIT(TRANSCODER_C),
.require_force_probe = 1, .require_force_probe = 1,
.display.has_hti = 1,
.display.has_psr_hw_tracking = 0, .display.has_psr_hw_tracking = 0,
.platform_engine_mask = .platform_engine_mask =
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0), BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0),
......
...@@ -2921,6 +2921,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) ...@@ -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_S1 _MMIO(0x45040)
#define MBUS_BBOX_CTL_S2 _MMIO(0x45044) #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 /* Make render/texture TLB fetches lower priorty than associated data
* fetches. This is not turned on by default * fetches. This is not turned on by default
*/ */
......
...@@ -146,6 +146,7 @@ enum intel_ppgtt_type { ...@@ -146,6 +146,7 @@ enum intel_ppgtt_type {
func(has_gmch); \ func(has_gmch); \
func(has_hdcp); \ func(has_hdcp); \
func(has_hotplug); \ func(has_hotplug); \
func(has_hti); \
func(has_ipc); \ func(has_ipc); \
func(has_modular_fia); \ func(has_modular_fia); \
func(has_overlay); \ func(has_overlay); \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment