mmc: sdhci-acpi: Set MMC_CAP_CMD_DURING_TFR for Intel eMMC controllers
[deliverable/linux.git] / drivers / gpu / drm / drm_fourcc.c
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
38 /**
39 * drm_get_format_name - return a string for drm fourcc format
40 * @format: format to compute name of
41 *
42 * Note that the buffer used by this function is globally shared and owned by
43 * the function itself.
44 *
45 * FIXME: This isn't really multithreading safe.
46 */
47 const char *drm_get_format_name(uint32_t format)
48 {
49 static char buf[32];
50
51 snprintf(buf, sizeof(buf),
52 "%c%c%c%c %s-endian (0x%08x)",
53 printable_char(format & 0xff),
54 printable_char((format >> 8) & 0xff),
55 printable_char((format >> 16) & 0xff),
56 printable_char((format >> 24) & 0x7f),
57 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
58 format);
59
60 return buf;
61 }
62 EXPORT_SYMBOL(drm_get_format_name);
63
64 /**
65 * drm_fb_get_bpp_depth - get the bpp/depth values for format
66 * @format: pixel format (DRM_FORMAT_*)
67 * @depth: storage for the depth value
68 * @bpp: storage for the bpp value
69 *
70 * This only supports RGB formats here for compat with code that doesn't use
71 * pixel formats directly yet.
72 */
73 void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
74 int *bpp)
75 {
76 switch (format) {
77 case DRM_FORMAT_C8:
78 case DRM_FORMAT_RGB332:
79 case DRM_FORMAT_BGR233:
80 *depth = 8;
81 *bpp = 8;
82 break;
83 case DRM_FORMAT_XRGB1555:
84 case DRM_FORMAT_XBGR1555:
85 case DRM_FORMAT_RGBX5551:
86 case DRM_FORMAT_BGRX5551:
87 case DRM_FORMAT_ARGB1555:
88 case DRM_FORMAT_ABGR1555:
89 case DRM_FORMAT_RGBA5551:
90 case DRM_FORMAT_BGRA5551:
91 *depth = 15;
92 *bpp = 16;
93 break;
94 case DRM_FORMAT_RGB565:
95 case DRM_FORMAT_BGR565:
96 *depth = 16;
97 *bpp = 16;
98 break;
99 case DRM_FORMAT_RGB888:
100 case DRM_FORMAT_BGR888:
101 *depth = 24;
102 *bpp = 24;
103 break;
104 case DRM_FORMAT_XRGB8888:
105 case DRM_FORMAT_XBGR8888:
106 case DRM_FORMAT_RGBX8888:
107 case DRM_FORMAT_BGRX8888:
108 *depth = 24;
109 *bpp = 32;
110 break;
111 case DRM_FORMAT_XRGB2101010:
112 case DRM_FORMAT_XBGR2101010:
113 case DRM_FORMAT_RGBX1010102:
114 case DRM_FORMAT_BGRX1010102:
115 case DRM_FORMAT_ARGB2101010:
116 case DRM_FORMAT_ABGR2101010:
117 case DRM_FORMAT_RGBA1010102:
118 case DRM_FORMAT_BGRA1010102:
119 *depth = 30;
120 *bpp = 32;
121 break;
122 case DRM_FORMAT_ARGB8888:
123 case DRM_FORMAT_ABGR8888:
124 case DRM_FORMAT_RGBA8888:
125 case DRM_FORMAT_BGRA8888:
126 *depth = 32;
127 *bpp = 32;
128 break;
129 default:
130 DRM_DEBUG_KMS("unsupported pixel format %s\n",
131 drm_get_format_name(format));
132 *depth = 0;
133 *bpp = 0;
134 break;
135 }
136 }
137 EXPORT_SYMBOL(drm_fb_get_bpp_depth);
138
139 /**
140 * drm_format_num_planes - get the number of planes for format
141 * @format: pixel format (DRM_FORMAT_*)
142 *
143 * Returns:
144 * The number of planes used by the specified pixel format.
145 */
146 int drm_format_num_planes(uint32_t format)
147 {
148 switch (format) {
149 case DRM_FORMAT_YUV410:
150 case DRM_FORMAT_YVU410:
151 case DRM_FORMAT_YUV411:
152 case DRM_FORMAT_YVU411:
153 case DRM_FORMAT_YUV420:
154 case DRM_FORMAT_YVU420:
155 case DRM_FORMAT_YUV422:
156 case DRM_FORMAT_YVU422:
157 case DRM_FORMAT_YUV444:
158 case DRM_FORMAT_YVU444:
159 return 3;
160 case DRM_FORMAT_NV12:
161 case DRM_FORMAT_NV21:
162 case DRM_FORMAT_NV16:
163 case DRM_FORMAT_NV61:
164 case DRM_FORMAT_NV24:
165 case DRM_FORMAT_NV42:
166 return 2;
167 default:
168 return 1;
169 }
170 }
171 EXPORT_SYMBOL(drm_format_num_planes);
172
173 /**
174 * drm_format_plane_cpp - determine the bytes per pixel value
175 * @format: pixel format (DRM_FORMAT_*)
176 * @plane: plane index
177 *
178 * Returns:
179 * The bytes per pixel value for the specified plane.
180 */
181 int drm_format_plane_cpp(uint32_t format, int plane)
182 {
183 unsigned int depth;
184 int bpp;
185
186 if (plane >= drm_format_num_planes(format))
187 return 0;
188
189 switch (format) {
190 case DRM_FORMAT_YUYV:
191 case DRM_FORMAT_YVYU:
192 case DRM_FORMAT_UYVY:
193 case DRM_FORMAT_VYUY:
194 return 2;
195 case DRM_FORMAT_NV12:
196 case DRM_FORMAT_NV21:
197 case DRM_FORMAT_NV16:
198 case DRM_FORMAT_NV61:
199 case DRM_FORMAT_NV24:
200 case DRM_FORMAT_NV42:
201 return plane ? 2 : 1;
202 case DRM_FORMAT_YUV410:
203 case DRM_FORMAT_YVU410:
204 case DRM_FORMAT_YUV411:
205 case DRM_FORMAT_YVU411:
206 case DRM_FORMAT_YUV420:
207 case DRM_FORMAT_YVU420:
208 case DRM_FORMAT_YUV422:
209 case DRM_FORMAT_YVU422:
210 case DRM_FORMAT_YUV444:
211 case DRM_FORMAT_YVU444:
212 return 1;
213 default:
214 drm_fb_get_bpp_depth(format, &depth, &bpp);
215 return bpp >> 3;
216 }
217 }
218 EXPORT_SYMBOL(drm_format_plane_cpp);
219
220 /**
221 * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
222 * @format: pixel format (DRM_FORMAT_*)
223 *
224 * Returns:
225 * The horizontal chroma subsampling factor for the
226 * specified pixel format.
227 */
228 int drm_format_horz_chroma_subsampling(uint32_t format)
229 {
230 switch (format) {
231 case DRM_FORMAT_YUV411:
232 case DRM_FORMAT_YVU411:
233 case DRM_FORMAT_YUV410:
234 case DRM_FORMAT_YVU410:
235 return 4;
236 case DRM_FORMAT_YUYV:
237 case DRM_FORMAT_YVYU:
238 case DRM_FORMAT_UYVY:
239 case DRM_FORMAT_VYUY:
240 case DRM_FORMAT_NV12:
241 case DRM_FORMAT_NV21:
242 case DRM_FORMAT_NV16:
243 case DRM_FORMAT_NV61:
244 case DRM_FORMAT_YUV422:
245 case DRM_FORMAT_YVU422:
246 case DRM_FORMAT_YUV420:
247 case DRM_FORMAT_YVU420:
248 return 2;
249 default:
250 return 1;
251 }
252 }
253 EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
254
255 /**
256 * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
257 * @format: pixel format (DRM_FORMAT_*)
258 *
259 * Returns:
260 * The vertical chroma subsampling factor for the
261 * specified pixel format.
262 */
263 int drm_format_vert_chroma_subsampling(uint32_t format)
264 {
265 switch (format) {
266 case DRM_FORMAT_YUV410:
267 case DRM_FORMAT_YVU410:
268 return 4;
269 case DRM_FORMAT_YUV420:
270 case DRM_FORMAT_YVU420:
271 case DRM_FORMAT_NV12:
272 case DRM_FORMAT_NV21:
273 return 2;
274 default:
275 return 1;
276 }
277 }
278 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
279
280 /**
281 * drm_format_plane_width - width of the plane given the first plane
282 * @width: width of the first plane
283 * @format: pixel format
284 * @plane: plane index
285 *
286 * Returns:
287 * The width of @plane, given that the width of the first plane is @width.
288 */
289 int drm_format_plane_width(int width, uint32_t format, int plane)
290 {
291 if (plane >= drm_format_num_planes(format))
292 return 0;
293
294 if (plane == 0)
295 return width;
296
297 return width / drm_format_horz_chroma_subsampling(format);
298 }
299 EXPORT_SYMBOL(drm_format_plane_width);
300
301 /**
302 * drm_format_plane_height - height of the plane given the first plane
303 * @height: height of the first plane
304 * @format: pixel format
305 * @plane: plane index
306 *
307 * Returns:
308 * The height of @plane, given that the height of the first plane is @height.
309 */
310 int drm_format_plane_height(int height, uint32_t format, int plane)
311 {
312 if (plane >= drm_format_num_planes(format))
313 return 0;
314
315 if (plane == 0)
316 return height;
317
318 return height / drm_format_vert_chroma_subsampling(format);
319 }
320 EXPORT_SYMBOL(drm_format_plane_height);
This page took 0.037934 seconds and 5 git commands to generate.