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

Commit d0093404 authored by Dave Airlie's avatar Dave Airlie
Browse files

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

- skl plane scaler support (Chandra Kondru)
- enable hsw cmd parser (Daniel and fix from Rebecca Palmer)
- skl dc5/6 support (low power display modes) from Suketu&Sunil
- dp compliance testing patches (Todd Previte)
- dp link training optimization (Mika Kahola)
- fixes to make skl resume work (Damien)
- rework modeset code to fully use atomic state objects (Ander&Maarten)
- pile of bxt w/a patchs from Nick Hoath
- (linear) partial gtt mmap support (Joonas Lahtinen)

* tag 'drm-intel-next-2015-05-08' of git://anongit.freedesktop.org/drm-intel: (103 commits)
  drm/i915: Update DRIVER_DATE to 20150508
  drm/i915: Only wait for required lanes in vlv_wait_port_ready()
  drm/i915: Fix possible security hole in command parsing
  drm/edid: Kerneldoc for newly added edid_corrupt
  drm/i915: Reject huge tiled objects
  Revert "drm/i915: Hack to tie both common lanes together on chv"
  drm/i915: Work around DISPLAY_PHY_CONTROL register corruption on CHV
  drm/i915: Implement chv display PHY lane stagger setup
  drm/i915/vlv: remove wait for previous GFX clk disable request
  drm/i915: Set crtc_state->active to false when CRTC is disabled (v2)
  drm/i915/skl: Re-indent part of skl_ddi_calculate_wrpll()
  drm/i915: Use partial view in mmap fault handler
  drm/i915: Add a partial GGTT view type
  drm/i915: Consider object pinned if any VMA is pinned
  drm/i915: Do not make assumptions on GGTT VMA sizes
  drm/i915/bxt: Mark WaCcsTlbPrefetchDisable as for Broxton also.
  drm/i915/bxt: Mark WaDisablePartialResolveInVc as for Broxton also.
  drm/i915/bxt: Mark Wa4x4STCOptimizationDisable as for Broxton also.
  drm/i915/bxt: Move WaForceEnableNonCoherent to Skylake only
  drm/i915/bxt: Enable WaEnableYV12BugFixInHalfSliceChicken7 for Broxton
  ...
parents dde10068 214a2b7f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -280,6 +280,8 @@ mode_fixup(struct drm_atomic_state *state)
		 */
		encoder = conn_state->best_encoder;
		funcs = encoder->helper_private;
		if (!funcs)
			continue;

		if (encoder->bridge && encoder->bridge->funcs->mode_fixup) {
			ret = encoder->bridge->funcs->mode_fixup(
@@ -317,6 +319,9 @@ mode_fixup(struct drm_atomic_state *state)
			continue;

		funcs = crtc->helper_private;
		if (!funcs->mode_fixup)
			continue;

		ret = funcs->mode_fixup(crtc, &crtc_state->mode,
					&crtc_state->adjusted_mode);
		if (!ret) {
+26 −6
Original line number Diff line number Diff line
@@ -1041,13 +1041,15 @@ static bool drm_edid_is_zero(const u8 *in_edid, int length)
 * @raw_edid: pointer to raw EDID block
 * @block: type of block to validate (0 for base, extension otherwise)
 * @print_bad_edid: if true, dump bad EDID blocks to the console
 * @edid_corrupt: if true, the header or checksum is invalid
 *
 * Validate a base or extension EDID block and optionally dump bad blocks to
 * the console.
 *
 * Return: True if the block is valid, false otherwise.
 */
bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
			  bool *edid_corrupt)
{
	u8 csum;
	struct edid *edid = (struct edid *)raw_edid;
@@ -1060,11 +1062,22 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)

	if (block == 0) {
		int score = drm_edid_header_is_valid(raw_edid);
		if (score == 8) ;
		else if (score >= edid_fixup) {
		if (score == 8) {
			if (edid_corrupt)
				*edid_corrupt = false;
		} else if (score >= edid_fixup) {
			/* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
			 * The corrupt flag needs to be set here otherwise, the
			 * fix-up code here will correct the problem, the
			 * checksum is correct and the test fails
			 */
			if (edid_corrupt)
				*edid_corrupt = true;
			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
			memcpy(raw_edid, edid_header, sizeof(edid_header));
		} else {
			if (edid_corrupt)
				*edid_corrupt = true;
			goto bad;
		}
	}
@@ -1075,6 +1088,9 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
			DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
		}

		if (edid_corrupt)
			*edid_corrupt = true;

		/* allow CEA to slide through, switches mangle this */
		if (raw_edid[0] != 0x02)
			goto bad;
@@ -1129,7 +1145,7 @@ bool drm_edid_is_valid(struct edid *edid)
		return false;

	for (i = 0; i <= edid->extensions; i++)
		if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true))
		if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
			return false;

	return true;
