xref: /linux/drivers/gpu/drm/drm_draw.c (revision 2c1ed907520c50326b8f604907a8478b27881a2e)
1*31fa2c1cSJocelyn Falempe // SPDX-License-Identifier: GPL-2.0 or MIT
2*31fa2c1cSJocelyn Falempe /*
3*31fa2c1cSJocelyn Falempe  * Copyright (c) 2023 Red Hat.
4*31fa2c1cSJocelyn Falempe  * Author: Jocelyn Falempe <jfalempe@redhat.com>
5*31fa2c1cSJocelyn Falempe  */
6*31fa2c1cSJocelyn Falempe 
7*31fa2c1cSJocelyn Falempe #include <linux/bits.h>
8*31fa2c1cSJocelyn Falempe #include <linux/iosys-map.h>
9*31fa2c1cSJocelyn Falempe #include <linux/types.h>
10*31fa2c1cSJocelyn Falempe 
11*31fa2c1cSJocelyn Falempe #include <drm/drm_fourcc.h>
12*31fa2c1cSJocelyn Falempe 
13*31fa2c1cSJocelyn Falempe #include "drm_draw_internal.h"
14*31fa2c1cSJocelyn Falempe 
15*31fa2c1cSJocelyn Falempe /*
16*31fa2c1cSJocelyn Falempe  * Conversions from xrgb8888
17*31fa2c1cSJocelyn Falempe  */
18*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_rgb565(u32 pix)19*31fa2c1cSJocelyn Falempe static u16 convert_xrgb8888_to_rgb565(u32 pix)
20*31fa2c1cSJocelyn Falempe {
21*31fa2c1cSJocelyn Falempe 	return ((pix & 0x00F80000) >> 8) |
22*31fa2c1cSJocelyn Falempe 	       ((pix & 0x0000FC00) >> 5) |
23*31fa2c1cSJocelyn Falempe 	       ((pix & 0x000000F8) >> 3);
24*31fa2c1cSJocelyn Falempe }
25*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_rgba5551(u32 pix)26*31fa2c1cSJocelyn Falempe static u16 convert_xrgb8888_to_rgba5551(u32 pix)
27*31fa2c1cSJocelyn Falempe {
28*31fa2c1cSJocelyn Falempe 	return ((pix & 0x00f80000) >> 8) |
29*31fa2c1cSJocelyn Falempe 	       ((pix & 0x0000f800) >> 5) |
30*31fa2c1cSJocelyn Falempe 	       ((pix & 0x000000f8) >> 2) |
31*31fa2c1cSJocelyn Falempe 	       BIT(0); /* set alpha bit */
32*31fa2c1cSJocelyn Falempe }
33*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_xrgb1555(u32 pix)34*31fa2c1cSJocelyn Falempe static u16 convert_xrgb8888_to_xrgb1555(u32 pix)
35*31fa2c1cSJocelyn Falempe {
36*31fa2c1cSJocelyn Falempe 	return ((pix & 0x00f80000) >> 9) |
37*31fa2c1cSJocelyn Falempe 	       ((pix & 0x0000f800) >> 6) |
38*31fa2c1cSJocelyn Falempe 	       ((pix & 0x000000f8) >> 3);
39*31fa2c1cSJocelyn Falempe }
40*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_argb1555(u32 pix)41*31fa2c1cSJocelyn Falempe static u16 convert_xrgb8888_to_argb1555(u32 pix)
42*31fa2c1cSJocelyn Falempe {
43*31fa2c1cSJocelyn Falempe 	return BIT(15) | /* set alpha bit */
44*31fa2c1cSJocelyn Falempe 	       ((pix & 0x00f80000) >> 9) |
45*31fa2c1cSJocelyn Falempe 	       ((pix & 0x0000f800) >> 6) |
46*31fa2c1cSJocelyn Falempe 	       ((pix & 0x000000f8) >> 3);
47*31fa2c1cSJocelyn Falempe }
48*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_argb8888(u32 pix)49*31fa2c1cSJocelyn Falempe static u32 convert_xrgb8888_to_argb8888(u32 pix)
50*31fa2c1cSJocelyn Falempe {
51*31fa2c1cSJocelyn Falempe 	return pix | GENMASK(31, 24); /* fill alpha bits */
52*31fa2c1cSJocelyn Falempe }
53*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_xbgr8888(u32 pix)54*31fa2c1cSJocelyn Falempe static u32 convert_xrgb8888_to_xbgr8888(u32 pix)
55*31fa2c1cSJocelyn Falempe {
56*31fa2c1cSJocelyn Falempe 	return ((pix & 0x00ff0000) >> 16) <<  0 |
57*31fa2c1cSJocelyn Falempe 	       ((pix & 0x0000ff00) >>  8) <<  8 |
58*31fa2c1cSJocelyn Falempe 	       ((pix & 0x000000ff) >>  0) << 16 |
59*31fa2c1cSJocelyn Falempe 	       ((pix & 0xff000000) >> 24) << 24;
60*31fa2c1cSJocelyn Falempe }
61*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_abgr8888(u32 pix)62*31fa2c1cSJocelyn Falempe static u32 convert_xrgb8888_to_abgr8888(u32 pix)
63*31fa2c1cSJocelyn Falempe {
64*31fa2c1cSJocelyn Falempe 	return ((pix & 0x00ff0000) >> 16) <<  0 |
65*31fa2c1cSJocelyn Falempe 	       ((pix & 0x0000ff00) >>  8) <<  8 |
66*31fa2c1cSJocelyn Falempe 	       ((pix & 0x000000ff) >>  0) << 16 |
67*31fa2c1cSJocelyn Falempe 	       GENMASK(31, 24); /* fill alpha bits */
68*31fa2c1cSJocelyn Falempe }
69*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_xrgb2101010(u32 pix)70*31fa2c1cSJocelyn Falempe static u32 convert_xrgb8888_to_xrgb2101010(u32 pix)
71*31fa2c1cSJocelyn Falempe {
72*31fa2c1cSJocelyn Falempe 	pix = ((pix & 0x000000FF) << 2) |
73*31fa2c1cSJocelyn Falempe 	      ((pix & 0x0000FF00) << 4) |
74*31fa2c1cSJocelyn Falempe 	      ((pix & 0x00FF0000) << 6);
75*31fa2c1cSJocelyn Falempe 	return pix | ((pix >> 8) & 0x00300C03);
76*31fa2c1cSJocelyn Falempe }
77*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_argb2101010(u32 pix)78*31fa2c1cSJocelyn Falempe static u32 convert_xrgb8888_to_argb2101010(u32 pix)
79*31fa2c1cSJocelyn Falempe {
80*31fa2c1cSJocelyn Falempe 	pix = ((pix & 0x000000FF) << 2) |
81*31fa2c1cSJocelyn Falempe 	      ((pix & 0x0000FF00) << 4) |
82*31fa2c1cSJocelyn Falempe 	      ((pix & 0x00FF0000) << 6);
83*31fa2c1cSJocelyn Falempe 	return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03);
84*31fa2c1cSJocelyn Falempe }
85*31fa2c1cSJocelyn Falempe 
convert_xrgb8888_to_abgr2101010(u32 pix)86*31fa2c1cSJocelyn Falempe static u32 convert_xrgb8888_to_abgr2101010(u32 pix)
87*31fa2c1cSJocelyn Falempe {
88*31fa2c1cSJocelyn Falempe 	pix = ((pix & 0x00FF0000) >> 14) |
89*31fa2c1cSJocelyn Falempe 	      ((pix & 0x0000FF00) << 4) |
90*31fa2c1cSJocelyn Falempe 	      ((pix & 0x000000FF) << 22);
91*31fa2c1cSJocelyn Falempe 	return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03);
92*31fa2c1cSJocelyn Falempe }
93*31fa2c1cSJocelyn Falempe 
94*31fa2c1cSJocelyn Falempe /**
95*31fa2c1cSJocelyn Falempe  * drm_draw_color_from_xrgb8888 - convert one pixel from xrgb8888 to the desired format
96*31fa2c1cSJocelyn Falempe  * @color: input color, in xrgb8888 format
97*31fa2c1cSJocelyn Falempe  * @format: output format
98*31fa2c1cSJocelyn Falempe  *
99*31fa2c1cSJocelyn Falempe  * Returns:
100*31fa2c1cSJocelyn Falempe  * Color in the format specified, casted to u32.
101*31fa2c1cSJocelyn Falempe  * Or 0 if the format is not supported.
102*31fa2c1cSJocelyn Falempe  */
drm_draw_color_from_xrgb8888(u32 color,u32 format)103*31fa2c1cSJocelyn Falempe u32 drm_draw_color_from_xrgb8888(u32 color, u32 format)
104*31fa2c1cSJocelyn Falempe {
105*31fa2c1cSJocelyn Falempe 	switch (format) {
106*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_RGB565:
107*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_rgb565(color);
108*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_RGBA5551:
109*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_rgba5551(color);
110*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_XRGB1555:
111*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_xrgb1555(color);
112*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_ARGB1555:
113*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_argb1555(color);
114*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_RGB888:
115*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_XRGB8888:
116*31fa2c1cSJocelyn Falempe 		return color;
117*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_ARGB8888:
118*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_argb8888(color);
119*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_XBGR8888:
120*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_xbgr8888(color);
121*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_ABGR8888:
122*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_abgr8888(color);
123*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_XRGB2101010:
124*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_xrgb2101010(color);
125*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_ARGB2101010:
126*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_argb2101010(color);
127*31fa2c1cSJocelyn Falempe 	case DRM_FORMAT_ABGR2101010:
128*31fa2c1cSJocelyn Falempe 		return convert_xrgb8888_to_abgr2101010(color);
129*31fa2c1cSJocelyn Falempe 	default:
130*31fa2c1cSJocelyn Falempe 		WARN_ONCE(1, "Can't convert to %p4cc\n", &format);
131*31fa2c1cSJocelyn Falempe 		return 0;
132*31fa2c1cSJocelyn Falempe 	}
133*31fa2c1cSJocelyn Falempe }
134*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_color_from_xrgb8888);
135*31fa2c1cSJocelyn Falempe 
136*31fa2c1cSJocelyn Falempe /*
137*31fa2c1cSJocelyn Falempe  * Blit functions
138*31fa2c1cSJocelyn Falempe  */
drm_draw_blit16(struct iosys_map * dmap,unsigned int dpitch,const u8 * sbuf8,unsigned int spitch,unsigned int height,unsigned int width,unsigned int scale,u16 fg16)139*31fa2c1cSJocelyn Falempe void drm_draw_blit16(struct iosys_map *dmap, unsigned int dpitch,
140*31fa2c1cSJocelyn Falempe 		     const u8 *sbuf8, unsigned int spitch,
141*31fa2c1cSJocelyn Falempe 		     unsigned int height, unsigned int width,
142*31fa2c1cSJocelyn Falempe 		     unsigned int scale, u16 fg16)
143*31fa2c1cSJocelyn Falempe {
144*31fa2c1cSJocelyn Falempe 	unsigned int y, x;
145*31fa2c1cSJocelyn Falempe 
146*31fa2c1cSJocelyn Falempe 	for (y = 0; y < height; y++)
147*31fa2c1cSJocelyn Falempe 		for (x = 0; x < width; x++)
148*31fa2c1cSJocelyn Falempe 			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
149*31fa2c1cSJocelyn Falempe 				iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16);
150*31fa2c1cSJocelyn Falempe }
151*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_blit16);
152*31fa2c1cSJocelyn Falempe 
drm_draw_blit24(struct iosys_map * dmap,unsigned int dpitch,const u8 * sbuf8,unsigned int spitch,unsigned int height,unsigned int width,unsigned int scale,u32 fg32)153*31fa2c1cSJocelyn Falempe void drm_draw_blit24(struct iosys_map *dmap, unsigned int dpitch,
154*31fa2c1cSJocelyn Falempe 		     const u8 *sbuf8, unsigned int spitch,
155*31fa2c1cSJocelyn Falempe 		     unsigned int height, unsigned int width,
156*31fa2c1cSJocelyn Falempe 		     unsigned int scale, u32 fg32)
157*31fa2c1cSJocelyn Falempe {
158*31fa2c1cSJocelyn Falempe 	unsigned int y, x;
159*31fa2c1cSJocelyn Falempe 
160*31fa2c1cSJocelyn Falempe 	for (y = 0; y < height; y++) {
161*31fa2c1cSJocelyn Falempe 		for (x = 0; x < width; x++) {
162*31fa2c1cSJocelyn Falempe 			u32 off = y * dpitch + x * 3;
163*31fa2c1cSJocelyn Falempe 
164*31fa2c1cSJocelyn Falempe 			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
165*31fa2c1cSJocelyn Falempe 				/* write blue-green-red to output in little endianness */
166*31fa2c1cSJocelyn Falempe 				iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0);
167*31fa2c1cSJocelyn Falempe 				iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8);
168*31fa2c1cSJocelyn Falempe 				iosys_map_wr(dmap, off + 2, u8, (fg32 & 0x00FF0000) >> 16);
169*31fa2c1cSJocelyn Falempe 			}
170*31fa2c1cSJocelyn Falempe 		}
171*31fa2c1cSJocelyn Falempe 	}
172*31fa2c1cSJocelyn Falempe }
173*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_blit24);
174*31fa2c1cSJocelyn Falempe 
drm_draw_blit32(struct iosys_map * dmap,unsigned int dpitch,const u8 * sbuf8,unsigned int spitch,unsigned int height,unsigned int width,unsigned int scale,u32 fg32)175*31fa2c1cSJocelyn Falempe void drm_draw_blit32(struct iosys_map *dmap, unsigned int dpitch,
176*31fa2c1cSJocelyn Falempe 		     const u8 *sbuf8, unsigned int spitch,
177*31fa2c1cSJocelyn Falempe 		     unsigned int height, unsigned int width,
178*31fa2c1cSJocelyn Falempe 		     unsigned int scale, u32 fg32)
179*31fa2c1cSJocelyn Falempe {
180*31fa2c1cSJocelyn Falempe 	unsigned int y, x;
181*31fa2c1cSJocelyn Falempe 
182*31fa2c1cSJocelyn Falempe 	for (y = 0; y < height; y++)
183*31fa2c1cSJocelyn Falempe 		for (x = 0; x < width; x++)
184*31fa2c1cSJocelyn Falempe 			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
185*31fa2c1cSJocelyn Falempe 				iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32);
186*31fa2c1cSJocelyn Falempe }
187*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_blit32);
188*31fa2c1cSJocelyn Falempe 
189*31fa2c1cSJocelyn Falempe /*
190*31fa2c1cSJocelyn Falempe  * Fill functions
191*31fa2c1cSJocelyn Falempe  */
drm_draw_fill16(struct iosys_map * dmap,unsigned int dpitch,unsigned int height,unsigned int width,u16 color)192*31fa2c1cSJocelyn Falempe void drm_draw_fill16(struct iosys_map *dmap, unsigned int dpitch,
193*31fa2c1cSJocelyn Falempe 		     unsigned int height, unsigned int width,
194*31fa2c1cSJocelyn Falempe 		     u16 color)
195*31fa2c1cSJocelyn Falempe {
196*31fa2c1cSJocelyn Falempe 	unsigned int y, x;
197*31fa2c1cSJocelyn Falempe 
198*31fa2c1cSJocelyn Falempe 	for (y = 0; y < height; y++)
199*31fa2c1cSJocelyn Falempe 		for (x = 0; x < width; x++)
200*31fa2c1cSJocelyn Falempe 			iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, color);
201*31fa2c1cSJocelyn Falempe }
202*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_fill16);
203*31fa2c1cSJocelyn Falempe 
drm_draw_fill24(struct iosys_map * dmap,unsigned int dpitch,unsigned int height,unsigned int width,u16 color)204*31fa2c1cSJocelyn Falempe void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
205*31fa2c1cSJocelyn Falempe 		     unsigned int height, unsigned int width,
206*31fa2c1cSJocelyn Falempe 		     u16 color)
207*31fa2c1cSJocelyn Falempe {
208*31fa2c1cSJocelyn Falempe 	unsigned int y, x;
209*31fa2c1cSJocelyn Falempe 
210*31fa2c1cSJocelyn Falempe 	for (y = 0; y < height; y++) {
211*31fa2c1cSJocelyn Falempe 		for (x = 0; x < width; x++) {
212*31fa2c1cSJocelyn Falempe 			unsigned int off = y * dpitch + x * 3;
213*31fa2c1cSJocelyn Falempe 
214*31fa2c1cSJocelyn Falempe 			/* write blue-green-red to output in little endianness */
215*31fa2c1cSJocelyn Falempe 			iosys_map_wr(dmap, off, u8, (color & 0x000000FF) >> 0);
216*31fa2c1cSJocelyn Falempe 			iosys_map_wr(dmap, off + 1, u8, (color & 0x0000FF00) >> 8);
217*31fa2c1cSJocelyn Falempe 			iosys_map_wr(dmap, off + 2, u8, (color & 0x00FF0000) >> 16);
218*31fa2c1cSJocelyn Falempe 		}
219*31fa2c1cSJocelyn Falempe 	}
220*31fa2c1cSJocelyn Falempe }
221*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_fill24);
222*31fa2c1cSJocelyn Falempe 
drm_draw_fill32(struct iosys_map * dmap,unsigned int dpitch,unsigned int height,unsigned int width,u32 color)223*31fa2c1cSJocelyn Falempe void drm_draw_fill32(struct iosys_map *dmap, unsigned int dpitch,
224*31fa2c1cSJocelyn Falempe 		     unsigned int height, unsigned int width,
225*31fa2c1cSJocelyn Falempe 		     u32 color)
226*31fa2c1cSJocelyn Falempe {
227*31fa2c1cSJocelyn Falempe 	unsigned int y, x;
228*31fa2c1cSJocelyn Falempe 
229*31fa2c1cSJocelyn Falempe 	for (y = 0; y < height; y++)
230*31fa2c1cSJocelyn Falempe 		for (x = 0; x < width; x++)
231*31fa2c1cSJocelyn Falempe 			iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color);
232*31fa2c1cSJocelyn Falempe }
233*31fa2c1cSJocelyn Falempe EXPORT_SYMBOL(drm_draw_fill32);
234