459 lines · c
1/*2 * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com>3 *4 * DRM core format related functions5 *6 * Permission to use, copy, modify, distribute, and sell this software and its7 * documentation for any purpose is hereby granted without fee, provided that8 * the above copyright notice appear in all copies and that both that copyright9 * notice and this permission notice appear in supporting documentation, and10 * that the name of the copyright holders not be used in advertising or11 * publicity pertaining to distribution of the software without specific,12 * written prior permission. The copyright holders make no representations13 * about the suitability of this software for any purpose. It is provided "as14 * is" without express or implied warranty.15 *16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO18 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE22 * OF THIS SOFTWARE.23 */24 25#include <linux/bug.h>26#include <linux/ctype.h>27#include <linux/export.h>28#include <linux/kernel.h>29 30#include <drm/drm_device.h>31#include <drm/drm_fourcc.h>32 33/**34 * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description35 * @bpp: bits per pixels36 * @depth: bit depth per pixel37 *38 * Computes a drm fourcc pixel format code for the given @bpp/@depth values.39 * Useful in fbdev emulation code, since that deals in those values.40 */41uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)42{43 uint32_t fmt = DRM_FORMAT_INVALID;44 45 switch (bpp) {46 case 1:47 if (depth == 1)48 fmt = DRM_FORMAT_C1;49 break;50 51 case 2:52 if (depth == 2)53 fmt = DRM_FORMAT_C2;54 break;55 56 case 4:57 if (depth == 4)58 fmt = DRM_FORMAT_C4;59 break;60 61 case 8:62 if (depth == 8)63 fmt = DRM_FORMAT_C8;64 break;65 66 case 16:67 switch (depth) {68 case 15:69 fmt = DRM_FORMAT_XRGB1555;70 break;71 case 16:72 fmt = DRM_FORMAT_RGB565;73 break;74 default:75 break;76 }77 break;78 79 case 24:80 if (depth == 24)81 fmt = DRM_FORMAT_RGB888;82 break;83 84 case 32:85 switch (depth) {86 case 24:87 fmt = DRM_FORMAT_XRGB8888;88 break;89 case 30:90 fmt = DRM_FORMAT_XRGB2101010;91 break;92 case 32:93 fmt = DRM_FORMAT_ARGB8888;94 break;95 default:96 break;97 }98 break;99 100 default:101 break;102 }103 104 return fmt;105}106EXPORT_SYMBOL(drm_mode_legacy_fb_format);107 108/**109 * drm_driver_legacy_fb_format - compute drm fourcc code from legacy description110 * @dev: DRM device111 * @bpp: bits per pixels112 * @depth: bit depth per pixel113 *114 * Computes a drm fourcc pixel format code for the given @bpp/@depth values.115 * Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config,116 * and depending on the &drm_mode_config.quirk_addfb_prefer_host_byte_order flag117 * it returns little endian byte order or host byte order framebuffer formats.118 */119uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,120 uint32_t bpp, uint32_t depth)121{122 uint32_t fmt = drm_mode_legacy_fb_format(bpp, depth);123 124 if (dev->mode_config.quirk_addfb_prefer_host_byte_order) {125 if (fmt == DRM_FORMAT_XRGB8888)126 fmt = DRM_FORMAT_HOST_XRGB8888;127 if (fmt == DRM_FORMAT_ARGB8888)128 fmt = DRM_FORMAT_HOST_ARGB8888;129 if (fmt == DRM_FORMAT_RGB565)130 fmt = DRM_FORMAT_HOST_RGB565;131 if (fmt == DRM_FORMAT_XRGB1555)132 fmt = DRM_FORMAT_HOST_XRGB1555;133 }134 135 if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp &&136 fmt == DRM_FORMAT_XRGB2101010)137 fmt = DRM_FORMAT_XBGR2101010;138 139 return fmt;140}141EXPORT_SYMBOL(drm_driver_legacy_fb_format);142 143/*144 * Internal function to query information for a given format. See145 * drm_format_info() for the public API.146 */147const struct drm_format_info *__drm_format_info(u32 format)148{149 static const struct drm_format_info formats[] = {150 { .format = DRM_FORMAT_C1, .depth = 1, .num_planes = 1,151 .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true },152 { .format = DRM_FORMAT_C2, .depth = 2, .num_planes = 1,153 .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true },154 { .format = DRM_FORMAT_C4, .depth = 4, .num_planes = 1,155 .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true },156 { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1, .is_color_indexed = true },157 { .format = DRM_FORMAT_D1, .depth = 1, .num_planes = 1,158 .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 },159 { .format = DRM_FORMAT_D2, .depth = 2, .num_planes = 1,160 .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 },161 { .format = DRM_FORMAT_D4, .depth = 4, .num_planes = 1,162 .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 },163 { .format = DRM_FORMAT_D8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },164 { .format = DRM_FORMAT_R1, .depth = 1, .num_planes = 1,165 .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 },166 { .format = DRM_FORMAT_R2, .depth = 2, .num_planes = 1,167 .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 },168 { .format = DRM_FORMAT_R4, .depth = 4, .num_planes = 1,169 .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 },170 { .format = DRM_FORMAT_R8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },171 { .format = DRM_FORMAT_R10, .depth = 10, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },172 { .format = DRM_FORMAT_R12, .depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },173 { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },174 { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },175 { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },176 { .format = DRM_FORMAT_XBGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },177 { .format = DRM_FORMAT_RGBX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },178 { .format = DRM_FORMAT_BGRX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },179 { .format = DRM_FORMAT_ARGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },180 { .format = DRM_FORMAT_ABGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },181 { .format = DRM_FORMAT_RGBA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },182 { .format = DRM_FORMAT_BGRA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },183 { .format = DRM_FORMAT_XRGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },184 { .format = DRM_FORMAT_XBGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },185 { .format = DRM_FORMAT_RGBX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },186 { .format = DRM_FORMAT_BGRX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },187 { .format = DRM_FORMAT_ARGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },188 { .format = DRM_FORMAT_ABGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },189 { .format = DRM_FORMAT_RGBA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },190 { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },191 { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },192 { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },193#ifdef __BIG_ENDIAN194 { .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },195 { .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },196#endif197 { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },198 { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },199 { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },200 { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },201 { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },202 { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },203 { .format = DRM_FORMAT_RGB565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },204 { .format = DRM_FORMAT_BGR565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },205 { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },206 { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },207 { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },208 { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },209 { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },210 { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },211 { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },212 { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },213 { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },214 { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },215 { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },216 { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },217 { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 },218 { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 },219 { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },220 { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },221 { .format = DRM_FORMAT_AXBXGXRX106106106106, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },222 { .format = DRM_FORMAT_XRGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 },223 { .format = DRM_FORMAT_XBGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 },224 { .format = DRM_FORMAT_ARGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },225 { .format = DRM_FORMAT_ABGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },226 { .format = DRM_FORMAT_RGB888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },227 { .format = DRM_FORMAT_BGR888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },228 { .format = DRM_FORMAT_XRGB8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },229 { .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },230 { .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },231 { .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },232 { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true },233 { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true },234 { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true },235 { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true },236 { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true },237 { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true },238 { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },239 { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },240 { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },241 { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },242 { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },243 { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },244 { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },245 { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },246 { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },247 { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },248 { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },249 { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },250 { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },251 { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },252 { .format = DRM_FORMAT_XYUV8888, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },253 { .format = DRM_FORMAT_VUY888, .depth = 0, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },254 { .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },255 { .format = DRM_FORMAT_Y210, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },256 { .format = DRM_FORMAT_Y212, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },257 { .format = DRM_FORMAT_Y216, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },258 { .format = DRM_FORMAT_Y410, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },259 { .format = DRM_FORMAT_Y412, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },260 { .format = DRM_FORMAT_Y416, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },261 { .format = DRM_FORMAT_XVYU2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },262 { .format = DRM_FORMAT_XVYU12_16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },263 { .format = DRM_FORMAT_XVYU16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },264 { .format = DRM_FORMAT_Y0L0, .depth = 0, .num_planes = 1,265 .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },266 .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },267 { .format = DRM_FORMAT_X0L0, .depth = 0, .num_planes = 1,268 .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },269 .hsub = 2, .vsub = 2, .is_yuv = true },270 { .format = DRM_FORMAT_Y0L2, .depth = 0, .num_planes = 1,271 .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },272 .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },273 { .format = DRM_FORMAT_X0L2, .depth = 0, .num_planes = 1,274 .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },275 .hsub = 2, .vsub = 2, .is_yuv = true },276 { .format = DRM_FORMAT_P010, .depth = 0, .num_planes = 2,277 .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },278 .hsub = 2, .vsub = 2, .is_yuv = true},279 { .format = DRM_FORMAT_P012, .depth = 0, .num_planes = 2,280 .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },281 .hsub = 2, .vsub = 2, .is_yuv = true},282 { .format = DRM_FORMAT_P016, .depth = 0, .num_planes = 2,283 .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 },284 .hsub = 2, .vsub = 2, .is_yuv = true},285 { .format = DRM_FORMAT_P210, .depth = 0,286 .num_planes = 2, .char_per_block = { 2, 4, 0 },287 .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,288 .vsub = 1, .is_yuv = true },289 { .format = DRM_FORMAT_VUY101010, .depth = 0,290 .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1,291 .is_yuv = true },292 { .format = DRM_FORMAT_YUV420_8BIT, .depth = 0,293 .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2,294 .is_yuv = true },295 { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0,296 .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2,297 .is_yuv = true },298 { .format = DRM_FORMAT_NV15, .depth = 0,299 .num_planes = 2, .char_per_block = { 5, 5, 0 },300 .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,301 .vsub = 2, .is_yuv = true },302 { .format = DRM_FORMAT_NV20, .depth = 0,303 .num_planes = 2, .char_per_block = { 5, 5, 0 },304 .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,305 .vsub = 1, .is_yuv = true },306 { .format = DRM_FORMAT_NV30, .depth = 0,307 .num_planes = 2, .char_per_block = { 5, 5, 0 },308 .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1,309 .vsub = 1, .is_yuv = true },310 { .format = DRM_FORMAT_Q410, .depth = 0,311 .num_planes = 3, .char_per_block = { 2, 2, 2 },312 .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,313 .vsub = 1, .is_yuv = true },314 { .format = DRM_FORMAT_Q401, .depth = 0,315 .num_planes = 3, .char_per_block = { 2, 2, 2 },316 .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,317 .vsub = 1, .is_yuv = true },318 { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2,319 .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },320 .hsub = 2, .vsub = 2, .is_yuv = true},321 };322 323 unsigned int i;324 325 for (i = 0; i < ARRAY_SIZE(formats); ++i) {326 if (formats[i].format == format)327 return &formats[i];328 }329 330 return NULL;331}332 333/**334 * drm_format_info - query information for a given format335 * @format: pixel format (DRM_FORMAT_*)336 *337 * The caller should only pass a supported pixel format to this function.338 * Unsupported pixel formats will generate a warning in the kernel log.339 *340 * Returns:341 * The instance of struct drm_format_info that describes the pixel format, or342 * NULL if the format is unsupported.343 */344const struct drm_format_info *drm_format_info(u32 format)345{346 const struct drm_format_info *info;347 348 info = __drm_format_info(format);349 WARN_ON(!info);350 return info;351}352EXPORT_SYMBOL(drm_format_info);353 354/**355 * drm_get_format_info - query information for a given framebuffer configuration356 * @dev: DRM device357 * @mode_cmd: metadata from the userspace fb creation request358 *359 * Returns:360 * The instance of struct drm_format_info that describes the pixel format, or361 * NULL if the format is unsupported.362 */363const struct drm_format_info *364drm_get_format_info(struct drm_device *dev,365 const struct drm_mode_fb_cmd2 *mode_cmd)366{367 const struct drm_format_info *info = NULL;368 369 if (dev->mode_config.funcs->get_format_info)370 info = dev->mode_config.funcs->get_format_info(mode_cmd);371 372 if (!info)373 info = drm_format_info(mode_cmd->pixel_format);374 375 return info;376}377EXPORT_SYMBOL(drm_get_format_info);378 379/**380 * drm_format_info_block_width - width in pixels of block.381 * @info: pixel format info382 * @plane: plane index383 *384 * Returns:385 * The width in pixels of a block, depending on the plane index.386 */387unsigned int drm_format_info_block_width(const struct drm_format_info *info,388 int plane)389{390 if (!info || plane < 0 || plane >= info->num_planes)391 return 0;392 393 if (!info->block_w[plane])394 return 1;395 return info->block_w[plane];396}397EXPORT_SYMBOL(drm_format_info_block_width);398 399/**400 * drm_format_info_block_height - height in pixels of a block401 * @info: pixel format info402 * @plane: plane index403 *404 * Returns:405 * The height in pixels of a block, depending on the plane index.406 */407unsigned int drm_format_info_block_height(const struct drm_format_info *info,408 int plane)409{410 if (!info || plane < 0 || plane >= info->num_planes)411 return 0;412 413 if (!info->block_h[plane])414 return 1;415 return info->block_h[plane];416}417EXPORT_SYMBOL(drm_format_info_block_height);418 419/**420 * drm_format_info_bpp - number of bits per pixel421 * @info: pixel format info422 * @plane: plane index423 *424 * Returns:425 * The actual number of bits per pixel, depending on the plane index.426 */427unsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane)428{429 if (!info || plane < 0 || plane >= info->num_planes)430 return 0;431 432 return info->char_per_block[plane] * 8 /433 (drm_format_info_block_width(info, plane) *434 drm_format_info_block_height(info, plane));435}436EXPORT_SYMBOL(drm_format_info_bpp);437 438/**439 * drm_format_info_min_pitch - computes the minimum required pitch in bytes440 * @info: pixel format info441 * @plane: plane index442 * @buffer_width: buffer width in pixels443 *444 * Returns:445 * The minimum required pitch in bytes for a buffer by taking into consideration446 * the pixel format information and the buffer width.447 */448uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,449 int plane, unsigned int buffer_width)450{451 if (!info || plane < 0 || plane >= info->num_planes)452 return 0;453 454 return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane],455 drm_format_info_block_width(info, plane) *456 drm_format_info_block_height(info, plane));457}458EXPORT_SYMBOL(drm_format_info_min_pitch);459