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 | ||
0500c04e | 30 | #include <drm/drm_device.h> |
ae4df11a LP |
31 | #include <drm/drm_fourcc.h> |
32 | ||
ec5e3047 DV |
33 | /** |
34 | * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description | |
35 | * @bpp: bits per pixels | |
36 | * @depth: bit depth per pixel | |
37 | * | |
38 | * Computes a drm fourcc pixel format code for the given @bpp/@depth values. | |
39 | * Useful in fbdev emulation code, since that deals in those values. | |
40 | */ | |
41 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) | |
42 | { | |
70109354 | 43 | uint32_t fmt = DRM_FORMAT_INVALID; |
ec5e3047 DV |
44 | |
45 | switch (bpp) { | |
e5bd7e3e GU |
46 | case 1: |
47 | if (depth == 1) | |
48 | fmt = DRM_FORMAT_C1; | |
49 | break; | |
50 | ||
51 | case 2: | |
52 | if (depth == 2) | |
53 | fmt = DRM_FORMAT_C2; | |
54 | break; | |
55 | ||
56 | case 4: | |
57 | if (depth == 4) | |
58 | fmt = DRM_FORMAT_C4; | |
59 | break; | |
60 | ||
ec5e3047 | 61 | case 8: |
70109354 CW |
62 | if (depth == 8) |
63 | fmt = DRM_FORMAT_C8; | |
ec5e3047 | 64 | break; |
70109354 | 65 | |
ec5e3047 | 66 | case 16: |
70109354 CW |
67 | switch (depth) { |
68 | case 15: | |
ec5e3047 | 69 | fmt = DRM_FORMAT_XRGB1555; |
70109354 CW |
70 | break; |
71 | case 16: | |
ec5e3047 | 72 | fmt = DRM_FORMAT_RGB565; |
70109354 CW |
73 | break; |
74 | default: | |
75 | break; | |
76 | } | |
ec5e3047 | 77 | break; |
70109354 | 78 | |
ec5e3047 | 79 | case 24: |
70109354 CW |
80 | if (depth == 24) |
81 | fmt = DRM_FORMAT_RGB888; | |
ec5e3047 | 82 | break; |
70109354 | 83 | |
ec5e3047 | 84 | case 32: |
70109354 CW |
85 | switch (depth) { |
86 | case 24: | |
ec5e3047 | 87 | fmt = DRM_FORMAT_XRGB8888; |
70109354 CW |
88 | break; |
89 | case 30: | |
ec5e3047 | 90 | fmt = DRM_FORMAT_XRGB2101010; |
70109354 CW |
91 | break; |
92 | case 32: | |
ec5e3047 | 93 | fmt = DRM_FORMAT_ARGB8888; |
70109354 CW |
94 | break; |
95 | default: | |
96 | break; | |
97 | } | |
ec5e3047 | 98 | break; |
70109354 | 99 | |
ec5e3047 | 100 | default: |
ec5e3047 DV |
101 | break; |
102 | } | |
103 | ||
104 | return fmt; | |
105 | } | |
106 | EXPORT_SYMBOL(drm_mode_legacy_fb_format); | |
107 | ||
059b5eb5 GH |
108 | /** |
109 | * drm_driver_legacy_fb_format - compute drm fourcc code from legacy description | |
4af67def | 110 | * @dev: DRM device |
059b5eb5 GH |
111 | * @bpp: bits per pixels |
112 | * @depth: bit depth per pixel | |
059b5eb5 GH |
113 | * |
114 | * Computes a drm fourcc pixel format code for the given @bpp/@depth values. | |
115 | * Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config, | |
4af67def DV |
116 | * and depending on the &drm_mode_config.quirk_addfb_prefer_host_byte_order flag |
117 | * it returns little endian byte order or host byte order framebuffer formats. | |
059b5eb5 GH |
118 | */ |
119 | uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, | |
120 | uint32_t bpp, uint32_t depth) | |
121 | { | |
122 | uint32_t fmt = drm_mode_legacy_fb_format(bpp, depth); | |
123 | ||
124 | if (dev->mode_config.quirk_addfb_prefer_host_byte_order) { | |
125 | if (fmt == DRM_FORMAT_XRGB8888) | |
126 | fmt = DRM_FORMAT_HOST_XRGB8888; | |
127 | if (fmt == DRM_FORMAT_ARGB8888) | |
128 | fmt = DRM_FORMAT_HOST_ARGB8888; | |
129 | if (fmt == DRM_FORMAT_RGB565) | |
130 | fmt = DRM_FORMAT_HOST_RGB565; | |
131 | if (fmt == DRM_FORMAT_XRGB1555) | |
132 | fmt = DRM_FORMAT_HOST_XRGB1555; | |
133 | } | |
9dd3cb24 GH |
134 | |
135 | if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp && | |
136 | fmt == DRM_FORMAT_XRGB2101010) | |
137 | fmt = DRM_FORMAT_XBGR2101010; | |
138 | ||
059b5eb5 GH |
139 | return fmt; |
140 | } | |
141 | EXPORT_SYMBOL(drm_driver_legacy_fb_format); | |
142 | ||
333d2da5 LP |
143 | /* |
144 | * Internal function to query information for a given format. See | |
145 | * drm_format_info() for the public API. | |
84770cc2 | 146 | */ |
333d2da5 | 147 | const struct drm_format_info *__drm_format_info(u32 format) |
84770cc2 LP |
148 | { |
149 | static const struct drm_format_info formats[] = { | |
e5bd7e3e GU |
150 | { .format = DRM_FORMAT_C1, .depth = 1, .num_planes = 1, |
151 | .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, | |
152 | { .format = DRM_FORMAT_C2, .depth = 2, .num_planes = 1, | |
153 | .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, | |
154 | { .format = DRM_FORMAT_C4, .depth = 4, .num_planes = 1, | |
155 | .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, | |
dc1dc76b | 156 | { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1, .is_color_indexed = true }, |
b92db7e4 GU |
157 | { .format = DRM_FORMAT_D1, .depth = 1, .num_planes = 1, |
158 | .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, | |
159 | { .format = DRM_FORMAT_D2, .depth = 2, .num_planes = 1, | |
160 | .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, | |
161 | { .format = DRM_FORMAT_D4, .depth = 4, .num_planes = 1, | |
162 | .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, | |
163 | { .format = DRM_FORMAT_D8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
d093100b GU |
164 | { .format = DRM_FORMAT_R1, .depth = 1, .num_planes = 1, |
165 | .char_per_block = { 1, }, .block_w = { 8, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, | |
166 | { .format = DRM_FORMAT_R2, .depth = 2, .num_planes = 1, | |
167 | .char_per_block = { 1, }, .block_w = { 4, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, | |
168 | { .format = DRM_FORMAT_R4, .depth = 4, .num_planes = 1, | |
169 | .char_per_block = { 1, }, .block_w = { 2, }, .block_h = { 1, }, .hsub = 1, .vsub = 1 }, | |
a0b1d355 | 170 | { .format = DRM_FORMAT_R8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, |
31fa8cbc LP |
171 | { .format = DRM_FORMAT_R10, .depth = 10, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
172 | { .format = DRM_FORMAT_R12, .depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
84770cc2 LP |
173 | { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, |
174 | { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
175 | { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
176 | { .format = DRM_FORMAT_XBGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
177 | { .format = DRM_FORMAT_RGBX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
178 | { .format = DRM_FORMAT_BGRX4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
179 | { .format = DRM_FORMAT_ARGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
180 | { .format = DRM_FORMAT_ABGR4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
181 | { .format = DRM_FORMAT_RGBA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
182 | { .format = DRM_FORMAT_BGRA4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
183 | { .format = DRM_FORMAT_XRGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
184 | { .format = DRM_FORMAT_XBGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
185 | { .format = DRM_FORMAT_RGBX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
186 | { .format = DRM_FORMAT_BGRX5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
187 | { .format = DRM_FORMAT_ARGB1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
188 | { .format = DRM_FORMAT_ABGR1555, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
189 | { .format = DRM_FORMAT_RGBA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
190 | { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
191 | { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, |
192 | { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
6fb6c979 GU |
193 | #ifdef __BIG_ENDIAN |
194 | { .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
195 | { .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
196 | #endif | |
84770cc2 LP |
197 | { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, |
198 | { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
199 | { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
200 | { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
201 | { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
202 | { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
203 | { .format = DRM_FORMAT_RGB565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
204 | { .format = DRM_FORMAT_BGR565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
205 | { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, |
206 | { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
207 | { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
208 | { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
209 | { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
210 | { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
211 | { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
212 | { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
213 | { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
214 | { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
215 | { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
216 | { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
88ab9c76 KS |
217 | { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, |
218 | { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
219 | { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
220 | { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
47170f89 | 221 | { .format = DRM_FORMAT_AXBXGXRX106106106106, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
ff92ecf5 MK |
222 | { .format = DRM_FORMAT_XRGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, |
223 | { .format = DRM_FORMAT_XBGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
224 | { .format = DRM_FORMAT_ARGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
225 | { .format = DRM_FORMAT_ABGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
4cc4e1b4 MR |
226 | { .format = DRM_FORMAT_RGB888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
227 | { .format = DRM_FORMAT_BGR888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
228 | { .format = DRM_FORMAT_XRGB8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
229 | { .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
230 | { .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
231 | { .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
ce2d5461 AKH |
232 | { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, |
233 | { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, | |
234 | { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
235 | { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
236 | { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
237 | { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
238 | { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
239 | { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
240 | { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
241 | { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
242 | { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
243 | { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
244 | { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
245 | { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
246 | { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
247 | { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
248 | { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
249 | { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
250 | { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
251 | { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
61e49394 | 252 | { .format = DRM_FORMAT_XYUV8888, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, |
7ba0fee2 | 253 | { .format = DRM_FORMAT_VUY888, .depth = 0, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, |
ce2d5461 | 254 | { .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, |
50bf5d7d SS |
255 | { .format = DRM_FORMAT_Y210, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, |
256 | { .format = DRM_FORMAT_Y212, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
257 | { .format = DRM_FORMAT_Y216, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
ff01e697 ML |
258 | { .format = DRM_FORMAT_Y410, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, |
259 | { .format = DRM_FORMAT_Y412, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, | |
260 | { .format = DRM_FORMAT_Y416, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, | |
261 | { .format = DRM_FORMAT_XVYU2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
262 | { .format = DRM_FORMAT_XVYU12_16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
263 | { .format = DRM_FORMAT_XVYU16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
697b6b85 AG |
264 | { .format = DRM_FORMAT_Y0L0, .depth = 0, .num_planes = 1, |
265 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
266 | .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true }, | |
267 | { .format = DRM_FORMAT_X0L0, .depth = 0, .num_planes = 1, | |
268 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
269 | .hsub = 2, .vsub = 2, .is_yuv = true }, | |
270 | { .format = DRM_FORMAT_Y0L2, .depth = 0, .num_planes = 1, | |
271 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
272 | .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true }, | |
273 | { .format = DRM_FORMAT_X0L2, .depth = 0, .num_planes = 1, | |
274 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
275 | .hsub = 2, .vsub = 2, .is_yuv = true }, | |
05f8bc82 | 276 | { .format = DRM_FORMAT_P010, .depth = 0, .num_planes = 2, |
836b131d | 277 | .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, |
05f8bc82 RL |
278 | .hsub = 2, .vsub = 2, .is_yuv = true}, |
279 | { .format = DRM_FORMAT_P012, .depth = 0, .num_planes = 2, | |
836b131d | 280 | .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, |
05f8bc82 RL |
281 | .hsub = 2, .vsub = 2, .is_yuv = true}, |
282 | { .format = DRM_FORMAT_P016, .depth = 0, .num_planes = 2, | |
836b131d | 283 | .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, |
05f8bc82 | 284 | .hsub = 2, .vsub = 2, .is_yuv = true}, |
7ba0fee2 BS |
285 | { .format = DRM_FORMAT_P210, .depth = 0, |
286 | .num_planes = 2, .char_per_block = { 2, 4, 0 }, | |
96227287 | 287 | .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, |
7ba0fee2 BS |
288 | .vsub = 1, .is_yuv = true }, |
289 | { .format = DRM_FORMAT_VUY101010, .depth = 0, | |
290 | .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1, | |
291 | .is_yuv = true }, | |
292 | { .format = DRM_FORMAT_YUV420_8BIT, .depth = 0, | |
293 | .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, | |
294 | .is_yuv = true }, | |
295 | { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0, | |
296 | .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, | |
297 | .is_yuv = true }, | |
94b292b2 BD |
298 | { .format = DRM_FORMAT_NV15, .depth = 0, |
299 | .num_planes = 2, .char_per_block = { 5, 5, 0 }, | |
300 | .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, | |
301 | .vsub = 2, .is_yuv = true }, | |
728c15b4 JK |
302 | { .format = DRM_FORMAT_NV20, .depth = 0, |
303 | .num_planes = 2, .char_per_block = { 5, 5, 0 }, | |
304 | .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, | |
305 | .vsub = 1, .is_yuv = true }, | |
306 | { .format = DRM_FORMAT_NV30, .depth = 0, | |
307 | .num_planes = 2, .char_per_block = { 5, 5, 0 }, | |
308 | .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, | |
309 | .vsub = 1, .is_yuv = true }, | |
94b292b2 BD |
310 | { .format = DRM_FORMAT_Q410, .depth = 0, |
311 | .num_planes = 3, .char_per_block = { 2, 2, 2 }, | |
b230555f BS |
312 | .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, |
313 | .vsub = 1, .is_yuv = true }, | |
94b292b2 BD |
314 | { .format = DRM_FORMAT_Q401, .depth = 0, |
315 | .num_planes = 3, .char_per_block = { 2, 2, 2 }, | |
b230555f BS |
316 | .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, |
317 | .vsub = 1, .is_yuv = true }, | |
006ea1b5 DS |
318 | { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2, |
319 | .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, | |
320 | .hsub = 2, .vsub = 2, .is_yuv = true}, | |
84770cc2 LP |
321 | }; |
322 | ||
323 | unsigned int i; | |
324 | ||
325 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | |
326 | if (formats[i].format == format) | |
327 | return &formats[i]; | |
328 | } | |
329 | ||
330 | return NULL; | |
331 | } | |
333d2da5 LP |
332 | |
333 | /** | |
334 | * drm_format_info - query information for a given format | |
335 | * @format: pixel format (DRM_FORMAT_*) | |
336 | * | |
337 | * The caller should only pass a supported pixel format to this function. | |
338 | * Unsupported pixel formats will generate a warning in the kernel log. | |
339 | * | |
340 | * Returns: | |
341 | * The instance of struct drm_format_info that describes the pixel format, or | |
342 | * NULL if the format is unsupported. | |
343 | */ | |
344 | const struct drm_format_info *drm_format_info(u32 format) | |
345 | { | |
346 | const struct drm_format_info *info; | |
347 | ||
348 | info = __drm_format_info(format); | |
349 | WARN_ON(!info); | |
350 | return info; | |
351 | } | |
84770cc2 LP |
352 | EXPORT_SYMBOL(drm_format_info); |
353 | ||
6a0f9ebf VS |
354 | /** |
355 | * drm_get_format_info - query information for a given framebuffer configuration | |
356 | * @dev: DRM device | |
357 | * @mode_cmd: metadata from the userspace fb creation request | |
358 | * | |
359 | * Returns: | |
360 | * The instance of struct drm_format_info that describes the pixel format, or | |
361 | * NULL if the format is unsupported. | |
362 | */ | |
363 | const struct drm_format_info * | |
364 | drm_get_format_info(struct drm_device *dev, | |
365 | const struct drm_mode_fb_cmd2 *mode_cmd) | |
366 | { | |
367 | const struct drm_format_info *info = NULL; | |
368 | ||
369 | if (dev->mode_config.funcs->get_format_info) | |
370 | info = dev->mode_config.funcs->get_format_info(mode_cmd); | |
371 | ||
372 | if (!info) | |
373 | info = drm_format_info(mode_cmd->pixel_format); | |
374 | ||
375 | return info; | |
376 | } | |
377 | EXPORT_SYMBOL(drm_get_format_info); | |
378 | ||
042bf753 AG |
379 | /** |
380 | * drm_format_info_block_width - width in pixels of block. | |
381 | * @info: pixel format info | |
382 | * @plane: plane index | |
383 | * | |
384 | * Returns: | |
385 | * The width in pixels of a block, depending on the plane index. | |
386 | */ | |
387 | unsigned int drm_format_info_block_width(const struct drm_format_info *info, | |
388 | int plane) | |
389 | { | |
390 | if (!info || plane < 0 || plane >= info->num_planes) | |
391 | return 0; | |
392 | ||
393 | if (!info->block_w[plane]) | |
394 | return 1; | |
395 | return info->block_w[plane]; | |
396 | } | |
397 | EXPORT_SYMBOL(drm_format_info_block_width); | |
398 | ||
399 | /** | |
400 | * drm_format_info_block_height - height in pixels of a block | |
401 | * @info: pixel format info | |
402 | * @plane: plane index | |
403 | * | |
404 | * Returns: | |
405 | * The height in pixels of a block, depending on the plane index. | |
406 | */ | |
407 | unsigned int drm_format_info_block_height(const struct drm_format_info *info, | |
408 | int plane) | |
409 | { | |
410 | if (!info || plane < 0 || plane >= info->num_planes) | |
411 | return 0; | |
412 | ||
413 | if (!info->block_h[plane]) | |
414 | return 1; | |
415 | return info->block_h[plane]; | |
416 | } | |
417 | EXPORT_SYMBOL(drm_format_info_block_height); | |
418 | ||
96dc635d GU |
419 | /** |
420 | * drm_format_info_bpp - number of bits per pixel | |
421 | * @info: pixel format info | |
422 | * @plane: plane index | |
423 | * | |
424 | * Returns: | |
425 | * The actual number of bits per pixel, depending on the plane index. | |
426 | */ | |
427 | unsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane) | |
428 | { | |
429 | if (!info || plane < 0 || plane >= info->num_planes) | |
430 | return 0; | |
431 | ||
432 | return info->char_per_block[plane] * 8 / | |
433 | (drm_format_info_block_width(info, plane) * | |
434 | drm_format_info_block_height(info, plane)); | |
435 | } | |
436 | EXPORT_SYMBOL(drm_format_info_bpp); | |
437 | ||
042bf753 AG |
438 | /** |
439 | * drm_format_info_min_pitch - computes the minimum required pitch in bytes | |
440 | * @info: pixel format info | |
441 | * @plane: plane index | |
442 | * @buffer_width: buffer width in pixels | |
443 | * | |
444 | * Returns: | |
445 | * The minimum required pitch in bytes for a buffer by taking into consideration | |
446 | * the pixel format information and the buffer width. | |
447 | */ | |
448 | uint64_t drm_format_info_min_pitch(const struct drm_format_info *info, | |
449 | int plane, unsigned int buffer_width) | |
450 | { | |
451 | if (!info || plane < 0 || plane >= info->num_planes) | |
452 | return 0; | |
453 | ||
454 | return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane], | |
455 | drm_format_info_block_width(info, plane) * | |
456 | drm_format_info_block_height(info, plane)); | |
457 | } | |
458 | EXPORT_SYMBOL(drm_format_info_min_pitch); |