mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 02:19:54 +00:00
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
This commit is contained in:
@@ -132,7 +132,7 @@ int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane,
|
|||||||
struct drm_sysfb_crtc_state {
|
struct drm_sysfb_crtc_state {
|
||||||
struct drm_crtc_state base;
|
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;
|
const struct drm_format_info *format;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,12 @@ int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
|
|||||||
else if (!new_plane_state->visible)
|
else if (!new_plane_state->visible)
|
||||||
return 0;
|
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;
|
void *buf;
|
||||||
|
|
||||||
/* format conversion necessary; reserve buffer */
|
/* format conversion necessary; reserve buffer */
|
||||||
@@ -220,11 +225,6 @@ int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
|
|||||||
return -ENOMEM;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_sysfb_plane_helper_atomic_check);
|
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_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
|
||||||
struct drm_framebuffer *fb = plane_state->fb;
|
struct drm_framebuffer *fb = plane_state->fb;
|
||||||
unsigned int dst_pitch = sysfb->fb_pitch;
|
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_atomic_helper_damage_iter iter;
|
||||||
struct drm_rect damage;
|
struct drm_rect damage;
|
||||||
int ret, idx;
|
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);
|
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 */
|
void __iomem *dst_vmap = dst.vaddr_iomem; /* TODO: Use mapping abstraction */
|
||||||
unsigned int dst_pitch = sysfb->fb_pitch;
|
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;
|
struct drm_rect dst_clip;
|
||||||
unsigned long lines, linepixels, i;
|
unsigned long lines, linepixels, i;
|
||||||
int idx;
|
int idx;
|
||||||
@@ -370,17 +376,20 @@ EXPORT_SYMBOL(drm_sysfb_crtc_helper_atomic_check);
|
|||||||
|
|
||||||
void drm_sysfb_crtc_reset(struct drm_crtc *crtc)
|
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;
|
struct drm_sysfb_crtc_state *sysfb_crtc_state;
|
||||||
|
|
||||||
if (crtc->state)
|
if (crtc->state)
|
||||||
drm_sysfb_crtc_state_destroy(to_drm_sysfb_crtc_state(crtc->state));
|
drm_sysfb_crtc_state_destroy(to_drm_sysfb_crtc_state(crtc->state));
|
||||||
|
|
||||||
sysfb_crtc_state = kzalloc(sizeof(*sysfb_crtc_state), GFP_KERNEL);
|
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);
|
__drm_atomic_helper_crtc_reset(crtc, &sysfb_crtc_state->base);
|
||||||
else
|
} else {
|
||||||
__drm_atomic_helper_crtc_reset(crtc, NULL);
|
__drm_atomic_helper_crtc_reset(crtc, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(drm_sysfb_crtc_reset);
|
EXPORT_SYMBOL(drm_sysfb_crtc_reset);
|
||||||
|
|
||||||
struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
|
struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
|
||||||
|
|||||||
Reference in New Issue
Block a user