Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26951caf authored by Xiong Zhang's avatar Xiong Zhang Committed by Jani Nikula
Browse files

drm/i915/skl: enable DDI-E hotplug



v2: fix one error found by checkpath.pl
v3: Add one ignored break for switch-case. DDI-E hotplug
    function doesn't work after updating drm-intel tree,
    I checked the code and found this missing which isn't
    the root cause for broke DDI-E hp.  The broken
    DDI-E hp function is fixed by "Adding DDI_E power
    well domain".

Signed-off-by: default avatarXiong Zhang <xiong.y.zhang@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Tested-by: default avatarTimo Aaltonen <timo.aaltonen@canonical.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 8e9d597a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ enum hpd_pin {
	HPD_PORT_B,
	HPD_PORT_C,
	HPD_PORT_D,
	HPD_PORT_E,
	HPD_NUM_PINS
};

+44 −4
Original line number Diff line number Diff line
@@ -61,6 +61,13 @@ static const u32 hpd_cpt[HPD_NUM_PINS] = {
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
};

static const u32 hpd_spt[HPD_NUM_PINS] = {
	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
	[HPD_PORT_E] = SDE_PORTE_HOTPLUG_SPT
};

static const u32 hpd_mask_i915[HPD_NUM_PINS] = {
	[HPD_CRT] = CRT_HOTPLUG_INT_EN,
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
@@ -1252,6 +1259,8 @@ static bool pch_port_hotplug_long_detect(enum port port, u32 val)
		return val & PORTC_HOTPLUG_LONG_DETECT;
	case PORT_D:
		return val & PORTD_HOTPLUG_LONG_DETECT;
	case PORT_E:
		return val & PORTE_HOTPLUG_LONG_DETECT;
	default:
		return false;
	}
@@ -1752,7 +1761,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int pipe;
	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
	u32 hotplug_trigger;

	if (HAS_PCH_SPT(dev))
		hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT;
	else
		hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;

	if (hotplug_trigger) {
		u32 dig_hotplug_reg, pin_mask, long_mask;
@@ -1760,9 +1774,23 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
		dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
		I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);

		intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger,
		if (HAS_PCH_SPT(dev)) {
			intel_get_hpd_pins(&pin_mask, &long_mask,
					   hotplug_trigger,
					   dig_hotplug_reg, hpd_spt,
					   pch_port_hotplug_long_detect);

			/* detect PORTE HP event */
			dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
			if (pch_port_hotplug_long_detect(PORT_E,
							 dig_hotplug_reg))
				long_mask |= 1 << HPD_PORT_E;
		} else
			intel_get_hpd_pins(&pin_mask, &long_mask,
					   hotplug_trigger,
					   dig_hotplug_reg, hpd_cpt,
					   pch_port_hotplug_long_detect);

		intel_hpd_irq_handler(dev, pin_mask, long_mask);
	}

@@ -2984,6 +3012,11 @@ static void ibx_hpd_irq_setup(struct drm_device *dev)
		for_each_intel_encoder(dev, intel_encoder)
			if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
				enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin];
	} else if (HAS_PCH_SPT(dev)) {
		hotplug_irqs = SDE_HOTPLUG_MASK_SPT;
		for_each_intel_encoder(dev, intel_encoder)
			if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
				enabled_irqs |= hpd_spt[intel_encoder->hpd_pin];
	} else {
		hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
		for_each_intel_encoder(dev, intel_encoder)
@@ -3005,6 +3038,13 @@ static void ibx_hpd_irq_setup(struct drm_device *dev)
	hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms;
	hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms;
	I915_WRITE(PCH_PORT_HOTPLUG, hotplug);

	/* enable SPT PORTE hot plug */
	if (HAS_PCH_SPT(dev)) {
		hotplug = I915_READ(PCH_PORT_HOTPLUG2);
		hotplug |= PORTE_HOTPLUG_ENABLE;
		I915_WRITE(PCH_PORT_HOTPLUG2, hotplug);
	}
}

static void bxt_hpd_irq_setup(struct drm_device *dev)
+12 −0
Original line number Diff line number Diff line
@@ -5949,6 +5949,7 @@ enum skl_disp_power_wells {
#define SDE_AUXC_CPT		(1 << 26)
#define SDE_AUXB_CPT		(1 << 25)
#define SDE_AUX_MASK_CPT	(7 << 25)
#define SDE_PORTE_HOTPLUG_SPT	(1 << 25)
#define SDE_PORTD_HOTPLUG_CPT	(1 << 23)
#define SDE_PORTC_HOTPLUG_CPT	(1 << 22)
#define SDE_PORTB_HOTPLUG_CPT	(1 << 21)
@@ -5959,6 +5960,10 @@ enum skl_disp_power_wells {
				 SDE_PORTD_HOTPLUG_CPT |	\
				 SDE_PORTC_HOTPLUG_CPT |	\
				 SDE_PORTB_HOTPLUG_CPT)
#define SDE_HOTPLUG_MASK_SPT	(SDE_PORTE_HOTPLUG_SPT |	\
				 SDE_PORTD_HOTPLUG_CPT |	\
				 SDE_PORTC_HOTPLUG_CPT |	\
				 SDE_PORTB_HOTPLUG_CPT)
#define SDE_GMBUS_CPT		(1 << 17)
#define SDE_ERROR_CPT		(1 << 16)
#define SDE_AUDIO_CP_REQ_C_CPT	(1 << 10)
@@ -6030,6 +6035,13 @@ enum skl_disp_power_wells {
#define  PORTB_HOTPLUG_SHORT_DETECT	(1 << 0)
#define  PORTB_HOTPLUG_LONG_DETECT	(2 << 0)

#define PCH_PORT_HOTPLUG2        0xc403C		/* SHOTPLUG_CTL2 */
#define PORTE_HOTPLUG_ENABLE            (1 << 4)
#define PORTE_HOTPLUG_STATUS_MASK	(0x3 << 0)
#define  PORTE_HOTPLUG_NO_DETECT	(0 << 0)
#define  PORTE_HOTPLUG_SHORT_DETECT	(1 << 0)
#define  PORTE_HOTPLUG_LONG_DETECT	(2 << 0)

#define PCH_GPIOA               0xc5010
#define PCH_GPIOB               0xc5014
#define PCH_GPIOC               0xc5018
+3 −0
Original line number Diff line number Diff line
@@ -1098,6 +1098,9 @@ bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
		case PORT_D:
			bit = SDE_PORTD_HOTPLUG_CPT;
			break;
		case PORT_E:
			bit = SDE_PORTE_HOTPLUG_SPT;
			break;
		default:
			return true;
		}
+3 −0
Original line number Diff line number Diff line
@@ -5860,6 +5860,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
	case PORT_D:
		intel_encoder->hpd_pin = HPD_PORT_D;
		break;
	case PORT_E:
		intel_encoder->hpd_pin = HPD_PORT_E;
		break;
	default:
		BUG();
	}
Loading