All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandra Yates <alexandra.yates@linux.intel.com>
To: intel-gfx@lists.freedesktop.org, rodrigo.vivi@intel.com,
	nivedita.swaminathan@intel.com, joe.konno@intel.com
Cc: Alexandra Yates <alexandra.yates@linux.intel.com>
Subject: [PATCH 5/5] drm-i915: Add sys IPS toggle interface
Date: Tue, 12 Apr 2016 12:18:48 -0700	[thread overview]
Message-ID: <1460488728-23319-6-git-send-email-alexandra.yates@linux.intel.com> (raw)
In-Reply-To: <1460488728-23319-1-git-send-email-alexandra.yates@linux.intel.com>

This interface allows enabling/disabling of IPS feature.  It allows
to see immediately the power management savings and will allow
to expose this through sysfs interface for powertop to leverage its
functionality.

Signed-off-by: Alexandra Yates <alexandra.yates@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  5 ++-
 drivers/gpu/drm/i915/i915_drv.h      |  8 ++++
 drivers/gpu/drm/i915/i915_sysfs.c    | 78 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_color.c   | 12 ++++--
 drivers/gpu/drm/i915/intel_display.c | 37 +++++++++++++----
 drivers/gpu/drm/i915/intel_dp.c      | 11 +++--
 drivers/gpu/drm/i915/intel_drv.h     |  4 +-
 7 files changed, 136 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 2d11b49..e338c8a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4022,6 +4022,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 	enum intel_display_power_domain power_domain;
 	u32 val = 0; /* shut up gcc */
 	int ret;
+	bool sysfs_set = false;
 
 	if (pipe_crc->source == source)
 		return 0;
@@ -4071,7 +4072,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 		 * user space can't make reliable use of the CRCs, so let's just
 		 * completely disable it.
 		 */
-		hsw_disable_ips(crtc);
+		hsw_disable_ips(crtc, sysfs_set);
 
 		spin_lock_irq(&pipe_crc->lock);
 		kfree(pipe_crc->entries);
@@ -4116,7 +4117,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 		else if (IS_HASWELL(dev) && pipe == PIPE_A)
 			hsw_trans_edp_pipe_A_crc_wa(dev, false);
 
-		hsw_enable_ips(crtc);
+		hsw_enable_ips(crtc, sysfs_set);
 	}
 
 	ret = 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4c5eea6..0df0030 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -967,6 +967,12 @@ struct i915_drrs {
 	bool sysfs_set;
 };
 
