Re: [PATCH v2] drm/format-helper: Only advertise supported formats for conversion

2022-10-31 Thread Hector Martin
On 01/11/2022 01.15, Justin Forbes wrote:
> On Thu, Oct 27, 2022 at 8:57 AM Hector Martin  wrote:
>>
>> drm_fb_build_fourcc_list() currently returns all emulated formats
>> unconditionally as long as the native format is among them, even though
>> not all combinations have conversion helpers. Although the list is
>> arguably provided to userspace in precedence order, userspace can pick
>> something out-of-order (and thus break when it shouldn't), or simply
>> only support a format that is unsupported (and thus think it can work,
>> which results in the appearance of a hang as FB blits fail later on,
>> instead of the initialization error you'd expect in this case).
>>
>> Add checks to filter the list of emulated formats to only those
>> supported for conversion to the native format. This presumes that there
>> is a single native format (only the first is checked, if there are
>> multiple). Refactoring this API to drop the native list or support it
>> properly (by returning the appropriate emulated->native mapping table)
>> is left for a future patch.
>>
>> The simpledrm driver is left as-is with a full table of emulated
>> formats. This keeps all currently working conversions available and
>> drops all the broken ones (i.e. this a strict bugfix patch, adding no
>> new supported formats nor removing any actually working ones). In order
>> to avoid proliferation of emulated formats, future drivers should
>> advertise only XRGB as the sole emulated format (since some
>> userspace assumes its presence).
>>
>> This fixes a real user regression where the ?RGB2101010 support commit
>> started advertising it unconditionally where not supported, and KWin
>> decided to start to use it over the native format and broke, but also
>> the fixes the spurious RGB565/RGB888 formats which have been wrongly
>> unconditionally advertised since the dawn of simpledrm.
>>
>> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB210101
> 
> 
>> Cc: sta...@vger.kernel.org
>> Signed-off-by: Hector Martin 
> 
> There is a CC for stable on here, but this patch does not apply in any
> way on 6.0 or older kernels as the fourcc bits and considerable churn
> came in with the 6.1 merge window.  You don't happen to have a
> backport of this to 6.0 do you?

v1 is probably closer to such a backport, and I offered to figure it out
on Matrix but I heard you're already working on it ;)

- Hector


Re: [PATCH v2] drm/format-helper: Only advertise supported formats for conversion

2022-10-28 Thread Hector Martin
On 28/10/2022 17.07, Thomas Zimmermann wrote:
> In yesterday's discussion on IRC, it was said that several devices 
> advertise ARGB framebuffers when the hardware actually uses XRGB? Is 
> there hardware that supports transparent primary planes?

ARGB hardware probably exists in the form of embedded systems with
preconfigured blending. For example, one could imagine an OSD-type setup
where there is a hardware video scaler controlled entirely outside of
DRM/KMS (probably by a horrible vendor driver), and the overlay
framebuffer is exposed via simpledrm as a dumb memory region, and
expects ARGB to work. So ideally, we wouldn't expose XRGB on
ARGB systems.

But there is this problem:

arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts:
format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts:
format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts:
format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi:
   format = "a8r8g8b8";
arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi:
   format = "a8r8g8b8";
arch/arm64/boot/dts/socionext/uniphier-ld20-akebi96.dts:
format = "a8r8g8b8";

I'm pretty sure those phones don't have transparent screens, nor
magically put video planes below the firmware framebuffer. If there are
12 device trees for phones in mainline which lie about having alpha
support, who knows how many more exist outside? If we stop advertising
pretend-XRGB on them, I suspect we're going to break a lot of
software...

Of course, there is one "correct" solution here: have an actual
xrgb->argb conversion helper that just clears the high byte.
Then those platforms lying about having alpha and using xrgb from
userspace will take a performace hit, but they should arguably just fix
their device tree in that case. Maybe this is the way to go in this
case? Note that there would be no inverse conversion (no advertising
argb on xrgb backends), so that one would be dropped vs. what we
have today. This effectively keeps the "xrgb helpers and nothing
else" rule while actually supporting it for argb backend
framebuffers correctly. Any platforms actually wanting to use argb
framebuffers with meaningful alpha should be configuring their userspace
to preferentially render directly to argb to avoid the perf hit anyway.

- Hector


[PATCH v2] drm/format-helper: Only advertise supported formats for conversion

2022-10-27 Thread Hector Martin
drm_fb_build_fourcc_list() currently returns all emulated formats
unconditionally as long as the native format is among them, even though
not all combinations have conversion helpers. Although the list is
arguably provided to userspace in precedence order, userspace can pick
something out-of-order (and thus break when it shouldn't), or simply
only support a format that is unsupported (and thus think it can work,
which results in the appearance of a hang as FB blits fail later on,
instead of the initialization error you'd expect in this case).

Add checks to filter the list of emulated formats to only those
supported for conversion to the native format. This presumes that there
is a single native format (only the first is checked, if there are
multiple). Refactoring this API to drop the native list or support it
properly (by returning the appropriate emulated->native mapping table)
is left for a future patch.

The simpledrm driver is left as-is with a full table of emulated
formats. This keeps all currently working conversions available and
drops all the broken ones (i.e. this a strict bugfix patch, adding no
new supported formats nor removing any actually working ones). In order
to avoid proliferation of emulated formats, future drivers should
advertise only XRGB as the sole emulated format (since some
userspace assumes its presence).

This fixes a real user regression where the ?RGB2101010 support commit
started advertising it unconditionally where not supported, and KWin
decided to start to use it over the native format and broke, but also
the fixes the spurious RGB565/RGB888 formats which have been wrongly
unconditionally advertised since the dawn of simpledrm.

Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats")
Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
Cc: sta...@vger.kernel.org
Signed-off-by: Hector Martin 
---
I'm proposing this alternative approach after a heated discussion on
IRC. I'm out of ideas, if y'all don't like this one you can figure it
out for yourseves :-)

Changes since v1:
This v2 moves all the changes to the helper (so they will apply to
the upcoming ofdrm, though ofdrm also needs to be fixed to trim its
format table to only formats that should be emulated, probably only
XRGB, to avoid further proliferating the use of conversions),
and avoids touching more than one file. The API still needs cleanup
as mentioned (supporting more than one native format is fundamentally
broken, since the helper would need to tell the driver *what* native
format to use for *each* emulated format somehow), but all current and
planned users only pass in one native format, so this can (and should)
be fixed later.

Aside: After other IRC discussion, I'm testing nuking the
XRGB2101010 <-> ARGB2101010 advertisement (which does not involve
conversion) by removing those entries from simpledrm in the Asahi Linux
downstream tree. As far as I'm concerned, it can be removed if nobody
complains (by removing those entries from the simpledrm array), if
maintainers are generally okay with removing advertised formats at all.
If so, there might be other opportunities for further trimming the list
non-native formats advertised to userspace.

Tested with KWin-X11, KWin-Wayland, GNOME-X11, GNOME-Wayland, and Weston
on both XRGB2101010 and RGB simpledrm framebuffers.

 drivers/gpu/drm/drm_format_helper.c | 66 -
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index e2f76621453c..3ee59bae9d2f 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, 
size_t nfourccs, uint32_t
return false;
 }
 
+static const uint32_t conv_from_xrgb[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGB888,
+};
+
+static const uint32_t conv_from_rgb565_888[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+};
+
+static bool is_conversion_supported(uint32_t from, uint32_t to)
+{
+   switch (from) {
+   case DRM_FORMAT_XRGB:
+   case DRM_FORMAT_ARGB:
+   return is_listed_fourcc(conv_from_xrgb, 
ARRAY_SIZE(conv_from_xrgb), to);
+   case DRM_FORMAT_RGB565:
+   case DRM_FORMAT_RGB888:
+   return is_listed_fourcc(conv_from_rgb565_888, 
ARRAY_SIZE(conv_from_rgb565_888), to);
+   case DRM_FORMAT_XRGB2101010:
+   return to == DRM_FORMAT_ARGB2101010;
+   case DRM_FORMAT_ARGB2101010:
+   return to == DRM_FORMAT_XRGB2101010;
+   default:
+   return false;
+   }
+}
+
 /**
  * drm_fb_build_fourcc_list - Filters a list of supported color formats against
  *  

Re: [PATCH] drm/simpledrm: Only advertise formats that are supported

2022-10-27 Thread Hector Martin
On 27/10/2022 20.08, Thomas Zimmermann wrote:
> We currently have two DRM drivers that call drm_fb_build_fourcc_list(): 
> simpledrm and ofdrm. I've been very careful to keep the format selection 
> in sync between them. (That's the reason why the helper exists at all.) 
> If the drivers start to use different logic, it will only become more 
> chaotic.
> 
> The format array of ofdrm is at [1]. At a minimum, ofdrm should get the 
> same fix as simpledrm.

Looks like this was merged recently, so I didn't see it on my tree (I
was basing off of 6.1-rc2).

Since this patch is a regression fix, it should be applied to drm-fixes
(and automatically picked up by stable folks) soon to be fixed in 6.1,
and then we can fix whatever is needed in ofdrm separately in drm-tip.
As long as ofdrm is ready for the new behavior prior to the merge of
drm-tip with 6.1, there will be no breakage.

In this case, the change required to ofdrm is probably just to replace
that array with just DRM_FORMAT_XRGB (which should be the only
supported fallback format for new drivers) and then to add a test to
only expose it for formats for which we actually have conversion
helpers, similar to what the the switch() enumerates here. That logic
could later be moved into the helper as a refactor.

>>  /* Primary plane */
>> +switch (format->format) {
> 
> I trust you when you say that ->XRGB is not enough. But 
> although I've read your replies, I still don't understand why this 
> switch is necessary.
> 
> Why don't we call drm_fb_build_fourcc_list() with the native 
> format/formats and let it append a number of formats, such as adding 
> XRGB888, adding ARGB if necessary, adding ARGB2101010 if necessary. 
> Each with a elaborate comment why and which userspace needs the format. (?)

That would be fine to do, it would just be moving the logic to the
helper. That kind of refactoring is better suited for subsequent
patches. This is a regression fix, it attempts to minimize the amount of
refactoring, which means keeping the logic in simpledrm, to make it
easier to review for correctness.

Also, that would change the API of that function, which would likely
make the merge with the new ofdrm painful. The way things are now, a
small fix to ofdrm will make it compatible with both the state before
and after this patch, which means the merge will go through painlessly,
and then we can just refactor everything once everything is in the same
tree.

- Hector


Re: [PATCH] drm/simpledrm: Only advertise formats that are supported

2022-10-27 Thread Hector Martin
On 27/10/2022 19.13, Hector Martin wrote:
> Until now, simpledrm unconditionally advertised all formats that can be
> supported natively as conversions. However, we don't actually have a
> full conversion matrix of helpers. Although the list is arguably
> provided to userspace in precedence order, userspace can pick something
> out-of-order (and thus break when it shouldn't), or simply only support
> a format that is unsupported (and thus think it can work, which results
> in the appearance of a hang as FB blits fail later on, instead of the
> initialization error you'd expect in this case).
> 
> Split up the format table into separate ones for each required subset,
> and then pick one based on the native format. Also remove the
> native<->conversion overlap check from the helper (which doesn't make
> sense any more, since the native format is advertised anyway and this
> way RGB565/RGB888 can share a format table), and instead print the same
> message in simpledrm when the native format is not one for which we have
> conversions at all.
> 
> This fixes a real user regression where the ?RGB2101010 support commit
> started advertising it unconditionally where not supported, and KWin
> decided to start to use it over the native format, but also the fixes
> the spurious RGB565/RGB888 formats which have been wrongly
> unconditionally advertised since the dawn of simpledrm.
> 
> Note: this patch is merged because splitting it into two patches, one
> for the helper and one for simpledrm, would regress at the midpoint
> regardless of the order. If simpledrm is changed first, that would break
> working conversions to RGB565/RGB888 (since those share a table that
> does not include the native formats). If the helper is changed first, it
> would start spuriously advertising all conversion formats when the
> native format doesn't have any supported conversions at all.
> 
> Acked-by: Pekka Paalanen 
> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats")
> Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
> Cc: sta...@vger.kernel.org
> Signed-off-by: Hector Martin 
> ---
>  drivers/gpu/drm/drm_format_helper.c | 15 ---
>  drivers/gpu/drm/tiny/simpledrm.c| 62 +
>  2 files changed, 55 insertions(+), 22 deletions(-)
> 

To answer some issues that came up on IRC:

Q: Why not move this logic / the tables to the helper?
A: Because simpledrm is the only user so far, and this patch is Cc:
stable because we have an actual regression that broke KDE. I'm going
for the minimal patch that keeps everything that worked to this day
working, and stops advertising things that never worked, no more, no
less. Future refactoring can always happen later (and is probably a good
idea when other drivers start using the helper).

Q: XRGB is supposed to be the only canonical format. Why not just
drop everything but conversions to/from XRGB?
A: Because that would regress things that work today, and could break
existing userspace on some platforms. That may be a good idea, but I
think we should fix the bugs first, and leave the discussion of whether
we want to actually remove existing functionality for later.

Q: Why not just add a conversion from XRGB2101010 to XRGB?
A: Because that would only fix KDE, and would make it slower vs. not
advertising XRGB2101010 at all (double conversions, plus kernel
conversion can be slower). Plus, it doesn't make any sense as it only
fills in one entry in the conversion matrix. If we wanted to actually
fill out the conversion matrix, and thus support everything simpledrm
has advertised to day correctly, we would need helpers for:

rgb565->rgb888
rgb888->rgb565
rgb565->xrgb2101010
rgb888->xrgb2101010
xrgb2101010->rgb565
xrgb2101010->rgb888
xrgb2101010->xrgb

That seems like overkill and unlikely to actually help anyone, it'd just
give userspace more options to shoot itself in the foot with a
sub-optimal format choice. And it's a pile of code.

- Hector


[PATCH] drm/simpledrm: Only advertise formats that are supported

2022-10-27 Thread Hector Martin
Until now, simpledrm unconditionally advertised all formats that can be
supported natively as conversions. However, we don't actually have a
full conversion matrix of helpers. Although the list is arguably
provided to userspace in precedence order, userspace can pick something
out-of-order (and thus break when it shouldn't), or simply only support
a format that is unsupported (and thus think it can work, which results
in the appearance of a hang as FB blits fail later on, instead of the
initialization error you'd expect in this case).

Split up the format table into separate ones for each required subset,
and then pick one based on the native format. Also remove the
native<->conversion overlap check from the helper (which doesn't make
sense any more, since the native format is advertised anyway and this
way RGB565/RGB888 can share a format table), and instead print the same
message in simpledrm when the native format is not one for which we have
conversions at all.

This fixes a real user regression where the ?RGB2101010 support commit
started advertising it unconditionally where not supported, and KWin
decided to start to use it over the native format, but also the fixes
the spurious RGB565/RGB888 formats which have been wrongly
unconditionally advertised since the dawn of simpledrm.

Note: this patch is merged because splitting it into two patches, one
for the helper and one for simpledrm, would regress at the midpoint
regardless of the order. If simpledrm is changed first, that would break
working conversions to RGB565/RGB888 (since those share a table that
does not include the native formats). If the helper is changed first, it
would start spuriously advertising all conversion formats when the
native format doesn't have any supported conversions at all.

Acked-by: Pekka Paalanen 
Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats")
Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
Cc: sta...@vger.kernel.org
Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/drm_format_helper.c | 15 ---
 drivers/gpu/drm/tiny/simpledrm.c| 62 +
 2 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index e2f76621453c..c60c13f3a872 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -864,20 +864,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev,
++fourccs;
}
 
-   /*
-* The plane's atomic_update helper converts the framebuffer's color 
format
-* to a native format when copying to device memory.
-*
-* If there is not a single format supported by both, device and
-* driver, the native formats are likely not supported by the conversion
-* helpers. Therefore *only* support the native formats and add a
-* conversion helper ASAP.
-*/
-   if (!found_native) {
-   drm_warn(dev, "Format conversion helpers required to add extra 
formats.\n");
-   goto out;
-   }
-
/*
 * The extra formats, emulated by the driver, go second.
 */
@@ -898,7 +884,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev,
++fourccs;
}
 
-out:
return fourccs - fourccs_out;
 }
 EXPORT_SYMBOL(drm_fb_build_fourcc_list);
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 18489779fb8a..1257411f3d44 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -446,22 +446,48 @@ static int simpledrm_device_init_regulators(struct 
simpledrm_device *sdev)
  */
 
 /*
- * Support all formats of simplefb and maybe more; in order
- * of preference. The display's update function will do any
+ * Support the subset of formats that we have conversion helpers for,
+ * in order of preference. The display's update function will do any
  * conversion necessary.
  *
  * TODO: Add blit helpers for remaining formats and uncomment
  *   constants.
  */
-static const uint32_t simpledrm_primary_plane_formats[] = {
+
+/*
+ * Supported conversions to RGB565 and RGB888:
+ *   from [AX]RGB
+ */
+static const uint32_t simpledrm_primary_plane_formats_base[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+};
+
+/*
+ * Supported conversions to [AX]RGB:
+ *   A/X variants (no-op)
+ *   from RGB565
+ *   from RGB888
+ */
+static const uint32_t simpledrm_primary_plane_formats_xrgb[] = {
DRM_FORMAT_XRGB,
DRM_FORMAT_ARGB,
+   DRM_FORMAT_RGB888,
DRM_FORMAT_RGB565,
//DRM_FORMAT_XRGB1555,
//DRM_FORMAT_ARGB1555,
-   DRM_FORMAT_RGB888,
+};
+
+/*
+ * Supported conversions to [AX]RGB2101010:
+ *   A/X variants (no-op)
+ *   from [AX]RGB
+ */
+static const uint32_t simpledrm_primary_plane_formats

Re: [PATCH v3 1/3] of: Move simple-framebuffer device handling from simplefb to of

2021-12-13 Thread Hector Martin

On 13/12/2021 20.30, Javier Martinez Canillas wrote:

On Mon, Dec 13, 2021 at 11:46 AM Hector Martin  wrote:


On 13/12/2021 17.44, Javier Martinez Canillas wrote:

Hello Hector,

On Sun, Dec 12, 2021 at 7:24 AM Hector Martin  wrote:


This code is required for both simplefb and simpledrm, so let's move it
into the OF core instead of having it as an ad-hoc initcall in the
drivers.

Acked-by: Thomas Zimmermann 
Signed-off-by: Hector Martin 
---
   drivers/of/platform.c  |  4 
   drivers/video/fbdev/simplefb.c | 21 +
   2 files changed, 5 insertions(+), 20 deletions(-)



This is indeed a much better approach than what I suggested. I just
have one comment.


diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b3faf89744aa..793350028906 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -540,6 +540,10 @@ static int __init of_platform_default_populate_init(void)
  of_node_put(node);
  }

+   node = of_get_compatible_child(of_chosen, "simple-framebuffer");


You have to check if the node variable is NULL here.


+   of_platform_device_create(node, NULL, NULL);


Otherwise this could lead to a NULL pointer dereference if debug
output is enabled (the node->full_name is printed).


Where is it printed? I thought I might need a NULL check, but this code


Sorry, I misread of_amba_device_create() as
of_platform_device_create(), which uses the "%pOF" printk format
specifier [0] to print the node's full name as a debug output [1].

[0]: 
https://elixir.bootlin.com/linux/v5.16-rc5/source/Documentation/core-api/printk-formats.rst#L462
[1]: 
https://elixir.bootlin.com/linux/v5.16-rc5/source/drivers/of/platform.c#L233


was suggested verbatim by Rob in v2 without the NULL check and digging
through I found that the NULL codepath is safe.



You are right that passing NULL is a safe code path for now due the
of_device_is_available(node) check, but that seems fragile to me since
just adding a similar debug output to of_platform_device_create()
could trigger the NULL pointer dereference.


Since Rob is the DT maintainer, I'm going to defer to his opinion on 
this one :-)


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


Re: [PATCH v3 1/3] of: Move simple-framebuffer device handling from simplefb to of

2021-12-13 Thread Hector Martin

On 13/12/2021 17.44, Javier Martinez Canillas wrote:

Hello Hector,

On Sun, Dec 12, 2021 at 7:24 AM Hector Martin  wrote:


This code is required for both simplefb and simpledrm, so let's move it
into the OF core instead of having it as an ad-hoc initcall in the
drivers.

Acked-by: Thomas Zimmermann 
Signed-off-by: Hector Martin 
---
  drivers/of/platform.c  |  4 
  drivers/video/fbdev/simplefb.c | 21 +
  2 files changed, 5 insertions(+), 20 deletions(-)



This is indeed a much better approach than what I suggested. I just
have one comment.


diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b3faf89744aa..793350028906 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -540,6 +540,10 @@ static int __init of_platform_default_populate_init(void)
 of_node_put(node);
 }

+   node = of_get_compatible_child(of_chosen, "simple-framebuffer");


You have to check if the node variable is NULL here.


+   of_platform_device_create(node, NULL, NULL);


Otherwise this could lead to a NULL pointer dereference if debug
output is enabled (the node->full_name is printed).


Where is it printed? I thought I might need a NULL check, but this code 
was suggested verbatim by Rob in v2 without the NULL check and digging 
through I found that the NULL codepath is safe.


of_platform_device_create calls of_platform_device_create_pdata 
directly, and:


static struct platform_device *of_platform_device_create_pdata(
struct device_node *np,
const char *bus_id,
void *platform_data,
struct device *parent)
{
struct platform_device *dev;

if (!of_device_is_available(np) ||
of_node_test_and_set_flag(np, OF_POPULATED))
return NULL;

of_device_is_available takes a global spinlock and then calls 
__of_device_is_available, and that does:


static bool __of_device_is_available(const struct device_node *device)
{
const char *status;
int statlen;

if (!device)
return false;

... so I don't see how this can do anything but immediately return false 
if node is NULL.


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


[PATCH v3 3/3] drm/simpledrm: Add [AX]RGB2101010 formats

2021-12-11 Thread Hector Martin
This is the format used by the bootloader framebuffer on Apple ARM64
platforms.

Reviewed-by: Thomas Zimmermann 
Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/tiny/simpledrm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 2f15b9aa..b977f5c94562 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -571,8 +571,8 @@ static const uint32_t simpledrm_default_formats[] = {
//DRM_FORMAT_XRGB1555,
//DRM_FORMAT_ARGB1555,
DRM_FORMAT_RGB888,
-   //DRM_FORMAT_XRGB2101010,
-   //DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_ARGB2101010,
 };
 
 static const uint64_t simpledrm_format_modifiers[] = {
-- 
2.33.0



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

2021-12-11 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.

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

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index dbe3e830096e..0f28dd2bdd72 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -409,6 +409,61 @@ void drm_fb_xrgb_to_rgb888_toio(void __iomem *dst, 
unsigned int dst_pitch,
 }
 EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888_toio);
 
+static void drm_fb_xrgb_to_xrgb2101010_line(u32 *dbuf, const u32 *sbuf,
+   unsigned int pixels)
+{
+   unsigned int x;
+   u32 val32;
+
+   for (x = 0; x < pixels; x++) {
+   val32 = ((sbuf[x] & 0x00FF) << 2) |
+   ((sbuf[x] & 0xFF00) << 4) |
+   ((sbuf[x] & 0x00FF) << 6);
+   *dbuf++ = val32 | ((val32 >> 8) & 0x00300C03);
+   }
+}
+
+/**
+ * drm_fb_xrgb_to_xrgb2101010_toio - Convert XRGB to XRGB2101010 clip
+ * buffer
+ * @dst: XRGB2101010 destination buffer (iomem)
+ * @dst_pitch: Number of bytes between two consecutive scanlines within dst
+ * @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.
+ */
+void drm_fb_xrgb_to_xrgb2101010_toio(void __iomem *dst,
+unsigned int dst_pitch, const void 
*vaddr,
+const struct drm_framebuffer *fb,
+const struct drm_rect *clip)
+{
+   size_t linepixels = clip->x2 - clip->x1;
+   size_t dst_len = linepixels * sizeof(u32);
+   unsigned int y, lines = clip->y2 - clip->y1;
+   void *dbuf;
+
+   if (!dst_pitch)
+   dst_pitch = dst_len;
+
+   dbuf = kmalloc(dst_len, GFP_KERNEL);
+   if (!dbuf)
+   return;
+
+   vaddr += clip_offset(clip, fb->pitches[0], 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_toio);
+
 /**
  * drm_fb_xrgb_to_gray8 - Convert XRGB to grayscale
  * @dst: 8-bit grayscale destination buffer
@@ -500,6 +555,10 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int 
dst_pitch, uint32_t dst_for
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_toio(dst, dst_pitch, vmap, fb, clip);
@@ -515,6 +574,11 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int 
dst_pitch, uint32_t dst_for
drm_fb_xrgb_to_rgb888_toio(dst, 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_toio(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 97e4c3223af3..b30ed5de0a33 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -33,6 +33,9 @@ void drm_fb_xrgb_to_rgb888(void *dst, unsigned int 
dst_pitch, const void *sr
 void drm_fb_xrgb_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch,
const void *vaddr, const struct 
drm_framebuffer *fb,
const struct drm_rect *clip);
+void drm_fb_xrgb_to_xrgb2101010_toio(void __iomem *dst, unsigned int 
dst_pitch,
+const void *vaddr, const struct 
drm_framebuffer *fb,
+const struct drm_rect *clip);
 void drm_fb_xrgb_to_gray8(void *dst, unsigned int dst_pitch, const void 
*vaddr,
  const struct drm_framebuffer *fb, const struct 
drm_rect *clip);
 
-- 
2.33.0



[PATCH v3 1/3] of: Move simple-framebuffer device handling from simplefb to of

2021-12-11 Thread Hector Martin
This code is required for both simplefb and simpledrm, so let's move it
into the OF core instead of having it as an ad-hoc initcall in the
drivers.

Acked-by: Thomas Zimmermann 
Signed-off-by: Hector Martin 
---
 drivers/of/platform.c  |  4 
 drivers/video/fbdev/simplefb.c | 21 +
 2 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b3faf89744aa..793350028906 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -540,6 +540,10 @@ static int __init of_platform_default_populate_init(void)
of_node_put(node);
}
 
+   node = of_get_compatible_child(of_chosen, "simple-framebuffer");
+   of_platform_device_create(node, NULL, NULL);
+   of_node_put(node);
+
/* Populate everything else. */
of_platform_default_populate(NULL, NULL, NULL);
 
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index b63074fd892e..57541887188b 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -541,26 +541,7 @@ static struct platform_driver simplefb_driver = {
.remove = simplefb_remove,
 };
 
-static int __init simplefb_init(void)
-{
-   int ret;
-   struct device_node *np;
-
-   ret = platform_driver_register(&simplefb_driver);
-   if (ret)
-   return ret;
-
-   if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
-   for_each_child_of_node(of_chosen, np) {
-   if (of_device_is_compatible(np, "simple-framebuffer"))
-   of_platform_device_create(np, NULL, NULL);
-   }
-   }
-
-   return 0;
-}
-
-fs_initcall(simplefb_init);
+module_platform_driver(simplefb_driver);
 
 MODULE_AUTHOR("Stephen Warren ");
 MODULE_DESCRIPTION("Simple framebuffer driver");
-- 
2.33.0



[PATCH v3 0/3] drm/simpledrm: Apple M1 / DT platform support fixes

2021-12-11 Thread Hector Martin
Hi DRM folks,

This short series makes simpledrm work on Apple M1 (including Pro/Max)
platforms the way simplefb already does, by adding XRGB2101010 support
and making it bind to framebuffers in /chosen the same way simplefb
does.

This avoids breaking the bootloader-provided framebuffer console when
simpledrm is selected to replace simplefb, as these FBs always seem to
be 10-bit (at least when a real screen is attached).

Changes since v2:
- Made 10-bit conversion code fill the LSBs
- Added ARGB2101010 to supported formats list
- Simplified OF core code per review feedback
Hector Martin (3):
  of: Move simple-framebuffer device handling from simplefb to of
  drm/format-helper: Add drm_fb_xrgb_to_xrgb2101010_toio()
  drm/simpledrm: Add [AX]RGB2101010 formats

 drivers/gpu/drm/drm_format_helper.c | 64 +
 drivers/gpu/drm/tiny/simpledrm.c|  4 +-
 drivers/of/platform.c   |  4 ++
 drivers/video/fbdev/simplefb.c  | 21 +-
 include/drm/drm_format_helper.h |  3 ++
 5 files changed, 74 insertions(+), 22 deletions(-)

-- 
2.33.0



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

2021-12-07 Thread Hector Martin

Hi, thanks for the review!

On 07/12/2021 18.40, Thomas Zimmermann wrote:

Hi

Am 07.12.21 um 08:29 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.

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

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index dbe3e830096e..edd611d3ab6a 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -409,6 +409,59 @@ void drm_fb_xrgb_to_rgb888_toio(void __iomem *dst, 
unsigned int dst_pitch,
   }
   EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888_toio);
   
+static void drm_fb_xrgb_to_xrgb2101010_line(u32 *dbuf, const 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);


This isn't quite right. The lowest two destination bits in each
component will always be zero. You have to do the shifting as above and
for each component the two highest source bits have to be OR'ed into the
two lowest destination bits. For example the source bits in a component
are numbered 7 to 0

   | 7 6 5 4 3 2 1 0 |

then the destination bits should be

   | 7 6 5 4 3 2 1 0 7 6 |



I think both approaches have pros and cons. Leaving the two LSBs always 
at 0 yields a fully linear transfer curve with no discontinuities, but 
means the maximum brightness is slightly less than full. Setting them 
fully maps the brightness range, but creates 4 double wide steps in the 
transfer curve (also it's potentially slightly slower CPU-wise).


If you prefer the latter I'll do that for v2.

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


[PATCH v2 3/3] drm/simpledrm: Add XRGB2101010 format

2021-12-06 Thread Hector Martin
This is the format used by the bootloader framebuffer on Apple ARM64
platforms.

Reviewed-by: Thomas Zimmermann 
Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/tiny/simpledrm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 2f15b9aa..edadfd9ee882 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -571,7 +571,7 @@ static const uint32_t simpledrm_default_formats[] = {
//DRM_FORMAT_XRGB1555,
//DRM_FORMAT_ARGB1555,
DRM_FORMAT_RGB888,
-   //DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XRGB2101010,
//DRM_FORMAT_ARGB2101010,
 };
 
-- 
2.33.0



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

2021-12-06 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.

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

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index dbe3e830096e..edd611d3ab6a 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -409,6 +409,59 @@ void drm_fb_xrgb_to_rgb888_toio(void __iomem *dst, 
unsigned int dst_pitch,
 }
 EXPORT_SYMBOL(drm_fb_xrgb_to_rgb888_toio);
 
+static void drm_fb_xrgb_to_xrgb2101010_line(u32 *dbuf, const 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_toio - Convert XRGB to XRGB2101010 clip
+ * buffer
+ * @dst: XRGB2101010 destination buffer (iomem)
+ * @dst_pitch: Number of bytes between two consecutive scanlines within dst
+ * @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.
+ */
+void drm_fb_xrgb_to_xrgb2101010_toio(void __iomem *dst,
+unsigned int dst_pitch, const void 
*vaddr,
+const struct drm_framebuffer *fb,
+const struct drm_rect *clip)
+{
+   size_t linepixels = clip->x2 - clip->x1;
+   size_t dst_len = linepixels * sizeof(u32);
+   unsigned y, lines = clip->y2 - clip->y1;
+   void *dbuf;
+
+   if (!dst_pitch)
+   dst_pitch = dst_len;
+
+   dbuf = kmalloc(dst_len, GFP_KERNEL);
+   if (!dbuf)
+   return;
+
+   vaddr += clip_offset(clip, fb->pitches[0], 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_toio);
+
 /**
  * drm_fb_xrgb_to_gray8 - Convert XRGB to grayscale
  * @dst: 8-bit grayscale destination buffer
@@ -500,6 +553,10 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int 
dst_pitch, uint32_t dst_for
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_toio(dst, dst_pitch, vmap, fb, clip);
@@ -515,6 +572,11 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int 
dst_pitch, uint32_t dst_for
drm_fb_xrgb_to_rgb888_toio(dst, 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_toio(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 97e4c3223af3..b30ed5de0a33 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -33,6 +33,9 @@ void drm_fb_xrgb_to_rgb888(void *dst, unsigned int 
dst_pitch, const void *sr
 void drm_fb_xrgb_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch,
const void *vaddr, const struct 
drm_framebuffer *fb,
const struct drm_rect *clip);
+void drm_fb_xrgb_to_xrgb2101010_toio(void __iomem *dst, unsigned int 
dst_pitch,
+const void *vaddr, const struct 
drm_framebuffer *fb,
+const struct drm_rect *clip);
 void drm_fb_xrgb_to_gray8(void *dst, unsigned int dst_pitch, const void 
*vaddr,
  const struct drm_framebuffer *fb, const struct 
drm_rect *clip);
 
-- 
2.33.0



[PATCH v2 1/3] of: Move simple-framebuffer device handling from simplefb to of

2021-12-06 Thread Hector Martin
This code is required for both simplefb and simpledrm, so let's move it
into the OF core instead of having it as an ad-hoc initcall in the
drivers.

Signed-off-by: Hector Martin 
---
 drivers/of/platform.c  |  5 +
 drivers/video/fbdev/simplefb.c | 21 +
 2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b3faf89744aa..e097f40b03c0 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -540,6 +540,11 @@ static int __init of_platform_default_populate_init(void)
of_node_put(node);
}
 
+   for_each_child_of_node(of_chosen, node) {
+   if (of_device_is_compatible(node, "simple-framebuffer"))
+   of_platform_device_create(node, NULL, NULL);
+   }
+
/* Populate everything else. */
of_platform_default_populate(NULL, NULL, NULL);
 
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index b63074fd892e..57541887188b 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -541,26 +541,7 @@ static struct platform_driver simplefb_driver = {
.remove = simplefb_remove,
 };
 
-static int __init simplefb_init(void)
-{
-   int ret;
-   struct device_node *np;
-
-   ret = platform_driver_register(&simplefb_driver);
-   if (ret)
-   return ret;
-
-   if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
-   for_each_child_of_node(of_chosen, np) {
-   if (of_device_is_compatible(np, "simple-framebuffer"))
-   of_platform_device_create(np, NULL, NULL);
-   }
-   }
-
-   return 0;
-}
-
-fs_initcall(simplefb_init);
+module_platform_driver(simplefb_driver);
 
 MODULE_AUTHOR("Stephen Warren ");
 MODULE_DESCRIPTION("Simple framebuffer driver");
-- 
2.33.0



[PATCH v2 0/3] drm/simpledrm: Apple M1 / DT platform support fixes

2021-12-06 Thread Hector Martin
Hi DRM folks,

This short series makes simpledrm work on Apple M1 (including Pro/Max)
platforms the way simplefb already does, by adding XRGB2101010 support
and making it bind to framebuffers in /chosen the same way simplefb
does.

This avoids breaking the bootloader-provided framebuffer console when
simpledrm is selected to replace simplefb, as these FBs always seem to
be 10-bit (at least when a real screen is attached).

Changes since v1:
- Moved the OF platform device setup code from simplefb into common
  code, instead of duplicating it in simpledrm
- Rebased on drm-tip

Hector Martin (3):
  of: Move simple-framebuffer device handling from simplefb to of
  drm/format-helper: Add drm_fb_xrgb_to_xrgb2101010_toio()
  drm/simpledrm: Add XRGB2101010 format

 drivers/gpu/drm/drm_format_helper.c | 62 +
 drivers/gpu/drm/tiny/simpledrm.c|  2 +-
 drivers/of/platform.c   |  5 +++
 drivers/video/fbdev/simplefb.c  | 21 +-
 include/drm/drm_format_helper.h |  3 ++
 5 files changed, 72 insertions(+), 21 deletions(-)

-- 
2.33.0



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 1/3] drm/simpledrm: Bind to OF framebuffers in /chosen

2021-11-19 Thread Hector Martin

On 18/11/2021 18.19, Thomas Zimmermann wrote:

Hi

Am 17.11.21 um 15:58 schrieb Hector Martin:

@@ -897,5 +898,21 @@ static struct platform_driver simpledrm_platform_driver = {
   
   module_platform_driver(simpledrm_platform_driver);
   
+static int __init simpledrm_init(void)

+{
+   struct device_node *np;
+
+   if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
+   for_each_child_of_node(of_chosen, np) {
+   if (of_device_is_compatible(np, "simple-framebuffer"))
+   of_platform_device_create(np, NULL, NULL);
+   }
+   }
+
+   return 0;
+}
+
+fs_initcall(simpledrm_init);
+


Simpledrm is just a driver, but this is platform setup code. Why is this
code located here and not under arch/ or drivers/firmware/?

I know that other drivers do similar things, it doesn't seem to belong here.


This definitely doesn't belong in either of those, since it is not arch- 
or firmware-specific. It is implementing support for the standard 
simple-framebuffer OF binding, which specifies that it must be located 
within the /chosen node (and thus the default OF setup code won't do the 
matching for you); this applies to all OF platforms [1]


Adding Rob; do you think this should move from simplefb/simpledrm to 
common OF code? (where?)


[1] Documentation/devicetree/bindings/display/simple-framebuffer.yaml

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


Re: [PATCH] drm/format-helper: Fix dst computation in drm_fb_xrgb8888_to_rgb888_dstclip()

2021-11-17 Thread Hector Martin

On 17/11/2021 23.56, Thomas Zimmermann wrote:

Hi

Am 17.11.21 um 15:22 schrieb Hector Martin:

The dst pointer was being advanced by the clip width, not the full line
stride, resulting in corruption. The clip offset was also calculated
incorrectly.

Cc: sta...@vger.kernel.org
Signed-off-by: Hector Martin 


Thanks for your patch, but you're probably on the wrong branch. We
rewrote this code recently and fixed the issue in drm-misc-next. [1][2]


Oops. I was on linux-next as of Nov 1. Looks like I missed it by a week!

Sounds like I'm going to have to rebase/rewrite the other series I just 
sent too...


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


[PATCH 3/3] drm/simpledrm: Enable XRGB2101010 format

2021-11-17 Thread Hector Martin
This is the format used by the bootloader framebuffer on Apple ARM64
platforms, and is already supported by simplefb. This avoids regressing
on these platforms when simpledrm is enabled and replaces simplefb.

Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/tiny/simpledrm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 2c84f2ea1fa2..b4b69f3a7e79 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -571,7 +571,7 @@ static const uint32_t simpledrm_default_formats[] = {
//DRM_FORMAT_XRGB1555,
//DRM_FORMAT_ARGB1555,
DRM_FORMAT_RGB888,
-   //DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XRGB2101010,
//DRM_FORMAT_ARGB2101010,
 };
 
-- 
2.33.0



[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



[PATCH 1/3] drm/simpledrm: Bind to OF framebuffers in /chosen

2021-11-17 Thread Hector Martin
This matches the simplefb behavior; these nodes are not matched by the
standard OF machinery. This fixes a regression when simpledrm replaces
simeplefb.

Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/tiny/simpledrm.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 481b48bde047..2c84f2ea1fa2 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -2,6 +2,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -897,5 +898,21 @@ static struct platform_driver simpledrm_platform_driver = {
 
 module_platform_driver(simpledrm_platform_driver);
 
+static int __init simpledrm_init(void)
+{
+   struct device_node *np;
+
+   if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
+   for_each_child_of_node(of_chosen, np) {
+   if (of_device_is_compatible(np, "simple-framebuffer"))
+   of_platform_device_create(np, NULL, NULL);
+   }
+   }
+
+   return 0;
+}
+
+fs_initcall(simpledrm_init);
+
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL v2");
-- 
2.33.0



[PATCH 0/3] drm/simpledrm: Apple M1 / DT platform support fixes

2021-11-17 Thread Hector Martin
Hi DRM folks,

This short series makes simpledrm work on Apple M1 (including Pro/Max)
platforms the way simplefb already does, by adding XRGB2101010 support
and making it bind to framebuffers in /chosen the same way simplefb
does.

This avoids breaking the bootloader-provided framebuffer console when
simpledrm is selected to replace simplefb, as these FBs always seem to
be 10-bit (at least when a real screen is attached).

Hector Martin (3):
  drm/simpledrm: Bind to OF framebuffers in /chosen
  drm/format-helper: Add drm_fb_xrgb_to_xrgb2101010_dstclip()
  drm/simpledrm: Enable XRGB2101010 format

 drivers/gpu/drm/drm_format_helper.c | 64 +
 drivers/gpu/drm/tiny/simpledrm.c| 19 -
 include/drm/drm_format_helper.h |  4 ++
 3 files changed, 86 insertions(+), 1 deletion(-)

-- 
2.33.0



[PATCH] drm/format-helper: Fix dst computation in drm_fb_xrgb8888_to_rgb888_dstclip()

2021-11-17 Thread Hector Martin
The dst pointer was being advanced by the clip width, not the full line
stride, resulting in corruption. The clip offset was also calculated
incorrectly.

Cc: sta...@vger.kernel.org
Signed-off-by: Hector Martin 
---
 drivers/gpu/drm/drm_format_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index e676921422b8..12bc6b45e95b 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -366,12 +366,12 @@ void drm_fb_xrgb_to_rgb888_dstclip(void __iomem *dst, 
unsigned int dst_pitch
return;
 
vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32));
-   dst += clip_offset(clip, dst_pitch, sizeof(u16));
+   dst += clip_offset(clip, dst_pitch, 3);
for (y = 0; y < lines; y++) {
drm_fb_xrgb_to_rgb888_line(dbuf, vaddr, linepixels);
memcpy_toio(dst, dbuf, dst_len);
vaddr += fb->pitches[0];
-   dst += dst_len;
+   dst += dst_pitch;
}
 
kfree(dbuf);
-- 
2.33.0



Re: [PATCH 2/2] maintainers: Update freedesktop.org IRC channels

2021-05-30 Thread Hector Martin

On 30/05/2021 20.01, Lukas Wunner wrote:

On Sat, May 29, 2021 at 10:16:38AM -0400, Alyssa Rosenzweig wrote:

--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1651,7 +1651,7 @@ L:linux-arm-ker...@lists.infradead.org (moderated 
for non-subscribers)
  S:Maintained
  W:https://asahilinux.org
  B:https://github.com/AsahiLinux/linux/issues
-C: irc://chat.freenode.net/asahi-dev
+C: irc://irc.oftc.net/asahi-dev
  T:git https://github.com/AsahiLinux/linux.git
  F:Documentation/devicetree/bindings/arm/apple.yaml
  F:Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml


This isn't a freedesktop.org project, so either needs to be dropped
from the patch or the patch needs an ack from Hector Martin (+cc).


Heh, I totally forgot we had the IRC info in MAINTAINERS too when I did 
the move. Thanks :)


Acked-By: Hector Martin 

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