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 <mrip...@kernel.org>
---
 drivers/gpu/drm/drm_hdmi_connector.c | 145 +++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h          |  26 +++++++
 2 files changed, 171 insertions(+)

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

-- 
2.41.0

Reply via email to