Re: [PATCH 2/3] drm/format-helper: Add drm_fb_xrgb8888_to_xrgb2101010_dstclip()

2021-11-22 Thread Pekka Paalanen
On Mon, 22 Nov 2021 19:05:16 +0900
Hector Martin  wrote:

> On 22/11/2021 18.52, Pekka Paalanen wrote:
> > On Wed, 17 Nov 2021 23:58:28 +0900
> > Hector Martin  wrote:
> >   
> >> Add XRGB emulation support for devices that can only do XRGB2101010.
> >>
> >> This is chiefly useful for simpledrm on Apple devices where the
> >> bootloader-provided framebuffer is 10-bit, which already works fine with
> >> simplefb. This is required to make simpledrm support this too.
> >>
> >> Signed-off-by: Hector Martin 
> >> ---
> >>   drivers/gpu/drm/drm_format_helper.c | 64 +
> >>   include/drm/drm_format_helper.h |  4 ++
> >>   2 files changed, 68 insertions(+)  
> > 
> > Hi Hector,
> > 
> > I'm curious, since the bootloader seems to always set up a 10-bit mode,
> > is there a reason for it that you can guess? Is the monitor in WCG or
> > even HDR mode?  
> 
> My guess is that Apple prefer to use 10-bit framebuffers for seamless 
> handover with their graphics stack, which presumably uses 10-bit 
> framebuffers these days. It seems to be unconditional; I've never seen 
> anything but 10 bits across all Apple devices, both with the internal 
> panels on laptops and with bog standard external displays on the Mac 
> Mini via HDMI. HDR is not necessary, even very dumb capture cards and 
> old screens get a 10-bit framebufer in memory.

That makes perfect sense, thanks!

Switching between sRGB and WCG or HDR mode is not a modeset, it's just
HDMI/DP/whatever metadata/infoframe.

