Commit | Line | Data |
---|---|---|
ae4df11a LP |
1 | /* |
2 | * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> | |
3 | * | |
4 | * DRM core format related functions | |
5 | * | |
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. | |
15 | * | |
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 | |
22 | * 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/drmP.h> | |
31 | #include <drm/drm_fourcc.h> | |
32 | ||
33 | static char printable_char(int c) | |
34 | { | |
35 | return isascii(c) && isprint(c) ? c : '?'; | |
36 | } | |
37 | ||
ec5e3047 DV |
38 | /** |
39 | * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description | |
40 | * @bpp: bits per pixels | |
41 | * @depth: bit depth per pixel | |
42 | * | |
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. | |
45 | */ | |
46 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) | |
47 | { | |
70109354 | 48 | uint32_t fmt = DRM_FORMAT_INVALID; |
ec5e3047 DV |
49 | |
50 | switch (bpp) { | |
51 | case 8: | |
70109354 CW |
52 | if (depth == 8) |
53 | fmt = DRM_FORMAT_C8; | |
ec5e3047 | 54 | break; |
70109354 | 55 | |
ec5e3047 | 56 | case 16: |
70109354 CW |
57 | switch (depth) { |
58 | case 15: | |
ec5e3047 | 59 | fmt = DRM_FORMAT_XRGB1555; |
70109354 CW |
60 | break; |
61 | case 16: | |
ec5e3047 | 62 | fmt = DRM_FORMAT_RGB565; |
70109354 CW |
63 | break; |
64 | default: | |
65 | break; | |
66 | } | |
ec5e3047 | 67 | break; |
70109354 | 68 | |
ec5e3047 | 69 | case 24: |
70109354 CW |
70 | if (depth == 24) |
71 | fmt = DRM_FORMAT_RGB888; | |
ec5e3047 | 72 | break; |
70109354 | 73 | |
ec5e3047 | 74 | case 32: |
70109354 CW |
75 | switch (depth) { |
76 | case 24: | |
ec5e3047 | 77 | fmt = DRM_FORMAT_XRGB8888; |
70109354 CW |
78 | break; |
79 | case 30: | |
ec5e3047 | 80 | fmt = DRM_FORMAT_XRGB2101010; |
70109354 CW |
81 | break; |
82 | case 32: | |
ec5e3047 | 83 | fmt = DRM_FORMAT_ARGB8888; |
70109354 CW |
84 | break; |
85 | default: | |
86 | break; | |
87 | } | |
ec5e3047 | 88 | break; |
70109354 | 89 | |
ec5e3047 | 90 | default: |
ec5e3047 DV |
91 | break; |
92 | } | |
93 | ||
94 | return fmt; | |
95 | } | |
96 | EXPORT_SYMBOL(drm_mode_legacy_fb_format); | |
97 | ||
059b5eb5 GH |
98 | /** |
99 | * drm_driver_legacy_fb_format - compute drm fourcc code from legacy description | |
100 | * @bpp: bits per pixels | |
101 | * @depth: bit depth per pixel | |
102 | * @native: use host native byte order | |
103 | * | |
104 | * Computes a drm fourcc pixel format code for the given @bpp/@depth values. | |
105 | * Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config, | |
106 | * and depending on the quirk_addfb_prefer_host_byte_order flag it returns | |
107 | * little endian byte order or host byte order framebuffer formats. | |
108 | */ | |
109 | uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, | |
110 | uint32_t bpp, uint32_t depth) | |
111 | { | |
112 | uint32_t fmt = drm_mode_legacy_fb_format(bpp, depth); | |
113 | ||
114 | if (dev->mode_config.quirk_addfb_prefer_host_byte_order) { | |
115 | if (fmt == DRM_FORMAT_XRGB8888) | |
116 | fmt = DRM_FORMAT_HOST_XRGB8888; | |
117 | if (fmt == DRM_FORMAT_ARGB8888) | |
118 | fmt = DRM_FORMAT_HOST_ARGB8888; | |
119 | if (fmt == DRM_FORMAT_RGB565) | |
120 | fmt = DRM_FORMAT_HOST_RGB565; | |
121 | if (fmt == DRM_FORMAT_XRGB1555) | |
122 | fmt = DRM_FORMAT_HOST_XRGB1555; | |
123 | } | |
124 | return fmt; | |
125 | } | |
126 | EXPORT_SYMBOL(drm_driver_legacy_fb_format); | |
127 | ||
ae4df11a | 128 | /** |
b3c11ac2 | 129 | * drm_get_format_name - fill a string with a drm fourcc format's name |
ae4df11a | 130 | * @format: format to compute name of |
b3c11ac2 | 131 | * @buf: caller-supplied buffer |
ae4df11a | 132 | */ |
b3c11ac2 | 133 | const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf) |
ae4df11a | 134 | { |
b3c11ac2 | 135 | snprintf(buf->str, sizeof(buf->str), |
ae4df11a LP |
136 | "%c%c%c%c %s-endian (0x%08x)", |
137 | printable_char(format & 0xff), | |
138 | printable_char((format >> 8) & 0xff), | |
139 | printable_char((format >> 16) & 0xff), | |
140 | printable_char((format >> 24) & 0x7f), | |
141 | format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", | |
142 | format); | |
143 | ||
b3c11ac2 | 144 | return buf->str; |
ae4df11a LP |
145 | } |
146 | EXPORT_SYMBOL(drm_get_format_name); | |
147 | ||
333d2da5 LP |
148 | /* |
149 | * Internal function to query information for a given format. See | |
150 | * drm_format_info() for the public API. | |
84770cc2 | 151 | */ |
333d2da5 | 152 | const struct drm_format_info *__drm_format_info(u32 format) |
84770cc2 LP |
153 | { |
154 | static const struct drm_format_info formats[] = { | |
155 | { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
156 | { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
157 | { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
158 | { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
159 | { .format = DRM_FORMAT_XBGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
160 | { .format = DRM_FORMAT_RGBX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
161 | { .format = DRM_FORMAT_BGRX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
162 | { .format = DRM_FORMAT_ARGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
163 | { .format = DRM_FORMAT_ABGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
164 | { .format = DRM_FORMAT_RGBA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
165 | { .format = DRM_FORMAT_BGRA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
166 | { .format = DRM_FORMAT_XRGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
167 | { .format = DRM_FORMAT_XBGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
168 | { .format = DRM_FORMAT_RGBX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
169 | { .format = DRM_FORMAT_BGRX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
170 | { .format = DRM_FORMAT_ARGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
171 | { .format = DRM_FORMAT_ABGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
172 | { .format = DRM_FORMAT_RGBA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
173 | { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
174 | { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
175 | { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
176 | { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
177 | { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
178 | { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
179 | { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
180 | { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
181 | { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
182 | { .format = DRM_FORMAT_RGB565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
183 | { .format = DRM_FORMAT_BGR565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
184 | { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, |
185 | { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
186 | { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
187 | { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
188 | { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
189 | { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
190 | { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
191 | { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
192 | { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
193 | { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
194 | { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
195 | { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
196 | { .format = DRM_FORMAT_RGB888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
197 | { .format = DRM_FORMAT_BGR888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
198 | { .format = DRM_FORMAT_XRGB8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
199 | { .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
200 | { .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
201 | { .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
ce2d5461 AKH |
202 | { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, |
203 | { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, | |
204 | { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
205 | { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
206 | { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
207 | { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
208 | { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
209 | { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
210 | { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
211 | { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
212 | { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
213 | { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
214 | { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
215 | { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
216 | { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
217 | { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
218 | { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
219 | { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
220 | { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
221 | { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
222 | { .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, | |
84770cc2 LP |
223 | }; |
224 | ||
225 | unsigned int i; | |
226 | ||
227 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | |
228 | if (formats[i].format == format) | |
229 | return &formats[i]; | |
230 | } | |
231 | ||
232 | return NULL; | |
233 | } | |
333d2da5 LP |
234 | |
235 | /** | |
236 | * drm_format_info - query information for a given format | |
237 | * @format: pixel format (DRM_FORMAT_*) | |
238 | * | |
239 | * The caller should only pass a supported pixel format to this function. | |
240 | * Unsupported pixel formats will generate a warning in the kernel log. | |
241 | * | |
242 | * Returns: | |
243 | * The instance of struct drm_format_info that describes the pixel format, or | |
244 | * NULL if the format is unsupported. | |
245 | */ | |
246 | const struct drm_format_info *drm_format_info(u32 format) | |
247 | { | |
248 | const struct drm_format_info *info; | |
249 | ||
250 | info = __drm_format_info(format); | |
251 | WARN_ON(!info); | |
252 | return info; | |
253 | } | |
84770cc2 LP |
254 | EXPORT_SYMBOL(drm_format_info); |
255 | ||
6a0f9ebf VS |
256 | /** |
257 | * drm_get_format_info - query information for a given framebuffer configuration | |
258 | * @dev: DRM device | |
259 | * @mode_cmd: metadata from the userspace fb creation request | |
260 | * | |
261 | * Returns: | |
262 | * The instance of struct drm_format_info that describes the pixel format, or | |
263 | * NULL if the format is unsupported. | |
264 | */ | |
265 | const struct drm_format_info * | |
266 | drm_get_format_info(struct drm_device *dev, | |
267 | const struct drm_mode_fb_cmd2 *mode_cmd) | |
268 | { | |
269 | const struct drm_format_info *info = NULL; | |
270 | ||
271 | if (dev->mode_config.funcs->get_format_info) | |
272 | info = dev->mode_config.funcs->get_format_info(mode_cmd); | |
273 | ||
274 | if (!info) | |
275 | info = drm_format_info(mode_cmd->pixel_format); | |
276 | ||
277 | return info; | |
278 | } | |
279 | EXPORT_SYMBOL(drm_get_format_info); | |
280 | ||
ae4df11a LP |
281 | /** |
282 | * drm_format_num_planes - get the number of planes for format | |
283 | * @format: pixel format (DRM_FORMAT_*) | |
284 | * | |
285 | * Returns: | |
286 | * The number of planes used by the specified pixel format. | |
287 | */ | |
288 | int drm_format_num_planes(uint32_t format) | |
289 | { | |
86c238aa LP |
290 | const struct drm_format_info *info; |
291 | ||
292 | info = drm_format_info(format); | |
293 | return info ? info->num_planes : 1; | |
ae4df11a LP |
294 | } |
295 | EXPORT_SYMBOL(drm_format_num_planes); | |
296 | ||
297 | /** | |
298 | * drm_format_plane_cpp - determine the bytes per pixel value | |
299 | * @format: pixel format (DRM_FORMAT_*) | |
300 | * @plane: plane index | |
301 | * | |
302 | * Returns: | |
303 | * The bytes per pixel value for the specified plane. | |
304 | */ | |
305 | int drm_format_plane_cpp(uint32_t format, int plane) | |
306 | { | |
86c238aa | 307 | const struct drm_format_info *info; |
ae4df11a | 308 | |
86c238aa LP |
309 | info = drm_format_info(format); |
310 | if (!info || plane >= info->num_planes) | |
ae4df11a LP |
311 | return 0; |
312 | ||
86c238aa | 313 | return info->cpp[plane]; |
ae4df11a LP |
314 | } |
315 | EXPORT_SYMBOL(drm_format_plane_cpp); | |
316 | ||
317 | /** | |
318 | * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor | |
319 | * @format: pixel format (DRM_FORMAT_*) | |
320 | * | |
321 | * Returns: | |
322 | * The horizontal chroma subsampling factor for the | |
323 | * specified pixel format. | |
324 | */ | |
325 | int drm_format_horz_chroma_subsampling(uint32_t format) | |
326 | { | |
86c238aa LP |
327 | const struct drm_format_info *info; |
328 | ||
329 | info = drm_format_info(format); | |
330 | return info ? info->hsub : 1; | |
ae4df11a LP |
331 | } |
332 | EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); | |
333 | ||
334 | /** | |
335 | * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor | |
336 | * @format: pixel format (DRM_FORMAT_*) | |
337 | * | |
338 | * Returns: | |
339 | * The vertical chroma subsampling factor for the | |
340 | * specified pixel format. | |
341 | */ | |
342 | int drm_format_vert_chroma_subsampling(uint32_t format) | |
343 | { | |
86c238aa LP |
344 | const struct drm_format_info *info; |
345 | ||
346 | info = drm_format_info(format); | |
347 | return info ? info->vsub : 1; | |
ae4df11a LP |
348 | } |
349 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); | |
350 | ||
351 | /** | |
352 | * drm_format_plane_width - width of the plane given the first plane | |
353 | * @width: width of the first plane | |
354 | * @format: pixel format | |
355 | * @plane: plane index | |
356 | * | |
357 | * Returns: | |
358 | * The width of @plane, given that the width of the first plane is @width. | |
359 | */ | |
360 | int drm_format_plane_width(int width, uint32_t format, int plane) | |
361 | { | |
86c238aa LP |
362 | const struct drm_format_info *info; |
363 | ||
364 | info = drm_format_info(format); | |
365 | if (!info || plane >= info->num_planes) | |
ae4df11a LP |
366 | return 0; |
367 | ||
368 | if (plane == 0) | |
369 | return width; | |
370 | ||
86c238aa | 371 | return width / info->hsub; |
ae4df11a LP |
372 | } |
373 | EXPORT_SYMBOL(drm_format_plane_width); | |
374 | ||
375 | /** | |
376 | * drm_format_plane_height - height of the plane given the first plane | |
377 | * @height: height of the first plane | |
378 | * @format: pixel format | |
379 | * @plane: plane index | |
380 | * | |
381 | * Returns: | |
382 | * The height of @plane, given that the height of the first plane is @height. | |
383 | */ | |
384 | int drm_format_plane_height(int height, uint32_t format, int plane) | |
385 | { | |
86c238aa LP |
386 | const struct drm_format_info *info; |
387 | ||
388 | info = drm_format_info(format); | |
389 | if (!info || plane >= info->num_planes) | |
ae4df11a LP |
390 | return 0; |
391 | ||
392 | if (plane == 0) | |
393 | return height; | |
394 | ||
86c238aa | 395 | return height / info->vsub; |
ae4df11a LP |
396 | } |
397 | EXPORT_SYMBOL(drm_format_plane_height); |