162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * DRM core format related functions 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Permission to use, copy, modify, distribute, and sell this software and its 762306a36Sopenharmony_ci * documentation for any purpose is hereby granted without fee, provided that 862306a36Sopenharmony_ci * the above copyright notice appear in all copies and that both that copyright 962306a36Sopenharmony_ci * notice and this permission notice appear in supporting documentation, and 1062306a36Sopenharmony_ci * that the name of the copyright holders not be used in advertising or 1162306a36Sopenharmony_ci * publicity pertaining to distribution of the software without specific, 1262306a36Sopenharmony_ci * written prior permission. The copyright holders make no representations 1362306a36Sopenharmony_ci * about the suitability of this software for any purpose. It is provided "as 1462306a36Sopenharmony_ci * is" without express or implied warranty. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1762306a36Sopenharmony_ci * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1862306a36Sopenharmony_ci * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1962306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2062306a36Sopenharmony_ci * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 2162306a36Sopenharmony_ci * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2262306a36Sopenharmony_ci * OF THIS SOFTWARE. 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <linux/bug.h> 2662306a36Sopenharmony_ci#include <linux/ctype.h> 2762306a36Sopenharmony_ci#include <linux/export.h> 2862306a36Sopenharmony_ci#include <linux/kernel.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include <drm/drm_device.h> 3162306a36Sopenharmony_ci#include <drm/drm_fourcc.h> 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/** 3462306a36Sopenharmony_ci * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description 3562306a36Sopenharmony_ci * @bpp: bits per pixels 3662306a36Sopenharmony_ci * @depth: bit depth per pixel 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * Computes a drm fourcc pixel format code for the given @bpp/@depth values. 3962306a36Sopenharmony_ci * Useful in fbdev emulation code, since that deals in those values. 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_ciuint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci uint32_t fmt = DRM_FORMAT_INVALID; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci switch (bpp) { 4662306a36Sopenharmony_ci case 1: 4762306a36Sopenharmony_ci if (depth == 1) 4862306a36Sopenharmony_ci fmt = DRM_FORMAT_C1; 4962306a36Sopenharmony_ci break; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci case 2: 5262306a36Sopenharmony_ci if (depth == 2) 5362306a36Sopenharmony_ci fmt = DRM_FORMAT_C2; 5462306a36Sopenharmony_ci break; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci case 4: 5762306a36Sopenharmony_ci if (depth == 4) 5862306a36Sopenharmony_ci fmt = DRM_FORMAT_C4; 5962306a36Sopenharmony_ci break; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci case 8: 6262306a36Sopenharmony_ci if (depth == 8) 6362306a36Sopenharmony_ci fmt = DRM_FORMAT_C8; 6462306a36Sopenharmony_ci break; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci case 16: 6762306a36Sopenharmony_ci switch (depth) { 6862306a36Sopenharmony_ci case 15: 6962306a36Sopenharmony_ci fmt = DRM_FORMAT_XRGB1555; 7062306a36Sopenharmony_ci break; 7162306a36Sopenharmony_ci case 16: 7262306a36Sopenharmony_ci fmt = DRM_FORMAT_RGB565; 7362306a36Sopenharmony_ci break; 7462306a36Sopenharmony_ci default: 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci break; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci case 24: 8062306a36Sopenharmony_ci if (depth == 24) 8162306a36Sopenharmony_ci fmt = DRM_FORMAT_RGB888; 8262306a36Sopenharmony_ci break; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci case 32: 8562306a36Sopenharmony_ci switch (depth) { 8662306a36Sopenharmony_ci case 24: 8762306a36Sopenharmony_ci fmt = DRM_FORMAT_XRGB8888; 8862306a36Sopenharmony_ci break; 8962306a36Sopenharmony_ci case 30: 9062306a36Sopenharmony_ci fmt = DRM_FORMAT_XRGB2101010; 9162306a36Sopenharmony_ci break; 9262306a36Sopenharmony_ci case 32: 9362306a36Sopenharmony_ci fmt = DRM_FORMAT_ARGB8888; 9462306a36Sopenharmony_ci break; 9562306a36Sopenharmony_ci default: 9662306a36Sopenharmony_ci break; 9762306a36Sopenharmony_ci } 9862306a36Sopenharmony_ci break; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci default: 10162306a36Sopenharmony_ci break; 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci return fmt; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ciEXPORT_SYMBOL(drm_mode_legacy_fb_format); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/** 10962306a36Sopenharmony_ci * drm_driver_legacy_fb_format - compute drm fourcc code from legacy description 11062306a36Sopenharmony_ci * @dev: DRM device 11162306a36Sopenharmony_ci * @bpp: bits per pixels 11262306a36Sopenharmony_ci * @depth: bit depth per pixel 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * Computes a drm fourcc pixel format code for the given @bpp/@depth values. 11562306a36Sopenharmony_ci * Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config, 11662306a36Sopenharmony_ci * and depending on the &drm_mode_config.quirk_addfb_prefer_host_byte_order flag 11762306a36Sopenharmony_ci * it returns little endian byte order or host byte order framebuffer formats. 11862306a36Sopenharmony_ci */ 11962306a36Sopenharmony_ciuint32_t drm_driver_legacy_fb_format(struct drm_device *dev, 12062306a36Sopenharmony_ci uint32_t bpp, uint32_t depth) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci uint32_t fmt = drm_mode_legacy_fb_format(bpp, depth); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci if (dev->mode_config.quirk_addfb_prefer_host_byte_order) { 12562306a36Sopenharmony_ci if (fmt == DRM_FORMAT_XRGB8888) 12662306a36Sopenharmony_ci fmt = DRM_FORMAT_HOST_XRGB8888; 12762306a36Sopenharmony_ci if (fmt == DRM_FORMAT_ARGB8888) 12862306a36Sopenharmony_ci fmt = DRM_FORMAT_HOST_ARGB8888; 12962306a36Sopenharmony_ci if (fmt == DRM_FORMAT_RGB565) 13062306a36Sopenharmony_ci fmt = DRM_FORMAT_HOST_RGB565; 13162306a36Sopenharmony_ci if (fmt == DRM_FORMAT_XRGB1555) 13262306a36Sopenharmony_ci fmt = DRM_FORMAT_HOST_XRGB1555; 13362306a36Sopenharmony_ci } 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp && 13662306a36Sopenharmony_ci fmt == DRM_FORMAT_XRGB2101010) 13762306a36Sopenharmony_ci fmt = DRM_FORMAT_XBGR2101010; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci return fmt; 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ciEXPORT_SYMBOL(drm_driver_legacy_fb_format); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/* 14462306a36Sopenharmony_ci * Internal function to query information for a given format. See 14562306a36Sopenharmony_ci * drm_format_info() for the public API. 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_ciconst struct drm_format_info *__drm_format_info(u32 format) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci static const struct drm_format_info formats[] = { 15062306a36Sopenharmony_ci { .format = DRM_FORMAT_C1, .depth = 1, .num_planes = 1, 15162306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, 15262306a36Sopenharmony_ci { .format = DRM_FORMAT_C2, .depth = 2, .num_planes = 1, 15362306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, 15462306a36Sopenharmony_ci { .format = DRM_FORMAT_C4, .depth = 4, .num_planes = 1, 15562306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, 15662306a36Sopenharmony_ci { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, 15762306a36Sopenharmony_ci { .format = DRM_FORMAT_D1, .depth = 1, .num_planes = 1, 15862306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, 15962306a36Sopenharmony_ci { .format = DRM_FORMAT_D2, .depth = 2, .num_planes = 1, 16062306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, 16162306a36Sopenharmony_ci { .format = DRM_FORMAT_D4, .depth = 4, .num_planes = 1, 16262306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, 16362306a36Sopenharmony_ci { .format = DRM_FORMAT_D8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, 16462306a36Sopenharmony_ci { .format = DRM_FORMAT_R1, .depth = 1, .num_planes = 1, 16562306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, 16662306a36Sopenharmony_ci { .format = DRM_FORMAT_R2, .depth = 2, .num_planes = 1, 16762306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, 16862306a36Sopenharmony_ci { .format = DRM_FORMAT_R4, .depth = 4, .num_planes = 1, 16962306a36Sopenharmony_ci .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, 17062306a36Sopenharmony_ci { .format = DRM_FORMAT_R8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, 17162306a36Sopenharmony_ci { .format = DRM_FORMAT_R10, .depth = 10, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 17262306a36Sopenharmony_ci { .format = DRM_FORMAT_R12, .depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 17362306a36Sopenharmony_ci { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, 17462306a36Sopenharmony_ci { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, 17562306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 17662306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 17762306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 17862306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 17962306a36Sopenharmony_ci { .format = DRM_FORMAT_ARGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 18062306a36Sopenharmony_ci { .format = DRM_FORMAT_ABGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 18162306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 18262306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 18362306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 18462306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 18562306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 18662306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 18762306a36Sopenharmony_ci { .format = DRM_FORMAT_ARGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 18862306a36Sopenharmony_ci { .format = DRM_FORMAT_ABGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 18962306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 19062306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 19162306a36Sopenharmony_ci { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 19262306a36Sopenharmony_ci { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 19362306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 19462306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 19562306a36Sopenharmony_ci { .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, 19662306a36Sopenharmony_ci#endif 19762306a36Sopenharmony_ci { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, 19862306a36Sopenharmony_ci { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, 19962306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20062306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20162306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20262306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20362306a36Sopenharmony_ci { .format = DRM_FORMAT_RGB565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 20462306a36Sopenharmony_ci { .format = DRM_FORMAT_BGR565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 20562306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20662306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20762306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20862306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, 20962306a36Sopenharmony_ci { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21062306a36Sopenharmony_ci { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21162306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21262306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21362306a36Sopenharmony_ci { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21462306a36Sopenharmony_ci { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21562306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21662306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 21762306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, 21862306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, 21962306a36Sopenharmony_ci { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22062306a36Sopenharmony_ci { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22162306a36Sopenharmony_ci { .format = DRM_FORMAT_AXBXGXRX106106106106, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22262306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, 22362306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, 22462306a36Sopenharmony_ci { .format = DRM_FORMAT_ARGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22562306a36Sopenharmony_ci { .format = DRM_FORMAT_ABGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22662306a36Sopenharmony_ci { .format = DRM_FORMAT_RGB888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22762306a36Sopenharmony_ci { .format = DRM_FORMAT_BGR888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22862306a36Sopenharmony_ci { .format = DRM_FORMAT_XRGB8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 22962306a36Sopenharmony_ci { .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 23062306a36Sopenharmony_ci { .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 23162306a36Sopenharmony_ci { .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, 23262306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, 23362306a36Sopenharmony_ci { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, 23462306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, 23562306a36Sopenharmony_ci { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, 23662306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, 23762306a36Sopenharmony_ci { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, 23862306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 23962306a36Sopenharmony_ci { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 24062306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 24162306a36Sopenharmony_ci { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 24262306a36Sopenharmony_ci { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, 24362306a36Sopenharmony_ci { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, 24462306a36Sopenharmony_ci { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 24562306a36Sopenharmony_ci { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 24662306a36Sopenharmony_ci { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 24762306a36Sopenharmony_ci { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 24862306a36Sopenharmony_ci { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 24962306a36Sopenharmony_ci { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 25062306a36Sopenharmony_ci { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 25162306a36Sopenharmony_ci { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 25262306a36Sopenharmony_ci { .format = DRM_FORMAT_XYUV8888, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 25362306a36Sopenharmony_ci { .format = DRM_FORMAT_VUY888, .depth = 0, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 25462306a36Sopenharmony_ci { .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, 25562306a36Sopenharmony_ci { .format = DRM_FORMAT_Y210, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 25662306a36Sopenharmony_ci { .format = DRM_FORMAT_Y212, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 25762306a36Sopenharmony_ci { .format = DRM_FORMAT_Y216, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, 25862306a36Sopenharmony_ci { .format = DRM_FORMAT_Y410, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, 25962306a36Sopenharmony_ci { .format = DRM_FORMAT_Y412, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, 26062306a36Sopenharmony_ci { .format = DRM_FORMAT_Y416, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, 26162306a36Sopenharmony_ci { .format = DRM_FORMAT_XVYU2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 26262306a36Sopenharmony_ci { .format = DRM_FORMAT_XVYU12_16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 26362306a36Sopenharmony_ci { .format = DRM_FORMAT_XVYU16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, 26462306a36Sopenharmony_ci { .format = DRM_FORMAT_Y0L0, .depth = 0, .num_planes = 1, 26562306a36Sopenharmony_ci .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, 26662306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true }, 26762306a36Sopenharmony_ci { .format = DRM_FORMAT_X0L0, .depth = 0, .num_planes = 1, 26862306a36Sopenharmony_ci .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, 26962306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .is_yuv = true }, 27062306a36Sopenharmony_ci { .format = DRM_FORMAT_Y0L2, .depth = 0, .num_planes = 1, 27162306a36Sopenharmony_ci .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, 27262306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true }, 27362306a36Sopenharmony_ci { .format = DRM_FORMAT_X0L2, .depth = 0, .num_planes = 1, 27462306a36Sopenharmony_ci .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, 27562306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .is_yuv = true }, 27662306a36Sopenharmony_ci { .format = DRM_FORMAT_P010, .depth = 0, .num_planes = 2, 27762306a36Sopenharmony_ci .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, 27862306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .is_yuv = true}, 27962306a36Sopenharmony_ci { .format = DRM_FORMAT_P012, .depth = 0, .num_planes = 2, 28062306a36Sopenharmony_ci .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, 28162306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .is_yuv = true}, 28262306a36Sopenharmony_ci { .format = DRM_FORMAT_P016, .depth = 0, .num_planes = 2, 28362306a36Sopenharmony_ci .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, 28462306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .is_yuv = true}, 28562306a36Sopenharmony_ci { .format = DRM_FORMAT_P210, .depth = 0, 28662306a36Sopenharmony_ci .num_planes = 2, .char_per_block = { 2, 4, 0 }, 28762306a36Sopenharmony_ci .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, 28862306a36Sopenharmony_ci .vsub = 1, .is_yuv = true }, 28962306a36Sopenharmony_ci { .format = DRM_FORMAT_VUY101010, .depth = 0, 29062306a36Sopenharmony_ci .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1, 29162306a36Sopenharmony_ci .is_yuv = true }, 29262306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV420_8BIT, .depth = 0, 29362306a36Sopenharmony_ci .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, 29462306a36Sopenharmony_ci .is_yuv = true }, 29562306a36Sopenharmony_ci { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0, 29662306a36Sopenharmony_ci .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, 29762306a36Sopenharmony_ci .is_yuv = true }, 29862306a36Sopenharmony_ci { .format = DRM_FORMAT_NV15, .depth = 0, 29962306a36Sopenharmony_ci .num_planes = 2, .char_per_block = { 5, 5, 0 }, 30062306a36Sopenharmony_ci .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, 30162306a36Sopenharmony_ci .vsub = 2, .is_yuv = true }, 30262306a36Sopenharmony_ci { .format = DRM_FORMAT_Q410, .depth = 0, 30362306a36Sopenharmony_ci .num_planes = 3, .char_per_block = { 2, 2, 2 }, 30462306a36Sopenharmony_ci .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, 30562306a36Sopenharmony_ci .vsub = 1, .is_yuv = true }, 30662306a36Sopenharmony_ci { .format = DRM_FORMAT_Q401, .depth = 0, 30762306a36Sopenharmony_ci .num_planes = 3, .char_per_block = { 2, 2, 2 }, 30862306a36Sopenharmony_ci .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, 30962306a36Sopenharmony_ci .vsub = 1, .is_yuv = true }, 31062306a36Sopenharmony_ci { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2, 31162306a36Sopenharmony_ci .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, 31262306a36Sopenharmony_ci .hsub = 2, .vsub = 2, .is_yuv = true}, 31362306a36Sopenharmony_ci }; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci unsigned int i; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(formats); ++i) { 31862306a36Sopenharmony_ci if (formats[i].format == format) 31962306a36Sopenharmony_ci return &formats[i]; 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci return NULL; 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci/** 32662306a36Sopenharmony_ci * drm_format_info - query information for a given format 32762306a36Sopenharmony_ci * @format: pixel format (DRM_FORMAT_*) 32862306a36Sopenharmony_ci * 32962306a36Sopenharmony_ci * The caller should only pass a supported pixel format to this function. 33062306a36Sopenharmony_ci * Unsupported pixel formats will generate a warning in the kernel log. 33162306a36Sopenharmony_ci * 33262306a36Sopenharmony_ci * Returns: 33362306a36Sopenharmony_ci * The instance of struct drm_format_info that describes the pixel format, or 33462306a36Sopenharmony_ci * NULL if the format is unsupported. 33562306a36Sopenharmony_ci */ 33662306a36Sopenharmony_ciconst struct drm_format_info *drm_format_info(u32 format) 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci const struct drm_format_info *info; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci info = __drm_format_info(format); 34162306a36Sopenharmony_ci WARN_ON(!info); 34262306a36Sopenharmony_ci return info; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ciEXPORT_SYMBOL(drm_format_info); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci/** 34762306a36Sopenharmony_ci * drm_get_format_info - query information for a given framebuffer configuration 34862306a36Sopenharmony_ci * @dev: DRM device 34962306a36Sopenharmony_ci * @mode_cmd: metadata from the userspace fb creation request 35062306a36Sopenharmony_ci * 35162306a36Sopenharmony_ci * Returns: 35262306a36Sopenharmony_ci * The instance of struct drm_format_info that describes the pixel format, or 35362306a36Sopenharmony_ci * NULL if the format is unsupported. 35462306a36Sopenharmony_ci */ 35562306a36Sopenharmony_ciconst struct drm_format_info * 35662306a36Sopenharmony_cidrm_get_format_info(struct drm_device *dev, 35762306a36Sopenharmony_ci const struct drm_mode_fb_cmd2 *mode_cmd) 35862306a36Sopenharmony_ci{ 35962306a36Sopenharmony_ci const struct drm_format_info *info = NULL; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci if (dev->mode_config.funcs->get_format_info) 36262306a36Sopenharmony_ci info = dev->mode_config.funcs->get_format_info(mode_cmd); 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci if (!info) 36562306a36Sopenharmony_ci info = drm_format_info(mode_cmd->pixel_format); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci return info; 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ciEXPORT_SYMBOL(drm_get_format_info); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci/** 37262306a36Sopenharmony_ci * drm_format_info_block_width - width in pixels of block. 37362306a36Sopenharmony_ci * @info: pixel format info 37462306a36Sopenharmony_ci * @plane: plane index 37562306a36Sopenharmony_ci * 37662306a36Sopenharmony_ci * Returns: 37762306a36Sopenharmony_ci * The width in pixels of a block, depending on the plane index. 37862306a36Sopenharmony_ci */ 37962306a36Sopenharmony_ciunsigned int drm_format_info_block_width(const struct drm_format_info *info, 38062306a36Sopenharmony_ci int plane) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci if (!info || plane < 0 || plane >= info->num_planes) 38362306a36Sopenharmony_ci return 0; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci if (!info->block_w[plane]) 38662306a36Sopenharmony_ci return 1; 38762306a36Sopenharmony_ci return info->block_w[plane]; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ciEXPORT_SYMBOL(drm_format_info_block_width); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci/** 39262306a36Sopenharmony_ci * drm_format_info_block_height - height in pixels of a block 39362306a36Sopenharmony_ci * @info: pixel format info 39462306a36Sopenharmony_ci * @plane: plane index 39562306a36Sopenharmony_ci * 39662306a36Sopenharmony_ci * Returns: 39762306a36Sopenharmony_ci * The height in pixels of a block, depending on the plane index. 39862306a36Sopenharmony_ci */ 39962306a36Sopenharmony_ciunsigned int drm_format_info_block_height(const struct drm_format_info *info, 40062306a36Sopenharmony_ci int plane) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci if (!info || plane < 0 || plane >= info->num_planes) 40362306a36Sopenharmony_ci return 0; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci if (!info->block_h[plane]) 40662306a36Sopenharmony_ci return 1; 40762306a36Sopenharmony_ci return info->block_h[plane]; 40862306a36Sopenharmony_ci} 40962306a36Sopenharmony_ciEXPORT_SYMBOL(drm_format_info_block_height); 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci/** 41262306a36Sopenharmony_ci * drm_format_info_bpp - number of bits per pixel 41362306a36Sopenharmony_ci * @info: pixel format info 41462306a36Sopenharmony_ci * @plane: plane index 41562306a36Sopenharmony_ci * 41662306a36Sopenharmony_ci * Returns: 41762306a36Sopenharmony_ci * The actual number of bits per pixel, depending on the plane index. 41862306a36Sopenharmony_ci */ 41962306a36Sopenharmony_ciunsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane) 42062306a36Sopenharmony_ci{ 42162306a36Sopenharmony_ci if (!info || plane < 0 || plane >= info->num_planes) 42262306a36Sopenharmony_ci return 0; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci return info->char_per_block[plane] * 8 / 42562306a36Sopenharmony_ci (drm_format_info_block_width(info, plane) * 42662306a36Sopenharmony_ci drm_format_info_block_height(info, plane)); 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ciEXPORT_SYMBOL(drm_format_info_bpp); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci/** 43162306a36Sopenharmony_ci * drm_format_info_min_pitch - computes the minimum required pitch in bytes 43262306a36Sopenharmony_ci * @info: pixel format info 43362306a36Sopenharmony_ci * @plane: plane index 43462306a36Sopenharmony_ci * @buffer_width: buffer width in pixels 43562306a36Sopenharmony_ci * 43662306a36Sopenharmony_ci * Returns: 43762306a36Sopenharmony_ci * The minimum required pitch in bytes for a buffer by taking into consideration 43862306a36Sopenharmony_ci * the pixel format information and the buffer width. 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_ciuint64_t drm_format_info_min_pitch(const struct drm_format_info *info, 44162306a36Sopenharmony_ci int plane, unsigned int buffer_width) 44262306a36Sopenharmony_ci{ 44362306a36Sopenharmony_ci if (!info || plane < 0 || plane >= info->num_planes) 44462306a36Sopenharmony_ci return 0; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane], 44762306a36Sopenharmony_ci drm_format_info_block_width(info, plane) * 44862306a36Sopenharmony_ci drm_format_info_block_height(info, plane)); 44962306a36Sopenharmony_ci} 45062306a36Sopenharmony_ciEXPORT_SYMBOL(drm_format_info_min_pitch); 451