diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2025-07-14 17:13:04 +0200 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2025-08-26 09:54:17 +0200 |
| commit | 061963cd9e5b60672695e9a592be440469a6bf72 (patch) | |
| tree | 59396eeaf5e6599a5e65dd68c88d0e73925b295b | |
| parent | 31eea29d727ce35b747e68c6be350ca07b7ecd9b (diff) | |
drm/sysfb: Blit to CRTC destination format
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 <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250714151513.309475-5-tzimmermann@suse.de
| -rw-r--r-- | drivers/gpu/drm/sysfb/drm_sysfb_helper.h | 2 | ||||
| -rw-r--r-- | 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); |
