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
41 41
42#include "i915_drv.h"42#include "i915_drv.h"
43#include "i915_reg.h"43#include "i915_reg.h"
44#include "intel_de.h"
44#include "intel_display_types.h"45#include "intel_display_types.h"
45#include "intel_dsi.h"46#include "intel_dsi.h"
46#include "intel_dsi_vbt.h"47#include "intel_dsi_vbt.h"
48#include "intel_gmbus_regs.h"
47#include "vlv_dsi.h"49#include "vlv_dsi.h"
48#include "vlv_dsi_regs.h"50#include "vlv_dsi_regs.h"
49#include "vlv_sideband.h"51#include "vlv_sideband.h"
@@ -377,6 +379,85 @@ static void icl_exec_gpio(struct intel_connector *connector, · 327 unmodified lines
377 drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n");379 drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n");
378}380}
379 381
382enum {
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
395static 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
380static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)461static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
381{462{
382 struct drm_device *dev = intel_dsi->base.base.dev;463 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
384 struct intel_connector *connector = intel_dsi->attached_connector;465 struct intel_connector *connector = intel_dsi->attached_connector;
385 u8 gpio_source, gpio_index = 0, gpio_number;466 u8 gpio_source, gpio_index = 0, gpio_number;
386 bool value;467 bool value;
387 468 bool native = DISPLAY_VER(dev_priv) >= 11;
388 drm_dbg_kms(&dev_priv->drm, "\n");
389 469
390 if (connector->panel.vbt.dsi.seq_version >= 3)470 if (connector->panel.vbt.dsi.seq_version >= 3)
391 gpio_index = *data++;471 gpio_index = *data++;
@@ -398,10 +478,18 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) · 6 unmodified lines
398 else478 else
399 gpio_source = 0;479 gpio_source = 0;
400 480
481 if (connector->panel.vbt.dsi.seq_version >= 4 && *data & BIT(1))
482 native = false;
483
401 /* pull up/down */484 /* pull up/down */
402 value = *data++ & 1;485 value = *data++ & 1;
403 486
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)
405 icl_exec_gpio(connector, gpio_source, gpio_index, value);493 icl_exec_gpio(connector, gpio_source, gpio_index, value);
406 else if (IS_VALLEYVIEW(dev_priv))494 else if (IS_VALLEYVIEW(dev_priv))
407 vlv_exec_gpio(connector, gpio_source, gpio_number, value);495 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
1974 if (ddi_hotplug_trigger) {1974 if (ddi_hotplug_trigger) {
1975 u32 dig_hotplug_reg;1975 u32 dig_hotplug_reg;
1976 1976
1977 /* Locking due to DSI native GPIO sequences */
1978 spin_lock(&dev_priv->irq_lock);
1977 dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0);1979 dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0);
1980 spin_unlock(&dev_priv->irq_lock);
1978 1981
1979 intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,1982 intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
1980 ddi_hotplug_trigger, dig_hotplug_reg,1983 ddi_hotplug_trigger, dig_hotplug_reg,
drivers/gpu/drm/i915/i915_reg.h+1−0
@@ -5988,6 +5988,7 @@ · 5987 unmodified lines
5988 5988
5989#define SHOTPLUG_CTL_DDI _MMIO(0xc4030)5989#define SHOTPLUG_CTL_DDI _MMIO(0xc4030)
5990#define SHOTPLUG_CTL_DDI_HPD_ENABLE(hpd_pin) (0x8 << (_HPD_PIN_DDI(hpd_pin) * 4))5990#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))
5991#define SHOTPLUG_CTL_DDI_HPD_STATUS_MASK(hpd_pin) (0x3 << (_HPD_PIN_DDI(hpd_pin) * 4))5992#define SHOTPLUG_CTL_DDI_HPD_STATUS_MASK(hpd_pin) (0x3 << (_HPD_PIN_DDI(hpd_pin) * 4))
5992#define SHOTPLUG_CTL_DDI_HPD_NO_DETECT(hpd_pin) (0x0 << (_HPD_PIN_DDI(hpd_pin) * 4))5993#define SHOTPLUG_CTL_DDI_HPD_NO_DETECT(hpd_pin) (0x0 << (_HPD_PIN_DDI(hpd_pin) * 4))
5993#define SHOTPLUG_CTL_DDI_HPD_SHORT_DETECT(hpd_pin) (0x1 << (_HPD_PIN_DDI(hpd_pin) * 4))5994#define SHOTPLUG_CTL_DDI_HPD_SHORT_DETECT(hpd_pin) (0x1 << (_HPD_PIN_DDI(hpd_pin) * 4))