]>
Commit | Line | Data |
---|---|---|
ae4df11a LP |
1 | /* |
2 | * Copyright (c) 2016 Laurent Pinchart <[email protected]> | |
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 SV |
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 SV |
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 SV |
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 | |
cf3d02a1 | 100 | * @dev: DRM device |
059b5eb5 GH |
101 | * @bpp: bits per pixels |
102 | * @depth: bit depth per pixel | |
059b5eb5 GH |
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 | } | |
9dd3cb24 GH |
124 | |
125 | if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp && | |
126 | fmt == DRM_FORMAT_XRGB2101010) | |
127 | fmt = DRM_FORMAT_XBGR2101010; | |
128 | ||
059b5eb5 GH |
129 | return fmt; |
130 | } | |
131 | EXPORT_SYMBOL(drm_driver_legacy_fb_format); | |
132 | ||
ae4df11a | 133 | /** |
b3c11ac2 | 134 | * drm_get_format_name - fill a string with a drm fourcc format's name |
ae4df11a | 135 | * @format: format to compute name of |
b3c11ac2 | 136 | * @buf: caller-supplied buffer |
ae4df11a | 137 | */ |
b3c11ac2 | 138 | const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf) |
ae4df11a | 139 | { |
b3c11ac2 | 140 | snprintf(buf->str, sizeof(buf->str), |
ae4df11a LP |
141 | "%c%c%c%c %s-endian (0x%08x)", |
142 | printable_char(format & 0xff), | |
143 | printable_char((format >> 8) & 0xff), | |
144 | printable_char((format >> 16) & 0xff), | |
145 | printable_char((format >> 24) & 0x7f), | |
146 | format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", | |
147 | format); | |
148 | ||
b3c11ac2 | 149 | return buf->str; |
ae4df11a LP |
150 | } |
151 | EXPORT_SYMBOL(drm_get_format_name); | |
152 | ||
333d2da5 LP |
153 | /* |
154 | * Internal function to query information for a given format. See | |
155 | * drm_format_info() for the public API. | |
84770cc2 | 156 | */ |
333d2da5 | 157 | const struct drm_format_info *__drm_format_info(u32 format) |
84770cc2 LP |
158 | { |
159 | static const struct drm_format_info formats[] = { | |
160 | { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
161 | { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
162 | { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
163 | { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
164 | { .format = DRM_FORMAT_XBGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
165 | { .format = DRM_FORMAT_RGBX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
166 | { .format = DRM_FORMAT_BGRX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
167 | { .format = DRM_FORMAT_ARGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
168 | { .format = DRM_FORMAT_ABGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
169 | { .format = DRM_FORMAT_RGBA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
170 | { .format = DRM_FORMAT_BGRA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
171 | { .format = DRM_FORMAT_XRGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
172 | { .format = DRM_FORMAT_XBGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
173 | { .format = DRM_FORMAT_RGBX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
174 | { .format = DRM_FORMAT_BGRX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
175 | { .format = DRM_FORMAT_ARGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
176 | { .format = DRM_FORMAT_ABGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
177 | { .format = DRM_FORMAT_RGBA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
178 | { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
179 | { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
180 | { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
181 | { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
182 | { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
183 | { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
184 | { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
185 | { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
186 | { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
187 | { .format = DRM_FORMAT_RGB565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
188 | { .format = DRM_FORMAT_BGR565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
189 | { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, |
190 | { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
191 | { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
192 | { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
193 | { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
194 | { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
195 | { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
196 | { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
197 | { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
198 | { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
199 | { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
200 | { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
201 | { .format = DRM_FORMAT_RGB888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
202 | { .format = DRM_FORMAT_BGR888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
203 | { .format = DRM_FORMAT_XRGB8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
204 | { .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
205 | { .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
206 | { .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
ce2d5461 AKH |
207 | { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, |
208 | { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, | |
209 | { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
210 | { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
211 | { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
212 | { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
213 | { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
214 | { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
215 | { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
216 | { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
217 | { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
218 | { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
219 | { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
220 | { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
221 | { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
222 | { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
223 | { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
224 | { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
225 | { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
226 | { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
227 | { .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 |
228 | }; |
229 | ||
230 | unsigned int i; | |
231 | ||
232 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | |
233 | if (formats[i].format == format) | |
234 | return &formats[i]; | |
235 | } | |
236 | ||
237 | return NULL; | |
238 | } | |
333d2da5 LP |
239 | |
240 | /** | |
241 | * drm_format_info - query information for a given format | |
242 | * @format: pixel format (DRM_FORMAT_*) | |
243 | * | |
244 | * The caller should only pass a supported pixel format to this function. | |
245 | * Unsupported pixel formats will generate a warning in the kernel log. | |
246 | * | |
247 | * Returns: | |
248 | * The instance of struct drm_format_info that describes the pixel format, or | |
249 | * NULL if the format is unsupported. | |
250 | */ | |
251 | const struct drm_format_info *drm_format_info(u32 format) | |
252 | { | |
253 | const struct drm_format_info *info; | |
254 | ||
255 | info = __drm_format_info(format); | |
256 | WARN_ON(!info); | |
257 | return info; | |
258 | } | |
84770cc2 LP |
259 | EXPORT_SYMBOL(drm_format_info); |
260 | ||
6a0f9ebf VS |
261 | /** |
262 | * drm_get_format_info - query information for a given framebuffer configuration | |
263 | * @dev: DRM device | |
264 | * @mode_cmd: metadata from the userspace fb creation request | |
265 | * | |
266 | * Returns: | |
267 | * The instance of struct drm_format_info that describes the pixel format, or | |
268 | * NULL if the format is unsupported. | |
269 | */ | |
270 | const struct drm_format_info * | |
271 | drm_get_format_info(struct drm_device *dev, | |
272 | const struct drm_mode_fb_cmd2 *mode_cmd) | |
273 | { | |
274 | const struct drm_format_info *info = NULL; | |
275 | ||
276 | if (dev->mode_config.funcs->get_format_info) | |
277 | info = dev->mode_config.funcs->get_format_info(mode_cmd); | |
278 | ||
279 | if (!info) | |
280 | info = drm_format_info(mode_cmd->pixel_format); | |
281 | ||
282 | return info; | |
283 | } | |
284 | EXPORT_SYMBOL(drm_get_format_info); | |
285 | ||
ae4df11a LP |
286 | /** |
287 | * drm_format_num_planes - get the number of planes for format | |
288 | * @format: pixel format (DRM_FORMAT_*) | |
289 | * | |
290 | * Returns: | |
291 | * The number of planes used by the specified pixel format. | |
292 | */ | |
293 | int drm_format_num_planes(uint32_t format) | |
294 | { | |
86c238aa LP |
295 | const struct drm_format_info *info; |
296 | ||
297 | info = drm_format_info(format); | |
298 | return info ? info->num_planes : 1; | |
ae4df11a LP |
299 | } |
300 | EXPORT_SYMBOL(drm_format_num_planes); | |
301 | ||
302 | /** | |
303 | * drm_format_plane_cpp - determine the bytes per pixel value | |
304 | * @format: pixel format (DRM_FORMAT_*) | |
305 | * @plane: plane index | |
306 | * | |
307 | * Returns: | |
308 | * The bytes per pixel value for the specified plane. | |
309 | */ | |
310 | int drm_format_plane_cpp(uint32_t format, int plane) | |
311 | { | |
86c238aa | 312 | const struct drm_format_info *info; |
ae4df11a | 313 | |
86c238aa LP |
314 | info = drm_format_info(format); |
315 | if (!info || plane >= info->num_planes) | |
ae4df11a LP |
316 | return 0; |
317 | ||
86c238aa | 318 | return info->cpp[plane]; |
ae4df11a LP |
319 | } |
320 | EXPORT_SYMBOL(drm_format_plane_cpp); | |
321 | ||
322 | /** | |
323 | * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor | |
324 | * @format: pixel format (DRM_FORMAT_*) | |
325 | * | |
326 | * Returns: | |
327 | * The horizontal chroma subsampling factor for the | |
328 | * specified pixel format. | |
329 | */ | |
330 | int drm_format_horz_chroma_subsampling(uint32_t format) | |
331 | { | |
86c238aa LP |
332 | const struct drm_format_info *info; |
333 | ||
334 | info = drm_format_info(format); | |
335 | return info ? info->hsub : 1; | |
ae4df11a LP |
336 | } |
337 | EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); | |
338 | ||
339 | /** | |
340 | * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor | |
341 | * @format: pixel format (DRM_FORMAT_*) | |
342 | * | |
343 | * Returns: | |
344 | * The vertical chroma subsampling factor for the | |
345 | * specified pixel format. | |
346 | */ | |
347 | int drm_format_vert_chroma_subsampling(uint32_t format) | |
348 | { | |
86c238aa LP |
349 | const struct drm_format_info *info; |
350 | ||
351 | info = drm_format_info(format); | |
352 | return info ? info->vsub : 1; | |
ae4df11a LP |
353 | } |
354 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); | |
355 | ||
356 | /** | |
357 | * drm_format_plane_width - width of the plane given the first plane | |
358 | * @width: width of the first plane | |
359 | * @format: pixel format | |
360 | * @plane: plane index | |
361 | * | |
362 | * Returns: | |
363 | * The width of @plane, given that the width of the first plane is @width. | |
364 | */ | |
365 | int drm_format_plane_width(int width, uint32_t format, int plane) | |
366 | { | |
86c238aa LP |
367 | const struct drm_format_info *info; |
368 | ||
369 | info = drm_format_info(format); | |
370 | if (!info || plane >= info->num_planes) | |
ae4df11a LP |
371 | return 0; |
372 | ||
373 | if (plane == 0) | |
374 | return width; | |
375 | ||
86c238aa | 376 | return width / info->hsub; |
ae4df11a LP |
377 | } |
378 | EXPORT_SYMBOL(drm_format_plane_width); | |
379 | ||
380 | /** | |
381 | * drm_format_plane_height - height of the plane given the first plane | |
382 | * @height: height of the first plane | |
383 | * @format: pixel format | |
384 | * @plane: plane index | |
385 | * | |
386 | * Returns: | |
387 | * The height of @plane, given that the height of the first plane is @height. | |
388 | */ | |
389 | int drm_format_plane_height(int height, uint32_t format, int plane) | |
390 | { | |
86c238aa LP |
391 | const struct drm_format_info *info; |
392 | ||
393 | info = drm_format_info(format); | |
394 | if (!info || plane >= info->num_planes) | |
ae4df11a LP |
395 | return 0; |
396 | ||
397 | if (plane == 0) | |
398 | return height; | |
399 | ||
86c238aa | 400 | return height / info->vsub; |
ae4df11a LP |
401 | } |
402 | EXPORT_SYMBOL(drm_format_plane_height); |