drm/ofdrm: Add CRTC state
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 11 Oct 2022 15:07:09 +0000 (17:07 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Fri, 14 Oct 2022 07:50:04 +0000 (09:50 +0200)
Add a dedicated CRTC state to ofdrm to later store information for
palette updates.

v3:
* rework CRTC state helpers (Javier)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221011150712.3928-3-tzimmermann@suse.de
drivers/gpu/drm/tiny/ofdrm.c

index 96a4607..6782589 100644 (file)
@@ -278,6 +278,21 @@ static struct resource *ofdrm_find_fb_resource(struct ofdrm_device *odev,
  * Modesetting
  */
 
+struct ofdrm_crtc_state {
+       struct drm_crtc_state base;
+};
+
+static struct ofdrm_crtc_state *to_ofdrm_crtc_state(struct drm_crtc_state *base)
+{
+       return container_of(base, struct ofdrm_crtc_state, base);
+}
+
+static void ofdrm_crtc_state_destroy(struct ofdrm_crtc_state *ofdrm_crtc_state)
+{
+       __drm_atomic_helper_crtc_destroy_state(&ofdrm_crtc_state->base);
+       kfree(ofdrm_crtc_state);
+}
+
 /*
  * Support all formats of OF display and maybe more; in order
  * of preference. The display's update function will do any
@@ -431,13 +446,51 @@ static const struct drm_crtc_helper_funcs ofdrm_crtc_helper_funcs = {
        .atomic_check = ofdrm_crtc_helper_atomic_check,
 };
 
+static void ofdrm_crtc_reset(struct drm_crtc *crtc)
+{
+       struct ofdrm_crtc_state *ofdrm_crtc_state =
+               kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
+
+       if (crtc->state)
+               ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
+
+       if (ofdrm_crtc_state)
+               __drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
+       else
+               __drm_atomic_helper_crtc_reset(crtc, NULL);
+}
+
+static struct drm_crtc_state *ofdrm_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_crtc_state *crtc_state = crtc->state;
+       struct ofdrm_crtc_state *new_ofdrm_crtc_state;
+
+       if (drm_WARN_ON(dev, !crtc_state))
+               return NULL;
+
+       new_ofdrm_crtc_state = kzalloc(sizeof(*new_ofdrm_crtc_state), GFP_KERNEL);
+       if (!new_ofdrm_crtc_state)
+               return NULL;
+
+       __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ofdrm_crtc_state->base);
+
+       return &new_ofdrm_crtc_state->base;
+}
+
+static void ofdrm_crtc_atomic_destroy_state(struct drm_crtc *crtc,
+                                           struct drm_crtc_state *crtc_state)
+{
+       ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc_state));
+}
+
 static const struct drm_crtc_funcs ofdrm_crtc_funcs = {
-       .reset = drm_atomic_helper_crtc_reset,
+       .reset = ofdrm_crtc_reset,
        .destroy = drm_crtc_cleanup,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
-       .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
-       .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+       .atomic_duplicate_state = ofdrm_crtc_atomic_duplicate_state,
+       .atomic_destroy_state = ofdrm_crtc_atomic_destroy_state,
 };
 
 static int ofdrm_connector_helper_get_modes(struct drm_connector *connector)