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