aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_combo_phy.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2020-02-27 08:59:19 +1000
committerDave Airlie <airlied@redhat.com>2020-02-27 09:00:25 +1000
commit4825b61a3d39eceef7db723808103aa60fc24520 (patch)
tree87e1a754aef38ef088a5ec8e1613790c5a17c078 /drivers/gpu/drm/i915/display/intel_combo_phy.c
parentaaa9d265a21e7c4fcec12b1203cbfa516277e4ad (diff)
parent53e3ca6749186b5c147964bddc4eb47ba8b5f69e (diff)
Merge tag 'drm-intel-next-2020-02-25' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- A backmerge of drm-next solving conflicts on i915/gt/intel_lrc.c - Clean up shadow batch after I915_EXEC_SECURE - Drop assertion that active->fence is unchanged Here goes drm-intel-next-2020-02-25: - A backmerge of drm-next solving conflicts on i915/gt/intel_lrc.c - Clean up shadow batch after I915_EXEC_SECURE - Drop assertion that active->fence is unchanged drm-intel-next-2020-02-24-1: - RC6 fixes - Chris - Add extra slice common debug register - Lionel - Align virtual engines uabi_class/instance with i915_drm.h - Tvrtko - Avoid potential division by zero in computing CS timestamp - Chris - Avoid using various globals - Michal Winiarski, Matt Auld - Break up long lists of GEM object reclaim - Chris - Check that the vma hasn't been closed before we insert it - Chris - Consolidate SDVO HDMI force_dvi handling - Ville - Conversion to new logging and warn macros and functions - Pankaj, Wambul, Chris - DC3CO fixes - Jose - Disable use of hwsp_cacheline for kernel_context - Chris - Display IRQ pre/post uninstall refactor - Jani - Display port sync refactor for robustness and fixes - Ville, Manasi - Do not attempt to reprogram IA/ring frequencies for dgfx - Chris - Drop alpha_support for good in favor of force_probe - Jani - DSI ACPI related fixes and refactors - Vivek, Jani, Rajat - Encoder refactor for flexibility to add more information, especiallly DSI related - Jani, Vandita - Engine workarounds refactor for robustness around resue - Daniele - FBC simplification and tracepoints - Various fixes for build - Jani, Kees Cook, Chris, Zhang Xiaoxu - Fix cmdparser - Chris - Fix DRM_I915_GEM_MMAP_OFFFSET - Chris - Fix i915_request flags - Chris - Fix inconsistency between pfit enable and scaler freeing - Stanislav - Fix inverted warn_on on display code - Chris - Fix modeset locks in sanitize_watermarks - Ville - Fix OA context id overlap with idle context id - Umesh - Fix pipe and vblank enable for MST - Jani - Fix VBT handling for timing parameters - Vandita - Fixes o kernel doc - Chris, Ville - Force full modeset whenever DSC is enabled at probe - Jani - Various GEM locking simplification and fixes - Jani , Chris, Jose - Including some changes in preparation for making GEM execbuf parallel - Chris - Gen11 pcode error codes - Matt Roper - Gen8+ interrupt handler refactor - Chris - Many fixes and improvements around GuC code - Daniele, Michal Wajdeczko - i915 parameters improvements sfor flexible input and better debugability - Chris, Jani - Ice Lake and Elkhart Lake Fixes and workarounds - Matt Roper, Jose, Vivek, Matt Atwood - Improvements on execlists, requests and other areas, fixing hangs and also improving hang detection, recover and debugability - Chris - Also introducing offline GT error capture - Chris - Introduce encoder->compute_config_late() to help MST - Ville - Make dbuf configuration const - Jani - Few misc clean ups - Ville, Chris - Never allow userptr into the new mapping types - Janusz - Poison rings after use and GTT scratch pages - Chris - Protect signaler walk with RCU - Chris - PSR fixes - Jose - Pull sseu context updates under gt - Chris - Read rawclk_freq earlier - Chris - Refactor around VBT handling to allow geting information through the encoder - Jani - Refactor l3cc/mocs availability - Chris - Refactor to use intel_connector over drm_connector - Ville - Remove i915_energy_uJ from debugfs - Tvrtko - Remove lite restore defines - Mika Kuoppala - Remove prefault_disable modparam - Chris - Many selftests fixes and improvements - Chris - Set intel_dp_set_m_n() for MST slaves - Jose - Simplify hot plug pin handling and other fixes around pin and polled modes - Ville - Skip CPU synchronization on dma-buf attachments - chris - Skip global serialization of clear_range for bxt vtd - Chris - Skip rmw for marked register - Chris - Some other GEM Fixes - Chris - Some small changes for satisfying static code analysis - Colin, Chris - Suppress warnings for unused debugging locals - Tiger Lake enabling, including re-enable -f RPS, workarounds and other display fixes and changes - Chris, Matt Roper, Mika Kuoppala, Anshuman, Jose, Radhakrishna, Rafael. - Track hw reported context runtime - Tvrtko - Update bug filling URL - Jani - Use async bind for PIN_USER into bsw/bxt ggtt - Chris - Use the kernel_context to measuer the breadcrumb size - Chris - Userptr fixes and robustness for big pages - Matt Auld - Various Display refactors and clean-ups, specially around logs and use of drm_i915_private - Jani, Ville - Various display refactors and fixes, especially around cdclk, modeset, and encoder - Chris, Jani - Various eDP/DP fixes around DPCD - Lyude - Various fixes and refactors for better Display watermark handling - Ville, Stanislav - Various other display refactors - Ville - Various refactor for better handling of display plane states - Ville - Wean off drm_pci_alloc/drm_pci_free - Chris - Correctly terminate connector iteration- Ville - Downgrade gen7 (ivb, byt, hsw) back to aliasing-ppgtt - Chris Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200225185853.GA3282832@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_combo_phy.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy.c163
1 files changed, 92 insertions, 71 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 44bbc7e74fc3..9ff05ec12115 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -48,7 +48,7 @@ cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
const struct cnl_procmon *procmon;
u32 val;
- val = I915_READ(ICL_PORT_COMP_DW3(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy));
switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
default:
MISSING_CASE(val);
@@ -81,26 +81,27 @@ static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
procmon = cnl_get_procmon_ref_values(dev_priv, phy);
- val = I915_READ(ICL_PORT_COMP_DW1(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_COMP_DW1(phy));
val &= ~((0xff << 16) | 0xff);
val |= procmon->dw1;
- I915_WRITE(ICL_PORT_COMP_DW1(phy), val);
+ intel_de_write(dev_priv, ICL_PORT_COMP_DW1(phy), val);
- I915_WRITE(ICL_PORT_COMP_DW9(phy), procmon->dw9);
- I915_WRITE(ICL_PORT_COMP_DW10(phy), procmon->dw10);
+ intel_de_write(dev_priv, ICL_PORT_COMP_DW9(phy), procmon->dw9);
+ intel_de_write(dev_priv, ICL_PORT_COMP_DW10(phy), procmon->dw10);
}
static bool check_phy_reg(struct drm_i915_private *dev_priv,
enum phy phy, i915_reg_t reg, u32 mask,
u32 expected_val)
{
- u32 val = I915_READ(reg);
+ u32 val = intel_de_read(dev_priv, reg);
if ((val & mask) != expected_val) {
- DRM_DEBUG_DRIVER("Combo PHY %c reg %08x state mismatch: "
- "current %08x mask %08x expected %08x\n",
- phy_name(phy),
- reg.reg, val, mask, expected_val);
+ drm_dbg(&dev_priv->drm,
+ "Combo PHY %c reg %08x state mismatch: "
+ "current %08x mask %08x expected %08x\n",
+ phy_name(phy),
+ reg.reg, val, mask, expected_val);
return false;
}
@@ -127,8 +128,8 @@ static bool cnl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
static bool cnl_combo_phy_enabled(struct drm_i915_private *dev_priv)
{
- return !(I915_READ(CHICKEN_MISC_2) & CNL_COMP_PWR_DOWN) &&
- (I915_READ(CNL_PORT_COMP_DW0) & COMP_INIT);
+ return !(intel_de_read(dev_priv, CHICKEN_MISC_2) & CNL_COMP_PWR_DOWN) &&
+ (intel_de_read(dev_priv, CNL_PORT_COMP_DW0) & COMP_INIT);
}
static bool cnl_combo_phy_verify_state(struct drm_i915_private *dev_priv)
@@ -151,20 +152,20 @@ static void cnl_combo_phys_init(struct drm_i915_private *dev_priv)
{
u32 val;
- val = I915_READ(CHICKEN_MISC_2);
+ val = intel_de_read(dev_priv, CHICKEN_MISC_2);
val &= ~CNL_COMP_PWR_DOWN;
- I915_WRITE(CHICKEN_MISC_2, val);
+ intel_de_write(dev_priv, CHICKEN_MISC_2, val);
/* Dummy PORT_A to get the correct CNL register from the ICL macro */
cnl_set_procmon_ref_values(dev_priv, PHY_A);
- val = I915_READ(CNL_PORT_COMP_DW0);
+ val = intel_de_read(dev_priv, CNL_PORT_COMP_DW0);
val |= COMP_INIT;
- I915_WRITE(CNL_PORT_COMP_DW0, val);
+ intel_de_write(dev_priv, CNL_PORT_COMP_DW0, val);
- val = I915_READ(CNL_PORT_CL1CM_DW5);
+ val = intel_de_read(dev_priv, CNL_PORT_CL1CM_DW5);
val |= CL_POWER_DOWN_ENABLE;
- I915_WRITE(CNL_PORT_CL1CM_DW5, val);
+ intel_de_write(dev_priv, CNL_PORT_CL1CM_DW5, val);
}
static void cnl_combo_phys_uninit(struct drm_i915_private *dev_priv)
@@ -172,11 +173,12 @@ static void cnl_combo_phys_uninit(struct drm_i915_private *dev_priv)
u32 val;
if (!cnl_combo_phy_verify_state(dev_priv))
- DRM_WARN("Combo PHY HW state changed unexpectedly.\n");
+ drm_warn(&dev_priv->drm,
+ "Combo PHY HW state changed unexpectedly.\n");
- val = I915_READ(CHICKEN_MISC_2);
+ val = intel_de_read(dev_priv, CHICKEN_MISC_2);
val |= CNL_COMP_PWR_DOWN;
- I915_WRITE(CHICKEN_MISC_2, val);
+ intel_de_write(dev_priv, CHICKEN_MISC_2, val);
}
static bool icl_combo_phy_enabled(struct drm_i915_private *dev_priv,
@@ -184,27 +186,65 @@ static bool icl_combo_phy_enabled(struct drm_i915_private *dev_priv,
{
/* The PHY C added by EHL has no PHY_MISC register */
if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
- return I915_READ(ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
+ return intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
else
- return !(I915_READ(ICL_PHY_MISC(phy)) &
+ return !(intel_de_read(dev_priv, ICL_PHY_MISC(phy)) &
ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN) &&
- (I915_READ(ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
+ (intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
+}
+
+static bool ehl_vbt_ddi_d_present(struct drm_i915_private *i915)
+{
+ bool ddi_a_present = intel_bios_is_port_present(i915, PORT_A);
+ bool ddi_d_present = intel_bios_is_port_present(i915, PORT_D);
+ 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 true;
+
+ /*
+ * 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_err(&i915->drm,
+ "VBT claims to have both internal and external displays on PHY A. Configuring for internal.\n");
+
+ return false;
}
static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
enum phy phy)
{
bool ret;
+ u32 expected_val = 0;
if (!icl_combo_phy_enabled(dev_priv, phy))
return false;
ret = cnl_verify_procmon_ref_values(dev_priv, phy);
- if (phy == PHY_A)
+ if (phy == PHY_A) {
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy),
IREFGEN, IREFGEN);
+ if (IS_ELKHARTLAKE(dev_priv)) {
+ if (ehl_vbt_ddi_d_present(dev_priv))
+ expected_val = ICL_PHY_MISC_MUX_DDID;
+
+ ret &= check_phy_reg(dev_priv, phy, ICL_PHY_MISC(phy),
+ ICL_PHY_MISC_MUX_DDID,
+ expected_val);
+ }
+ }
+
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_CL_DW5(phy),
CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);
@@ -219,7 +259,7 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
u32 val;
if (is_dsi) {
- WARN_ON(lane_reversal);
+ drm_WARN_ON(&dev_priv->drm, lane_reversal);
switch (lane_count) {
case 1:
@@ -257,36 +297,10 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
}
}
- val = I915_READ(ICL_PORT_CL_DW10(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_CL_DW10(phy));
val &= ~PWR_DOWN_LN_MASK;
val |= lane_mask << PWR_DOWN_LN_SHIFT;
- I915_WRITE(ICL_PORT_CL_DW10(phy), 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;
+ intel_de_write(dev_priv, ICL_PORT_CL_DW10(phy), val);
}
static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
@@ -297,8 +311,9 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
u32 val;
if (icl_combo_phy_verify_state(dev_priv, phy)) {
- DRM_DEBUG_DRIVER("Combo PHY %c already enabled, won't reprogram it.\n",
- phy_name(phy));
+ drm_dbg(&dev_priv->drm,
+ "Combo PHY %c already enabled, won't reprogram it.\n",
+ phy_name(phy));
continue;
}
@@ -318,28 +333,33 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
* based on whether our VBT indicates the presence of any
* "internal" child devices.
*/
- val = I915_READ(ICL_PHY_MISC(phy));
- if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_A)
- val = ehl_combo_phy_a_mux(dev_priv, val);
+ val = intel_de_read(dev_priv, ICL_PHY_MISC(phy));
+ if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_A) {
+ val &= ~ICL_PHY_MISC_MUX_DDID;
+
+ if (ehl_vbt_ddi_d_present(dev_priv))
+ val |= ICL_PHY_MISC_MUX_DDID;
+ }
+
val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
- I915_WRITE(ICL_PHY_MISC(phy), val);
+ intel_de_write(dev_priv, ICL_PHY_MISC(phy), val);
skip_phy_misc:
cnl_set_procmon_ref_values(dev_priv, phy);
if (phy == PHY_A) {
- val = I915_READ(ICL_PORT_COMP_DW8(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_COMP_DW8(phy));
val |= IREFGEN;
- I915_WRITE(ICL_PORT_COMP_DW8(phy), val);
+ intel_de_write(dev_priv, ICL_PORT_COMP_DW8(phy), val);
}
- val = I915_READ(ICL_PORT_COMP_DW0(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy));
val |= COMP_INIT;
- I915_WRITE(ICL_PORT_COMP_DW0(phy), val);
+ intel_de_write(dev_priv, ICL_PORT_COMP_DW0(phy), val);
- val = I915_READ(ICL_PORT_CL_DW5(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_CL_DW5(phy));
val |= CL_POWER_DOWN_ENABLE;
- I915_WRITE(ICL_PORT_CL_DW5(phy), val);
+ intel_de_write(dev_priv, ICL_PORT_CL_DW5(phy), val);
}
}
@@ -352,7 +372,8 @@ static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv)
if (phy == PHY_A &&
!icl_combo_phy_verify_state(dev_priv, phy))
- DRM_WARN("Combo PHY %c HW state changed unexpectedly\n",
+ drm_warn(&dev_priv->drm,
+ "Combo PHY %c HW state changed unexpectedly\n",
phy_name(phy));
/*
@@ -363,14 +384,14 @@ static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv)
if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
goto skip_phy_misc;
- val = I915_READ(ICL_PHY_MISC(phy));
+ val = intel_de_read(dev_priv, ICL_PHY_MISC(phy));
val |= ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
- I915_WRITE(ICL_PHY_MISC(phy), val);
+ intel_de_write(dev_priv, ICL_PHY_MISC(phy), val);
skip_phy_misc:
- val = I915_READ(ICL_PORT_COMP_DW0(phy));
+ val = intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy));
val &= ~COMP_INIT;
- I915_WRITE(ICL_PORT_COMP_DW0(phy), val);
+ intel_de_write(dev_priv, ICL_PORT_COMP_DW0(phy), val);
}
}