@@ -1232,7 +1248,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
	for (i = 0; i < 4; i++) {
		if (get_edid_block(data, block, 0, EDID_LENGTH))
			goto out;
		if (drm_edid_block_valid(block, 0, print_bad_edid))
		if (drm_edid_block_valid(block, 0, print_bad_edid,
					 &connector->edid_corrupt))
			break;
		if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
			connector->null_edid_counter++;
@@ -1257,7 +1274,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
				  block + (valid_extensions + 1) * EDID_LENGTH,
				  j, EDID_LENGTH))
				goto out;
			if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j, print_bad_edid)) {
			if (drm_edid_block_valid(block + (valid_extensions + 1)
						 * EDID_LENGTH, j,
						 print_bad_edid,
						 NULL)) {
				valid_extensions++;
				break;
			}
+5 −2
Original line number Diff line number Diff line
@@ -216,7 +216,8 @@ static void *edid_load(struct drm_connector *connector, const char *name,
		goto out;
	}

	if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
	if (!drm_edid_block_valid(edid, 0, print_bad_edid,
				  &connector->edid_corrupt)) {
		connector->bad_edid_counter++;
		DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
		    name);
@@ -229,7 +230,9 @@ static void *edid_load(struct drm_connector *connector, const char *name,
		if (i != valid_extensions + 1)
			memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
			    edid + i * EDID_LENGTH, EDID_LENGTH);
		if (drm_edid_block_valid(edid + i * EDID_LENGTH, i, print_bad_edid))
		if (drm_edid_block_valid(edid + i * EDID_LENGTH, i,
					 print_bad_edid,
					 NULL))
			valid_extensions++;
	}

+2 −1
Original line number Diff line number Diff line
@@ -12,7 +12,8 @@ i915-y := i915_drv.o \
          i915_suspend.o \
	  i915_sysfs.o \
	  intel_pm.o \
	  intel_runtime_pm.o
	  intel_runtime_pm.o \
	  intel_csr.o

i915-$(CONFIG_COMPAT)   += i915_ioc32.o
i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
+232 −8
Original line number Diff line number Diff line
@@ -1211,12 +1211,17 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "RP PREV UP: %dus\n", rpprevup &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "Up threshold: %d%%\n",
			   dev_priv->rps.up_threshold);

		seq_printf(m, "RP CUR DOWN EI: %dus\n", rpdownei &
			   GEN6_CURIAVG_MASK);
		seq_printf(m, "RP CUR DOWN: %dus\n", rpcurdown &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "RP PREV DOWN: %dus\n", rpprevdown &
			   GEN6_CURBSYTAVG_MASK);
		seq_printf(m, "Down threshold: %d%%\n",
			   dev_priv->rps.down_threshold);

		max_freq = (rp_state_cap & 0xff0000) >> 16;
		max_freq *= (IS_SKYLAKE(dev) ? GEN9_FREQ_SCALER : 1);
