18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission to use, copy, modify, distribute, and sell this software and its 58c2ecf20Sopenharmony_ci * documentation for any purpose is hereby granted without fee, provided that 68c2ecf20Sopenharmony_ci * the above copyright notice appear in all copies and that both that copyright 78c2ecf20Sopenharmony_ci * notice and this permission notice appear in supporting documentation, and 88c2ecf20Sopenharmony_ci * that the name of the copyright holders not be used in advertising or 98c2ecf20Sopenharmony_ci * publicity pertaining to distribution of the software without specific, 108c2ecf20Sopenharmony_ci * written prior permission. The copyright holders make no representations 118c2ecf20Sopenharmony_ci * about the suitability of this software for any purpose. It is provided "as 128c2ecf20Sopenharmony_ci * is" without express or implied warranty. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 158c2ecf20Sopenharmony_ci * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 168c2ecf20Sopenharmony_ci * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 178c2ecf20Sopenharmony_ci * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 188c2ecf20Sopenharmony_ci * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 198c2ecf20Sopenharmony_ci * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 208c2ecf20Sopenharmony_ci * OF THIS SOFTWARE. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci#ifndef __DRM_FOURCC_H__ 238c2ecf20Sopenharmony_ci#define __DRM_FOURCC_H__ 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#include <linux/types.h> 268c2ecf20Sopenharmony_ci#include <uapi/drm/drm_fourcc.h> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* 298c2ecf20Sopenharmony_ci * DRM formats are little endian. Define host endian variants for the 308c2ecf20Sopenharmony_ci * most common formats here, to reduce the #ifdefs needed in drivers. 318c2ecf20Sopenharmony_ci * 328c2ecf20Sopenharmony_ci * Note that the DRM_FORMAT_BIG_ENDIAN flag should only be used in 338c2ecf20Sopenharmony_ci * case the format can't be specified otherwise, so we don't end up 348c2ecf20Sopenharmony_ci * with two values describing the same format. 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN 378c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_XRGB1555 (DRM_FORMAT_XRGB1555 | \ 388c2ecf20Sopenharmony_ci DRM_FORMAT_BIG_ENDIAN) 398c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_RGB565 (DRM_FORMAT_RGB565 | \ 408c2ecf20Sopenharmony_ci DRM_FORMAT_BIG_ENDIAN) 418c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_XRGB8888 DRM_FORMAT_BGRX8888 428c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_ARGB8888 DRM_FORMAT_BGRA8888 438c2ecf20Sopenharmony_ci#else 448c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_XRGB1555 DRM_FORMAT_XRGB1555 458c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_RGB565 DRM_FORMAT_RGB565 468c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_XRGB8888 DRM_FORMAT_XRGB8888 478c2ecf20Sopenharmony_ci# define DRM_FORMAT_HOST_ARGB8888 DRM_FORMAT_ARGB8888 488c2ecf20Sopenharmony_ci#endif 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistruct drm_device; 518c2ecf20Sopenharmony_cistruct drm_mode_fb_cmd2; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/** 548c2ecf20Sopenharmony_ci * struct drm_format_info - information about a DRM format 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_cistruct drm_format_info { 578c2ecf20Sopenharmony_ci /** @format: 4CC format identifier (DRM_FORMAT_*) */ 588c2ecf20Sopenharmony_ci u32 format; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci /** 618c2ecf20Sopenharmony_ci * @depth: 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * Color depth (number of bits per pixel excluding padding bits), 648c2ecf20Sopenharmony_ci * valid for a subset of RGB formats only. This is a legacy field, do 658c2ecf20Sopenharmony_ci * not use in new code and set to 0 for new formats. 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ci u8 depth; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci /** @num_planes: Number of color planes (1 to 3) */ 708c2ecf20Sopenharmony_ci u8 num_planes; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci union { 738c2ecf20Sopenharmony_ci /** 748c2ecf20Sopenharmony_ci * @cpp: 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * Number of bytes per pixel (per plane), this is aliased with 778c2ecf20Sopenharmony_ci * @char_per_block. It is deprecated in favour of using the 788c2ecf20Sopenharmony_ci * triplet @char_per_block, @block_w, @block_h for better 798c2ecf20Sopenharmony_ci * describing the pixel format. 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci u8 cpp[4]; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /** 848c2ecf20Sopenharmony_ci * @char_per_block: 858c2ecf20Sopenharmony_ci * 868c2ecf20Sopenharmony_ci * Number of bytes per block (per plane), where blocks are 878c2ecf20Sopenharmony_ci * defined as a rectangle of pixels which are stored next to 888c2ecf20Sopenharmony_ci * each other in a byte aligned memory region. Together with 898c2ecf20Sopenharmony_ci * @block_w and @block_h this is used to properly describe tiles 908c2ecf20Sopenharmony_ci * in tiled formats or to describe groups of pixels in packed 918c2ecf20Sopenharmony_ci * formats for which the memory needed for a single pixel is not 928c2ecf20Sopenharmony_ci * byte aligned. 938c2ecf20Sopenharmony_ci * 948c2ecf20Sopenharmony_ci * @cpp has been kept for historical reasons because there are 958c2ecf20Sopenharmony_ci * a lot of places in drivers where it's used. In drm core for 968c2ecf20Sopenharmony_ci * generic code paths the preferred way is to use 978c2ecf20Sopenharmony_ci * @char_per_block, drm_format_info_block_width() and 988c2ecf20Sopenharmony_ci * drm_format_info_block_height() which allows handling both 998c2ecf20Sopenharmony_ci * block and non-block formats in the same way. 1008c2ecf20Sopenharmony_ci * 1018c2ecf20Sopenharmony_ci * For formats that are intended to be used only with non-linear 1028c2ecf20Sopenharmony_ci * modifiers both @cpp and @char_per_block must be 0 in the 1038c2ecf20Sopenharmony_ci * generic format table. Drivers could supply accurate 1048c2ecf20Sopenharmony_ci * information from their drm_mode_config.get_format_info hook 1058c2ecf20Sopenharmony_ci * if they want the core to be validating the pitch. 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_ci u8 char_per_block[4]; 1088c2ecf20Sopenharmony_ci }; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci /** 1118c2ecf20Sopenharmony_ci * @block_w: 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * Block width in pixels, this is intended to be accessed through 1148c2ecf20Sopenharmony_ci * drm_format_info_block_width() 1158c2ecf20Sopenharmony_ci */ 1168c2ecf20Sopenharmony_ci u8 block_w[4]; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci /** 1198c2ecf20Sopenharmony_ci * @block_h: 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * Block height in pixels, this is intended to be accessed through 1228c2ecf20Sopenharmony_ci * drm_format_info_block_height() 1238c2ecf20Sopenharmony_ci */ 1248c2ecf20Sopenharmony_ci u8 block_h[4]; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /** @hsub: Horizontal chroma subsampling factor */ 1278c2ecf20Sopenharmony_ci u8 hsub; 1288c2ecf20Sopenharmony_ci /** @vsub: Vertical chroma subsampling factor */ 1298c2ecf20Sopenharmony_ci u8 vsub; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci /** @has_alpha: Does the format embeds an alpha component? */ 1328c2ecf20Sopenharmony_ci bool has_alpha; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /** @is_yuv: Is it a YUV format? */ 1358c2ecf20Sopenharmony_ci bool is_yuv; 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/** 1398c2ecf20Sopenharmony_ci * struct drm_format_name_buf - name of a DRM format 1408c2ecf20Sopenharmony_ci * @str: string buffer containing the format name 1418c2ecf20Sopenharmony_ci */ 1428c2ecf20Sopenharmony_cistruct drm_format_name_buf { 1438c2ecf20Sopenharmony_ci char str[32]; 1448c2ecf20Sopenharmony_ci}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci/** 1478c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_packed - check that the format info matches a YUV 1488c2ecf20Sopenharmony_ci * format with data laid in a single plane 1498c2ecf20Sopenharmony_ci * @info: format info 1508c2ecf20Sopenharmony_ci * 1518c2ecf20Sopenharmony_ci * Returns: 1528c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a packed YUV format. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_cistatic inline bool 1558c2ecf20Sopenharmony_cidrm_format_info_is_yuv_packed(const struct drm_format_info *info) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci return info->is_yuv && info->num_planes == 1; 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci/** 1618c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_semiplanar - check that the format info matches a YUV 1628c2ecf20Sopenharmony_ci * format with data laid in two planes (luminance and chrominance) 1638c2ecf20Sopenharmony_ci * @info: format info 1648c2ecf20Sopenharmony_ci * 1658c2ecf20Sopenharmony_ci * Returns: 1668c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a semiplanar YUV format. 1678c2ecf20Sopenharmony_ci */ 1688c2ecf20Sopenharmony_cistatic inline bool 1698c2ecf20Sopenharmony_cidrm_format_info_is_yuv_semiplanar(const struct drm_format_info *info) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci return info->is_yuv && info->num_planes == 2; 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci/** 1758c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_planar - check that the format info matches a YUV 1768c2ecf20Sopenharmony_ci * format with data laid in three planes (one for each YUV component) 1778c2ecf20Sopenharmony_ci * @info: format info 1788c2ecf20Sopenharmony_ci * 1798c2ecf20Sopenharmony_ci * Returns: 1808c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a planar YUV format. 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_cistatic inline bool 1838c2ecf20Sopenharmony_cidrm_format_info_is_yuv_planar(const struct drm_format_info *info) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci return info->is_yuv && info->num_planes == 3; 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci/** 1898c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_sampling_410 - check that the format info matches a 1908c2ecf20Sopenharmony_ci * YUV format with 4:1:0 sub-sampling 1918c2ecf20Sopenharmony_ci * @info: format info 1928c2ecf20Sopenharmony_ci * 1938c2ecf20Sopenharmony_ci * Returns: 1948c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a YUV format with 4:1:0 1958c2ecf20Sopenharmony_ci * sub-sampling. 1968c2ecf20Sopenharmony_ci */ 1978c2ecf20Sopenharmony_cistatic inline bool 1988c2ecf20Sopenharmony_cidrm_format_info_is_yuv_sampling_410(const struct drm_format_info *info) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci return info->is_yuv && info->hsub == 4 && info->vsub == 4; 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci/** 2048c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_sampling_411 - check that the format info matches a 2058c2ecf20Sopenharmony_ci * YUV format with 4:1:1 sub-sampling 2068c2ecf20Sopenharmony_ci * @info: format info 2078c2ecf20Sopenharmony_ci * 2088c2ecf20Sopenharmony_ci * Returns: 2098c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a YUV format with 4:1:1 2108c2ecf20Sopenharmony_ci * sub-sampling. 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_cistatic inline bool 2138c2ecf20Sopenharmony_cidrm_format_info_is_yuv_sampling_411(const struct drm_format_info *info) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci return info->is_yuv && info->hsub == 4 && info->vsub == 1; 2168c2ecf20Sopenharmony_ci} 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci/** 2198c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_sampling_420 - check that the format info matches a 2208c2ecf20Sopenharmony_ci * YUV format with 4:2:0 sub-sampling 2218c2ecf20Sopenharmony_ci * @info: format info 2228c2ecf20Sopenharmony_ci * 2238c2ecf20Sopenharmony_ci * Returns: 2248c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a YUV format with 4:2:0 2258c2ecf20Sopenharmony_ci * sub-sampling. 2268c2ecf20Sopenharmony_ci */ 2278c2ecf20Sopenharmony_cistatic inline bool 2288c2ecf20Sopenharmony_cidrm_format_info_is_yuv_sampling_420(const struct drm_format_info *info) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci return info->is_yuv && info->hsub == 2 && info->vsub == 2; 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci/** 2348c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_sampling_422 - check that the format info matches a 2358c2ecf20Sopenharmony_ci * YUV format with 4:2:2 sub-sampling 2368c2ecf20Sopenharmony_ci * @info: format info 2378c2ecf20Sopenharmony_ci * 2388c2ecf20Sopenharmony_ci * Returns: 2398c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a YUV format with 4:2:2 2408c2ecf20Sopenharmony_ci * sub-sampling. 2418c2ecf20Sopenharmony_ci */ 2428c2ecf20Sopenharmony_cistatic inline bool 2438c2ecf20Sopenharmony_cidrm_format_info_is_yuv_sampling_422(const struct drm_format_info *info) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci return info->is_yuv && info->hsub == 2 && info->vsub == 1; 2468c2ecf20Sopenharmony_ci} 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci/** 2498c2ecf20Sopenharmony_ci * drm_format_info_is_yuv_sampling_444 - check that the format info matches a 2508c2ecf20Sopenharmony_ci * YUV format with 4:4:4 sub-sampling 2518c2ecf20Sopenharmony_ci * @info: format info 2528c2ecf20Sopenharmony_ci * 2538c2ecf20Sopenharmony_ci * Returns: 2548c2ecf20Sopenharmony_ci * A boolean indicating whether the format info matches a YUV format with 4:4:4 2558c2ecf20Sopenharmony_ci * sub-sampling. 2568c2ecf20Sopenharmony_ci */ 2578c2ecf20Sopenharmony_cistatic inline bool 2588c2ecf20Sopenharmony_cidrm_format_info_is_yuv_sampling_444(const struct drm_format_info *info) 2598c2ecf20Sopenharmony_ci{ 2608c2ecf20Sopenharmony_ci return info->is_yuv && info->hsub == 1 && info->vsub == 1; 2618c2ecf20Sopenharmony_ci} 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci/** 2648c2ecf20Sopenharmony_ci * drm_format_info_plane_width - width of the plane given the first plane 2658c2ecf20Sopenharmony_ci * @info: pixel format info 2668c2ecf20Sopenharmony_ci * @width: width of the first plane 2678c2ecf20Sopenharmony_ci * @plane: plane index 2688c2ecf20Sopenharmony_ci * 2698c2ecf20Sopenharmony_ci * Returns: 2708c2ecf20Sopenharmony_ci * The width of @plane, given that the width of the first plane is @width. 2718c2ecf20Sopenharmony_ci */ 2728c2ecf20Sopenharmony_cistatic inline 2738c2ecf20Sopenharmony_ciint drm_format_info_plane_width(const struct drm_format_info *info, int width, 2748c2ecf20Sopenharmony_ci int plane) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci if (!info || plane >= info->num_planes) 2778c2ecf20Sopenharmony_ci return 0; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci if (plane == 0) 2808c2ecf20Sopenharmony_ci return width; 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci return width / info->hsub; 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci/** 2868c2ecf20Sopenharmony_ci * drm_format_info_plane_height - height of the plane given the first plane 2878c2ecf20Sopenharmony_ci * @info: pixel format info 2888c2ecf20Sopenharmony_ci * @height: height of the first plane 2898c2ecf20Sopenharmony_ci * @plane: plane index 2908c2ecf20Sopenharmony_ci * 2918c2ecf20Sopenharmony_ci * Returns: 2928c2ecf20Sopenharmony_ci * The height of @plane, given that the height of the first plane is @height. 2938c2ecf20Sopenharmony_ci */ 2948c2ecf20Sopenharmony_cistatic inline 2958c2ecf20Sopenharmony_ciint drm_format_info_plane_height(const struct drm_format_info *info, int height, 2968c2ecf20Sopenharmony_ci int plane) 2978c2ecf20Sopenharmony_ci{ 2988c2ecf20Sopenharmony_ci if (!info || plane >= info->num_planes) 2998c2ecf20Sopenharmony_ci return 0; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci if (plane == 0) 3028c2ecf20Sopenharmony_ci return height; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci return height / info->vsub; 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ciconst struct drm_format_info *__drm_format_info(u32 format); 3088c2ecf20Sopenharmony_ciconst struct drm_format_info *drm_format_info(u32 format); 3098c2ecf20Sopenharmony_ciconst struct drm_format_info * 3108c2ecf20Sopenharmony_cidrm_get_format_info(struct drm_device *dev, 3118c2ecf20Sopenharmony_ci const struct drm_mode_fb_cmd2 *mode_cmd); 3128c2ecf20Sopenharmony_ciuint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); 3138c2ecf20Sopenharmony_ciuint32_t drm_driver_legacy_fb_format(struct drm_device *dev, 3148c2ecf20Sopenharmony_ci uint32_t bpp, uint32_t depth); 3158c2ecf20Sopenharmony_ciunsigned int drm_format_info_block_width(const struct drm_format_info *info, 3168c2ecf20Sopenharmony_ci int plane); 3178c2ecf20Sopenharmony_ciunsigned int drm_format_info_block_height(const struct drm_format_info *info, 3188c2ecf20Sopenharmony_ci int plane); 3198c2ecf20Sopenharmony_ciuint64_t drm_format_info_min_pitch(const struct drm_format_info *info, 3208c2ecf20Sopenharmony_ci int plane, unsigned int buffer_width); 3218c2ecf20Sopenharmony_ciconst char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf); 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci#endif /* __DRM_FOURCC_H__ */ 324