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 }, | |
193 | { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
194 | { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
195 | { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
196 | { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
197 | { .format = DRM_FORMAT_RGBX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
198 | { .format = DRM_FORMAT_BGRX8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
199 | { .format = DRM_FORMAT_RGB565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
200 | { .format = DRM_FORMAT_BGR565_A8, .depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
84770cc2 LP |
201 | { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, |
202 | { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
203 | { .format = DRM_FORMAT_RGBX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
204 | { .format = DRM_FORMAT_BGRX1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
4cc4e1b4 MR |
205 | { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
206 | { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
207 | { .format = DRM_FORMAT_RGBA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
208 | { .format = DRM_FORMAT_BGRA1010102, .depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
209 | { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
210 | { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
211 | { .format = DRM_FORMAT_RGBA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
212 | { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
88ab9c76 KS |
213 | { .format = DRM_FORMAT_XRGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, |
214 | { .format = DRM_FORMAT_XBGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
215 | { .format = DRM_FORMAT_ARGB16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
216 | { .format = DRM_FORMAT_ABGR16161616F, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
47170f89 | 217 | { .format = DRM_FORMAT_AXBXGXRX106106106106, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
ff92ecf5 MK |
218 | { .format = DRM_FORMAT_XRGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, |
219 | { .format = DRM_FORMAT_XBGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1 }, | |
220 | { .format = DRM_FORMAT_ARGB16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
221 | { .format = DRM_FORMAT_ABGR16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
4cc4e1b4 MR |
222 | { .format = DRM_FORMAT_RGB888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, |
223 | { .format = DRM_FORMAT_BGR888_A8, .depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
224 | { .format = DRM_FORMAT_XRGB8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
225 | { .format = DRM_FORMAT_XBGR8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
226 | { .format = DRM_FORMAT_RGBX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
227 | { .format = DRM_FORMAT_BGRX8888_A8, .depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, | |
ce2d5461 AKH |
228 | { .format = DRM_FORMAT_YUV410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, |
229 | { .format = DRM_FORMAT_YVU410, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true }, | |
230 | { .format = DRM_FORMAT_YUV411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
231 | { .format = DRM_FORMAT_YVU411, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true }, | |
232 | { .format = DRM_FORMAT_YUV420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
233 | { .format = DRM_FORMAT_YVU420, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
234 | { .format = DRM_FORMAT_YUV422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
235 | { .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
236 | { .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
237 | { .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
238 | { .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
239 | { .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, | |
240 | { .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
241 | { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
242 | { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
243 | { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
244 | { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
245 | { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
246 | { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
247 | { .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
61e49394 | 248 | { .format = DRM_FORMAT_XYUV8888, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, |
7ba0fee2 | 249 | { .format = DRM_FORMAT_VUY888, .depth = 0, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, |
ce2d5461 | 250 | { .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 |
251 | { .format = DRM_FORMAT_Y210, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, |
252 | { .format = DRM_FORMAT_Y212, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
253 | { .format = DRM_FORMAT_Y216, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, | |
ff01e697 ML |
254 | { .format = DRM_FORMAT_Y410, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, |
255 | { .format = DRM_FORMAT_Y412, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, | |
256 | { .format = DRM_FORMAT_Y416, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true }, | |
257 | { .format = DRM_FORMAT_XVYU2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
258 | { .format = DRM_FORMAT_XVYU12_16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
259 | { .format = DRM_FORMAT_XVYU16161616, .depth = 0, .num_planes = 1, .cpp = { 8, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, | |
697b6b85 AG |
260 | { .format = DRM_FORMAT_Y0L0, .depth = 0, .num_planes = 1, |
261 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
262 | .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true }, | |
263 | { .format = DRM_FORMAT_X0L0, .depth = 0, .num_planes = 1, | |
264 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
265 | .hsub = 2, .vsub = 2, .is_yuv = true }, | |
266 | { .format = DRM_FORMAT_Y0L2, .depth = 0, .num_planes = 1, | |
267 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
268 | .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true }, | |
269 | { .format = DRM_FORMAT_X0L2, .depth = 0, .num_planes = 1, | |
270 | .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 }, | |
271 | .hsub = 2, .vsub = 2, .is_yuv = true }, | |
05f8bc82 | 272 | { .format = DRM_FORMAT_P010, .depth = 0, .num_planes = 2, |
836b131d | 273 | .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, |
05f8bc82 RL |
274 | .hsub = 2, .vsub = 2, .is_yuv = true}, |
275 | { .format = DRM_FORMAT_P012, .depth = 0, .num_planes = 2, | |
836b131d | 276 | .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, |
05f8bc82 RL |
277 | .hsub = 2, .vsub = 2, .is_yuv = true}, |
278 | { .format = DRM_FORMAT_P016, .depth = 0, .num_planes = 2, | |
836b131d | 279 | .char_per_block = { 2, 4, 0 }, .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, |
05f8bc82 | 280 | .hsub = 2, .vsub = 2, .is_yuv = true}, |
7ba0fee2 BS |
281 | { .format = DRM_FORMAT_P210, .depth = 0, |
282 | .num_planes = 2, .char_per_block = { 2, 4, 0 }, | |
96227287 | 283 | .block_w = { 1, 1, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, |
7ba0fee2 BS |
284 | .vsub = 1, .is_yuv = true }, |
285 | { .format = DRM_FORMAT_VUY101010, .depth = 0, | |
286 | .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1, | |
287 | .is_yuv = true }, | |
288 | { .format = DRM_FORMAT_YUV420_8BIT, .depth = 0, | |
289 | .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, | |
290 | .is_yuv = true }, | |
291 | { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0, | |
292 | .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, | |
293 | .is_yuv = true }, | |
94b292b2 BD |
294 | { .format = DRM_FORMAT_NV15, .depth = 0, |
295 | .num_planes = 2, .char_per_block = { 5, 5, 0 }, | |
296 | .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, | |
297 | .vsub = 2, .is_yuv = true }, | |
298 | { .format = DRM_FORMAT_Q410, .depth = 0, | |
299 | .num_planes = 3, .char_per_block = { 2, 2, 2 }, | |
b230555f BS |
300 | .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, |
301 | .vsub = 1, .is_yuv = true }, | |
94b292b2 BD |
302 | { .format = DRM_FORMAT_Q401, .depth = 0, |
303 | .num_planes = 3, .char_per_block = { 2, 2, 2 }, | |
b230555f BS |
304 | .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1, |
305 | .vsub = 1, .is_yuv = true }, | |
006ea1b5 DS |
306 | { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2, |
307 | .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, | |
308 | .hsub = 2, .vsub = 2, .is_yuv = true}, | |
84770cc2 LP |
309 | }; |
310 | ||
311 | unsigned int i; | |
312 | ||
313 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | |
314 | if (formats[i].format == format) | |
315 | return &formats[i]; | |
316 | } | |
317 | ||
318 | return NULL; | |
319 | } | |
333d2da5 LP |
320 | |
321 | /** | |
322 | * drm_format_info - query information for a given format | |
323 | * @format: pixel format (DRM_FORMAT_*) | |
324 | * | |
325 | * The caller should only pass a supported pixel format to this function. | |
326 | * Unsupported pixel formats will generate a warning in the kernel log. | |
327 | * | |
328 | * Returns: | |
329 | * The instance of struct drm_format_info that describes the pixel format, or | |
330 | * NULL if the format is unsupported. | |
331 | */ | |
332 | const struct drm_format_info *drm_format_info(u32 format) | |
333 | { | |
334 | const struct drm_format_info *info; | |
335 | ||
336 | info = __drm_format_info(format); | |
337 | WARN_ON(!info); | |
338 | return info; | |
339 | } | |
84770cc2 LP |
340 | EXPORT_SYMBOL(drm_format_info); |
341 | ||
6a0f9ebf VS |
342 | /** |
343 | * drm_get_format_info - query information for a given framebuffer configuration | |
344 | * @dev: DRM device | |
345 | * @mode_cmd: metadata from the userspace fb creation request | |
346 | * | |
347 | * Returns: | |
348 | * The instance of struct drm_format_info that describes the pixel format, or | |
349 | * NULL if the format is unsupported. | |
350 | */ | |
351 | const struct drm_format_info * | |
352 | drm_get_format_info(struct drm_device *dev, | |
353 | const struct drm_mode_fb_cmd2 *mode_cmd) | |
354 | { | |
355 | const struct drm_format_info *info = NULL; | |
356 | ||
357 | if (dev->mode_config.funcs->get_format_info) | |
358 | info = dev->mode_config.funcs->get_format_info(mode_cmd); | |
359 | ||
360 | if (!info) | |
361 | info = drm_format_info(mode_cmd->pixel_format); | |
362 | ||
363 | return info; | |
364 | } | |
365 | EXPORT_SYMBOL(drm_get_format_info); | |
366 | ||
042bf753 AG |
367 | /** |
368 | * drm_format_info_block_width - width in pixels of block. | |
369 | * @info: pixel format info | |
370 | * @plane: plane index | |
371 | * | |
372 | * Returns: | |
373 | * The width in pixels of a block, depending on the plane index. | |
374 | */ | |
375 | unsigned int drm_format_info_block_width(const struct drm_format_info *info, | |
376 | int plane) | |
377 | { | |
378 | if (!info || plane < 0 || plane >= info->num_planes) | |
379 | return 0; | |
380 | ||
381 | if (!info->block_w[plane]) | |
382 | return 1; | |
383 | return info->block_w[plane]; | |
384 | } | |
385 | EXPORT_SYMBOL(drm_format_info_block_width); | |
386 | ||
387 | /** | |
388 | * drm_format_info_block_height - height in pixels of a block | |
389 | * @info: pixel format info | |
390 | * @plane: plane index | |
391 | * | |
392 | * Returns: | |
393 | * The height in pixels of a block, depending on the plane index. | |
394 | */ | |
395 | unsigned int drm_format_info_block_height(const struct drm_format_info *info, | |
396 | int plane) | |
397 | { | |
398 | if (!info || plane < 0 || plane >= info->num_planes) | |
399 | return 0; | |
400 | ||
401 | if (!info->block_h[plane]) | |
402 | return 1; | |
403 | return info->block_h[plane]; | |
404 | } | |
405 | EXPORT_SYMBOL(drm_format_info_block_height); | |
406 | ||
96dc635d GU |
407 | /** |
408 | * drm_format_info_bpp - number of bits per pixel | |
409 | * @info: pixel format info | |
410 | * @plane: plane index | |
411 | * | |
412 | * Returns: | |
413 | * The actual number of bits per pixel, depending on the plane index. | |
414 | */ | |
415 | unsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane) | |
416 | { | |
417 | if (!info || plane < 0 || plane >= info->num_planes) | |
418 | return 0; | |
419 | ||
420 | return info->char_per_block[plane] * 8 / | |
421 | (drm_format_info_block_width(info, plane) * | |
422 | drm_format_info_block_height(info, plane)); | |
423 | } | |
424 | EXPORT_SYMBOL(drm_format_info_bpp); | |
425 | ||
042bf753 AG |
426 | /** |
427 | * drm_format_info_min_pitch - computes the minimum required pitch in bytes | |
428 | * @info: pixel format info | |
429 | * @plane: plane index | |
430 | * @buffer_width: buffer width in pixels | |
431 | * | |
432 | * Returns: | |
433 | * The minimum required pitch in bytes for a buffer by taking into consideration | |
434 | * the pixel format information and the buffer width. | |
435 | */ | |
436 | uint64_t drm_format_info_min_pitch(const struct drm_format_info *info, | |
437 | int plane, unsigned int buffer_width) | |
438 | { | |
439 | if (!info || plane < 0 || plane >= info->num_planes) | |
440 | return 0; | |
441 | ||
442 | return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane], | |
443 | drm_format_info_block_width(info, plane) * | |
444 | drm_format_info_block_height(info, plane)); | |
445 | } | |
446 | EXPORT_SYMBOL(drm_format_info_min_pitch); |