History

drm/i915/dsi: add support for ICL+ native MIPI GPIO sequence

Starting from ICL, the default for MIPI GPIO sequences seems to be using native GPIOs i.e. GPIOs available in the GPU. These native GPIOs reuse many pins that quite frankly seem scary to poke based on the VBT sequences. We pretty much have to trust that the board is configured such that the relevant HPD, PP_CONTROL and GPIO bits aren't used for anything else. MIPI sequence v4 also adds a flag to fall back to non-native sequences. v5: - Wrap SHOTPLUG_CTL_DDI modification in spin_lock() in icp_irq_handler() too (Ville) - References instead of Closes issue 6131 because this does not fix everything v4: - Wrap SHOTPLUG_CTL_DDI modification in spin_lock_irq() (Ville) v3: - Fix -Wbitwise-conditional-parentheses (kernel test robot <lkp@intel.com>) v2: - Fix HPD pin output set (impacts GPIOs 0 and 5) - Fix GPIO data output direction set (impacts GPIOs 4 and 9) - Reduce register accesses to single intel_de_rwm()

Jani Nikula committed 3 years ago

Commit 963bbdb1 parent 11ce8fd3 files · +95 −3Browse files

Unified · Split

3 files
  1. drivers/gpu/drm/i915/display/intel_dsi_vbt.c +91 −3
  2. drivers/gpu/drm/i915/i915_irq.c +3 −0
  3. drivers/gpu/drm/i915/i915_reg.h +1 −0