+struct i915_ips {
+	struct mutex lock;
+	int enable;
+	bool sysfs_set;
+};
+
 struct i915_psr {
 	struct mutex lock;
 	bool sink_support;
@@ -1888,6 +1894,8 @@ struct drm_i915_private {
 
 	struct i915_power_domains power_domains;
 
+	struct i915_ips hsw_ips;
+
 	struct i915_psr psr;
 
 	struct i915_gpu_error gpu_error;
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index f489ab6..3bc830b 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -265,6 +265,64 @@ toggle_psr(struct device *kdev, struct device_attribute *attr,
 }
 
 static ssize_t
+show_ips(struct device *kdev, struct device_attribute *attr, char *buf)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = dminor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	ssize_t ret;
+
+	mutex_lock(&dev_priv->hsw_ips.lock);
+	ret = snprintf(buf, PAGE_SIZE, "%s\n", dev_priv->hsw_ips.enable ?
+			"enabled":"disabled");
+	mutex_unlock(&dev_priv->hsw_ips.lock);
+	return ret;
+}
+
+static ssize_t
+toggle_ips(struct device *kdev, struct device_attribute *attr,
+	const char *buf, size_t count)
+{
+	struct drm_minor *dminor = dev_to_drm_minor(kdev);
+	struct drm_device *dev = dminor->dev;
+	struct intel_connector *connector;
+	struct intel_encoder *encoder;
+	struct intel_crtc *crtc = NULL;
+	bool sysfs_set = true;
+	u32 val;
+	ssize_t ret;
+
+	ret = kstrtou32(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	for_each_intel_connector(dev, connector) {
+		if (!connector->base.encoder)
+			continue;
+		encoder = to_intel_encoder(connector->base.encoder);
+		crtc = to_intel_crtc(encoder->base.crtc);
+	}
+	if (!crtc)
+		return -ENODEV;
+
+	switch (val) {
+		case 0:
+			ret = hsw_disable_ips(crtc, sysfs_set);
+			if (ret)
+				return ret;
+			break;
+		case 1:
+			ret = hsw_enable_ips(crtc, sysfs_set);
+			if (ret)
+				return ret;
+			break;
+		default:
+			return -EINVAL;
+	}
+	return count;
+}
+
+static ssize_t
 show_drrs(struct device *kdev, struct device_attribute *attr, char *buf)
 {
 	struct drm_minor *dminor = dev_to_drm_minor(kdev);
@@ -329,6 +387,7 @@ toggle_drrs(struct device *kdev, struct device_attribute *attr,
 	return count;
 }
 
+static DEVICE_ATTR(ips_enable, S_IRUGO | S_IWUSR, show_ips, toggle_ips);
 static DEVICE_ATTR(drrs_enable, S_IRUGO | S_IWUSR, show_drrs, toggle_drrs);
 static DEVICE_ATTR(fbc_enable, S_IRUGO | S_IWUSR, show_fbc, toggle_fbc);
 static DEVICE_ATTR(psr_enable, S_IRUGO | S_IWUSR, show_psr, toggle_psr);
@@ -348,6 +407,16 @@ static struct attribute_group fbc_attr_group = {
 	.attrs = fbc_attrs
 };
 
+static struct attribute *ips_attrs[] = {
+	&dev_attr_ips_enable.attr,
+	NULL
+};
+
+static struct attribute_group ips_attr_group = {
+	.name = power_group_name,
+	.attrs = ips_attrs
+};
+
 static struct attribute *psr_attrs[] = {
 	&dev_attr_psr_enable.attr,
 	NULL
@@ -859,6 +928,14 @@ void i915_setup_sysfs(struct drm_device *dev)
 		if (ret)
 			DRM_ERROR("FBC sysfs setup failed\n");
 	}
+
+	if (HAS_IPS(dev)) {
+		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
+					&ips_attr_group);
+		if (ret)
+			DRM_ERROR("IPS sysfs setup failed\n");
+	}
+
 	if (HAS_PSR(dev)) {
 		ret = sysfs_merge_group(&dev->primary->kdev->kobj,
 					&psr_attr_group);
@@ -931,6 +1008,7 @@ void i915_teardown_sysfs(struct drm_device *dev)
 #ifdef CONFIG_PM
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &drrs_attr_group);
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &fbc_attr_group);
+	sysfs_unmerge_group(&dev->primary->kdev->kobj, &ips_attr_group);
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &psr_attr_group);
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group);
 	sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6p_attr_group);
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
index 1b3f974..27660a6 100644
--- a/drivers/gpu/drm/i915/intel_color.c
+++ b/drivers/gpu/drm/i915/intel_color.c
@@ -325,8 +325,10 @@ static void haswell_load_luts(struct drm_crtc_state *crtc_state)
 	 */
 	if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled &&
 	    (intel_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)) {
-		hsw_disable_ips(intel_crtc);
-		reenable_ips = true;
+		if (dev_priv->hsw_ips.sysfs_set != true){
+			hsw_disable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
+			reenable_ips = true;
+		}
 	}
 
 	intel_crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
@@ -334,8 +336,10 @@ static void haswell_load_luts(struct drm_crtc_state *crtc_state)
 
 	i9xx_load_luts(crtc_state);
 
-	if (reenable_ips)
-		hsw_enable_ips(intel_crtc);
+	if (reenable_ips){
+		if (dev_priv->hsw_ips.sysfs_set != true)
+			hsw_enable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
+	}
 }
 
 /* Loads the palette/gamma unit for the CRTC on Broadwell+. */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4a671e3..7a66d00 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4400,13 +4400,14 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
 	}
 }
 
-void hsw_enable_ips(struct intel_crtc *crtc)
+int hsw_enable_ips(struct intel_crtc *crtc, bool sysfs_set)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
 
 	if (!crtc->config->ips_enabled)
-		return;
+		return -EINVAL;
 
 	/*
 	 * We can only enable IPS after we enable a plane and wait for a vblank
@@ -4431,18 +4432,28 @@ void hsw_enable_ips(struct intel_crtc *crtc)
 		 * and don't wait for vblanks until the end of crtc_enable, then
 		 * the HW state readout code will complain that the expected
 		 * IPS_CTL value is not the one we read. */
-		if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50))
+		if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)){
 			DRM_ERROR("Timed out waiting for IPS enable\n");
+			ret = -ETIMEDOUT;
+		}
 	}
+
+	mutex_lock(&dev_priv->hsw_ips.lock);
+	dev_priv->hsw_ips.enable = 1;
+	dev_priv->hsw_ips.sysfs_set = sysfs_set;
+	mutex_unlock(&dev_priv->hsw_ips.lock);
+
+	return ret;
 }
 
-void hsw_disable_ips(struct intel_crtc *crtc)
+int hsw_disable_ips(struct intel_crtc *crtc, bool sysfs_set)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
 
 	if (!crtc->config->ips_enabled)
-		return;
+		return -EINVAL;
 
 	assert_plane_enabled(dev_priv, crtc->plane);
 	if (IS_BROADWELL(dev)) {
@@ -4450,15 +4461,23 @@ void hsw_disable_ips(struct intel_crtc *crtc)
 		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
 		mutex_unlock(&dev_priv->rps.hw_lock);
 		/* wait for pcode to finish disabling IPS, which may take up to 42ms */
-		if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42))
+		if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42)){
 			DRM_ERROR("Timed out waiting for IPS disable\n");
+			ret = -ETIMEDOUT;
+		}
 	} else {
 		I915_WRITE(IPS_CTL, 0);
 		POSTING_READ(IPS_CTL);
 	}
 
