All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: Jani Nikula <jani.nikula@linux.intel.com>,
	javierm@redhat.com, ardb@kernel.org, ilias.apalodimas@linaro.org,
	maarten.lankhorst@linux.intel.com, mripard@kernel.org,
	simona@ffwll.ch, airlied@gmail.com
Cc: dri-devel@lists.freedesktop.org, linux-efi@vger.kernel.org,
	sashiko-reviews@lists.linux.dev
Subject: Re: [PATCH v2 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks
Date: Mon, 31 Aug 2026 15:43:13 +0200	[thread overview]
Message-ID: <abe7ae7c-9df7-44d2-8760-2378fc72cf38@suse.de> (raw)
In-Reply-To: <81d5820013693b38a88084d6818c5809373c16c2@intel.com>

Hi

Am 31.08.26 um 15:23 schrieb Jani Nikula:
> On Mon, 31 Aug 2026, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> Sysfb drivers currently use the given display mode for looking up the
>> panel orientation. But the look-up table stores the native geometry of
>> the panels, so the lookup fails if the current mode sizes differs.
>>
>> Get the panel's native geometry with drm_edid_get_preferred_size() from
>> the EDID and use it for looking up the panel orientation.
>>
>> v2:
>> - ofdrm: validate EDID header before using it (Sashiko)
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
>> ---
>>   drivers/gpu/drm/sysfb/efidrm.c  | 17 ++++++++++++++++-
>>   drivers/gpu/drm/sysfb/ofdrm.c   | 18 ++++++++++++++++--
>>   drivers/gpu/drm/sysfb/vesadrm.c | 17 ++++++++++++++++-
>>   3 files changed, 48 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c
>> index 3f9cd5d03efb..7a7d12003304 100644
>> --- a/drivers/gpu/drm/sysfb/efidrm.c
>> +++ b/drivers/gpu/drm/sysfb/efidrm.c
>> @@ -152,6 +152,7 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
>>   	const struct screen_info *si;
>>   	const struct drm_format_info *format;
>>   	int width, height, stride;
>> +	unsigned int panel_width, panel_height;
>>   	s64 vsize;
>>   	u64 mem_flags;
>>   	struct resource resbuf;
>> @@ -217,6 +218,20 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
>>   	if (drm_edid_header_is_valid(dpy->edid.dummy) == 8)
>>   		sysfb->edid = dpy->edid.dummy;
>>   #endif
>> +
>> +	panel_width = width;
>> +	panel_height = height;
>> +
>> +	if (sysfb->edid) {
>> +		const struct drm_edid *drm_edid;
>> +
>> +		drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH);
>> +		if (drm_edid) {
>> +			drm_edid_get_preferred_size(drm_edid, &panel_width, &panel_height);
>> +			drm_edid_free(drm_edid);
>> +		}
>> +	}
>> +
> Unrelated to the patch at hand, but does all of this code assume EDID is
> always just one block? Scary. The whole sysfs->edid being a u8 pointer
> without size feels like a footgun.

For UEFI and VESA it's always one block of 128 bytes in size. The boot 
parameters hard-code this value and there's no space for additional 
blocks. [1]  On OpenFirmware, ofdrm checks the size to be EDID_LENGTH. 
[2] I guess there could more blocks there, but AFAIK the DT property 
only exists on ancient PPC MACs. I have no means of testing, but the 
test file I obtained from such a system is 128 bytes.

[1] 
https://elixir.bootlin.com/linux/v7.2.2/source/arch/x86/include/uapi/asm/bootparam.h#L133
[2] 
https://elixir.bootlin.com/linux/v7.2.2/source/drivers/gpu/drm/sysfb/ofdrm.c#L229


>
> Here, the above should work, but I've been kind of hoping to eradicate
> EDID_LENGTH assumptions and calculations from everywhere outside of
> drm_edid.c, because it's complicated.

We need some way of importing the raw data block into drm_edid.c, which 
in turn needs the buffer size. The drivers could do this without 
EDID_LENGTH if that helps. Note that the drivers use the regular 
machinery from drm_edid.c for dissecting the EDID block. See [3].

[3] 
https://elixir.bootlin.com/linux/v7.2.2/source/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c#L594

Best regards
Thomas


