Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200716220551.2730644-5-matthew.d.roper@intel.com
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Matt Roper and committed by
Rodrigo Vivi
ddff9a60 e66f609b

+54
+19
drivers/gpu/drm/i915/display/intel_ddi.c
··· 4923 4923 return max_lanes; 4924 4924 } 4925 4925 4926 + static bool hti_uses_phy(struct drm_i915_private *i915, enum phy phy) 4927 + { 4928 + return i915->hti_state & HDPORT_ENABLED && 4929 + (i915->hti_state & HDPORT_PHY_USED_DP(phy) || 4930 + i915->hti_state & HDPORT_PHY_USED_HDMI(phy)); 4931 + } 4932 + 4926 4933 void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) 4927 4934 { 4928 4935 struct intel_digital_port *dig_port; 4929 4936 struct intel_encoder *encoder; 4930 4937 bool init_hdmi, init_dp, init_lspcon = false; 4931 4938 enum phy phy = intel_port_to_phy(dev_priv, port); 4939 + 4940 + /* 4941 + * On platforms with HTI (aka HDPORT), if it's enabled at boot it may 4942 + * have taken over some of the PHYs and made them unavailable to the 4943 + * driver. In that case we should skip initializing the corresponding 4944 + * outputs. 4945 + */ 4946 + if (hti_uses_phy(dev_priv, phy)) { 4947 + drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n", 4948 + port_name(port), phy_name(phy)); 4949 + return; 4950 + } 4932 4951 4933 4952 init_hdmi = intel_bios_port_supports_dvi(dev_priv, port) || 4934 4953 intel_bios_port_supports_hdmi(dev_priv, port);
+8
drivers/gpu/drm/i915/display/intel_display.c
··· 47 47 #include "display/intel_ddi.h" 48 48 #include "display/intel_dp.h" 49 49 #include "display/intel_dp_mst.h" 50 + #include "display/intel_dpll_mgr.h" 50 51 #include "display/intel_dsi.h" 51 52 #include "display/intel_dvo.h" 52 53 #include "display/intel_gmbus.h" ··· 17903 17902 17904 17903 if (i915->max_cdclk_freq == 0) 17905 17904 intel_update_max_cdclk(i915); 17905 + 17906 + /* 17907 + * If the platform has HTI, we need to find out whether it has reserved 17908 + * any display resources before we create our display outputs. 17909 + */ 17910 + if (INTEL_INFO(i915)->display.has_hti) 17911 + i915->hti_state = intel_de_read(i915, HDPORT_STATE); 17906 17912 17907 17913 /* Just disable it once at startup */ 17908 17914 intel_vga_disable(i915);
+11
drivers/gpu/drm/i915/display/intel_dpll_mgr.c
··· 3475 3475 icl_set_active_port_dpll(crtc_state, port_dpll_id); 3476 3476 } 3477 3477 3478 + static u32 intel_get_hti_plls(struct drm_i915_private *i915) 3479 + { 3480 + if (!(i915->hti_state & HDPORT_ENABLED)) 3481 + return 0; 3482 + 3483 + return REG_FIELD_GET(HDPORT_DPLL_USED_MASK, i915->hti_state); 3484 + } 3485 + 3478 3486 static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state, 3479 3487 struct intel_crtc *crtc, 3480 3488 struct intel_encoder *encoder) ··· 3525 3517 } else { 3526 3518 dpll_mask = BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0); 3527 3519 } 3520 + 3521 + /* Eliminate DPLLs from consideration if reserved by HTI */ 3522 + dpll_mask &= ~intel_get_hti_plls(dev_priv); 3528 3523 3529 3524 port_dpll->pll = intel_find_shared_dpll(state, crtc, 3530 3525 &port_dpll->hw_state,
+8
drivers/gpu/drm/i915/i915_drv.h
··· 1045 1045 struct intel_l3_parity l3_parity; 1046 1046 1047 1047 /* 1048 + * HTI (aka HDPORT) state read during initial hw readout. Most 1049 + * platforms don't have HTI, so this will just stay 0. Those that do 1050 + * will use this later to figure out which PLLs and PHYs are unavailable 1051 + * for driver usage. 1052 + */ 1053 + u32 hti_state; 1054 + 1055 + /* 1048 1056 * edram size in MB. 1049 1057 * Cannot be determined by PCIID. You must always read a register. 1050 1058 */
+1
drivers/gpu/drm/i915/i915_pci.c
··· 890 890 .cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | 891 891 BIT(TRANSCODER_C), 892 892 .require_force_probe = 1, 893 + .display.has_hti = 1, 893 894 .display.has_psr_hw_tracking = 0, 894 895 .platform_engine_mask = 895 896 BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0),
+6
drivers/gpu/drm/i915/i915_reg.h
··· 2921 2921 #define MBUS_BBOX_CTL_S1 _MMIO(0x45040) 2922 2922 #define MBUS_BBOX_CTL_S2 _MMIO(0x45044) 2923 2923 2924 + #define HDPORT_STATE _MMIO(0x45050) 2925 + #define HDPORT_DPLL_USED_MASK REG_GENMASK(14, 12) 2926 + #define HDPORT_PHY_USED_DP(phy) REG_BIT(2 * (phy) + 2) 2927 + #define HDPORT_PHY_USED_HDMI(phy) REG_BIT(2 * (phy) + 1) 2928 + #define HDPORT_ENABLED REG_BIT(0) 2929 + 2924 2930 /* Make render/texture TLB fetches lower priorty than associated data 2925 2931 * fetches. This is not turned on by default 2926 2932 */
+1
drivers/gpu/drm/i915/intel_device_info.h
··· 146 146 func(has_gmch); \ 147 147 func(has_hdcp); \ 148 148 func(has_hotplug); \ 149 + func(has_hti); \ 149 150 func(has_ipc); \ 150 151 func(has_modular_fia); \ 151 152 func(has_overlay); \