+	mutex_lock(&dev_priv->hsw_ips.lock);
+	dev_priv->hsw_ips.enable = 0;
+	dev_priv->hsw_ips.sysfs_set = sysfs_set;
+	mutex_unlock(&dev_priv->hsw_ips.lock);
+
 	/* We need to wait for a vblank before we can disable the plane. */
 	intel_wait_for_vblank(dev, crtc->pipe);
+	return ret;
 }
 
 static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
@@ -4503,7 +4522,8 @@ intel_post_enable_primary(struct drm_crtc *crtc)
 	 * when going from primary only to sprite only and vice
 	 * versa.
 	 */
-	hsw_enable_ips(intel_crtc);
+	if (dev_priv->hsw_ips.sysfs_set != true)
+		hsw_enable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
 
 	/*
 	 * Gen2 reports pipe underruns whenever all planes are disabled.
@@ -4544,7 +4564,8 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 	 * when going from primary only to sprite only and vice
 	 * versa.
 	 */
-	hsw_disable_ips(intel_crtc);
+	if (dev_priv->hsw_ips.sysfs_set != true)
+		hsw_disable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
 }
 
 /* FIXME get rid of this and use pre_plane_update */
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ec4bd12..0fff2bd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3906,6 +3906,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
 	u8 buf;
 	int ret = 0;
@@ -3942,7 +3943,8 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
 	}
 
  out:
-	hsw_enable_ips(intel_crtc);
+	if (dev_priv->hsw_ips.sysfs_set != true)
+		hsw_enable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
 	return ret;
 }
 
@@ -3950,6 +3952,7 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc);
 	u8 buf;
 	int ret;
@@ -3969,11 +3972,13 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
 			return ret;
 	}
 
-	hsw_disable_ips(intel_crtc);
+	if (dev_priv->hsw_ips.sysfs_set != true)
+		hsw_disable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK,
 			       buf | DP_TEST_SINK_START) < 0) {
-		hsw_enable_ips(intel_crtc);
+		if (dev_priv->hsw_ips.sysfs_set != true)
+			hsw_enable_ips(intel_crtc, dev_priv->hsw_ips.sysfs_set);
 		return -EIO;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eda84ae..c616cb6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1244,8 +1244,8 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
 int chv_calc_dpll_params(int refclk, intel_clock_t *pll_clock);
 
 bool intel_crtc_active(struct drm_crtc *crtc);
-void hsw_enable_ips(struct intel_crtc *crtc);
-void hsw_disable_ips(struct intel_crtc *crtc);
+int hsw_enable_ips(struct intel_crtc *crtc, bool sysfs_set);
+int hsw_disable_ips(struct intel_crtc *crtc, bool sysfs_set);
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder);
 enum intel_display_power_domain
-- 
2.5.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2016-04-12 19:14 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <gfx-top>
2016-04-12 19:18 ` [PATCH 0/5] PowerManagement Toggle for PowerTOP Alexandra Yates
2016-04-12 19:18   ` [PATCH 1/5] drm/i915: Add sys PSR toggle interface Alexandra Yates
2016-04-13 13:26     ` Zanoni, Paulo R
2016-04-13 20:43       ` Vivi, Rodrigo
2016-04-14  7:58         ` Jani Nikula
2016-04-12 19:18   ` [PATCH 2/5] drm/i915: Add sys FBC " Alexandra Yates
2016-04-13 12:48     ` Zanoni, Paulo R
2016-04-12 19:18   ` [PATCH 3/5] drm/i915: Add sys RC6 " Alexandra Yates
2016-04-12 19:18   ` [PATCH 4/5] drm/i915: Add sys drrs " Alexandra Yates
2016-04-12 19:18   ` Alexandra Yates [this message]
2016-04-13 10:21   ` [PATCH 0/5] PowerManagement Toggle for PowerTOP Daniel Vetter
2016-04-13 10:24   ` Jani Nikula
2016-04-13 12:59   ` Zanoni, Paulo R
2016-04-13 14:50     ` Daniel Vetter
2016-04-13 20:38       ` Vivi, Rodrigo
2016-04-13 20:46         ` Daniel Vetter
2016-04-13 20:49           ` Daniel Vetter
2016-04-13 22:06           ` Vivi, Rodrigo
2016-04-14  9:48             ` Daniel Vetter
2016-04-14 17:17               ` Alexandra Yates
2016-04-15 18:12               ` Vivi, Rodrigo
2016-04-20 12:44                 ` Daniel Vetter
2016-04-13 15:25 ` ✗ Fi.CI.BAT: failure for series starting with [1/5] drm/i915: Add sys PSR toggle interface Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1460488728-23319-6-git-send-email-alexandra.yates@linux.intel.com \
    --to=alexandra.yates@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=joe.konno@intel.com \
    --cc=nivedita.swaminathan@intel.com \
    --cc=rodrigo.vivi@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.