All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Zanoni <przanoni@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 3/5] drm: add CRTC properties
Date: Tue, 20 Mar 2012 11:48:30 -0300	[thread overview]
Message-ID: <1332254912-4352-3-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <1332254912-4352-1-git-send-email-przanoni@gmail.com>

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

Code based on the connector properties code.

Two new ioctls:
- DRM_IOCTL_MODE_CRTC_GETPROPERTIES
- DRM_IOCTL_MODE_CRTC_SETPROPERTY

The i915 driver needs this for the rotation and overscan compensation
properties. Other drivers might need this too.

v2: replace BUG_ON() for WARN(), fix bugs, add functions to get/set
the value

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/drm_crtc.c |  150 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_drv.c  |    4 +-
 include/drm/drm.h          |    2 +
 include/drm/drm_crtc.h     |   28 ++++++++-
 include/drm/drm_mode.h     |   13 ++++
 5 files changed, 195 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 6260fc3..df00c29 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2712,6 +2712,55 @@ int drm_connector_property_get_value(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_property_get_value);
 
+void drm_crtc_attach_property(struct drm_crtc *crtc,
+			      struct drm_property *property, uint64_t init_val)
+{
+	int i;
+
+	for (i = 0; i < DRM_CRTC_MAX_PROPERTY; i++) {
+		if (crtc->property_ids[i] == 0) {
+			crtc->property_ids[i] = property->base.id;
+			crtc->property_values[i] = init_val;
+			return;
+		}
+	}
+
+	WARN(1, "Failed to attach crtc property\n");
+}
+EXPORT_SYMBOL(drm_crtc_attach_property);
+
+int drm_crtc_property_set_value(struct drm_crtc *crtc,
+				struct drm_property *property, uint64_t value)
+{
+	int i;
+
+	for (i = 0; i < DRM_CRTC_MAX_PROPERTY; i++) {
+		if (crtc->property_ids[i] == property->base.id) {
+			crtc->property_values[i] = value;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(drm_crtc_property_set_value);
+
+int drm_crtc_property_get_value(struct drm_crtc *crtc,
+				struct drm_property *property, uint64_t *val)
+{
+	int i;
+
+	for (i = 0; i < DRM_CRTC_MAX_PROPERTY; i++) {
+		if (crtc->property_ids[i] == property->base.id) {
+			*val = crtc->property_values[i];
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(drm_crtc_property_get_value);
+
 int drm_mode_getproperty_ioctl(struct drm_device *dev,
 			       void *data, struct drm_file *file_priv)
 {
@@ -2983,6 +3032,107 @@ out:
 	return ret;
 }
 
+int drm_mode_crtc_get_properties_ioctl(struct drm_device *dev, void *data,
+				       struct drm_file *file_priv)
+{
+	struct drm_mode_crtc_get_properties *arg = data;
+	struct drm_mode_object *obj;
+	struct drm_crtc *crtc;
+	int ret = 0;
+	int i;
+	int copied = 0;
+	int props_count = 0;
+	uint32_t __user *props_ptr;
+	uint64_t __user *prop_values_ptr;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC);
+	if (!obj) {
+		ret = -EINVAL;
+		goto out;
+	}
+	crtc = obj_to_crtc(obj);
+
+	for (props_count = 0; props_count < DRM_CRTC_MAX_PROPERTY &&
+	     crtc->property_ids[props_count] != 0; props_count++)
+		;
+
+	/* This ioctl is called twice, once to determine how much space is
+	 * needed, and the 2nd time to fill it. */
+	if ((arg->count_props >= props_count) && props_count) {
+		copied = 0;
+		props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
+		prop_values_ptr = (uint64_t __user *)(unsigned long)
+			      (arg->prop_values_ptr);
+		for (i = 0; i < props_count; i++) {
+			if (put_user(crtc->property_ids[i],
+				     props_ptr + copied)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			if (put_user(crtc->property_values[i],
+				     prop_values_ptr + copied)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			copied++;
+		}
+	}
+	arg->count_props = props_count;
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
+int drm_mode_crtc_set_property_ioctl(struct drm_device *dev, void *data,
+				     struct drm_file *file_priv)
+{
+	struct drm_mode_crtc_set_property *arg = data;
+	struct drm_mode_object *obj;
+	struct drm_property *property;
+	struct drm_crtc *crtc;
+	int ret = -EINVAL;
+	int i;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return -EINVAL;
+
+	mutex_lock(&dev->mode_config.mutex);
+
+	obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC);
+	if (!obj)
+		goto out;
+	crtc = obj_to_crtc(obj);
+
+	for (i = 0; i < DRM_CRTC_MAX_PROPERTY; i++)
+		if (crtc->property_ids[i] == arg->prop_id)
+			break;
+
+	if (i == DRM_CRTC_MAX_PROPERTY)
+		goto out;
+
+	obj = drm_mode_object_find(dev, arg->prop_id, DRM_MODE_OBJECT_PROPERTY);
+	if (!obj)
+		goto out;
+	property = obj_to_property(obj);
+
+	if (!drm_property_change_is_valid(property, arg->value))
+		goto out;
+
+	if (crtc->funcs->set_property)
+		ret = crtc->funcs->set_property(crtc, property, arg->value);
+	if (!ret) {
+		crtc->property_values[i] = arg->value;
+	}
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	return ret;
+}
+
 int drm_mode_connector_attach_encoder(struct drm_connector *connector,
 				      struct drm_encoder *encoder)
 {
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index d166bd0..815e3a9 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -159,7 +159,9 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED)
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CRTC_GETPROPERTIES, drm_mode_crtc_get_properties_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CRTC_SETPROPERTY, drm_mode_crtc_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED)
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 34a7b89..a397a93 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -718,6 +718,8 @@ struct drm_get_cap {
 #define DRM_IOCTL_MODE_GETPLANE	DRM_IOWR(0xB6, struct drm_mode_get_plane)
 #define DRM_IOCTL_MODE_SETPLANE	DRM_IOWR(0xB7, struct drm_mode_set_plane)
 #define DRM_IOCTL_MODE_ADDFB2		DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
+#define DRM_IOCTL_MODE_CRTC_GETPROPERTIES	DRM_IOWR(0xB9, struct drm_mode_crtc_get_properties)
+#define DRM_IOCTL_MODE_CRTC_SETPROPERTY	DRM_IOWR(0xBA, struct drm_mode_crtc_set_property)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 21681fe..a2d660d 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -283,6 +283,8 @@ struct drm_encoder;
 struct drm_pending_vblank_event;
 struct drm_plane;
 
+#define DRM_CRTC_MAX_PROPERTY 16
+
 /**
  * drm_crtc_funcs - control CRTCs for a given device
  * @reset: reset CRTC after state has been invalidate (e.g. resume)
@@ -297,7 +299,8 @@ struct drm_plane;
  * @mode_fixup: fixup proposed mode
  * @mode_set: set the desired mode on the CRTC
  * @gamma_set: specify color ramp for CRTC
- * @destroy: deinit and free object.
+ * @destroy: deinit and free object
+ * @set_property: called when a property is changed
  *
  * The drm_crtc_funcs structure is the central CRTC management structure
  * in the DRM.  Each CRTC controls one or more connectors (note that the name
@@ -341,6 +344,9 @@ struct drm_crtc_funcs {
 	int (*page_flip)(struct drm_crtc *crtc,
 			 struct drm_framebuffer *fb,
 			 struct drm_pending_vblank_event *event);
+
+	int (*set_property)(struct drm_crtc *crtc,
+			    struct drm_property *property, uint64_t val);
 };
 
 /**
@@ -360,6 +366,8 @@ struct drm_crtc_funcs {
  * @framedur_ns: precise line timing
  * @pixeldur_ns: precise pixel timing
  * @helper_private: mid-layer private data
+ * @property_ids: property tracking for this CRTC
+ * @property_values: property values
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
@@ -395,6 +403,9 @@ struct drm_crtc {
 
 	/* if you are using the helper */
 	void *helper_private;
+
+	u32 property_ids[DRM_CRTC_MAX_PROPERTY];
+	uint64_t property_values[DRM_CRTC_MAX_PROPERTY];
 };
 
 
@@ -895,6 +906,12 @@ extern int drm_connector_property_set_value(struct drm_connector *connector,
 extern int drm_connector_property_get_value(struct drm_connector *connector,
 					 struct drm_property *property,
 					 uint64_t *value);
+extern int drm_crtc_property_set_value(struct drm_crtc *crtc,
+				       struct drm_property *property,
+				       uint64_t value);
+extern int drm_crtc_property_get_value(struct drm_crtc *crtc,
+				       struct drm_property *property,
+				       uint64_t *value);
 extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
 extern void drm_framebuffer_set_object(struct drm_device *dev,
 				       unsigned long handle);
@@ -909,6 +926,9 @@ extern bool drm_crtc_in_use(struct drm_crtc *crtc);
 
 extern void drm_connector_attach_property(struct drm_connector *connector,
 					  struct drm_property *property, uint64_t init_val);
+extern void drm_crtc_attach_property(struct drm_crtc *crtc,
+				     struct drm_property *property,
+				     uint64_t init_val);
 extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
 						const char *name, int num_values);
 extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
@@ -1019,6 +1039,12 @@ extern int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
 				    void *data, struct drm_file *file_priv);
 extern int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
 				      void *data, struct drm_file *file_priv);
+extern int drm_mode_crtc_get_properties_ioctl(struct drm_device *dev,
+					      void *data,
+					      struct drm_file *file_priv);
+extern int drm_mode_crtc_set_property_ioctl(struct drm_device *dev,
+					    void *data,
+					    struct drm_file *file_priv);
 
 extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
 				 int *bpp);
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 2a2acda..890b930 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -252,6 +252,19 @@ struct drm_mode_connector_set_property {
 	__u32 connector_id;
 };
 
+struct drm_mode_crtc_get_properties {
+	__u64 props_ptr;
+	__u64 prop_values_ptr;
+	__u32 count_props;
+	__u32 crtc_id;
+};
+
+struct drm_mode_crtc_set_property {
+	__u64 value;
+	__u32 prop_id;
+	__u32 crtc_id;
+};
+
 struct drm_mode_get_blob {
 	__u32 blob_id;
 	__u32 length;
-- 
1.7.9.1

  parent reply	other threads:[~2012-03-20 14:49 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-20 14:48 [PATCH 1/5] drm: add drm_property_change_is_valid Paulo Zanoni
2012-03-20 14:48 ` [PATCH 2/5] drm: WARN() when drm_connector_attach_property fails Paulo Zanoni
2012-03-20 14:48 ` Paulo Zanoni [this message]
2012-03-20 15:00   ` [PATCH 3/5] drm: add CRTC properties Rob Clark
2012-03-20 15:09   ` Alex Deucher
2012-03-20 15:48     ` Daniel Vetter
2012-03-20 14:48 ` [PATCH 4/5] drm/i915: add 'rotation' CRTC property Paulo Zanoni
2012-03-20 16:48   ` Marcus Lorentzon
2012-03-20 18:49     ` Ville Syrjälä
2012-03-20 14:48 ` [PATCH 5/5] drm/i915: add overscan compensation CRTC properties Paulo Zanoni
2012-03-20 15:00   ` Alex Deucher
2012-03-20 15:37 ` [PATCH 1/5] drm: add drm_property_change_is_valid Ville Syrjälä

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=1332254912-4352-3-git-send-email-przanoni@gmail.com \
    --to=przanoni@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=paulo.r.zanoni@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.