[RFC,02/13] drm/connector: hdmi: Create a custom state

Message ID 20230814-kms-hdmi-connector-state-v1-2-048054df3654@kernel.org
State New
Headers
Series drm/connector: Create HDMI Connector infrastructure |

Commit Message

Maxime Ripard Aug. 14, 2023, 1:56 p.m. UTC
  The next features we will need to share across drivers will need to
store some parameters for drivers to use, such as the selected output
format.

Let's create a new connector state dedicated to HDMI controllers, that
will eventually store everything we need.

Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_hdmi_connector.c | 145 +++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h          |  26 +++++++
 2 files changed, 171 insertions(+)
  

Patch

diff --git a/drivers/gpu/drm/drm_hdmi_connector.c b/drivers/gpu/drm/drm_hdmi_connector.c
index 62f01dd2e6df..ff825c053b27 100644
--- a/drivers/gpu/drm/drm_hdmi_connector.c
+++ b/drivers/gpu/drm/drm_hdmi_connector.c
@@ -1,10 +1,155 @@ 
 // SPDX-License-Identifier: GPL-2.0+
 
+#include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_mode.h>
 
 #include <linux/export.h>
 
+/**
+ * __drm_atomic_helper_hdmi_connector_reset() - Initializes all @drm_hdmi_connector_state resources
+ * @hdmi_connector: the connector this state refers to
+ * @new_hdmi_state: the HDMI connector state to initialize
+ *
+ * Initializes all relevant resources from a @drm_hdmi_connector_state
+ * without actually allocating it. This is useful for drivers that
+ * subclass @drm_hdmi_connector_state.
+ */
+void __drm_atomic_helper_hdmi_connector_reset(struct drm_hdmi_connector *hdmi_connector,
+					      struct drm_hdmi_connector_state *new_hdmi_state)
+{
+	struct drm_connector *connector = &hdmi_connector->base;
+
+	__drm_atomic_helper_connector_reset(connector, &new_hdmi_state->base);
+}
+EXPORT_SYMBOL(__drm_atomic_helper_hdmi_connector_reset);
+
+/**
+ * drm_atomic_helper_hdmi_connector_reset() - Create a @drm_hdmi_connector_state object
+ * @connector: the parent connector
+ *
+ * This helper is meant to be the default &drm_connector_funcs.reset
+ * implementation for @drm_hdmi_connector that don't subclass
+ * @drm_hdmi_connector_state.
+ */
+void drm_atomic_helper_hdmi_connector_reset(struct drm_connector *connector)
+{
+	struct drm_hdmi_connector *hdmi_connector =
+		connector_to_hdmi_connector(connector);
+	struct drm_connector_state *old_state = connector->state;
+	struct drm_hdmi_connector_state *old_hdmi_state =
+		connector_state_to_hdmi_connector_state(old_state);
+	struct drm_hdmi_connector_state *new_hdmi_state;
+
+	if (old_state)
+		__drm_atomic_helper_connector_destroy_state(old_state);
+
+	kfree(old_hdmi_state);
+
+	new_hdmi_state = kzalloc(sizeof(*new_hdmi_state), GFP_KERNEL);
+	if (!new_hdmi_state)
+		return;
+
+	__drm_atomic_helper_hdmi_connector_reset(hdmi_connector, new_hdmi_state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_hdmi_connector_reset);
+
+/**
+ * __drm_atomic_helper_hdmi_connector_duplicate_state() - Copies all @drm_hdmi_connector_state resources
+ * @hdmi_connector: the connector this state refers to
+ * @new_hdmi_state: the HDMI connector state to copy to
+ *
+ * Copies all relevant resources from a @drm_hdmi_connector_state to a
+ * new one without actually allocating it. This is useful for drivers
+ * that subclass @drm_hdmi_connector_state.
+ */
+void
+__drm_atomic_helper_hdmi_connector_duplicate_state(struct drm_hdmi_connector *hdmi_connector,
+						   struct drm_hdmi_connector_state *new_hdmi_state)
+{
+	struct drm_connector *connector = &hdmi_connector->base;
+
+	__drm_atomic_helper_connector_duplicate_state(connector, &new_hdmi_state->base);
+}
+EXPORT_SYMBOL(__drm_atomic_helper_hdmi_connector_duplicate_state);
+
+/**
+ * drm_atomic_helper_hdmi_connector_duplicate_state() - Duplicate a @drm_hdmi_connector_state object
+ * @connector: the parent connector this state refers to
+ *
+ * This helper is meant to be the default
+ * &drm_connector_funcs.atomic_duplicate_state implementation for
+ * @drm_hdmi_connector that don't subclass @drm_hdmi_connector_state.
+ */
+struct drm_connector_state *
+drm_atomic_helper_hdmi_connector_duplicate_state(struct drm_connector *connector)
+{
+	struct drm_hdmi_connector *hdmi_connector =
+		connector_to_hdmi_connector(connector);
+	struct drm_hdmi_connector_state *new_hdmi_state;
+
+	new_hdmi_state = kzalloc(sizeof(*new_hdmi_state), GFP_KERNEL);
+	if (!new_hdmi_state)
+		return NULL;
+
+	__drm_atomic_helper_hdmi_connector_duplicate_state(hdmi_connector, new_hdmi_state);
+
+	return &new_hdmi_state->base;
+}
+EXPORT_SYMBOL(drm_atomic_helper_hdmi_connector_duplicate_state);
+
+/**
+ * __drm_atomic_helper_hdmi_connector_destroy_state() - Releases all @drm_hdmi_connector_state resources
+ * @hdmi_state: the HDMI connector state to release
+ *
+ * Release all resources stored in @drm_hdmi_connector_state without
+ * actually freeing it. This is useful for drivers that subclass
+ * @drm_hdmi_connector_state.
+ */
+void __drm_atomic_helper_hdmi_connector_destroy_state(struct drm_hdmi_connector_state *hdmi_state)
+{
+	__drm_atomic_helper_connector_destroy_state(&hdmi_state->base);
+}
+EXPORT_SYMBOL(__drm_atomic_helper_hdmi_connector_destroy_state);
+
+/**
+ * drm_atomic_helper_hdmi_connector_destroy_state() - Destroy a @drm_hdmi_connector_state object
+ * @connector: the parent connector this state refers to
+ * @state: the parent connector state to destroy
+ *
+ * Destroys an HDMI connector state previously created by
+ * &drm_atomic_helper_hdmi_connector_reset() or
+ * &drm_atomic_helper_hdmi_connector_duplicate_state().
+ *
+ * This helper is meant to be the default
+ * &drm_connector_funcs.atomic_destroy_state implementation for
+ * @drm_hdmi_connector that don't subclass @drm_hdmi_connector_state.
+ */
+void drm_atomic_helper_hdmi_connector_destroy_state(struct drm_connector *connector,
+						    struct drm_connector_state *state)
+{
+	struct drm_hdmi_connector_state *hdmi_state =
+		connector_state_to_hdmi_connector_state(state);
+
+	__drm_atomic_helper_hdmi_connector_destroy_state(hdmi_state);
+	kfree(hdmi_state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_hdmi_connector_destroy_state);
+
+/**
+ * drm_atomic_helper_hdmi_connector_print_state - Prints a @drm_hdmi_connector_state
+ * @p: output printer
+ * @state: Connector state to print
+ *
+ * Default implementation of @drm_connector_funcs.atomic_print_state for
+ * a @drm_hdmi_connector_state.
+ */
+void drm_atomic_helper_hdmi_connector_print_state(struct drm_printer *p,
+						  const struct drm_connector_state *state)
+{
+}
+EXPORT_SYMBOL(drm_atomic_helper_hdmi_connector_print_state);
+
 /**
  * drmm_hdmi_connector_init - Init a preallocated HDMI connector
  * @dev: DRM device
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1859b74083f5..0aa662e0a6ea 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2042,6 +2042,32 @@  void drm_connector_attach_privacy_screen_provider(
 	struct drm_connector *connector, struct drm_privacy_screen *priv);
 void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state);
 
+struct drm_hdmi_connector_state {
+	/**
+	 * @base: Base Connector State
+	 */
+	struct drm_connector_state base;
+};
+
+#define connector_state_to_hdmi_connector_state(state) \
+	container_of_const(state, struct drm_hdmi_connector_state, base)
+
+struct drm_hdmi_connector;
+
+void __drm_atomic_helper_hdmi_connector_reset(struct drm_hdmi_connector *hdmi_connector,
+					      struct drm_hdmi_connector_state *new_hdmi_state);
+void drm_atomic_helper_hdmi_connector_reset(struct drm_connector *connector);
+void
+__drm_atomic_helper_hdmi_connector_duplicate_state(struct drm_hdmi_connector *hdmi_connector,
+						   struct drm_hdmi_connector_state *new_hdmi_state);
+struct drm_connector_state *
+drm_atomic_helper_hdmi_connector_duplicate_state(struct drm_connector *connector);
+void __drm_atomic_helper_hdmi_connector_destroy_state(struct drm_hdmi_connector_state *hdmi_state);
+void drm_atomic_helper_hdmi_connector_destroy_state(struct drm_connector *connector,
+						    struct drm_connector_state *state);
+void drm_atomic_helper_hdmi_connector_print_state(struct drm_printer *p,
+						  const struct drm_connector_state *state);
+
 struct drm_hdmi_connector {
 	/**
 	 * @base: Base Connector