Use the color format stored in struct drm_sysfb_crtc_state for
color-format conversion instead of the scanout-buffer format
announced by firmware. Currently, both values are identical.

This will allow drivers to modify the CRTC's input format to a
certain extend. Specifically, vesadrm will be able to display RGB
framebuffers when the scanout buffer is of C8 format. With color-
format conversion to RGB332 and correct setup of the C8 palette,
displaying XRGB8888-based buffers under C8 can be achieved.

v2:
- refer to RGB332 as CRTC input format

Signed-off-by: Thomas Zimmermann <tzimmerm...@suse.de>
Reviewed-by: Javier Martinez Canillas <javi...@redhat.com>
---
 drivers/gpu/drm/sysfb/drm_sysfb_helper.h  |  2 +-
 drivers/gpu/drm/sysfb/drm_sysfb_modeset.c | 29 +++++++++++++++--------
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h 
b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
index 1424b63dde99..89633e30ca62 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
@@ -132,7 +132,7 @@ int drm_sysfb_plane_helper_get_scanout_buffer(struct 
drm_plane *plane,
 struct drm_sysfb_crtc_state {
        struct drm_crtc_state base;
 
-       /* Primary-plane format; required for color mgmt. */
+       /* CRTC input color format; required for color mgmt. */
        const struct drm_format_info *format;
 };
 
diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c 
b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
index 1bcdb5ee8f09..0e05345cdeee 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c
@@ -210,7 +210,12 @@ int drm_sysfb_plane_helper_atomic_check(struct drm_plane 
*plane,
        else if (!new_plane_state->visible)
                return 0;
 
-       if (new_fb->format != sysfb->fb_format) {
+       new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
new_plane_state->crtc);
+
+       new_sysfb_crtc_state = to_drm_sysfb_crtc_state(new_crtc_state);
+       new_sysfb_crtc_state->format = sysfb->fb_format;
+
+       if (new_fb->format != new_sysfb_crtc_state->format) {
                void *buf;
 
                /* format conversion necessary; reserve buffer */
@@ -220,11 +225,6 @@ int drm_sysfb_plane_helper_atomic_check(struct drm_plane 
*plane,
                        return -ENOMEM;
        }
 
-       new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
new_plane_state->crtc);
-
-       new_sysfb_crtc_state = to_drm_sysfb_crtc_state(new_crtc_state);
-       new_sysfb_crtc_state->format = new_fb->format;
-
        return 0;
 }
 EXPORT_SYMBOL(drm_sysfb_plane_helper_atomic_check);
@@ -238,7 +238,10 @@ void drm_sysfb_plane_helper_atomic_update(struct drm_plane 
*plane, struct drm_at
        struct drm_shadow_plane_state *shadow_plane_state = 
to_drm_shadow_plane_state(plane_state);
        struct drm_framebuffer *fb = plane_state->fb;
        unsigned int dst_pitch = sysfb->fb_pitch;
-       const struct drm_format_info *dst_format = sysfb->fb_format;
+       struct drm_crtc_state *crtc_state = crtc_state =
+               drm_atomic_get_new_crtc_state(state, plane_state->crtc);
+       struct drm_sysfb_crtc_state *sysfb_crtc_state = 
to_drm_sysfb_crtc_state(crtc_state);
+       const struct drm_format_info *dst_format = sysfb_crtc_state->format;
        struct drm_atomic_helper_damage_iter iter;
        struct drm_rect damage;
        int ret, idx;
@@ -278,7 +281,10 @@ void drm_sysfb_plane_helper_atomic_disable(struct 
drm_plane *plane,
        struct drm_plane_state *plane_state = 
drm_atomic_get_new_plane_state(state, plane);
        void __iomem *dst_vmap = dst.vaddr_iomem; /* TODO: Use mapping 
abstraction */
        unsigned int dst_pitch = sysfb->fb_pitch;
-       const struct drm_format_info *dst_format = sysfb->fb_format;
+       struct drm_crtc_state *crtc_state = crtc_state =
+               drm_atomic_get_new_crtc_state(state, plane_state->crtc);
+       struct drm_sysfb_crtc_state *sysfb_crtc_state = 
to_drm_sysfb_crtc_state(crtc_state);
+       const struct drm_format_info *dst_format = sysfb_crtc_state->format;
        struct drm_rect dst_clip;
        unsigned long lines, linepixels, i;
        int idx;
@@ -370,16 +376,19 @@ EXPORT_SYMBOL(drm_sysfb_crtc_helper_atomic_check);
 
 void drm_sysfb_crtc_reset(struct drm_crtc *crtc)
 {
+       struct drm_sysfb_device *sysfb = to_drm_sysfb_device(crtc->dev);
        struct drm_sysfb_crtc_state *sysfb_crtc_state;
 
        if (crtc->state)
                
drm_sysfb_crtc_state_destroy(to_drm_sysfb_crtc_state(crtc->state));
 
        sysfb_crtc_state = kzalloc(sizeof(*sysfb_crtc_state), GFP_KERNEL);
-       if (sysfb_crtc_state)
+       if (sysfb_crtc_state) {
+               sysfb_crtc_state->format = sysfb->fb_format;
                __drm_atomic_helper_crtc_reset(crtc, &sysfb_crtc_state->base);
-       else
+       } else {
                __drm_atomic_helper_crtc_reset(crtc, NULL);
+       }
 }
 EXPORT_SYMBOL(drm_sysfb_crtc_reset);
 
-- 
2.50.0

Reply via email to