From: "Noralf Trønnes" <noralf@tronnes.org>
To: dri-devel@lists.freedesktop.org, balbi@kernel.org
Cc: linux-usb@vger.kernel.org, sam@ravnborg.org
Subject: [PATCH v3 3/6] drm/client: Add a way to set modeset, properties and rotation
Date: Fri, 29 May 2020 19:56:40 +0200 [thread overview]
Message-ID: <20200529175643.46094-4-noralf@tronnes.org> (raw)
In-Reply-To: <20200529175643.46094-1-noralf@tronnes.org>
This adds functions for clients that need more control over the
configuration than what's setup by drm_client_modeset_probe().
Connector, fb and display mode can be set using drm_client_modeset_set().
Plane rotation can be set using drm_client_modeset_set_rotation() and
other properties using drm_client_modeset_set_property(). Property
setting is only implemented for atomic drivers.
v2:
- drm_client_modeset_set(): Remove undocumented functionality to clear
modesets. A disable function takes care of that need now.
- drm_client_modeset_set_property(): Return -EOPNOTSUPP if driver is not
atomic (Sam)
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
drivers/gpu/drm/drm_client_modeset.c | 137 +++++++++++++++++++++++++++
include/drm/drm_client.h | 38 +++++++-
2 files changed, 174 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
index 977bcd063520..9eee9567b9aa 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -83,6 +83,10 @@ static void drm_client_modeset_release(struct drm_client_dev *client)
}
modeset->num_connectors = 0;
}
+
+ kfree(client->properties);
+ client->properties = NULL;
+ client->num_properties = 0;
}
void drm_client_modeset_free(struct drm_client_dev *client)
@@ -879,6 +883,130 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
}
EXPORT_SYMBOL(drm_client_modeset_probe);
+/**
+ * drm_client_modeset_set() - Set modeset configuration
+ * @client: DRM client
+ * @connector: Connector
+ * @mode: Display mode
+ * @fb: Framebuffer
+ *
+ * This function releases any current modeset info, including properties, and
+ * sets the new modeset in the client's modeset array.
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_modeset_set(struct drm_client_dev *client, struct drm_connector *connector,
+ struct drm_display_mode *mode, struct drm_framebuffer *fb)
+{
+ struct drm_mode_set *modeset;
+ int ret = -ENOENT;
+
+ mutex_lock(&client->modeset_mutex);
+
+ drm_client_modeset_release(client);
+
+ drm_client_for_each_modeset(modeset, client) {
+ if (!connector_has_possible_crtc(connector, modeset->crtc))
+ continue;
+
+ modeset->mode = drm_mode_duplicate(client->dev, mode);
+ if (!modeset->mode) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ drm_mode_set_crtcinfo(modeset->mode, CRTC_INTERLACE_HALVE_V);
+
+ drm_connector_get(connector);
+ modeset->connectors[modeset->num_connectors++] = connector;
+
+ modeset->fb = fb;
+ ret = 0;
+ break;
+ }
+
+ mutex_unlock(&client->modeset_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_client_modeset_set);
+
+/**
+ * drm_client_modeset_set_property() - Set a property on the current configuration
+ * @client: DRM client
+ * @obj: DRM Mode Object
+ * @prop: DRM Property
+ * @value: Property value
+ *
+ * Note: Currently only implemented for atomic drivers.
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_modeset_set_property(struct drm_client_dev *client, struct drm_mode_object *obj,
+ struct drm_property *prop, u64 value)
+{
+ struct drm_client_property *properties;
+ int ret = 0;
+
+ if (!prop)
+ return -EINVAL;
+
+ if (!drm_drv_uses_atomic_modeset(client->dev))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&client->modeset_mutex);
+
+ properties = krealloc(client->properties,
+ (client->num_properties + 1) * sizeof(*properties), GFP_KERNEL);
+ if (!properties) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ properties[client->num_properties].obj = obj;
+ properties[client->num_properties].prop = prop;
+ properties[client->num_properties].value = value;
+ client->properties = properties;
+ client->num_properties++;
+unlock:
+ mutex_unlock(&client->modeset_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_client_modeset_set_property);
+
+/**
+ * drm_client_modeset_set_rotation() - Set rotation on the current configuration
+ * @client: DRM client
+ * @value: Rotation value
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_modeset_set_rotation(struct drm_client_dev *client, u64 value)
+{
+ struct drm_plane *plane = NULL;
+ struct drm_mode_set *modeset;
+
+ mutex_lock(&client->modeset_mutex);
+ drm_client_for_each_modeset(modeset, client) {
+ if (modeset->mode) {
+ plane = modeset->crtc->primary;
+ break;
+ }
+ }
+ mutex_unlock(&client->modeset_mutex);
+
+ if (!plane)
+ return -ENOENT;
+
+ return drm_client_modeset_set_property(client, &plane->base,
+ plane->rotation_property, value);
+}
+EXPORT_SYMBOL(drm_client_modeset_set_rotation);
+
/**
* drm_client_rotation() - Check the initial rotation value
* @modeset: DRM modeset
@@ -973,6 +1101,7 @@ static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool
struct drm_atomic_state *state;
struct drm_modeset_acquire_ctx ctx;
struct drm_mode_set *mode_set;
+ unsigned int i;
int ret;
drm_modeset_acquire_init(&ctx, 0);
@@ -1033,6 +1162,14 @@ static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool
}
}
+ for (i = 0; i < client->num_properties; i++) {
+ struct drm_client_property *prop = &client->properties[i];
+
+ ret = drm_atomic_set_property(state, NULL, prop->obj, prop->prop, prop->value);
+ if (ret)
+ goto out_state;
+ }
+
if (check)
ret = drm_atomic_check_only(state);
else
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index 498089b647da..bdcdc30519e6 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -16,6 +16,7 @@ struct drm_file;
struct drm_framebuffer;
struct drm_gem_object;
struct drm_minor;
+struct drm_property;
struct module;
/**
@@ -64,6 +65,26 @@ struct drm_client_funcs {
int (*hotplug)(struct drm_client_dev *client);
};
+/**
+ * struct drm_client_property - DRM client property
+ */
+struct drm_client_property {
+ /**
+ * @obj: DRM Mode Object to which the property belongs.
+ */
+ struct drm_mode_object *obj;
+
+ /**
+ * @prop: DRM Property.
+ */
+ struct drm_property *prop;
+
+ /**
+ * @value: Property value.
+ */
+ u64 value;
+};
+
/**
* struct drm_client_dev - DRM client instance
*/
@@ -97,7 +118,7 @@ struct drm_client_dev {
struct drm_file *file;
/**
- * @modeset_mutex: Protects @modesets.
+ * @modeset_mutex: Protects @modesets and @properties.
*/
struct mutex modeset_mutex;
@@ -105,6 +126,16 @@ struct drm_client_dev {
* @modesets: CRTC configurations
*/
struct drm_mode_set *modesets;
+
+ /**
+ * @properties: DRM properties attached to the configuration.
+ */
+ struct drm_client_property *properties;
+
+ /**
+ * @num_properties: Number of attached properties.
+ */
+ unsigned int num_properties;
};
int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
@@ -163,6 +194,11 @@ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer);
int drm_client_modeset_create(struct drm_client_dev *client);
void drm_client_modeset_free(struct drm_client_dev *client);
int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height);
+int drm_client_modeset_set(struct drm_client_dev *client, struct drm_connector *connector,
+ struct drm_display_mode *mode, struct drm_framebuffer *fb);
+int drm_client_modeset_set_property(struct drm_client_dev *client, struct drm_mode_object *obj,
+ struct drm_property *prop, u64 value);
+int drm_client_modeset_set_rotation(struct drm_client_dev *client, u64 value);
bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation);
int drm_client_modeset_check(struct drm_client_dev *client);
int drm_client_modeset_commit_locked(struct drm_client_dev *client);
--
2.23.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2020-05-29 17:57 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-29 17:56 [PATCH v3 0/6] Generic USB Display driver Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 1/6] drm/client: Add drm_client_init_from_id() Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 2/6] drm/client: Add drm_client_modeset_disable() Noralf Trønnes
2020-05-29 17:56 ` Noralf Trønnes [this message]
2020-05-29 17:56 ` [PATCH v3 4/6] drm: Add Generic USB Display driver Noralf Trønnes
2020-05-29 22:45 ` Peter Stuge
2020-06-01 16:57 ` Noralf Trønnes
2020-06-02 0:12 ` Peter Stuge
2020-06-02 2:32 ` Alan Stern
2020-06-02 5:21 ` Peter Stuge
2020-06-02 15:27 ` Alan Stern
2020-06-02 18:38 ` Peter Stuge
2020-06-05 12:03 ` Noralf Trønnes
2020-06-02 11:46 ` Noralf Trønnes
2020-07-14 15:30 ` Noralf Trønnes
2020-06-03 19:17 ` Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 5/6] drm/gud: Add functionality for the USB gadget side Noralf Trønnes
2020-05-29 17:56 ` [PATCH v3 6/6] usb: gadget: function: Add Generic USB Display support Noralf Trønnes
2020-06-02 17:05 ` Felipe Balbi
2020-06-02 19:14 ` Noralf Trønnes
2020-06-03 7:10 ` Felipe Balbi
2020-07-09 16:32 ` [PATCH v3 0/6] Generic USB Display driver Lubomir Rintel
2020-07-14 13:33 ` Noralf Trønnes
2020-07-14 17:40 ` Peter Stuge
2020-07-14 19:03 ` Noralf Trønnes
2020-07-14 19:38 ` Peter Stuge
2020-07-16 17:43 ` Noralf Trønnes
2020-07-15 7:30 ` Lubomir Rintel
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=20200529175643.46094-4-noralf@tronnes.org \
--to=noralf@tronnes.org \
--cc=balbi@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-usb@vger.kernel.org \
--cc=sam@ravnborg.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).