> The only time I see an 8-bit framebuffer is with *no* monitor connected 
> on the Mini, in which case you get an 8-bit 640x1136 dummy framebuffer 
> (that's the iPhone 5 screen resolution... :-) )
> 

Thanks,
pq


pgpOvhSaDNnIx.pgp
Description: OpenPGP digital signature


Re: [PATCH 2/3] drm/format-helper: Add drm_fb_xrgb8888_to_xrgb2101010_dstclip()

2021-11-22 Thread Hector Martin

On 22/11/2021 18.52, Pekka Paalanen wrote:

On Wed, 17 Nov 2021 23:58:28 +0900
Hector Martin  wrote:


Add XRGB emulation support for devices that can only do XRGB2101010.

This is chiefly useful for simpledrm on Apple devices where the
bootloader-provided framebuffer is 10-bit, which already works fine with
simplefb. This is required to make simpledrm support this too.

Signed-off-by: Hector Martin 
---
  drivers/gpu/drm/drm_format_helper.c | 64 +
  include/drm/drm_format_helper.h |  4 ++
  2 files changed, 68 insertions(+)


Hi Hector,

I'm curious, since the bootloader seems to always set up a 10-bit mode,
is there a reason for it that you can guess? Is the monitor in WCG or
even HDR mode?


My guess is that Apple prefer to use 10-bit framebuffers for seamless 
handover with their graphics stack, which presumably uses 10-bit 
framebuffers these days. It seems to be unconditional; I've never seen 
anything but 10 bits across all Apple devices, both with the internal 
panels on laptops and with bog standard external displays on the Mac 
Mini via HDMI. HDR is not necessary, even very dumb capture cards and 
old screens get a 10-bit framebufer in memory.


The only time I see an 8-bit framebuffer is with *no* monitor connected 
on the Mini, in which case you get an 8-bit 640x1136 dummy framebuffer 
(that's the iPhone 5 screen resolution... :-) )


--
Hector Martin (mar...@marcan.st)
Public Key: https://mrcn.st/pub


Re: [PATCH 2/3] drm/format-helper: Add drm_fb_xrgb8888_to_xrgb2101010_dstclip()

2021-11-22 Thread Pekka Paalanen
On Wed, 17 Nov 2021 23:58:28 +0900
Hector Martin  wrote:

> Add XRGB emulation support for devices that can only do XRGB2101010.
> 
> This is chiefly useful for simpledrm on Apple devices where the
> bootloader-provided framebuffer is 10-bit, which already works fine with
> simplefb. This is required to make simpledrm support this too.
> 
> Signed-off-by: Hector Martin 
> ---
>  drivers/gpu/drm/drm_format_helper.c | 64 +
>  include/drm/drm_format_helper.h |  4 ++
>  2 files changed, 68 insertions(+)

Hi Hector,

I'm curious, since the bootloader seems to always set up a 10-bit mode,
is there a reason for it that you can guess? Is the monitor in WCG or
even HDR mode?


Thanks,
pq


pgpfiAYNbZYeh.pgp
Description: OpenPGP digital signature


Re: [PATCH 2/3] drm/format-helper: Add drm_fb_xrgb8888_to_xrgb2101010_dstclip()

2021-11-18 Thread Thomas Zimmermann

Hi

Am 17.11.21 um 15:58 schrieb Hector Martin:

Add XRGB emulation support for devices that can only do XRGB2101010.

This is chiefly useful for simpledrm on Apple devices where the
bootloader-provided framebuffer is 10-bit, which already works fine with
simplefb. This is required to make simpledrm support this too.


As mentioned in the other review, this requires a rebase onto the latest 
DRM tree; preferably drm-tip.


Best regards
Thomas



Signed-off-by: Hector Martin 
---
  drivers/gpu/drm/drm_format_helper.c | 64 +
  include/drm/drm_format_helper.h |  4 ++
  2 files changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 69fde60e36b3..5998e57d6ff2 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -378,6 +378,60 @@ void drm_fb_xrgb_to_rgb888_dstclip(void __iomem *dst, 
unsigned int dst_pitch
  }
  EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888_dstclip);
  
+static void drm_fb_xrgb_to_xrgb2101010_line(u32 *dbuf, u32 *sbuf,

+   unsigned int pixels)
+{
+   unsigned int x;
+
+   for (x = 0; x < pixels; x++) {
+   *dbuf++ = ((sbuf[x] & 0x00FF) << 2) |
+ ((sbuf[x] & 0xFF00) << 4) |
+ ((sbuf[x] & 0x00FF) << 6);
+   }
+}
+
+/**
+ * drm_fb_xrgb_to_xrgb2101010_dstclip - Convert XRGB to XRGB2101010 
clip
+ * buffer
+ * @dst: XRGB2101010 destination buffer (iomem)
+ * @dst_pitch: destination buffer pitch
+ * @vaddr: XRGB source buffer
+ * @fb: DRM framebuffer
+ * @clip: Clip rectangle area to copy
+ *
+ * Drivers can use this function for XRGB2101010 devices that don't natively
+ * support XRGB.
+ *
+ * This function applies clipping on dst, i.e. the destination is a
+ * full (iomem) framebuffer but only the clip rect content is copied over.
+ */
+void drm_fb_xrgb_to_xrgb2101010_dstclip(void __iomem *dst,
+   unsigned int dst_pitch, void *vaddr,
+   struct drm_framebuffer *fb,
+   struct drm_rect *clip)
+{
+   size_t linepixels = clip->x2 - clip->x1;
+   size_t dst_len = linepixels * 4;
+   unsigned int y, lines = clip->y2 - clip->y1;
+   void *dbuf;
+
+   dbuf = kmalloc(dst_len, GFP_KERNEL);
+   if (!dbuf)
+   return;
+
+   vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
+   dst += clip_offset(clip, dst_pitch, sizeof(u32));
+   for (y = 0; y < lines; y++) {
+   drm_fb_xrgb_to_xrgb2101010_line(dbuf, vaddr, linepixels);
+   memcpy_toio(dst, dbuf, dst_len);
+   vaddr += fb->pitches[0];
+   dst += dst_pitch;
+   }
+
+   kfree(dbuf);
+}
+EXPORT_SYMBOL(drm_fb_xrgb_to_xrgb2101010_dstclip);
+
  /**
   * drm_fb_xrgb_to_gray8 - Convert XRGB to grayscale
   * @dst: 8-bit grayscale destination buffer
@@ -464,6 +518,10 @@ int drm_fb_blit_rect_dstclip(void __iomem *dst, unsigned 
int dst_pitch,
fb_format = DRM_FORMAT_XRGB;
if (dst_format == DRM_FORMAT_ARGB)
dst_format = DRM_FORMAT_XRGB;
+   if (fb_format == DRM_FORMAT_ARGB2101010)
+   fb_format = DRM_FORMAT_XRGB2101010;
+   if (dst_format == DRM_FORMAT_ARGB2101010)
+   dst_format = DRM_FORMAT_XRGB2101010;
  
  	if (dst_format == fb_format) {

drm_fb_memcpy_dstclip(dst, dst_pitch, vmap, fb, clip);
@@ -482,6 +540,12 @@ int drm_fb_blit_rect_dstclip(void __iomem *dst, unsigned 
int dst_pitch,
  vmap, fb, clip);
return 0;
}
+   } else if (dst_format == DRM_FORMAT_XRGB2101010) {
+   if (fb_format == DRM_FORMAT_XRGB) {
+   drm_fb_xrgb_to_xrgb2101010_dstclip(dst, dst_pitch,
+  vmap, fb, clip);
+   return 0;
+   }
}
  
  	return -EINVAL;

diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h
index e86925cf07b9..a0faa710878b 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -29,6 +29,10 @@ void drm_fb_xrgb_to_rgb888(void *dst, void *src, struct 
drm_framebuffer *fb,
  void drm_fb_xrgb_to_rgb888_dstclip(void __iomem *dst, unsigned int 
dst_pitch,
   void *vaddr, struct drm_framebuffer *fb,
   struct drm_rect *clip);
+void drm_fb_xrgb_to_xrgb2101010_dstclip(void __iomem *dst,
+   unsigned int dst_pitch, void *vaddr,
+   struct drm_framebuffer *fb,
+   struct

[PATCH 2/3] drm/format-helper: Add drm_fb_xrgb8888_to_xrgb2101010_dstclip()

2021-11-17 Thread Hector Martin
Add XRGB emulation support for devices that can only do XRGB2101010.

This is chiefly useful for simpledrm on Apple devices where the
bootloader-provided framebuffer is 10-bit, which already works fine with
simplefb. This is required to make simpledrm support this too.

Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/drm_format_helper.c | 64 +
 include/drm/drm_format_helper.h |  4 ++
 2 files changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index 69fde60e36b3..5998e57d6ff2 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -378,6 +378,60 @@ void drm_fb_xrgb_to_rgb888_dstclip(void __iomem *dst, 
unsigned int dst_pitch
 }
 EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888_dstclip);
 
+static void drm_fb_xrgb_to_xrgb2101010_line(u32 *dbuf, u32 *sbuf,
+   unsigned int pixels)
+{
+   unsigned int x;
+
+   for (x = 0; x < pixels; x++) {
+   *dbuf++ = ((sbuf[x] & 0x00FF) << 2) |
+ ((sbuf[x] & 0xFF00) << 4) |
+ ((sbuf[x] & 0x00FF) << 6);
+   }
+}
+
+/**
+ * drm_fb_xrgb_to_xrgb2101010_dstclip - Convert XRGB to XRGB2101010 
clip
+ * buffer
+ * @dst: XRGB2101010 destination buffer (iomem)
+ * @dst_pitch: destination buffer pitch
+ * @vaddr: XRGB source buffer
+ * @fb: DRM framebuffer
+ * @clip: Clip rectangle area to copy
+ *
+ * Drivers can use this function for XRGB2101010 devices that don't natively
+ * support XRGB.
+ *
+ * This function applies clipping on dst, i.e. the destination is a
+ * full (iomem) framebuffer but only the clip rect content is copied over.
+ */
+void drm_fb_xrgb_to_xrgb2101010_dstclip(void __iomem *dst,
+   unsigned int dst_pitch, void *vaddr,
+   struct drm_framebuffer *fb,
+   struct drm_rect *clip)
+{
+   size_t linepixels = clip->x2 - clip->x1;
+   size_t dst_len = linepixels * 4;
+   unsigned int y, lines = clip->y2 - clip->y1;
+   void *dbuf;
+
+   dbuf = kmalloc(dst_len, GFP_KERNEL);
+   if (!dbuf)
+   return;
+
+   vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
+   dst += clip_offset(clip, dst_pitch, sizeof(u32));
+   for (y = 0; y < lines; y++) {
+   drm_fb_xrgb_to_xrgb2101010_line(dbuf, vaddr, linepixels);
+   memcpy_toio(dst, dbuf, dst_len);
+   vaddr += fb->pitches[0];
+   dst += dst_pitch;
+   }
+
+   kfree(dbuf);
+}
+EXPORT_SYMBOL(drm_fb_xrgb_to_xrgb2101010_dstclip);
+
 /**
  * drm_fb_xrgb_to_gray8 - Convert XRGB to grayscale
  * @dst: 8-bit grayscale destination buffer
@@ -464,6 +518,10 @@ int drm_fb_blit_rect_dstclip(void __iomem *dst, unsigned 
int dst_pitch,
fb_format = DRM_FORMAT_XRGB;
if (dst_format == DRM_FORMAT_ARGB)
dst_format = DRM_FORMAT_XRGB;
+   if (fb_format == DRM_FORMAT_ARGB2101010)
+   fb_format = DRM_FORMAT_XRGB2101010;
+   if (dst_format == DRM_FORMAT_ARGB2101010)
+   dst_format = DRM_FORMAT_XRGB2101010;
 
if (dst_format == fb_format) {
drm_fb_memcpy_dstclip(dst, dst_pitch, vmap, fb, clip);
@@ -482,6 +540,12 @@ int drm_fb_blit_rect_dstclip(void __iomem *dst, unsigned 
int dst_pitch,
  vmap, fb, clip);
return 0;
}
+   } else if (dst_format == DRM_FORMAT_XRGB2101010) {
+   if (fb_format == DRM_FORMAT_XRGB) {
+   drm_fb_xrgb_to_xrgb2101010_dstclip(dst, dst_pitch,
+  vmap, fb, clip);
+   return 0;
+   }
}
 
return -EINVAL;
diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h
index e86925cf07b9..a0faa710878b 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -29,6 +29,10 @@ void drm_fb_xrgb_to_rgb888(void *dst, void *src, struct 
drm_framebuffer *fb,
 void drm_fb_xrgb_to_rgb888_dstclip(void __iomem *dst, unsigned int 
dst_pitch,
   void *vaddr, struct drm_framebuffer *fb,
   struct drm_rect *clip);
+void drm_fb_xrgb_to_xrgb2101010_dstclip(void __iomem *dst,
+   unsigned int dst_pitch, void *vaddr,
+   struct drm_framebuffer *fb,
+   struct drm_rect *clip);
 void drm_fb_xrgb_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
  struct drm_rect *clip);
 
-- 
2.33.0