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, "Noralf Trønnes" <noralf@tronnes.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
WARNING: multiple messages have this Message-ID (diff)
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: 56+ 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 ` 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 ` 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 2020-05-29 17:56 ` Noralf Trønnes [this message] 2020-05-29 17:56 ` [PATCH v3 3/6] drm/client: Add a way to set modeset, properties and rotation Noralf Trønnes 2020-05-29 17:56 ` [PATCH v3 4/6] drm: Add Generic USB Display driver Noralf Trønnes 2020-05-29 17:56 ` Noralf Trønnes 2020-05-29 22:45 ` Peter Stuge 2020-05-29 22:45 ` Peter Stuge 2020-06-01 16:57 ` Noralf Trønnes 2020-06-01 16:57 ` Noralf Trønnes 2020-06-02 0:12 ` Peter Stuge 2020-06-02 0:12 ` Peter Stuge 2020-06-02 2:32 ` Alan Stern 2020-06-02 2:32 ` Alan Stern 2020-06-02 5:21 ` Peter Stuge 2020-06-02 5:21 ` Peter Stuge 2020-06-02 15:27 ` Alan Stern 2020-06-02 15:27 ` Alan Stern 2020-06-02 18:38 ` Peter Stuge 2020-06-02 18:38 ` Peter Stuge 2020-06-05 12:03 ` Noralf Trønnes 2020-06-05 12:03 ` Noralf Trønnes 2020-06-02 11:46 ` Noralf Trønnes 2020-06-02 11:46 ` Noralf Trønnes 2020-07-14 15:30 ` Noralf Trønnes 2020-07-14 15:30 ` Noralf Trønnes 2020-06-03 19:17 ` 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 ` Noralf Trønnes 2020-05-29 17:56 ` [PATCH v3 6/6] usb: gadget: function: Add Generic USB Display support Noralf Trønnes 2020-05-29 17:56 ` Noralf Trønnes 2020-06-02 17:05 ` Felipe Balbi 2020-06-02 17:05 ` Felipe Balbi 2020-06-02 19:14 ` Noralf Trønnes 2020-06-02 19:14 ` Noralf Trønnes 2020-06-03 7:10 ` Felipe Balbi 2020-06-03 7:10 ` Felipe Balbi 2020-07-09 16:32 ` [PATCH v3 0/6] Generic USB Display driver Lubomir Rintel 2020-07-09 16:32 ` Lubomir Rintel 2020-07-14 13:33 ` Noralf Trønnes 2020-07-14 13:33 ` Noralf Trønnes 2020-07-14 17:40 ` Peter Stuge 2020-07-14 17:40 ` Peter Stuge 2020-07-14 19:03 ` Noralf Trønnes 2020-07-14 19:03 ` Noralf Trønnes 2020-07-14 19:38 ` Peter Stuge 2020-07-14 19:38 ` Peter Stuge 2020-07-16 17:43 ` Noralf Trønnes 2020-07-16 17:43 ` Noralf Trønnes 2020-07-15 7:30 ` Lubomir Rintel 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: linkBe 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.