|
7 | 7 | * (at your option) any later version.
|
8 | 8 | */
|
9 | 9 |
|
10 |
| -#include <drm/tinydrm/tinydrm.h> |
11 |
| -#include <drm/tinydrm/tinydrm-helpers.h> |
12 | 10 | #include <linux/backlight.h>
|
| 11 | +#include <linux/dma-buf.h> |
13 | 12 | #include <linux/pm.h>
|
14 | 13 | #include <linux/spi/spi.h>
|
15 | 14 | #include <linux/swab.h>
|
16 | 15 |
|
| 16 | +#include <drm/tinydrm/tinydrm.h> |
| 17 | +#include <drm/tinydrm/tinydrm-helpers.h> |
| 18 | + |
17 | 19 | static unsigned int spi_max;
|
18 | 20 | module_param(spi_max, uint, 0400);
|
19 | 21 | MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
|
@@ -180,6 +182,74 @@ void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr,
|
180 | 182 | }
|
181 | 183 | EXPORT_SYMBOL(tinydrm_xrgb8888_to_rgb565);
|
182 | 184 |
|
| 185 | +/** |
| 186 | + * tinydrm_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale |
| 187 | + * @dst: 8-bit grayscale destination buffer |
| 188 | + * @fb: DRM framebuffer |
| 189 | + * |
| 190 | + * Drm doesn't have native monochrome or grayscale support. |
| 191 | + * Such drivers can announce the commonly supported XR24 format to userspace |
| 192 | + * and use this function to convert to the native format. |
| 193 | + * |
| 194 | + * Monochrome drivers will use the most significant bit, |
| 195 | + * where 1 means foreground color and 0 background color. |
| 196 | + * |
| 197 | + * ITU BT.601 is used for the RGB -> luma (brightness) conversion. |
| 198 | + * |
| 199 | + * Returns: |
| 200 | + * Zero on success, negative error code on failure. |
| 201 | + */ |
| 202 | +int tinydrm_xrgb8888_to_gray8(u8 *dst, struct drm_framebuffer *fb) |
| 203 | +{ |
| 204 | + struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); |
| 205 | + struct dma_buf_attachment *import_attach = cma_obj->base.import_attach; |
| 206 | + unsigned int x, y, pitch = fb->pitches[0]; |
| 207 | + int ret = 0; |
| 208 | + void *buf; |
| 209 | + u32 *src; |
| 210 | + |
| 211 | + if (WARN_ON(fb->format->format != DRM_FORMAT_XRGB8888)) |
| 212 | + return -EINVAL; |
| 213 | + /* |
| 214 | + * The cma memory is write-combined so reads are uncached. |
| 215 | + * Speed up by fetching one line at a time. |
| 216 | + */ |
| 217 | + buf = kmalloc(pitch, GFP_KERNEL); |
| 218 | + if (!buf) |
| 219 | + return -ENOMEM; |
| 220 | + |
| 221 | + if (import_attach) { |
| 222 | + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, |
| 223 | + DMA_FROM_DEVICE); |
| 224 | + if (ret) |
| 225 | + goto err_free; |
| 226 | + } |
| 227 | + |
| 228 | + for (y = 0; y < fb->height; y++) { |
| 229 | + src = cma_obj->vaddr + (y * pitch); |
| 230 | + memcpy(buf, src, pitch); |
| 231 | + src = buf; |
| 232 | + for (x = 0; x < fb->width; x++) { |
| 233 | + u8 r = (*src & 0x00ff0000) >> 16; |
| 234 | + u8 g = (*src & 0x0000ff00) >> 8; |
| 235 | + u8 b = *src & 0x000000ff; |
| 236 | + |
| 237 | + /* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */ |
| 238 | + *dst++ = (3 * r + 6 * g + b) / 10; |
| 239 | + src++; |
| 240 | + } |
| 241 | + } |
| 242 | + |
| 243 | + if (import_attach) |
| 244 | + ret = dma_buf_end_cpu_access(import_attach->dmabuf, |
| 245 | + DMA_FROM_DEVICE); |
| 246 | +err_free: |
| 247 | + kfree(buf); |
| 248 | + |
| 249 | + return ret; |
| 250 | +} |
| 251 | +EXPORT_SYMBOL(tinydrm_xrgb8888_to_gray8); |
| 252 | + |
183 | 253 | /**
|
184 | 254 | * tinydrm_of_find_backlight - Find backlight device in device-tree
|
185 | 255 | * @dev: Device
|
|
0 commit comments