>
>
> BR,
> Jani.
>
>
>>   	sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0);
>>   	sysfb->fb_format = format;
>>   	sysfb->fb_pitch = stride;
>> @@ -340,7 +355,7 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
>>   	drm_connector_helper_add(connector, &efidrm_connector_helper_funcs);
>>   	drm_connector_set_panel_orientation_with_quirk(connector,
>>   						       DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
>> -						       width, height);
>> +						       panel_width, panel_height);
>>   	if (sysfb->edid)
>>   		drm_connector_attach_edid_property(connector);
>>   
>> diff --git a/drivers/gpu/drm/sysfb/ofdrm.c b/drivers/gpu/drm/sysfb/ofdrm.c
>> index 9d60db45139c..a0a865aee098 100644
>> --- a/drivers/gpu/drm/sysfb/ofdrm.c
>> +++ b/drivers/gpu/drm/sysfb/ofdrm.c
>> @@ -229,7 +229,7 @@ static const u8 *display_get_edid_of(struct drm_device *dev, struct device_node
>>   {
>>   	int ret = of_property_read_u8_array(of_node, "EDID", buf, EDID_LENGTH);
>>   
>> -	if (ret)
>> +	if (ret || drm_edid_header_is_valid(buf) != 8)
>>   		return NULL;
>>   	return buf;
>>   }
>> @@ -828,6 +828,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
>>   	enum ofdrm_model model;
>>   	bool big_endian;
>>   	int width, height, depth, linebytes;
>> +	unsigned int panel_width, panel_height;
>>   	const struct drm_format_info *format;
>>   	u64 address;
>>   	const u8 *edid;
>> @@ -998,6 +999,19 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
>>   		sysfb->fb_gamma_lut_size = OFDRM_GAMMA_LUT_SIZE;
>>   	sysfb->edid = edid;
>>   
>> +	panel_width = width;
>> +	panel_height = height;
>> +
>> +	if (sysfb->edid) {
>> +		const struct drm_edid *drm_edid;
>> +
>> +		drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH);
>> +		if (drm_edid) {
>> +			drm_edid_get_preferred_size(drm_edid, &panel_width, &panel_height);
>> +			drm_edid_free(drm_edid);
>> +		}
>> +	}
>> +
>>   	drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sysfb->fb_mode));
>>   	drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, linebytes=%d byte\n",
>>   		&format->format, width, height, linebytes);
>> @@ -1069,7 +1083,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
>>   	drm_connector_helper_add(connector, &ofdrm_connector_helper_funcs);
>>   	drm_connector_set_panel_orientation_with_quirk(connector,
>>   						       DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
>> -						       width, height);
>> +						       panel_width, panel_height);
>>   	if (edid)
>>   		drm_connector_attach_edid_property(connector);
>>   
>> diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c
>> index 6a67b2d2e451..8c52bbac6d2f 100644
>> --- a/drivers/gpu/drm/sysfb/vesadrm.c
>> +++ b/drivers/gpu/drm/sysfb/vesadrm.c
>> @@ -402,6 +402,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
>>   	const struct screen_info *si;
>>   	const struct drm_format_info *format;
>>   	int width, height, stride;
>> +	unsigned int panel_width, panel_height;
>>   	s64 vsize;
>>   	struct resource resbuf;
>>   	struct resource *res;
>> @@ -484,6 +485,20 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
>>   	if (drm_edid_header_is_valid(dpy->edid.dummy) == 8)
>>   		sysfb->edid = dpy->edid.dummy;
>>   #endif
>> +
>> +	panel_width = width;
>> +	panel_height = height;
>> +
>> +	if (sysfb->edid) {
>> +		const struct drm_edid *drm_edid;
>> +
>> +		drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH);
>> +		if (drm_edid) {
>> +			drm_edid_get_preferred_size(drm_edid, &panel_width, &panel_height);
>> +			drm_edid_free(drm_edid);
>> +		}
>> +	}
>> +
>>   	sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0);
>>   	sysfb->fb_format = format;
>>   	sysfb->fb_pitch = stride;
>> @@ -585,7 +600,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
>>   	drm_connector_helper_add(connector, &vesadrm_connector_helper_funcs);
>>   	drm_connector_set_panel_orientation_with_quirk(connector,
>>   						       DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
>> -						       width, height);
>> +						       panel_width, panel_height);
>>   	if (sysfb->edid)
>>   		drm_connector_attach_edid_property(connector);

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, (HRB 36809, AG Nürnberg)



  reply	other threads:[~2026-08-31 13:43 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31  9:27 [PATCH v2 0/3] sysfb: Fix display output on Lenovo D330 (and others) Thomas Zimmermann
2026-08-31  9:27 ` [PATCH v2 1/3] firmware/sysfb: Remove rotation quirk for Lenovo D330 Thomas Zimmermann
2026-08-31  9:47   ` sashiko-bot
2026-08-31 12:49   ` Jani Nikula
2026-08-31 13:23     ` Thomas Zimmermann
2026-08-31 13:32       ` Jani Nikula
2026-08-31  9:27 ` [PATCH v2 2/3] drm/edid: Add drm_edid_get_preferred_size() Thomas Zimmermann
2026-08-31 13:13   ` Jani Nikula
2026-08-31 13:31     ` Thomas Zimmermann
2026-08-31 13:36       ` Jani Nikula
2026-08-31 16:56       ` Jani Nikula
2026-08-31  9:27 ` [PATCH v2 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks Thomas Zimmermann
2026-08-31 13:23   ` Jani Nikula
2026-08-31 13:43     ` Thomas Zimmermann [this message]
2026-08-31 14:11       ` Jani Nikula

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=abe7ae7c-9df7-44d2-8760-2378fc72cf38@suse.de \
    --to=tzimmermann@suse.de \
    --cc=airlied@gmail.com \
    --cc=ardb@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ilias.apalodimas@linaro.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=javierm@redhat.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=simona@ffwll.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.