2 * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4 * DRM core format related functions
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that copyright
9 * notice and this permission notice appear in supporting documentation, and
10 * that the name of the copyright holders not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. The copyright holders make no representations
13 * about the suitability of this software for any purpose. It is provided "as
14 * is" without express or implied warranty.
16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 #include <linux/bug.h>
26 #include <linux/ctype.h>
27 #include <linux/export.h>
28 #include <linux/kernel.h>
31 #include <drm/drm_fourcc.h>
33 static char printable_char(int c
)
35 return isascii(c
) && isprint(c
) ? c
: '?';
39 * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description
40 * @bpp: bits per pixels
41 * @depth: bit depth per pixel
43 * Computes a drm fourcc pixel format code for the given @bpp/@depth values.
44 * Useful in fbdev emulation code, since that deals in those values.
46 uint32_t drm_mode_legacy_fb_format(uint32_t bpp
, uint32_t depth
)
56 fmt
= DRM_FORMAT_XRGB1555
;
58 fmt
= DRM_FORMAT_RGB565
;
61 fmt
= DRM_FORMAT_RGB888
;
65 fmt
= DRM_FORMAT_XRGB8888
;
67 fmt
= DRM_FORMAT_XRGB2101010
;
69 fmt
= DRM_FORMAT_ARGB8888
;
72 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
73 fmt
= DRM_FORMAT_XRGB8888
;
79 EXPORT_SYMBOL(drm_mode_legacy_fb_format
);
82 * drm_get_format_name - return a string for drm fourcc format
83 * @format: format to compute name of
85 * Note that the buffer returned by this function is owned by the caller
86 * and will need to be freed using kfree().
88 char *drm_get_format_name(uint32_t format
)
90 char *buf
= kmalloc(32, GFP_KERNEL
);
93 "%c%c%c%c %s-endian (0x%08x)",
94 printable_char(format
& 0xff),
95 printable_char((format
>> 8) & 0xff),
96 printable_char((format
>> 16) & 0xff),
97 printable_char((format
>> 24) & 0x7f),
98 format
& DRM_FORMAT_BIG_ENDIAN
? "big" : "little",
103 EXPORT_SYMBOL(drm_get_format_name
);
106 * drm_fb_get_bpp_depth - get the bpp/depth values for format
107 * @format: pixel format (DRM_FORMAT_*)
108 * @depth: storage for the depth value
109 * @bpp: storage for the bpp value
111 * This only supports RGB formats here for compat with code that doesn't use
112 * pixel formats directly yet.
114 void drm_fb_get_bpp_depth(uint32_t format
, unsigned int *depth
,
121 case DRM_FORMAT_RGB332
:
122 case DRM_FORMAT_BGR233
:
126 case DRM_FORMAT_XRGB1555
:
127 case DRM_FORMAT_XBGR1555
:
128 case DRM_FORMAT_RGBX5551
:
129 case DRM_FORMAT_BGRX5551
:
130 case DRM_FORMAT_ARGB1555
:
131 case DRM_FORMAT_ABGR1555
:
132 case DRM_FORMAT_RGBA5551
:
133 case DRM_FORMAT_BGRA5551
:
137 case DRM_FORMAT_RGB565
:
138 case DRM_FORMAT_BGR565
:
142 case DRM_FORMAT_RGB888
:
143 case DRM_FORMAT_BGR888
:
147 case DRM_FORMAT_XRGB8888
:
148 case DRM_FORMAT_XBGR8888
:
149 case DRM_FORMAT_RGBX8888
:
150 case DRM_FORMAT_BGRX8888
:
154 case DRM_FORMAT_XRGB2101010
:
155 case DRM_FORMAT_XBGR2101010
:
156 case DRM_FORMAT_RGBX1010102
:
157 case DRM_FORMAT_BGRX1010102
:
158 case DRM_FORMAT_ARGB2101010
:
159 case DRM_FORMAT_ABGR2101010
:
160 case DRM_FORMAT_RGBA1010102
:
161 case DRM_FORMAT_BGRA1010102
:
165 case DRM_FORMAT_ARGB8888
:
166 case DRM_FORMAT_ABGR8888
:
167 case DRM_FORMAT_RGBA8888
:
168 case DRM_FORMAT_BGRA8888
:
173 format_name
= drm_get_format_name(format
);
174 DRM_DEBUG_KMS("unsupported pixel format %s\n", format_name
);
181 EXPORT_SYMBOL(drm_fb_get_bpp_depth
);
184 * drm_format_num_planes - get the number of planes for format
185 * @format: pixel format (DRM_FORMAT_*)
188 * The number of planes used by the specified pixel format.
190 int drm_format_num_planes(uint32_t format
)
193 case DRM_FORMAT_YUV410
:
194 case DRM_FORMAT_YVU410
:
195 case DRM_FORMAT_YUV411
:
196 case DRM_FORMAT_YVU411
:
197 case DRM_FORMAT_YUV420
:
198 case DRM_FORMAT_YVU420
:
199 case DRM_FORMAT_YUV422
:
200 case DRM_FORMAT_YVU422
:
201 case DRM_FORMAT_YUV444
:
202 case DRM_FORMAT_YVU444
:
204 case DRM_FORMAT_NV12
:
205 case DRM_FORMAT_NV21
:
206 case DRM_FORMAT_NV16
:
207 case DRM_FORMAT_NV61
:
208 case DRM_FORMAT_NV24
:
209 case DRM_FORMAT_NV42
:
215 EXPORT_SYMBOL(drm_format_num_planes
);
218 * drm_format_plane_cpp - determine the bytes per pixel value
219 * @format: pixel format (DRM_FORMAT_*)
220 * @plane: plane index
223 * The bytes per pixel value for the specified plane.
225 int drm_format_plane_cpp(uint32_t format
, int plane
)
230 if (plane
>= drm_format_num_planes(format
))
234 case DRM_FORMAT_YUYV
:
235 case DRM_FORMAT_YVYU
:
236 case DRM_FORMAT_UYVY
:
237 case DRM_FORMAT_VYUY
:
239 case DRM_FORMAT_NV12
:
240 case DRM_FORMAT_NV21
:
241 case DRM_FORMAT_NV16
:
242 case DRM_FORMAT_NV61
:
243 case DRM_FORMAT_NV24
:
244 case DRM_FORMAT_NV42
:
245 return plane
? 2 : 1;
246 case DRM_FORMAT_YUV410
:
247 case DRM_FORMAT_YVU410
:
248 case DRM_FORMAT_YUV411
:
249 case DRM_FORMAT_YVU411
:
250 case DRM_FORMAT_YUV420
:
251 case DRM_FORMAT_YVU420
:
252 case DRM_FORMAT_YUV422
:
253 case DRM_FORMAT_YVU422
:
254 case DRM_FORMAT_YUV444
:
255 case DRM_FORMAT_YVU444
:
258 drm_fb_get_bpp_depth(format
, &depth
, &bpp
);
262 EXPORT_SYMBOL(drm_format_plane_cpp
);
265 * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
266 * @format: pixel format (DRM_FORMAT_*)
269 * The horizontal chroma subsampling factor for the
270 * specified pixel format.
272 int drm_format_horz_chroma_subsampling(uint32_t format
)
275 case DRM_FORMAT_YUV411
:
276 case DRM_FORMAT_YVU411
:
277 case DRM_FORMAT_YUV410
:
278 case DRM_FORMAT_YVU410
:
280 case DRM_FORMAT_YUYV
:
281 case DRM_FORMAT_YVYU
:
282 case DRM_FORMAT_UYVY
:
283 case DRM_FORMAT_VYUY
:
284 case DRM_FORMAT_NV12
:
285 case DRM_FORMAT_NV21
:
286 case DRM_FORMAT_NV16
:
287 case DRM_FORMAT_NV61
:
288 case DRM_FORMAT_YUV422
:
289 case DRM_FORMAT_YVU422
:
290 case DRM_FORMAT_YUV420
:
291 case DRM_FORMAT_YVU420
:
297 EXPORT_SYMBOL(drm_format_horz_chroma_subsampling
);
300 * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
301 * @format: pixel format (DRM_FORMAT_*)
304 * The vertical chroma subsampling factor for the
305 * specified pixel format.
307 int drm_format_vert_chroma_subsampling(uint32_t format
)
310 case DRM_FORMAT_YUV410
:
311 case DRM_FORMAT_YVU410
:
313 case DRM_FORMAT_YUV420
:
314 case DRM_FORMAT_YVU420
:
315 case DRM_FORMAT_NV12
:
316 case DRM_FORMAT_NV21
:
322 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling
);
325 * drm_format_plane_width - width of the plane given the first plane
326 * @width: width of the first plane
327 * @format: pixel format
328 * @plane: plane index
331 * The width of @plane, given that the width of the first plane is @width.
333 int drm_format_plane_width(int width
, uint32_t format
, int plane
)
335 if (plane
>= drm_format_num_planes(format
))
341 return width
/ drm_format_horz_chroma_subsampling(format
);
343 EXPORT_SYMBOL(drm_format_plane_width
);
346 * drm_format_plane_height - height of the plane given the first plane
347 * @height: height of the first plane
348 * @format: pixel format
349 * @plane: plane index
352 * The height of @plane, given that the height of the first plane is @height.
354 int drm_format_plane_height(int height
, uint32_t format
, int plane
)
356 if (plane
>= drm_format_num_planes(format
))
362 return height
/ drm_format_vert_chroma_subsampling(format
);
364 EXPORT_SYMBOL(drm_format_plane_height
);