mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02: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:
		
							parent
							
								
									31eea29d72
								
							
						
					
					
						commit
						061963cd9e
					
				
					 2 changed files with 20 additions and 11 deletions
				
			
		|  | @ -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) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Thomas Zimmermann
						Thomas Zimmermann