1 // SPDX-License-Identifier: GPL-2.0 or MIT 2 /* 3 * Copyright (C) 2016 Noralf Trønnes 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 */ 10 11 #include <linux/io.h> 12 #include <linux/iosys-map.h> 13 #include <linux/module.h> 14 #include <linux/slab.h> 15 16 #include <drm/drm_device.h> 17 #include <drm/drm_format_helper.h> 18 #include <drm/drm_framebuffer.h> 19 #include <drm/drm_fourcc.h> 20 #include <drm/drm_print.h> 21 #include <drm/drm_rect.h> 22 23 /** 24 * drm_format_conv_state_init - Initialize format-conversion state 25 * @state: The state to initialize 26 * 27 * Clears all fields in struct drm_format_conv_state. The state will 28 * be empty with no preallocated resources. 29 */ 30 void drm_format_conv_state_init(struct drm_format_conv_state *state) 31 { 32 state->tmp.mem = NULL; 33 state->tmp.size = 0; 34 state->tmp.preallocated = false; 35 } 36 EXPORT_SYMBOL(drm_format_conv_state_init); 37 38 /** 39 * drm_format_conv_state_copy - Copy format-conversion state 40 * @state: Destination state 41 * @old_state: Source state 42 * 43 * Copies format-conversion state from @old_state to @state; except for 44 * temporary storage. 45 */ 46 void drm_format_conv_state_copy(struct drm_format_conv_state *state, 47 const struct drm_format_conv_state *old_state) 48 { 49 /* 50 * So far, there's only temporary storage here, which we don't 51 * duplicate. Just clear the fields. 52 */ 53 state->tmp.mem = NULL; 54 state->tmp.size = 0; 55 state->tmp.preallocated = false; 56 } 57 EXPORT_SYMBOL(drm_format_conv_state_copy); 58 59 /** 60 * drm_format_conv_state_reserve - Allocates storage for format conversion 61 * @state: The format-conversion state 62 * @new_size: The minimum allocation size 63 * @flags: Flags for kmalloc() 64 * 65 * Allocates at least @new_size bytes and returns a pointer to the memory 66 * range. After calling this function, previously returned memory blocks 67 * are invalid. It's best to collect all memory requirements of a format 68 * conversion and call this function once to allocate the range. 69 * 70 * Returns: 71 * A pointer to the allocated memory range, or NULL otherwise. 72 */ 73 void *drm_format_conv_state_reserve(struct drm_format_conv_state *state, 74 size_t new_size, gfp_t flags) 75 { 76 void *mem; 77 78 if (new_size <= state->tmp.size) 79 goto out; 80 else if (state->tmp.preallocated) 81 return NULL; 82 83 mem = krealloc(state->tmp.mem, new_size, flags); 84 if (!mem) 85 return NULL; 86 87 state->tmp.mem = mem; 88 state->tmp.size = new_size; 89 90 out: 91 return state->tmp.mem; 92 } 93 EXPORT_SYMBOL(drm_format_conv_state_reserve); 94 95 /** 96 * drm_format_conv_state_release - Releases an format-conversion storage 97 * @state: The format-conversion state 98 * 99 * Releases the memory range references by the format-conversion state. 100 * After this call, all pointers to the memory are invalid. Prefer 101 * drm_format_conv_state_init() for cleaning up and unloading a driver. 102 */ 103 void drm_format_conv_state_release(struct drm_format_conv_state *state) 104 { 105 if (state->tmp.preallocated) 106 return; 107 108 kfree(state->tmp.mem); 109 state->tmp.mem = NULL; 110 state->tmp.size = 0; 111 } 112 EXPORT_SYMBOL(drm_format_conv_state_release); 113 114 static unsigned int clip_offset(const struct drm_rect *clip, unsigned int pitch, unsigned int cpp) 115 { 116 return clip->y1 * pitch + clip->x1 * cpp; 117 } 118 119 /** 120 * drm_fb_clip_offset - Returns the clipping rectangles byte-offset in a framebuffer 121 * @pitch: Framebuffer line pitch in byte 122 * @format: Framebuffer format 123 * @clip: Clip rectangle 124 * 125 * Returns: 126 * The byte offset of the clip rectangle's top-left corner within the framebuffer. 127 */ 128 unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format, 129 const struct drm_rect *clip) 130 { 131 return clip_offset(clip, pitch, format->cpp[0]); 132 } 133 EXPORT_SYMBOL(drm_fb_clip_offset); 134 135 /* TODO: Make this function work with multi-plane formats. */ 136 static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize, 137 const void *vaddr, const struct drm_framebuffer *fb, 138 const struct drm_rect *clip, bool vaddr_cached_hint, 139 struct drm_format_conv_state *state, 140 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) 141 { 142 unsigned long linepixels = drm_rect_width(clip); 143 unsigned long lines = drm_rect_height(clip); 144 size_t sbuf_len = linepixels * fb->format->cpp[0]; 145 void *stmp = NULL; 146 unsigned long i; 147 const void *sbuf; 148 149 /* 150 * Some source buffers, such as DMA memory, use write-combine 151 * caching, so reads are uncached. Speed up access by fetching 152 * one line at a time. 153 */ 154 if (!vaddr_cached_hint) { 155 stmp = drm_format_conv_state_reserve(state, sbuf_len, GFP_KERNEL); 156 if (!stmp) 157 return -ENOMEM; 158 } 159 160 if (!dst_pitch) 161 dst_pitch = drm_rect_width(clip) * dst_pixsize; 162 vaddr += clip_offset(clip, fb->pitches[0], fb->format->cpp[0]); 163 164 for (i = 0; i < lines; ++i) { 165 if (stmp) 166 sbuf = memcpy(stmp, vaddr, sbuf_len); 167 else 168 sbuf = vaddr; 169 xfrm_line(dst, sbuf, linepixels); 170 vaddr += fb->pitches[0]; 171 dst += dst_pitch; 172 } 173 174 return 0; 175 } 176 177 /* TODO: Make this function work with multi-plane formats. */ 178 static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned long dst_pixsize, 179 const void *vaddr, const struct drm_framebuffer *fb, 180 const struct drm_rect *clip, bool vaddr_cached_hint, 181 struct drm_format_conv_state *state, 182 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) 183 { 184 unsigned long linepixels = drm_rect_width(clip); 185 unsigned long lines = drm_rect_height(clip); 186 size_t dbuf_len = linepixels * dst_pixsize; 187 size_t stmp_off = round_up(dbuf_len, ARCH_KMALLOC_MINALIGN); /* for sbuf alignment */ 188 size_t sbuf_len = linepixels * fb->format->cpp[0]; 189 void *stmp = NULL; 190 unsigned long i; 191 const void *sbuf; 192 void *dbuf; 193 194 if (vaddr_cached_hint) { 195 dbuf = drm_format_conv_state_reserve(state, dbuf_len, GFP_KERNEL); 196 } else { 197 dbuf = drm_format_conv_state_reserve(state, stmp_off + sbuf_len, GFP_KERNEL); 198 stmp = dbuf + stmp_off; 199 } 200 if (!dbuf) 201 return -ENOMEM; 202 203 if (!dst_pitch) 204 dst_pitch = linepixels * dst_pixsize; 205 vaddr += clip_offset(clip, fb->pitches[0], fb->format->cpp[0]); 206 207 for (i = 0; i < lines; ++i) { 208 if (stmp) 209 sbuf = memcpy(stmp, vaddr, sbuf_len); 210 else 211 sbuf = vaddr; 212 xfrm_line(dbuf, sbuf, linepixels); 213 memcpy_toio(dst, dbuf, dbuf_len); 214 vaddr += fb->pitches[0]; 215 dst += dst_pitch; 216 } 217 218 return 0; 219 } 220 221 /* TODO: Make this function work with multi-plane formats. */ 222 static int drm_fb_xfrm(struct iosys_map *dst, 223 const unsigned int *dst_pitch, const u8 *dst_pixsize, 224 const struct iosys_map *src, const struct drm_framebuffer *fb, 225 const struct drm_rect *clip, bool vaddr_cached_hint, 226 struct drm_format_conv_state *state, 227 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) 228 { 229 static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 230 0, 0, 0, 0 231 }; 232 233 if (!dst_pitch) 234 dst_pitch = default_dst_pitch; 235 236 /* TODO: handle src in I/O memory here */ 237 if (dst[0].is_iomem) 238 return __drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], dst_pixsize[0], 239 src[0].vaddr, fb, clip, vaddr_cached_hint, state, 240 xfrm_line); 241 else 242 return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0], 243 src[0].vaddr, fb, clip, vaddr_cached_hint, state, 244 xfrm_line); 245 } 246 247 /** 248 * drm_fb_memcpy - Copy clip buffer 249 * @dst: Array of destination buffers 250 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 251 * within @dst; can be NULL if scanlines are stored next to each other. 252 * @src: Array of source buffers 253 * @fb: DRM framebuffer 254 * @clip: Clip rectangle area to copy 255 * 256 * This function copies parts of a framebuffer to display memory. Destination and 257 * framebuffer formats must match. No conversion takes place. The parameters @dst, 258 * @dst_pitch and @src refer to arrays. Each array must have at least as many entries 259 * as there are planes in @fb's format. Each entry stores the value for the format's 260 * respective color plane at the same index. 261 * 262 * This function does not apply clipping on @dst (i.e. the destination is at the 263 * top-left corner). 264 */ 265 void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch, 266 const struct iosys_map *src, const struct drm_framebuffer *fb, 267 const struct drm_rect *clip) 268 { 269 static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 270 0, 0, 0, 0 271 }; 272 273 const struct drm_format_info *format = fb->format; 274 unsigned int i, y, lines = drm_rect_height(clip); 275 276 if (!dst_pitch) 277 dst_pitch = default_dst_pitch; 278 279 for (i = 0; i < format->num_planes; ++i) { 280 unsigned int bpp_i = drm_format_info_bpp(format, i); 281 unsigned int cpp_i = DIV_ROUND_UP(bpp_i, 8); 282 size_t len_i = DIV_ROUND_UP(drm_rect_width(clip) * bpp_i, 8); 283 unsigned int dst_pitch_i = dst_pitch[i]; 284 struct iosys_map dst_i = dst[i]; 285 struct iosys_map src_i = src[i]; 286 287 if (!dst_pitch_i) 288 dst_pitch_i = len_i; 289 290 iosys_map_incr(&src_i, clip_offset(clip, fb->pitches[i], cpp_i)); 291 for (y = 0; y < lines; y++) { 292 /* TODO: handle src_i in I/O memory here */ 293 iosys_map_memcpy_to(&dst_i, 0, src_i.vaddr, len_i); 294 iosys_map_incr(&src_i, fb->pitches[i]); 295 iosys_map_incr(&dst_i, dst_pitch_i); 296 } 297 } 298 } 299 EXPORT_SYMBOL(drm_fb_memcpy); 300 301 static void drm_fb_swab16_line(void *dbuf, const void *sbuf, unsigned int pixels) 302 { 303 u16 *dbuf16 = dbuf; 304 const u16 *sbuf16 = sbuf; 305 const u16 *send16 = sbuf16 + pixels; 306 307 while (sbuf16 < send16) 308 *dbuf16++ = swab16(*sbuf16++); 309 } 310 311 static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels) 312 { 313 u32 *dbuf32 = dbuf; 314 const u32 *sbuf32 = sbuf; 315 const u32 *send32 = sbuf32 + pixels; 316 317 while (sbuf32 < send32) 318 *dbuf32++ = swab32(*sbuf32++); 319 } 320 321 /** 322 * drm_fb_swab - Swap bytes into clip buffer 323 * @dst: Array of destination buffers 324 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 325 * within @dst; can be NULL if scanlines are stored next to each other. 326 * @src: Array of source buffers 327 * @fb: DRM framebuffer 328 * @clip: Clip rectangle area to copy 329 * @cached: Source buffer is mapped cached (eg. not write-combined) 330 * @state: Transform and conversion state 331 * 332 * This function copies parts of a framebuffer to display memory and swaps per-pixel 333 * bytes during the process. Destination and framebuffer formats must match. The 334 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 335 * least as many entries as there are planes in @fb's format. Each entry stores the 336 * value for the format's respective color plane at the same index. If @cached is 337 * false a temporary buffer is used to cache one pixel line at a time to speed up 338 * slow uncached reads. 339 * 340 * This function does not apply clipping on @dst (i.e. the destination is at the 341 * top-left corner). 342 */ 343 void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch, 344 const struct iosys_map *src, const struct drm_framebuffer *fb, 345 const struct drm_rect *clip, bool cached, 346 struct drm_format_conv_state *state) 347 { 348 const struct drm_format_info *format = fb->format; 349 u8 cpp = DIV_ROUND_UP(drm_format_info_bpp(format, 0), 8); 350 void (*swab_line)(void *dbuf, const void *sbuf, unsigned int npixels); 351 352 switch (cpp) { 353 case 4: 354 swab_line = drm_fb_swab32_line; 355 break; 356 case 2: 357 swab_line = drm_fb_swab16_line; 358 break; 359 default: 360 drm_warn_once(fb->dev, "Format %p4cc has unsupported pixel size.\n", 361 &format->format); 362 return; 363 } 364 365 drm_fb_xfrm(dst, dst_pitch, &cpp, src, fb, clip, cached, state, swab_line); 366 } 367 EXPORT_SYMBOL(drm_fb_swab); 368 369 static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels) 370 { 371 u8 *dbuf8 = dbuf; 372 const __le32 *sbuf32 = sbuf; 373 unsigned int x; 374 u32 pix; 375 376 for (x = 0; x < pixels; x++) { 377 pix = le32_to_cpu(sbuf32[x]); 378 dbuf8[x] = ((pix & 0x00e00000) >> 16) | 379 ((pix & 0x0000e000) >> 11) | 380 ((pix & 0x000000c0) >> 6); 381 } 382 } 383 384 /** 385 * drm_fb_xrgb8888_to_rgb332 - Convert XRGB8888 to RGB332 clip buffer 386 * @dst: Array of RGB332 destination buffers 387 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 388 * within @dst; can be NULL if scanlines are stored next to each other. 389 * @src: Array of XRGB8888 source buffers 390 * @fb: DRM framebuffer 391 * @clip: Clip rectangle area to copy 392 * @state: Transform and conversion state 393 * 394 * This function copies parts of a framebuffer to display memory and converts the 395 * color format during the process. Destination and framebuffer formats must match. The 396 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 397 * least as many entries as there are planes in @fb's format. Each entry stores the 398 * value for the format's respective color plane at the same index. 399 * 400 * This function does not apply clipping on @dst (i.e. the destination is at the 401 * top-left corner). 402 * 403 * Drivers can use this function for RGB332 devices that don't support XRGB8888 natively. 404 */ 405 void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch, 406 const struct iosys_map *src, const struct drm_framebuffer *fb, 407 const struct drm_rect *clip, struct drm_format_conv_state *state) 408 { 409 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 410 1, 411 }; 412 413 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 414 drm_fb_xrgb8888_to_rgb332_line); 415 } 416 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); 417 418 static void drm_fb_xrgb8888_to_rgb565_line(void *dbuf, const void *sbuf, unsigned int pixels) 419 { 420 __le16 *dbuf16 = dbuf; 421 const __le32 *sbuf32 = sbuf; 422 unsigned int x; 423 u16 val16; 424 u32 pix; 425 426 for (x = 0; x < pixels; x++) { 427 pix = le32_to_cpu(sbuf32[x]); 428 val16 = ((pix & 0x00F80000) >> 8) | 429 ((pix & 0x0000FC00) >> 5) | 430 ((pix & 0x000000F8) >> 3); 431 dbuf16[x] = cpu_to_le16(val16); 432 } 433 } 434 435 /* TODO: implement this helper as conversion to RGB565|BIG_ENDIAN */ 436 static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf, 437 unsigned int pixels) 438 { 439 __le16 *dbuf16 = dbuf; 440 const __le32 *sbuf32 = sbuf; 441 unsigned int x; 442 u16 val16; 443 u32 pix; 444 445 for (x = 0; x < pixels; x++) { 446 pix = le32_to_cpu(sbuf32[x]); 447 val16 = ((pix & 0x00F80000) >> 8) | 448 ((pix & 0x0000FC00) >> 5) | 449 ((pix & 0x000000F8) >> 3); 450 dbuf16[x] = cpu_to_le16(swab16(val16)); 451 } 452 } 453 454 /** 455 * drm_fb_xrgb8888_to_rgb565 - Convert XRGB8888 to RGB565 clip buffer 456 * @dst: Array of RGB565 destination buffers 457 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 458 * within @dst; can be NULL if scanlines are stored next to each other. 459 * @src: Array of XRGB8888 source buffer 460 * @fb: DRM framebuffer 461 * @clip: Clip rectangle area to copy 462 * @state: Transform and conversion state 463 * @swab: Swap bytes 464 * 465 * This function copies parts of a framebuffer to display memory and converts the 466 * color format during the process. Destination and framebuffer formats must match. The 467 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 468 * least as many entries as there are planes in @fb's format. Each entry stores the 469 * value for the format's respective color plane at the same index. 470 * 471 * This function does not apply clipping on @dst (i.e. the destination is at the 472 * top-left corner). 473 * 474 * Drivers can use this function for RGB565 devices that don't support XRGB8888 natively. 475 */ 476 void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch, 477 const struct iosys_map *src, const struct drm_framebuffer *fb, 478 const struct drm_rect *clip, struct drm_format_conv_state *state, 479 bool swab) 480 { 481 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 482 2, 483 }; 484 485 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels); 486 487 if (swab) 488 xfrm_line = drm_fb_xrgb8888_to_rgb565_swab_line; 489 else 490 xfrm_line = drm_fb_xrgb8888_to_rgb565_line; 491 492 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, xfrm_line); 493 } 494 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); 495 496 static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsigned int pixels) 497 { 498 __le16 *dbuf16 = dbuf; 499 const __le32 *sbuf32 = sbuf; 500 unsigned int x; 501 u16 val16; 502 u32 pix; 503 504 for (x = 0; x < pixels; x++) { 505 pix = le32_to_cpu(sbuf32[x]); 506 val16 = ((pix & 0x00f80000) >> 9) | 507 ((pix & 0x0000f800) >> 6) | 508 ((pix & 0x000000f8) >> 3); 509 dbuf16[x] = cpu_to_le16(val16); 510 } 511 } 512 513 /** 514 * drm_fb_xrgb8888_to_xrgb1555 - Convert XRGB8888 to XRGB1555 clip buffer 515 * @dst: Array of XRGB1555 destination buffers 516 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 517 * within @dst; can be NULL if scanlines are stored next to each other. 518 * @src: Array of XRGB8888 source buffer 519 * @fb: DRM framebuffer 520 * @clip: Clip rectangle area to copy 521 * @state: Transform and conversion state 522 * 523 * This function copies parts of a framebuffer to display memory and converts 524 * the color format during the process. The parameters @dst, @dst_pitch and 525 * @src refer to arrays. Each array must have at least as many entries as 526 * there are planes in @fb's format. Each entry stores the value for the 527 * format's respective color plane at the same index. 528 * 529 * This function does not apply clipping on @dst (i.e. the destination is at the 530 * top-left corner). 531 * 532 * Drivers can use this function for XRGB1555 devices that don't support 533 * XRGB8888 natively. 534 */ 535 void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_pitch, 536 const struct iosys_map *src, const struct drm_framebuffer *fb, 537 const struct drm_rect *clip, struct drm_format_conv_state *state) 538 { 539 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 540 2, 541 }; 542 543 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 544 drm_fb_xrgb8888_to_xrgb1555_line); 545 } 546 EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb1555); 547 548 static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsigned int pixels) 549 { 550 __le16 *dbuf16 = dbuf; 551 const __le32 *sbuf32 = sbuf; 552 unsigned int x; 553 u16 val16; 554 u32 pix; 555 556 for (x = 0; x < pixels; x++) { 557 pix = le32_to_cpu(sbuf32[x]); 558 val16 = BIT(15) | /* set alpha bit */ 559 ((pix & 0x00f80000) >> 9) | 560 ((pix & 0x0000f800) >> 6) | 561 ((pix & 0x000000f8) >> 3); 562 dbuf16[x] = cpu_to_le16(val16); 563 } 564 } 565 566 /** 567 * drm_fb_xrgb8888_to_argb1555 - Convert XRGB8888 to ARGB1555 clip buffer 568 * @dst: Array of ARGB1555 destination buffers 569 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 570 * within @dst; can be NULL if scanlines are stored next to each other. 571 * @src: Array of XRGB8888 source buffer 572 * @fb: DRM framebuffer 573 * @clip: Clip rectangle area to copy 574 * @state: Transform and conversion state 575 * 576 * This function copies parts of a framebuffer to display memory and converts 577 * the color format during the process. The parameters @dst, @dst_pitch and 578 * @src refer to arrays. Each array must have at least as many entries as 579 * there are planes in @fb's format. Each entry stores the value for the 580 * format's respective color plane at the same index. 581 * 582 * This function does not apply clipping on @dst (i.e. the destination is at the 583 * top-left corner). 584 * 585 * Drivers can use this function for ARGB1555 devices that don't support 586 * XRGB8888 natively. It sets an opaque alpha channel as part of the conversion. 587 */ 588 void drm_fb_xrgb8888_to_argb1555(struct iosys_map *dst, const unsigned int *dst_pitch, 589 const struct iosys_map *src, const struct drm_framebuffer *fb, 590 const struct drm_rect *clip, struct drm_format_conv_state *state) 591 { 592 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 593 2, 594 }; 595 596 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 597 drm_fb_xrgb8888_to_argb1555_line); 598 } 599 EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb1555); 600 601 static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsigned int pixels) 602 { 603 __le16 *dbuf16 = dbuf; 604 const __le32 *sbuf32 = sbuf; 605 unsigned int x; 606 u16 val16; 607 u32 pix; 608 609 for (x = 0; x < pixels; x++) { 610 pix = le32_to_cpu(sbuf32[x]); 611 val16 = ((pix & 0x00f80000) >> 8) | 612 ((pix & 0x0000f800) >> 5) | 613 ((pix & 0x000000f8) >> 2) | 614 BIT(0); /* set alpha bit */ 615 dbuf16[x] = cpu_to_le16(val16); 616 } 617 } 618 619 /** 620 * drm_fb_xrgb8888_to_rgba5551 - Convert XRGB8888 to RGBA5551 clip buffer 621 * @dst: Array of RGBA5551 destination buffers 622 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 623 * within @dst; can be NULL if scanlines are stored next to each other. 624 * @src: Array of XRGB8888 source buffer 625 * @fb: DRM framebuffer 626 * @clip: Clip rectangle area to copy 627 * @state: Transform and conversion state 628 * 629 * This function copies parts of a framebuffer to display memory and converts 630 * the color format during the process. The parameters @dst, @dst_pitch and 631 * @src refer to arrays. Each array must have at least as many entries as 632 * there are planes in @fb's format. Each entry stores the value for the 633 * format's respective color plane at the same index. 634 * 635 * This function does not apply clipping on @dst (i.e. the destination is at the 636 * top-left corner). 637 * 638 * Drivers can use this function for RGBA5551 devices that don't support 639 * XRGB8888 natively. It sets an opaque alpha channel as part of the conversion. 640 */ 641 void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_pitch, 642 const struct iosys_map *src, const struct drm_framebuffer *fb, 643 const struct drm_rect *clip, struct drm_format_conv_state *state) 644 { 645 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 646 2, 647 }; 648 649 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 650 drm_fb_xrgb8888_to_rgba5551_line); 651 } 652 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgba5551); 653 654 static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigned int pixels) 655 { 656 u8 *dbuf8 = dbuf; 657 const __le32 *sbuf32 = sbuf; 658 unsigned int x; 659 u32 pix; 660 661 for (x = 0; x < pixels; x++) { 662 pix = le32_to_cpu(sbuf32[x]); 663 /* write blue-green-red to output in little endianness */ 664 *dbuf8++ = (pix & 0x000000FF) >> 0; 665 *dbuf8++ = (pix & 0x0000FF00) >> 8; 666 *dbuf8++ = (pix & 0x00FF0000) >> 16; 667 } 668 } 669 670 /** 671 * drm_fb_xrgb8888_to_rgb888 - Convert XRGB8888 to RGB888 clip buffer 672 * @dst: Array of RGB888 destination buffers 673 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 674 * within @dst; can be NULL if scanlines are stored next to each other. 675 * @src: Array of XRGB8888 source buffers 676 * @fb: DRM framebuffer 677 * @clip: Clip rectangle area to copy 678 * @state: Transform and conversion state 679 * 680 * This function copies parts of a framebuffer to display memory and converts the 681 * color format during the process. Destination and framebuffer formats must match. The 682 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 683 * least as many entries as there are planes in @fb's format. Each entry stores the 684 * value for the format's respective color plane at the same index. 685 * 686 * This function does not apply clipping on @dst (i.e. the destination is at the 687 * top-left corner). 688 * 689 * Drivers can use this function for RGB888 devices that don't natively 690 * support XRGB8888. 691 */ 692 void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch, 693 const struct iosys_map *src, const struct drm_framebuffer *fb, 694 const struct drm_rect *clip, struct drm_format_conv_state *state) 695 { 696 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 697 3, 698 }; 699 700 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 701 drm_fb_xrgb8888_to_rgb888_line); 702 } 703 EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); 704 705 static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsigned int pixels) 706 { 707 __le32 *dbuf32 = dbuf; 708 const __le32 *sbuf32 = sbuf; 709 unsigned int x; 710 u32 pix; 711 712 for (x = 0; x < pixels; x++) { 713 pix = le32_to_cpu(sbuf32[x]); 714 pix |= GENMASK(31, 24); /* fill alpha bits */ 715 dbuf32[x] = cpu_to_le32(pix); 716 } 717 } 718 719 /** 720 * drm_fb_xrgb8888_to_argb8888 - Convert XRGB8888 to ARGB8888 clip buffer 721 * @dst: Array of ARGB8888 destination buffers 722 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 723 * within @dst; can be NULL if scanlines are stored next to each other. 724 * @src: Array of XRGB8888 source buffer 725 * @fb: DRM framebuffer 726 * @clip: Clip rectangle area to copy 727 * @state: Transform and conversion state 728 * 729 * This function copies parts of a framebuffer to display memory and converts the 730 * color format during the process. The parameters @dst, @dst_pitch and @src refer 731 * to arrays. Each array must have at least as many entries as there are planes in 732 * @fb's format. Each entry stores the value for the format's respective color plane 733 * at the same index. 734 * 735 * This function does not apply clipping on @dst (i.e. the destination is at the 736 * top-left corner). 737 * 738 * Drivers can use this function for ARGB8888 devices that don't support XRGB8888 739 * natively. It sets an opaque alpha channel as part of the conversion. 740 */ 741 void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_pitch, 742 const struct iosys_map *src, const struct drm_framebuffer *fb, 743 const struct drm_rect *clip, struct drm_format_conv_state *state) 744 { 745 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 746 4, 747 }; 748 749 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 750 drm_fb_xrgb8888_to_argb8888_line); 751 } 752 EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb8888); 753 754 static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels) 755 { 756 __le32 *dbuf32 = dbuf; 757 const __le32 *sbuf32 = sbuf; 758 unsigned int x; 759 u32 pix; 760 761 for (x = 0; x < pixels; x++) { 762 pix = le32_to_cpu(sbuf32[x]); 763 pix = ((pix & 0x00ff0000) >> 16) << 0 | 764 ((pix & 0x0000ff00) >> 8) << 8 | 765 ((pix & 0x000000ff) >> 0) << 16 | 766 GENMASK(31, 24); /* fill alpha bits */ 767 *dbuf32++ = cpu_to_le32(pix); 768 } 769 } 770 771 static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 772 const struct iosys_map *src, 773 const struct drm_framebuffer *fb, 774 const struct drm_rect *clip, 775 struct drm_format_conv_state *state) 776 { 777 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 778 4, 779 }; 780 781 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 782 drm_fb_xrgb8888_to_abgr8888_line); 783 } 784 785 static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsigned int pixels) 786 { 787 __le32 *dbuf32 = dbuf; 788 const __le32 *sbuf32 = sbuf; 789 unsigned int x; 790 u32 pix; 791 792 for (x = 0; x < pixels; x++) { 793 pix = le32_to_cpu(sbuf32[x]); 794 pix = ((pix & 0x00ff0000) >> 16) << 0 | 795 ((pix & 0x0000ff00) >> 8) << 8 | 796 ((pix & 0x000000ff) >> 0) << 16 | 797 ((pix & 0xff000000) >> 24) << 24; 798 *dbuf32++ = cpu_to_le32(pix); 799 } 800 } 801 802 static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch, 803 const struct iosys_map *src, 804 const struct drm_framebuffer *fb, 805 const struct drm_rect *clip, 806 struct drm_format_conv_state *state) 807 { 808 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 809 4, 810 }; 811 812 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 813 drm_fb_xrgb8888_to_xbgr8888_line); 814 } 815 816 static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels) 817 { 818 __le32 *dbuf32 = dbuf; 819 const __le32 *sbuf32 = sbuf; 820 unsigned int x; 821 u32 val32; 822 u32 pix; 823 824 for (x = 0; x < pixels; x++) { 825 pix = le32_to_cpu(sbuf32[x]); 826 val32 = ((pix & 0x000000FF) << 2) | 827 ((pix & 0x0000FF00) << 4) | 828 ((pix & 0x00FF0000) << 6); 829 pix = val32 | ((val32 >> 8) & 0x00300C03); 830 *dbuf32++ = cpu_to_le32(pix); 831 } 832 } 833 834 /** 835 * drm_fb_xrgb8888_to_xrgb2101010 - Convert XRGB8888 to XRGB2101010 clip buffer 836 * @dst: Array of XRGB2101010 destination buffers 837 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 838 * within @dst; can be NULL if scanlines are stored next to each other. 839 * @src: Array of XRGB8888 source buffers 840 * @fb: DRM framebuffer 841 * @clip: Clip rectangle area to copy 842 * @state: Transform and conversion state 843 * 844 * This function copies parts of a framebuffer to display memory and converts the 845 * color format during the process. Destination and framebuffer formats must match. The 846 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 847 * least as many entries as there are planes in @fb's format. Each entry stores the 848 * value for the format's respective color plane at the same index. 849 * 850 * This function does not apply clipping on @dst (i.e. the destination is at the 851 * top-left corner). 852 * 853 * Drivers can use this function for XRGB2101010 devices that don't support XRGB8888 854 * natively. 855 */ 856 void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, 857 const struct iosys_map *src, const struct drm_framebuffer *fb, 858 const struct drm_rect *clip, 859 struct drm_format_conv_state *state) 860 { 861 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 862 4, 863 }; 864 865 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 866 drm_fb_xrgb8888_to_xrgb2101010_line); 867 } 868 EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010); 869 870 static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels) 871 { 872 __le32 *dbuf32 = dbuf; 873 const __le32 *sbuf32 = sbuf; 874 unsigned int x; 875 u32 val32; 876 u32 pix; 877 878 for (x = 0; x < pixels; x++) { 879 pix = le32_to_cpu(sbuf32[x]); 880 val32 = ((pix & 0x000000ff) << 2) | 881 ((pix & 0x0000ff00) << 4) | 882 ((pix & 0x00ff0000) << 6); 883 pix = GENMASK(31, 30) | /* set alpha bits */ 884 val32 | ((val32 >> 8) & 0x00300c03); 885 *dbuf32++ = cpu_to_le32(pix); 886 } 887 } 888 889 /** 890 * drm_fb_xrgb8888_to_argb2101010 - Convert XRGB8888 to ARGB2101010 clip buffer 891 * @dst: Array of ARGB2101010 destination buffers 892 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 893 * within @dst; can be NULL if scanlines are stored next to each other. 894 * @src: Array of XRGB8888 source buffers 895 * @fb: DRM framebuffer 896 * @clip: Clip rectangle area to copy 897 * @state: Transform and conversion state 898 * 899 * This function copies parts of a framebuffer to display memory and converts 900 * the color format during the process. The parameters @dst, @dst_pitch and 901 * @src refer to arrays. Each array must have at least as many entries as 902 * there are planes in @fb's format. Each entry stores the value for the 903 * format's respective color plane at the same index. 904 * 905 * This function does not apply clipping on @dst (i.e. the destination is at the 906 * top-left corner). 907 * 908 * Drivers can use this function for ARGB2101010 devices that don't support XRGB8888 909 * natively. 910 */ 911 void drm_fb_xrgb8888_to_argb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, 912 const struct iosys_map *src, const struct drm_framebuffer *fb, 913 const struct drm_rect *clip, 914 struct drm_format_conv_state *state) 915 { 916 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 917 4, 918 }; 919 920 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 921 drm_fb_xrgb8888_to_argb2101010_line); 922 } 923 EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb2101010); 924 925 static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned int pixels) 926 { 927 u8 *dbuf8 = dbuf; 928 const __le32 *sbuf32 = sbuf; 929 unsigned int x; 930 931 for (x = 0; x < pixels; x++) { 932 u32 pix = le32_to_cpu(sbuf32[x]); 933 u8 r = (pix & 0x00ff0000) >> 16; 934 u8 g = (pix & 0x0000ff00) >> 8; 935 u8 b = pix & 0x000000ff; 936 937 /* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */ 938 *dbuf8++ = (3 * r + 6 * g + b) / 10; 939 } 940 } 941 942 /** 943 * drm_fb_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale 944 * @dst: Array of 8-bit grayscale destination buffers 945 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 946 * within @dst; can be NULL if scanlines are stored next to each other. 947 * @src: Array of XRGB8888 source buffers 948 * @fb: DRM framebuffer 949 * @clip: Clip rectangle area to copy 950 * @state: Transform and conversion state 951 * 952 * This function copies parts of a framebuffer to display memory and converts the 953 * color format during the process. Destination and framebuffer formats must match. The 954 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 955 * least as many entries as there are planes in @fb's format. Each entry stores the 956 * value for the format's respective color plane at the same index. 957 * 958 * This function does not apply clipping on @dst (i.e. the destination is at the 959 * top-left corner). 960 * 961 * DRM doesn't have native monochrome or grayscale support. Drivers can use this 962 * function for grayscale devices that don't support XRGB8888 natively.Such 963 * drivers can announce the commonly supported XR24 format to userspace and use 964 * this function to convert to the native format. Monochrome drivers will use the 965 * most significant bit, where 1 means foreground color and 0 background color. 966 * ITU BT.601 is being used for the RGB -> luma (brightness) conversion. 967 */ 968 void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch, 969 const struct iosys_map *src, const struct drm_framebuffer *fb, 970 const struct drm_rect *clip, struct drm_format_conv_state *state) 971 { 972 static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = { 973 1, 974 }; 975 976 drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, 977 drm_fb_xrgb8888_to_gray8_line); 978 } 979 EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); 980 981 /** 982 * drm_fb_blit - Copy parts of a framebuffer to display memory 983 * @dst: Array of display-memory addresses to copy to 984 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 985 * within @dst; can be NULL if scanlines are stored next to each other. 986 * @dst_format: FOURCC code of the display's color format 987 * @src: The framebuffer memory to copy from 988 * @fb: The framebuffer to copy from 989 * @clip: Clip rectangle area to copy 990 * @state: Transform and conversion state 991 * 992 * This function copies parts of a framebuffer to display memory. If the 993 * formats of the display and the framebuffer mismatch, the blit function 994 * will attempt to convert between them during the process. The parameters @dst, 995 * @dst_pitch and @src refer to arrays. Each array must have at least as many 996 * entries as there are planes in @dst_format's format. Each entry stores the 997 * value for the format's respective color plane at the same index. 998 * 999 * This function does not apply clipping on @dst (i.e. the destination is at the 1000 * top-left corner). 1001 * 1002 * Returns: 1003 * 0 on success, or 1004 * -EINVAL if the color-format conversion failed, or 1005 * a negative error code otherwise. 1006 */ 1007 int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, 1008 const struct iosys_map *src, const struct drm_framebuffer *fb, 1009 const struct drm_rect *clip, struct drm_format_conv_state *state) 1010 { 1011 uint32_t fb_format = fb->format->format; 1012 1013 if (fb_format == dst_format) { 1014 drm_fb_memcpy(dst, dst_pitch, src, fb, clip); 1015 return 0; 1016 } else if (fb_format == (dst_format | DRM_FORMAT_BIG_ENDIAN)) { 1017 drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state); 1018 return 0; 1019 } else if (fb_format == (dst_format & ~DRM_FORMAT_BIG_ENDIAN)) { 1020 drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state); 1021 return 0; 1022 } else if (fb_format == DRM_FORMAT_XRGB8888) { 1023 if (dst_format == DRM_FORMAT_RGB565) { 1024 drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, state, false); 1025 return 0; 1026 } else if (dst_format == DRM_FORMAT_XRGB1555) { 1027 drm_fb_xrgb8888_to_xrgb1555(dst, dst_pitch, src, fb, clip, state); 1028 return 0; 1029 } else if (dst_format == DRM_FORMAT_ARGB1555) { 1030 drm_fb_xrgb8888_to_argb1555(dst, dst_pitch, src, fb, clip, state); 1031 return 0; 1032 } else if (dst_format == DRM_FORMAT_RGBA5551) { 1033 drm_fb_xrgb8888_to_rgba5551(dst, dst_pitch, src, fb, clip, state); 1034 return 0; 1035 } else if (dst_format == DRM_FORMAT_RGB888) { 1036 drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip, state); 1037 return 0; 1038 } else if (dst_format == DRM_FORMAT_ARGB8888) { 1039 drm_fb_xrgb8888_to_argb8888(dst, dst_pitch, src, fb, clip, state); 1040 return 0; 1041 } else if (dst_format == DRM_FORMAT_XBGR8888) { 1042 drm_fb_xrgb8888_to_xbgr8888(dst, dst_pitch, src, fb, clip, state); 1043 return 0; 1044 } else if (dst_format == DRM_FORMAT_ABGR8888) { 1045 drm_fb_xrgb8888_to_abgr8888(dst, dst_pitch, src, fb, clip, state); 1046 return 0; 1047 } else if (dst_format == DRM_FORMAT_XRGB2101010) { 1048 drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip, state); 1049 return 0; 1050 } else if (dst_format == DRM_FORMAT_ARGB2101010) { 1051 drm_fb_xrgb8888_to_argb2101010(dst, dst_pitch, src, fb, clip, state); 1052 return 0; 1053 } else if (dst_format == DRM_FORMAT_BGRX8888) { 1054 drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state); 1055 return 0; 1056 } 1057 } 1058 1059 drm_warn_once(fb->dev, "No conversion helper from %p4cc to %p4cc found.\n", 1060 &fb_format, &dst_format); 1061 1062 return -EINVAL; 1063 } 1064 EXPORT_SYMBOL(drm_fb_blit); 1065 1066 static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int pixels) 1067 { 1068 u8 *dbuf8 = dbuf; 1069 const u8 *sbuf8 = sbuf; 1070 1071 while (pixels) { 1072 unsigned int i, bits = min(pixels, 8U); 1073 u8 byte = 0; 1074 1075 for (i = 0; i < bits; i++, pixels--) { 1076 if (*sbuf8++ >= 128) 1077 byte |= BIT(i); 1078 } 1079 *dbuf8++ = byte; 1080 } 1081 } 1082 1083 /** 1084 * drm_fb_xrgb8888_to_mono - Convert XRGB8888 to monochrome 1085 * @dst: Array of monochrome destination buffers (0=black, 1=white) 1086 * @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines 1087 * within @dst; can be NULL if scanlines are stored next to each other. 1088 * @src: Array of XRGB8888 source buffers 1089 * @fb: DRM framebuffer 1090 * @clip: Clip rectangle area to copy 1091 * @state: Transform and conversion state 1092 * 1093 * This function copies parts of a framebuffer to display memory and converts the 1094 * color format during the process. Destination and framebuffer formats must match. The 1095 * parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at 1096 * least as many entries as there are planes in @fb's format. Each entry stores the 1097 * value for the format's respective color plane at the same index. 1098 * 1099 * This function does not apply clipping on @dst (i.e. the destination is at the 1100 * top-left corner). The first pixel (upper left corner of the clip rectangle) will 1101 * be converted and copied to the first bit (LSB) in the first byte of the monochrome 1102 * destination buffer. If the caller requires that the first pixel in a byte must 1103 * be located at an x-coordinate that is a multiple of 8, then the caller must take 1104 * care itself of supplying a suitable clip rectangle. 1105 * 1106 * DRM doesn't have native monochrome support. Drivers can use this function for 1107 * monochrome devices that don't support XRGB8888 natively. Such drivers can 1108 * announce the commonly supported XR24 format to userspace and use this function 1109 * to convert to the native format. 1110 * 1111 * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and 1112 * then the result is converted from grayscale to monochrome. 1113 */ 1114 void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, 1115 const struct iosys_map *src, const struct drm_framebuffer *fb, 1116 const struct drm_rect *clip, struct drm_format_conv_state *state) 1117 { 1118 static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { 1119 0, 0, 0, 0 1120 }; 1121 unsigned int linepixels = drm_rect_width(clip); 1122 unsigned int lines = drm_rect_height(clip); 1123 unsigned int cpp = fb->format->cpp[0]; 1124 unsigned int len_src32 = linepixels * cpp; 1125 struct drm_device *dev = fb->dev; 1126 void *vaddr = src[0].vaddr; 1127 unsigned int dst_pitch_0; 1128 unsigned int y; 1129 u8 *mono = dst[0].vaddr, *gray8; 1130 u32 *src32; 1131 1132 if (drm_WARN_ON(dev, fb->format->format != DRM_FORMAT_XRGB8888)) 1133 return; 1134 1135 if (!dst_pitch) 1136 dst_pitch = default_dst_pitch; 1137 dst_pitch_0 = dst_pitch[0]; 1138 1139 /* 1140 * The mono destination buffer contains 1 bit per pixel 1141 */ 1142 if (!dst_pitch_0) 1143 dst_pitch_0 = DIV_ROUND_UP(linepixels, 8); 1144 1145 /* 1146 * The dma memory is write-combined so reads are uncached. 1147 * Speed up by fetching one line at a time. 1148 * 1149 * Also, format conversion from XR24 to monochrome are done 1150 * line-by-line but are converted to 8-bit grayscale as an 1151 * intermediate step. 1152 * 1153 * Allocate a buffer to be used for both copying from the cma 1154 * memory and to store the intermediate grayscale line pixels. 1155 */ 1156 src32 = drm_format_conv_state_reserve(state, len_src32 + linepixels, GFP_KERNEL); 1157 if (!src32) 1158 return; 1159 1160 gray8 = (u8 *)src32 + len_src32; 1161 1162 vaddr += clip_offset(clip, fb->pitches[0], cpp); 1163 for (y = 0; y < lines; y++) { 1164 src32 = memcpy(src32, vaddr, len_src32); 1165 drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels); 1166 drm_fb_gray8_to_mono_line(mono, gray8, linepixels); 1167 vaddr += fb->pitches[0]; 1168 mono += dst_pitch_0; 1169 } 1170 } 1171 EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono); 1172 1173 static uint32_t drm_fb_nonalpha_fourcc(uint32_t fourcc) 1174 { 1175 /* only handle formats with depth != 0 and alpha channel */ 1176 switch (fourcc) { 1177 case DRM_FORMAT_ARGB1555: 1178 return DRM_FORMAT_XRGB1555; 1179 case DRM_FORMAT_ABGR1555: 1180 return DRM_FORMAT_XBGR1555; 1181 case DRM_FORMAT_RGBA5551: 1182 return DRM_FORMAT_RGBX5551; 1183 case DRM_FORMAT_BGRA5551: 1184 return DRM_FORMAT_BGRX5551; 1185 case DRM_FORMAT_ARGB8888: 1186 return DRM_FORMAT_XRGB8888; 1187 case DRM_FORMAT_ABGR8888: 1188 return DRM_FORMAT_XBGR8888; 1189 case DRM_FORMAT_RGBA8888: 1190 return DRM_FORMAT_RGBX8888; 1191 case DRM_FORMAT_BGRA8888: 1192 return DRM_FORMAT_BGRX8888; 1193 case DRM_FORMAT_ARGB2101010: 1194 return DRM_FORMAT_XRGB2101010; 1195 case DRM_FORMAT_ABGR2101010: 1196 return DRM_FORMAT_XBGR2101010; 1197 case DRM_FORMAT_RGBA1010102: 1198 return DRM_FORMAT_RGBX1010102; 1199 case DRM_FORMAT_BGRA1010102: 1200 return DRM_FORMAT_BGRX1010102; 1201 } 1202 1203 return fourcc; 1204 } 1205 1206 static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t fourcc) 1207 { 1208 const uint32_t *fourccs_end = fourccs + nfourccs; 1209 1210 while (fourccs < fourccs_end) { 1211 if (*fourccs == fourcc) 1212 return true; 1213 ++fourccs; 1214 } 1215 return false; 1216 } 1217 1218 /** 1219 * drm_fb_build_fourcc_list - Filters a list of supported color formats against 1220 * the device's native formats 1221 * @dev: DRM device 1222 * @native_fourccs: 4CC codes of natively supported color formats 1223 * @native_nfourccs: The number of entries in @native_fourccs 1224 * @fourccs_out: Returns 4CC codes of supported color formats 1225 * @nfourccs_out: The number of available entries in @fourccs_out 1226 * 1227 * This function create a list of supported color format from natively 1228 * supported formats and additional emulated formats. 1229 * At a minimum, most userspace programs expect at least support for 1230 * XRGB8888 on the primary plane. Devices that have to emulate the 1231 * format, and possibly others, can use drm_fb_build_fourcc_list() to 1232 * create a list of supported color formats. The returned list can 1233 * be handed over to drm_universal_plane_init() et al. Native formats 1234 * will go before emulated formats. Native formats with alpha channel 1235 * will be replaced by such without, as primary planes usually don't 1236 * support alpha. Other heuristics might be applied 1237 * to optimize the order. Formats near the beginning of the list are 1238 * usually preferred over formats near the end of the list. 1239 * 1240 * Returns: 1241 * The number of color-formats 4CC codes returned in @fourccs_out. 1242 */ 1243 size_t drm_fb_build_fourcc_list(struct drm_device *dev, 1244 const u32 *native_fourccs, size_t native_nfourccs, 1245 u32 *fourccs_out, size_t nfourccs_out) 1246 { 1247 /* 1248 * XRGB8888 is the default fallback format for most of userspace 1249 * and it's currently the only format that should be emulated for 1250 * the primary plane. Only if there's ever another default fallback, 1251 * it should be added here. 1252 */ 1253 static const uint32_t extra_fourccs[] = { 1254 DRM_FORMAT_XRGB8888, 1255 }; 1256 static const size_t extra_nfourccs = ARRAY_SIZE(extra_fourccs); 1257 1258 u32 *fourccs = fourccs_out; 1259 const u32 *fourccs_end = fourccs_out + nfourccs_out; 1260 size_t i; 1261 1262 /* 1263 * The device's native formats go first. 1264 */ 1265 1266 for (i = 0; i < native_nfourccs; ++i) { 1267 /* 1268 * Several DTs, boot loaders and firmware report native 1269 * alpha formats that are non-alpha formats instead. So 1270 * replace alpha formats by non-alpha formats. 1271 */ 1272 u32 fourcc = drm_fb_nonalpha_fourcc(native_fourccs[i]); 1273 1274 if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) { 1275 continue; /* skip duplicate entries */ 1276 } else if (fourccs == fourccs_end) { 1277 drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc); 1278 continue; /* end of available output buffer */ 1279 } 1280 1281 drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); 1282 1283 *fourccs = fourcc; 1284 ++fourccs; 1285 } 1286 1287 /* 1288 * The extra formats, emulated by the driver, go second. 1289 */ 1290 1291 for (i = 0; (i < extra_nfourccs) && (fourccs < fourccs_end); ++i) { 1292 u32 fourcc = extra_fourccs[i]; 1293 1294 if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) { 1295 continue; /* skip duplicate and native entries */ 1296 } else if (fourccs == fourccs_end) { 1297 drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); 1298 continue; /* end of available output buffer */ 1299 } 1300 1301 drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); 1302 1303 *fourccs = fourcc; 1304 ++fourccs; 1305 } 1306 1307 return fourccs - fourccs_out; 1308 } 1309 EXPORT_SYMBOL(drm_fb_build_fourcc_list); 1310