[Intel-gfx] [PATCH] drm/i915: Attach a PSR property on eDP
Rodrigo Vivi
rodrigo.vivi at intel.com
Thu Mar 26 12:22:07 PDT 2015
Let userspace know the status of Panel Self-Refresh by virtue of a
property on the appropriate connector.
v2: Only attach the property if the driver is capable of PSR.
v3: Add docbook courtesy of Damien.
v4: Mark the initial value as 'unsupported' - it will be determined
correctly when we later read the DCPD from the panel.
v5: Done by Rodrigo:
- Add disabled state to match all cases
- Attach it anyway to eDP since it is started as unsupported
- Change prop name to PSR
- Add enum to make states more clear
- Rebased on intel_psr.c changing func name and fixing states
v6: Done by Rodrigo:
- Revert name to Panel Self-Refresh
- Only report Enable/Disable since Active/Exit change so rapidily
triggering many uevents as Chris pointed out.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Damien Lespiau <damien.lespiau at intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
---
Documentation/DocBook/drm.tmpl | 10 ++++++++-
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_dp.c | 1 +
drivers/gpu/drm/i915/intel_drv.h | 1 +
drivers/gpu/drm/i915/intel_psr.c | 47 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index f4976cd..bda3948 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2834,7 +2834,7 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >TBD</td>
</tr>
<tr>
- <td rowspan="21" valign="top" >i915</td>
+ <td rowspan="22" valign="top" >i915</td>
<td rowspan="2" valign="top" >Generic</td>
<td valign="top" >"Broadcast RGB"</td>
<td valign="top" >ENUM</td>
@@ -2986,6 +2986,14 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >TBD</td>
</tr>
<tr>
+ <td valign="top" >eDP</td>
+ <td valign="top" >“Panel Self-Refresh”</td>
+ <td valign="top" >ENUM | IMMUTABLE</td>
+ <td valign="top" >{ "Unsupported", "Idle", "Active" }</td>
+ <td valign="top" >Connector</td>
+ <td valign="top" >Whether the eDP panel supports using self-refresh, which is a power saving mode for static displays as the panel is able to read from its own buffer rather than require the host to send the same frame on every vertical refresh, and whether it is idle or active</td>
+ </tr>
+ <tr>
<td rowspan="2" valign="top" >CDV gma-500</td>
<td rowspan="2" valign="top" >Generic</td>
<td valign="top" >"Broadcast RGB"</td>
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 92a9e85..afb9741 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -878,6 +878,7 @@ struct i915_psr {
bool active;
struct delayed_work work;
unsigned busy_frontbuffer_bits;
+ struct drm_property *property;
};
enum intel_pch {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5551b3c..cfd64bd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4776,6 +4776,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
intel_dp->color_range_auto = true;
if (is_edp(intel_dp)) {
+ intel_attach_psr_property(connector);
drm_mode_create_scaling_mode_property(connector->dev);
drm_object_attach_property(
&connector->base,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 250d70c..d286ba3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1207,6 +1207,7 @@ void intel_backlight_unregister(struct drm_device *dev);
/* intel_psr.c */
+void intel_attach_psr_property(struct drm_connector *connector);
bool intel_psr_ready(struct intel_dp *intel_dp);
void intel_psr_enable(struct intel_dp *intel_dp);
void intel_psr_disable(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 72940d8..44742fc 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -56,6 +56,50 @@
#include "intel_drv.h"
#include "i915_drv.h"
+enum psr_state {
+ PSR_UNSUPPORTED = -1,
+ PSR_DISABLED,
+ PSR_ENABLED,
+};
+
+static const struct drm_prop_enum_list psr_names[] = {
+ { PSR_UNSUPPORTED, "Unsupported" },
+ { PSR_DISABLED, "Disabled" },
+ { PSR_ENABLED, "Enabled" },
+};
+
+void intel_attach_psr_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_property *prop;
+
+ prop = dev_priv->psr.property;
+ if (prop == NULL) {
+ prop = drm_property_create_enum(dev,
+ DRM_MODE_PROP_ENUM |
+ DRM_MODE_PROP_IMMUTABLE,
+ "Panel Self-Refresh",
+ psr_names,
+ ARRAY_SIZE(psr_names));
+ if (prop == NULL)
+ return;
+
+ dev_priv->psr.property = prop;
+ }
+
+ drm_object_attach_property(&connector->base, prop, PSR_UNSUPPORTED);
+}
+
+static void intel_psr_set_property(struct intel_connector *connector,
+ uint64_t val)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+
+ drm_object_property_set_value(&connector->base.base,
+ dev_priv->psr.property, val);
+}
+
static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -390,6 +434,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
}
dev_priv->psr.enabled = intel_dp;
+ intel_psr_set_property(intel_dp->attached_connector, PSR_ENABLED);
unlock:
mutex_unlock(&dev_priv->psr.lock);
}
@@ -466,6 +511,8 @@ void intel_psr_disable(struct intel_dp *intel_dp)
vlv_psr_disable(intel_dp);
dev_priv->psr.enabled = NULL;
+ intel_psr_set_property(intel_dp->attached_connector, PSR_DISABLED);
+
mutex_unlock(&dev_priv->psr.lock);
cancel_delayed_work_sync(&dev_priv->psr.work);
--
2.1.0
More information about the Intel-gfx
mailing list