@@ -1232,12 +1237,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		max_freq *= (IS_SKYLAKE(dev) ? GEN9_FREQ_SCALER : 1);
		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
			   intel_gpu_freq(dev_priv, max_freq));

		seq_printf(m, "Max overclocked frequency: %dMHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));

		seq_printf(m, "Current freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
		seq_printf(m, "Actual freq: %d MHz\n", cagf);
		seq_printf(m, "Idle freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq));
		seq_printf(m, "Min freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
		seq_printf(m, "Max freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
		seq_printf(m,
			   "efficient (RPe) frequency: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
	} else if (IS_VALLEYVIEW(dev)) {
		u32 freq_sts;

@@ -1246,6 +1260,12 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
		seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);

		seq_printf(m, "actual GPU freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));

		seq_printf(m, "current GPU freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));

		seq_printf(m, "max GPU freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));

@@ -1258,9 +1278,6 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
		seq_printf(m,
			   "efficient (RPe) frequency: %d MHz\n",
			   intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));

		seq_printf(m, "current GPU freq: %d MHz\n",
			   intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
		mutex_unlock(&dev_priv->rps.hw_lock);
	} else {
		seq_puts(m, "no P-state info available\n");
@@ -3594,8 +3611,7 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
		intel_display_power_get(dev_priv,
					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));

		dev_priv->display.crtc_disable(&crtc->base);
		dev_priv->display.crtc_enable(&crtc->base);
		intel_crtc_reset(crtc);
	}
	drm_modeset_unlock_all(dev);
}
@@ -3616,8 +3632,7 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
	if (crtc->config->pch_pfit.force_thru) {
		crtc->config->pch_pfit.force_thru = false;

		dev_priv->display.crtc_disable(&crtc->base);
		dev_priv->display.crtc_enable(&crtc->base);
		intel_crtc_reset(crtc);

		intel_display_power_put(dev_priv,
					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
@@ -3934,6 +3949,212 @@ static const struct file_operations i915_display_crc_ctl_fops = {
	.write = display_crc_ctl_write
};

static ssize_t i915_displayport_test_active_write(struct file *file,
					    const char __user *ubuf,
					    size_t len, loff_t *offp)
{
	char *input_buffer;
	int status = 0;
	struct seq_file *m;
	struct drm_device *dev;
	struct drm_connector *connector;
	struct list_head *connector_list;
	struct intel_dp *intel_dp;
	int val = 0;

	m = file->private_data;
	if (!m) {
		status = -ENODEV;
		return status;
	}
	dev = m->private;

	if (!dev) {
		status = -ENODEV;
		return status;
	}
	connector_list = &dev->mode_config.connector_list;

	if (len == 0)
		return 0;

	input_buffer = kmalloc(len + 1, GFP_KERNEL);
	if (!input_buffer)
		return -ENOMEM;

	if (copy_from_user(input_buffer, ubuf, len)) {
		status = -EFAULT;
		goto out;
	}

	input_buffer[len] = '\0';
	DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);

	list_for_each_entry(connector, connector_list, head) {

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->connector_type ==
		    DRM_MODE_CONNECTOR_DisplayPort &&
		    connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
			status = kstrtoint(input_buffer, 10, &val);
			if (status < 0)
				goto out;
			DRM_DEBUG_DRIVER("Got %d for test active\n", val);
			/* To prevent erroneous activation of the compliance
			 * testing code, only accept an actual value of 1 here
			 */
			if (val == 1)
				intel_dp->compliance_test_active = 1;
			else
				intel_dp->compliance_test_active = 0;
		}
	}
out:
	kfree(input_buffer);
	if (status < 0)
		return status;

	*offp += len;
	return len;
}

static int i915_displayport_test_active_show(struct seq_file *m, void *data)
{
	struct drm_device *dev = m->private;
	struct drm_connector *connector;
	struct list_head *connector_list = &dev->mode_config.connector_list;
	struct intel_dp *intel_dp;

	if (!dev)
		return -ENODEV;

	list_for_each_entry(connector, connector_list, head) {

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
			if (intel_dp->compliance_test_active)
				seq_puts(m, "1");
			else
				seq_puts(m, "0");
		} else
			seq_puts(m, "0");
	}

	return 0;
}

static int i915_displayport_test_active_open(struct inode *inode,
				       struct file *file)
{
	struct drm_device *dev = inode->i_private;

	return single_open(file, i915_displayport_test_active_show, dev);
}

static const struct file_operations i915_displayport_test_active_fops = {
	.owner = THIS_MODULE,
	.open = i915_displayport_test_active_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
	.write = i915_displayport_test_active_write
};

static int i915_displayport_test_data_show(struct seq_file *m, void *data)
{
	struct drm_device *dev = m->private;
	struct drm_connector *connector;
	struct list_head *connector_list = &dev->mode_config.connector_list;
	struct intel_dp *intel_dp;

	if (!dev)
		return -ENODEV;

	list_for_each_entry(connector, connector_list, head) {

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
			seq_printf(m, "%lx", intel_dp->compliance_test_data);
		} else
			seq_puts(m, "0");
	}

	return 0;
}
static int i915_displayport_test_data_open(struct inode *inode,
				       struct file *file)
{
	struct drm_device *dev = inode->i_private;

	return single_open(file, i915_displayport_test_data_show, dev);
}

static const struct file_operations i915_displayport_test_data_fops = {
	.owner = THIS_MODULE,
	.open = i915_displayport_test_data_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release
};

static int i915_displayport_test_type_show(struct seq_file *m, void *data)
{
	struct drm_device *dev = m->private;
	struct drm_connector *connector;
	struct list_head *connector_list = &dev->mode_config.connector_list;
	struct intel_dp *intel_dp;

	if (!dev)
		return -ENODEV;

	list_for_each_entry(connector, connector_list, head) {

		if (connector->connector_type !=
		    DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		if (connector->status == connector_status_connected &&
		    connector->encoder != NULL) {
			intel_dp = enc_to_intel_dp(connector->encoder);
			seq_printf(m, "%02lx", intel_dp->compliance_test_type);
		} else
			seq_puts(m, "0");
	}

	return 0;
}

static int i915_displayport_test_type_open(struct inode *inode,
				       struct file *file)
{
	struct drm_device *dev = inode->i_private;

	return single_open(file, i915_displayport_test_type_show, dev);
}

static const struct file_operations i915_displayport_test_type_fops = {
	.owner = THIS_MODULE,
	.open = i915_displayport_test_type_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release
};

static void wm_latency_show(struct seq_file *m, const uint16_t wm[8])
{
	struct drm_device *dev = m->private;
@@ -4829,6 +5050,9 @@ static const struct i915_debugfs_files {
	{"i915_spr_wm_latency", &i915_spr_wm_latency_fops},
	{"i915_cur_wm_latency", &i915_cur_wm_latency_fops},
	{"i915_fbc_false_color", &i915_fbc_fc_fops},
	{"i915_dp_test_data", &i915_displayport_test_data_fops},
	{"i915_dp_test_type", &i915_displayport_test_type_fops},
	{"i915_dp_test_active", &i915_displayport_test_active_fops}
};

void intel_display_crc_init(struct drm_device *dev)
Loading