Branch data Line data Source code
1 : : /* 2 : : * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 3 : : * 4 : : * Permission to use, copy, modify, distribute, and sell this software and its 5 : : * documentation for any purpose is hereby granted without fee, provided that 6 : : * the above copyright notice appear in all copies and that both that copyright 7 : : * notice and this permission notice appear in supporting documentation, and 8 : : * that the name of the copyright holders not be used in advertising or 9 : : * publicity pertaining to distribution of the software without specific, 10 : : * written prior permission. The copyright holders make no representations 11 : : * about the suitability of this software for any purpose. It is provided "as 12 : : * is" without express or implied warranty. 13 : : * 14 : : * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 : : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 : : * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 : : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 : : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 : : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 : : * OF THIS SOFTWARE. 21 : : */ 22 : : #ifndef __DRM_FOURCC_H__ 23 : : #define __DRM_FOURCC_H__ 24 : : 25 : : #include <linux/types.h> 26 : : #include <uapi/drm/drm_fourcc.h> 27 : : 28 : : /* 29 : : * DRM formats are little endian. Define host endian variants for the 30 : : * most common formats here, to reduce the #ifdefs needed in drivers. 31 : : * 32 : : * Note that the DRM_FORMAT_BIG_ENDIAN flag should only be used in 33 : : * case the format can't be specified otherwise, so we don't end up 34 : : * with two values describing the same format. 35 : : */ 36 : : #ifdef __BIG_ENDIAN 37 : : # define DRM_FORMAT_HOST_XRGB1555 (DRM_FORMAT_XRGB1555 | \ 38 : : DRM_FORMAT_BIG_ENDIAN) 39 : : # define DRM_FORMAT_HOST_RGB565 (DRM_FORMAT_RGB565 | \ 40 : : DRM_FORMAT_BIG_ENDIAN) 41 : : # define DRM_FORMAT_HOST_XRGB8888 DRM_FORMAT_BGRX8888 42 : : # define DRM_FORMAT_HOST_ARGB8888 DRM_FORMAT_BGRA8888 43 : : #else 44 : : # define DRM_FORMAT_HOST_XRGB1555 DRM_FORMAT_XRGB1555 45 : : # define DRM_FORMAT_HOST_RGB565 DRM_FORMAT_RGB565 46 : : # define DRM_FORMAT_HOST_XRGB8888 DRM_FORMAT_XRGB8888 47 : : # define DRM_FORMAT_HOST_ARGB8888 DRM_FORMAT_ARGB8888 48 : : #endif 49 : : 50 : : struct drm_device; 51 : : struct drm_mode_fb_cmd2; 52 : : 53 : : /** 54 : : * struct drm_format_info - information about a DRM format 55 : : */ 56 : : struct drm_format_info { 57 : : /** @format: 4CC format identifier (DRM_FORMAT_*) */ 58 : : u32 format; 59 : : 60 : : /** 61 : : * @depth: 62 : : * 63 : : * Color depth (number of bits per pixel excluding padding bits), 64 : : * valid for a subset of RGB formats only. This is a legacy field, do 65 : : * not use in new code and set to 0 for new formats. 66 : : */ 67 : : u8 depth; 68 : : 69 : : /** @num_planes: Number of color planes (1 to 3) */ 70 : : u8 num_planes; 71 : : 72 : : union { 73 : : /** 74 : : * @cpp: 75 : : * 76 : : * Number of bytes per pixel (per plane), this is aliased with 77 : : * @char_per_block. It is deprecated in favour of using the 78 : : * triplet @char_per_block, @block_w, @block_h for better 79 : : * describing the pixel format. 80 : : */ 81 : : u8 cpp[4]; 82 : : 83 : : /** 84 : : * @char_per_block: 85 : : * 86 : : * Number of bytes per block (per plane), where blocks are 87 : : * defined as a rectangle of pixels which are stored next to 88 : : * each other in a byte aligned memory region. Together with 89 : : * @block_w and @block_h this is used to properly describe tiles 90 : : * in tiled formats or to describe groups of pixels in packed 91 : : * formats for which the memory needed for a single pixel is not 92 : : * byte aligned. 93 : : * 94 : : * @cpp has been kept for historical reasons because there are 95 : : * a lot of places in drivers where it's used. In drm core for 96 : : * generic code paths the preferred way is to use 97 : : * @char_per_block, drm_format_info_block_width() and 98 : : * drm_format_info_block_height() which allows handling both 99 : : * block and non-block formats in the same way. 100 : : * 101 : : * For formats that are intended to be used only with non-linear 102 : : * modifiers both @cpp and @char_per_block must be 0 in the 103 : : * generic format table. Drivers could supply accurate 104 : : * information from their drm_mode_config.get_format_info hook 105 : : * if they want the core to be validating the pitch. 106 : : */ 107 : : u8 char_per_block[4]; 108 : : }; 109 : : 110 : : /** 111 : : * @block_w: 112 : : * 113 : : * Block width in pixels, this is intended to be accessed through 114 : : * drm_format_info_block_width() 115 : : */ 116 : : u8 block_w[4]; 117 : : 118 : : /** 119 : : * @block_h: 120 : : * 121 : : * Block height in pixels, this is intended to be accessed through 122 : : * drm_format_info_block_height() 123 : : */ 124 : : u8 block_h[4]; 125 : : 126 : : /** @hsub: Horizontal chroma subsampling factor */ 127 : : u8 hsub; 128 : : /** @vsub: Vertical chroma subsampling factor */ 129 : : u8 vsub; 130 : : 131 : : /** @has_alpha: Does the format embeds an alpha component? */ 132 : : bool has_alpha; 133 : : 134 : : /** @is_yuv: Is it a YUV format? */ 135 : : bool is_yuv; 136 : : }; 137 : : 138 : : /** 139 : : * struct drm_format_name_buf - name of a DRM format 140 : : * @str: string buffer containing the format name 141 : : */ 142 : : struct drm_format_name_buf { 143 : : char str[32]; 144 : : }; 145 : : 146 : : /** 147 : : * drm_format_info_is_yuv_packed - check that the format info matches a YUV 148 : : * format with data laid in a single plane 149 : : * @info: format info 150 : : * 151 : : * Returns: 152 : : * A boolean indicating whether the format info matches a packed YUV format. 153 : : */ 154 : : static inline bool 155 : : drm_format_info_is_yuv_packed(const struct drm_format_info *info) 156 : : { 157 : : return info->is_yuv && info->num_planes == 1; 158 : : } 159 : : 160 : : /** 161 : : * drm_format_info_is_yuv_semiplanar - check that the format info matches a YUV 162 : : * format with data laid in two planes (luminance and chrominance) 163 : : * @info: format info 164 : : * 165 : : * Returns: 166 : : * A boolean indicating whether the format info matches a semiplanar YUV format. 167 : : */ 168 : : static inline bool 169 : 0 : drm_format_info_is_yuv_semiplanar(const struct drm_format_info *info) 170 : : { 171 [ # # # # : 0 : return info->is_yuv && info->num_planes == 2; # # ] 172 : : } 173 : : 174 : : /** 175 : : * drm_format_info_is_yuv_planar - check that the format info matches a YUV 176 : : * format with data laid in three planes (one for each YUV component) 177 : : * @info: format info 178 : : * 179 : : * Returns: 180 : : * A boolean indicating whether the format info matches a planar YUV format. 181 : : */ 182 : : static inline bool 183 : : drm_format_info_is_yuv_planar(const struct drm_format_info *info) 184 : : { 185 : : return info->is_yuv && info->num_planes == 3; 186 : : } 187 : : 188 : : /** 189 : : * drm_format_info_is_yuv_sampling_410 - check that the format info matches a 190 : : * YUV format with 4:1:0 sub-sampling 191 : : * @info: format info 192 : : * 193 : : * Returns: 194 : : * A boolean indicating whether the format info matches a YUV format with 4:1:0 195 : : * sub-sampling. 196 : : */ 197 : : static inline bool 198 : : drm_format_info_is_yuv_sampling_410(const struct drm_format_info *info) 199 : : { 200 : : return info->is_yuv && info->hsub == 4 && info->vsub == 4; 201 : : } 202 : : 203 : : /** 204 : : * drm_format_info_is_yuv_sampling_411 - check that the format info matches a 205 : : * YUV format with 4:1:1 sub-sampling 206 : : * @info: format info 207 : : * 208 : : * Returns: 209 : : * A boolean indicating whether the format info matches a YUV format with 4:1:1 210 : : * sub-sampling. 211 : : */ 212 : : static inline bool 213 : : drm_format_info_is_yuv_sampling_411(const struct drm_format_info *info) 214 : : { 215 : : return info->is_yuv && info->hsub == 4 && info->vsub == 1; 216 : : } 217 : : 218 : : /** 219 : : * drm_format_info_is_yuv_sampling_420 - check that the format info matches a 220 : : * YUV format with 4:2:0 sub-sampling 221 : : * @info: format info 222 : : * 223 : : * Returns: 224 : : * A boolean indicating whether the format info matches a YUV format with 4:2:0 225 : : * sub-sampling. 226 : : */ 227 : : static inline bool 228 : : drm_format_info_is_yuv_sampling_420(const struct drm_format_info *info) 229 : : { 230 : : return info->is_yuv && info->hsub == 2 && info->vsub == 2; 231 : : } 232 : : 233 : : /** 234 : : * drm_format_info_is_yuv_sampling_422 - check that the format info matches a 235 : : * YUV format with 4:2:2 sub-sampling 236 : : * @info: format info 237 : : * 238 : : * Returns: 239 : : * A boolean indicating whether the format info matches a YUV format with 4:2:2 240 : : * sub-sampling. 241 : : */ 242 : : static inline bool 243 : : drm_format_info_is_yuv_sampling_422(const struct drm_format_info *info) 244 : : { 245 : : return info->is_yuv && info->hsub == 2 && info->vsub == 1; 246 : : } 247 : : 248 : : /** 249 : : * drm_format_info_is_yuv_sampling_444 - check that the format info matches a 250 : : * YUV format with 4:4:4 sub-sampling 251 : : * @info: format info 252 : : * 253 : : * Returns: 254 : : * A boolean indicating whether the format info matches a YUV format with 4:4:4 255 : : * sub-sampling. 256 : : */ 257 : : static inline bool 258 : : drm_format_info_is_yuv_sampling_444(const struct drm_format_info *info) 259 : : { 260 : : return info->is_yuv && info->hsub == 1 && info->vsub == 1; 261 : : } 262 : : 263 : : /** 264 : : * drm_format_info_plane_width - width of the plane given the first plane 265 : : * @info: pixel format info 266 : : * @width: width of the first plane 267 : : * @plane: plane index 268 : : * 269 : : * Returns: 270 : : * The width of @plane, given that the width of the first plane is @width. 271 : : */ 272 : : static inline 273 : : int drm_format_info_plane_width(const struct drm_format_info *info, int width, 274 : : int plane) 275 : : { 276 : : if (!info || plane >= info->num_planes) 277 : : return 0; 278 : : 279 : : if (plane == 0) 280 : : return width; 281 : : 282 : : return width / info->hsub; 283 : : } 284 : : 285 : : /** 286 : : * drm_format_info_plane_height - height of the plane given the first plane 287 : : * @info: pixel format info 288 : : * @height: height of the first plane 289 : : * @plane: plane index 290 : : * 291 : : * Returns: 292 : : * The height of @plane, given that the height of the first plane is @height. 293 : : */ 294 : : static inline 295 : : int drm_format_info_plane_height(const struct drm_format_info *info, int height, 296 : : int plane) 297 : : { 298 : : if (!info || plane >= info->num_planes) 299 : : return 0; 300 : : 301 : : if (plane == 0) 302 : : return height; 303 : : 304 : : return height / info->vsub; 305 : : } 306 : : 307 : : const struct drm_format_info *__drm_format_info(u32 format); 308 : : const struct drm_format_info *drm_format_info(u32 format); 309 : : const struct drm_format_info * 310 : : drm_get_format_info(struct drm_device *dev, 311 : : const struct drm_mode_fb_cmd2 *mode_cmd); 312 : : uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); 313 : : uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, 314 : : uint32_t bpp, uint32_t depth); 315 : : unsigned int drm_format_info_block_width(const struct drm_format_info *info, 316 : : int plane); 317 : : unsigned int drm_format_info_block_height(const struct drm_format_info *info, 318 : : int plane); 319 : : uint64_t drm_format_info_min_pitch(const struct drm_format_info *info, 320 : : int plane, unsigned int buffer_width); 321 : : const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf); 322 : : 323 : : #endif /* __DRM_FOURCC_H__ */