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

Commit 701078d5 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2015-08-28' of...

Merge tag 'drm-intel-next-fixes-2015-08-28' of git://anongit.freedesktop.org/drm-intel into drm-next

Some i915 fixes headed for v4.3. SKL DDI-E is a wip, but here's the
first in a series.

* tag 'drm-intel-next-fixes-2015-08-28' of git://anongit.freedesktop.org/drm-intel:
  drm/i915/skl: enable DDI-E hotplug
  drm/i915: Fix build warning on 32-bit
  drm/i915/skl: Update DDI buffer translation programming.
  drm/i915: Allow parsing of variable size child device entries from VBT
  drm/i915: fix link rates reported for SKL
  drm/i915: fix VBT parsing for SDVO child device mapping
parents d3e8ea50 26951caf
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
};

+1 −1
Original line number Diff line number Diff line
@@ -348,7 +348,7 @@ int i915_gem_init_stolen(struct drm_device *dev)
	 * memory, so just consider the start. */
	reserved_total = stolen_top - reserved_base;

	DRM_DEBUG_KMS("Memory reserved for graphics device: %luK, usable: %luK\n",
	DRM_DEBUG_KMS("Memory reserved for graphics device: %zuK, usable: %luK\n",
		      dev_priv->gtt.stolen_size >> 10,
		      (dev_priv->gtt.stolen_size - reserved_total) >> 10);

+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
+58 −29
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
{
	struct sdvo_device_mapping *p_mapping;
	const struct bdb_general_definitions *p_defs;
	const union child_device_config *p_child;
	const struct old_child_dev_config *child; /* legacy */
	int i, child_device_num, count;
	u16	block_size;

@@ -410,14 +410,14 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
		DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
		return;
	}
	/* judge whether the size of child device meets the requirements.
	 * If the child device size obtained from general definition block
	 * is different with sizeof(struct child_device_config), skip the
	 * parsing of sdvo device info

	/*
	 * Only parse SDVO mappings when the general definitions block child
	 * device size matches that of the *legacy* child device config
	 * struct. Thus, SDVO mapping will be skipped for newer VBT.
	 */
	if (p_defs->child_dev_size != sizeof(*p_child)) {
		/* different child dev size . Ignore it */
		DRM_DEBUG_KMS("different child size is found. Invalid.\n");
	if (p_defs->child_dev_size != sizeof(*child)) {
		DRM_DEBUG_KMS("Unsupported child device size for SDVO mapping.\n");
		return;
	}
	/* get the block size of general definitions */
@@ -427,37 +427,37 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
		p_defs->child_dev_size;
	count = 0;
	for (i = 0; i < child_device_num; i++) {
		p_child = child_device_ptr(p_defs, i);
		if (!p_child->old.device_type) {
		child = &child_device_ptr(p_defs, i)->old;
		if (!child->device_type) {
			/* skip the device block if device type is invalid */
			continue;
		}
		if (p_child->old.slave_addr != SLAVE_ADDR1 &&
			p_child->old.slave_addr != SLAVE_ADDR2) {
		if (child->slave_addr != SLAVE_ADDR1 &&
		    child->slave_addr != SLAVE_ADDR2) {
			/*
			 * If the slave address is neither 0x70 nor 0x72,
			 * it is not a SDVO device. Skip it.
			 */
			continue;
		}
		if (p_child->old.dvo_port != DEVICE_PORT_DVOB &&
			p_child->old.dvo_port != DEVICE_PORT_DVOC) {
		if (child->dvo_port != DEVICE_PORT_DVOB &&
		    child->dvo_port != DEVICE_PORT_DVOC) {
			/* skip the incorrect SDVO port */
			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
			continue;
		}
		DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
			      " %s port\n",
				p_child->old.slave_addr,
				(p_child->old.dvo_port == DEVICE_PORT_DVOB) ?
			      child->slave_addr,
			      (child->dvo_port == DEVICE_PORT_DVOB) ?
			      "SDVOB" : "SDVOC");
		p_mapping = &(dev_priv->sdvo_mappings[p_child->old.dvo_port - 1]);
		p_mapping = &(dev_priv->sdvo_mappings[child->dvo_port - 1]);
		if (!p_mapping->initialized) {
			p_mapping->dvo_port = p_child->old.dvo_port;
			p_mapping->slave_addr = p_child->old.slave_addr;
			p_mapping->dvo_wiring = p_child->old.dvo_wiring;
			p_mapping->ddc_pin = p_child->old.ddc_pin;
			p_mapping->i2c_pin = p_child->old.i2c_pin;
			p_mapping->dvo_port = child->dvo_port;
			p_mapping->slave_addr = child->slave_addr;
			p_mapping->dvo_wiring = child->dvo_wiring;
			p_mapping->ddc_pin = child->ddc_pin;
			p_mapping->i2c_pin = child->i2c_pin;
			p_mapping->initialized = 1;
			DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
				      p_mapping->dvo_port,
@@ -469,7 +469,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
					 "two SDVO device.\n");
		}
		if (p_child->old.slave2_addr) {
		if (child->slave2_addr) {
			/* Maybe this is a SDVO device with multiple inputs */
			/* And the mapping info is not added */
			DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
@@ -1051,6 +1051,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
	const union child_device_config *p_child;
	union child_device_config *child_dev_ptr;
	int i, child_device_num, count;
	u8 expected_size;
	u16 block_size;

	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
@@ -1058,10 +1059,31 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
		DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
		return;
	}
	if (p_defs->child_dev_size < sizeof(*p_child)) {
		DRM_ERROR("General definiton block child device size is too small.\n");
	if (bdb->version < 195) {
		expected_size = sizeof(struct old_child_dev_config);
	} else if (bdb->version == 195) {
		expected_size = 37;
	} else if (bdb->version <= 197) {
		expected_size = 38;
	} else {
		expected_size = 38;
		BUILD_BUG_ON(sizeof(*p_child) < 38);
		DRM_DEBUG_DRIVER("Expected child device config size for VBT version %u not known; assuming %u\n",
				 bdb->version, expected_size);
	}

	/* The legacy sized child device config is the minimum we need. */
	if (p_defs->child_dev_size < sizeof(struct old_child_dev_config)) {
		DRM_ERROR("Child device config size %u is too small.\n",
			  p_defs->child_dev_size);
		return;
	}

	/* Flag an error for unexpected size, but continue anyway. */
	if (p_defs->child_dev_size != expected_size)
		DRM_ERROR("Unexpected child device config size %u (expected %u for VBT version %u)\n",
			  p_defs->child_dev_size, expected_size, bdb->version);

	/* get the block size of general definitions */
	block_size = get_blocksize(p_defs);
	/* get the number of child device */
@@ -1106,7 +1128,14 @@ parse_device_mapping(struct drm_i915_private *dev_priv,

		child_dev_ptr = dev_priv->vbt.child_dev + count;
		count++;
		memcpy(child_dev_ptr, p_child, sizeof(*p_child));

		/*
		 * Copy as much as we know (sizeof) and is available
		 * (child_dev_size) of the child device. Accessing the data must
		 * depend on VBT version.
		 */
		memcpy(child_dev_ptr, p_child,
		       min_t(size_t, p_defs->child_dev_size, sizeof(*p_child)));
	}
	return;
}
Loading