drivers/gpu/drm/i915/display/intel_dsi_vbt.c+91−3
@@ -41,9 +41,11 @@ · 40 unmodified lines
4141
4242 #include "i915_drv.h"
4343 #include "i915_reg.h"
44+#include "intel_de.h"
4445 #include "intel_display_types.h"
4546 #include "intel_dsi.h"
4647 #include "intel_dsi_vbt.h"
48+#include "intel_gmbus_regs.h"
4749 #include "vlv_dsi.h"
4850 #include "vlv_dsi_regs.h"
4951 #include "vlv_sideband.h"
@@ -377,6 +379,85 @@ static void icl_exec_gpio(struct intel_connector *connector, · 327 unmodified lines
377379 drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n");
378380 }
379381
382+enum {
383+ MIPI_RESET_1 = 0,
384+ MIPI_AVDD_EN_1,
385+ MIPI_BKLT_EN_1,
386+ MIPI_AVEE_EN_1,
387+ MIPI_VIO_EN_1,
388+ MIPI_RESET_2,
389+ MIPI_AVDD_EN_2,
390+ MIPI_BKLT_EN_2,
391+ MIPI_AVEE_EN_2,
392+ MIPI_VIO_EN_2,
393+};
394+
395+static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
396+ int gpio, bool value)
397+{
398+ int index;
399+
400+ if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 11 && gpio >= MIPI_RESET_2))
401+ return;
402+
403+ switch (gpio) {
404+ case MIPI_RESET_1:
405+ case MIPI_RESET_2:
406+ index = gpio == MIPI_RESET_1 ? HPD_PORT_A : HPD_PORT_B;
407+
408+ /*
409+ * Disable HPD to set the pin to output, and set output
410+ * value. The HPD pin should not be enabled for DSI anyway,
411+ * assuming the board design and VBT are sane, and the pin isn't
412+ * used by a non-DSI encoder.
413+ *
414+ * The locking protects against concurrent SHOTPLUG_CTL_DDI
415+ * modifications in irq setup and handling.
416+ */
417+ spin_lock_irq(&dev_priv->irq_lock);
418+ intel_de_rmw(dev_priv, SHOTPLUG_CTL_DDI,
419+ SHOTPLUG_CTL_DDI_HPD_ENABLE(index) |
420+ SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index),
421+ value ? SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index) : 0);
422+ spin_unlock_irq(&dev_priv->irq_lock);
423+ break;
424+ case MIPI_AVDD_EN_1:
425+ case MIPI_AVDD_EN_2:
426+ index = gpio == MIPI_AVDD_EN_1 ? 0 : 1;
427+
428+ intel_de_rmw(dev_priv, PP_CONTROL(index), PANEL_POWER_ON,
429+ value ? PANEL_POWER_ON : 0);
430+ break;
431+ case MIPI_BKLT_EN_1:
432+ case MIPI_BKLT_EN_2:
433+ index = gpio == MIPI_AVDD_EN_1 ? 0 : 1;
434+
435+ intel_de_rmw(dev_priv, PP_CONTROL(index), EDP_BLC_ENABLE,
436+ value ? EDP_BLC_ENABLE : 0);
437+ break;
438+ case MIPI_AVEE_EN_1:
439+ case MIPI_AVEE_EN_2:
440+ index = gpio == MIPI_AVEE_EN_1 ? 1 : 2;
441+
442+ intel_de_rmw(dev_priv, GPIO(dev_priv, index),
443+ GPIO_CLOCK_VAL_OUT,
444+ GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_DIR_OUT |
445+ GPIO_CLOCK_VAL_MASK | (value ? GPIO_CLOCK_VAL_OUT : 0));
446+ break;
447+ case MIPI_VIO_EN_1:
448+ case MIPI_VIO_EN_2:
449+ index = gpio == MIPI_VIO_EN_1 ? 1 : 2;
450+
451+ intel_de_rmw(dev_priv, GPIO(dev_priv, index),
452+ GPIO_DATA_VAL_OUT,
453+ GPIO_DATA_DIR_MASK | GPIO_DATA_DIR_OUT |
454+ GPIO_DATA_VAL_MASK | (value ? GPIO_DATA_VAL_OUT : 0));
455+ break;
456+ default:
457+ MISSING_CASE(gpio);
458+ }
459+}
460+
380461 static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
381462 {
382463 struct drm_device *dev = intel_dsi->base.base.dev;
@@ -384,8 +465,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) · 1 unmodified line
384465 struct intel_connector *connector = intel_dsi->attached_connector;
385466 u8 gpio_source, gpio_index = 0, gpio_number;
386467 bool value;
387−
388− drm_dbg_kms(&dev_priv->drm, "\n");
468+ bool native = DISPLAY_VER(dev_priv) >= 11;
389469
390470 if (connector->panel.vbt.dsi.seq_version >= 3)
391471 gpio_index = *data++;
@@ -398,10 +478,18 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) · 6 unmodified lines
398478 else
399479 gpio_source = 0;
400480
481+ if (connector->panel.vbt.dsi.seq_version >= 4 && *data & BIT(1))
482+ native = false;
483+
401484 /* pull up/down */
402485 value = *data++ & 1;
403486
404− if (DISPLAY_VER(dev_priv) >= 11)
487+ drm_dbg_kms(&dev_priv->drm, "GPIO index %u, number %u, source %u, native %s, set to %s\n",
488+ gpio_index, gpio_number, gpio_source, str_yes_no(native), str_on_off(value));
489+
490+ if (native)
491+ icl_native_gpio_set_value(dev_priv, gpio_number, value);
492+ else if (DISPLAY_VER(dev_priv) >= 11)
405493 icl_exec_gpio(connector, gpio_source, gpio_index, value);
406494 else if (IS_VALLEYVIEW(dev_priv))
407495 vlv_exec_gpio(connector, gpio_source, gpio_number, value);
drivers/gpu/drm/i915/i915_irq.c+3−0
@@ -1974,7 +1974,10 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) · 1973 unmodified lines
19741974 if (ddi_hotplug_trigger) {
19751975 u32 dig_hotplug_reg;
19761976
1977+ /* Locking due to DSI native GPIO sequences */
1978+ spin_lock(&dev_priv->irq_lock);
19771979 dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0);
1980+ spin_unlock(&dev_priv->irq_lock);
19781981
19791982 intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
19801983 ddi_hotplug_trigger, dig_hotplug_reg,
drivers/gpu/drm/i915/i915_reg.h+1−0
@@ -5988,6 +5988,7 @@ · 5987 unmodified lines
59885988
59895989 #define SHOTPLUG_CTL_DDI _MMIO(0xc4030)
59905990 #define SHOTPLUG_CTL_DDI_HPD_ENABLE(hpd_pin) (0x8 << (_HPD_PIN_DDI(hpd_pin) * 4))
5991+#define SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(hpd_pin) (0x4 << (_HPD_PIN_DDI(hpd_pin) * 4))
59915992 #define SHOTPLUG_CTL_DDI_HPD_STATUS_MASK(hpd_pin) (0x3 << (_HPD_PIN_DDI(hpd_pin) * 4))
59925993 #define SHOTPLUG_CTL_DDI_HPD_NO_DETECT(hpd_pin) (0x0 << (_HPD_PIN_DDI(hpd_pin) * 4))
59935994 #define SHOTPLUG_CTL_DDI_HPD_SHORT_DETECT(hpd_pin) (0x1 << (_HPD_PIN_DDI(hpd_pin) * 4))