Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 0/7] drm: Fix the color-depth/bpp confusion
A number of drivers mix up the meaning of bits-per-pixel and color depth. For each of them, set the correct values. As a rule of thumb, the color depth is the number of color and alpha bits that affect image composition. The bpp value is the color depth in the pixel plus the filler bits. The color depth is exported to userspace, while the bpp value only affects fbdev emulation. Currently, fbdev fails if it selects a color format that is unsupported by the driver. The fix would be to fall back to a driver default value for the bpp. Getting the default fixed in drivers will then allow us to fix the fbdev format selection. v2: * leave out 15-bit color in logicvc (Javier) * minor typos (Javier) Thomas Zimmermann (7): drm/hisilicon/hibmc: Fix preferred depth and bpp drm/logicvc: Fix preferred fbdev cpp drm/cirrus: Decouple fbdev bpp value from color depth drm/ofdrm: Set preferred depth from format of scanout buffer drm/simpledrm: Set preferred depth from format of scanout buffer drm/solomon: Set preferred color depth and bpp to the correct values drm/fb-helper: Don't use the preferred depth for the BPP default drivers/gpu/drm/drm_fbdev_generic.c | 15 +++++++++------ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 ++-- drivers/gpu/drm/logicvc/logicvc_drm.c | 13 ++++++++++++- drivers/gpu/drm/solomon/ssd130x.c | 4 ++-- drivers/gpu/drm/tiny/cirrus.c | 2 +- drivers/gpu/drm/tiny/ofdrm.c | 13 +------------ drivers/gpu/drm/tiny/simpledrm.c | 4 ++-- 7 files changed, 29 insertions(+), 26 deletions(-) -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 1/7] drm/hisilicon/hibmc: Fix preferred depth and bpp
Set the preferred color depth to 24 bits and the fbdev bpp to 32 bits. This will signal XRGB8888 as default format to clients. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 22053c613644a..0c4aa4d9b0a77 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -106,7 +106,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) dev->mode_config.max_width = 1920; dev->mode_config.max_height = 1200; - dev->mode_config.preferred_depth = 32; + dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; dev->mode_config.funcs = (void *)&hibmc_mode_funcs; @@ -340,7 +340,7 @@ static int hibmc_pci_probe(struct pci_dev *pdev, goto err_unload; } - drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth); + drm_fbdev_generic_setup(dev, 32); return 0; -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 2/7] drm/logicvc: Fix preferred fbdev cpp
Logicvc can have different values for the preferred color depth. Set the fbdev bpp value depending on the runtime value. v2: * remove unused color depth of 15 from switch (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/logicvc/logicvc_drm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c index 9de24d9f0c963..2fb23697740a2 100644 --- a/drivers/gpu/drm/logicvc/logicvc_drm.c +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c @@ -301,6 +301,7 @@ static int logicvc_drm_probe(struct platform_device *pdev) struct regmap *regmap = NULL; struct resource res; void __iomem *base; + unsigned int preferred_bpp; int irq; int ret; @@ -438,7 +439,17 @@ static int logicvc_drm_probe(struct platform_device *pdev) goto error_mode; } - drm_fbdev_generic_setup(drm_dev, drm_dev->mode_config.preferred_depth); + switch (drm_dev->mode_config.preferred_depth) { + case 16: + preferred_bpp = 16; + break; + case 24: + case 32: + default: + preferred_bpp = 32; + break; + } + drm_fbdev_generic_setup(drm_dev, preferred_bpp); return 0; -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 3/7] drm/cirrus: Decouple fbdev bpp value from color depth
Cirrus has a preferred color depth of 16 bit; also use it as fbdev bpp value. Don't use the color depth directly. It has a different meaning than bpp and both cannot be used interchangeably. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/tiny/cirrus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 678c2ef1cae70..cf35b60905032 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -604,7 +604,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev, if (ret) return ret; - drm_fbdev_generic_setup(dev, dev->mode_config.preferred_depth); + drm_fbdev_generic_setup(dev, 16); return 0; } -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 4/7] drm/ofdrm: Set preferred depth from format of scanout buffer
Set the preferred depth from the format of the scanout buffer. The value cannot be hardcoded, as the scanout buffer is only known at runtime. Keeping the existing switch statement just duplicates the driver's existing logic for format detection. Also remove the FIXME comment from the call to drm_fbdev_generic_setup() as the driver now handles color depth and bpp values correctly. v2: * fix commit-message typo Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/tiny/ofdrm.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index dc9e4d71b12ae..33eefeba437c5 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -1284,14 +1284,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, dev->mode_config.min_height = height; dev->mode_config.max_height = max_height; dev->mode_config.funcs = &ofdrm_mode_config_funcs; - switch (depth) { - case 32: - dev->mode_config.preferred_depth = 24; - break; - default: - dev->mode_config.preferred_depth = depth; - break; - } + dev->mode_config.preferred_depth = format->depth; dev->mode_config.quirk_addfb_prefer_host_byte_order = true; /* Primary plane */ @@ -1390,10 +1383,6 @@ static int ofdrm_probe(struct platform_device *pdev) if (ret) return ret; - /* - * FIXME: 24-bit color depth does not work reliably with a 32-bpp - * value. Force the bpp value of the scanout buffer's format. - */ drm_fbdev_generic_setup(dev, drm_format_info_bpp(odev->format, 0)); return 0; -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 5/7] drm/simpledrm: Set preferred depth from format of scanout buffer
Set the preferred depth from the format of the scanout buffer. The value cannot be hardcoded, as the scanout buffer is only known at runtime. Also derive the fbdev emulation's bpp value from the scanout format. v2: * fix commit-message typo Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- 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 162eb44dcba89..30e928d627e8f 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -739,7 +739,7 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, dev->mode_config.max_width = max_width; dev->mode_config.min_height = height; dev->mode_config.max_height = max_height; - dev->mode_config.preferred_depth = format->cpp[0] * 8; + dev->mode_config.preferred_depth = format->depth; dev->mode_config.funcs = &simpledrm_mode_config_funcs; /* Primary plane */ @@ -834,7 +834,7 @@ static int simpledrm_probe(struct platform_device *pdev) if (ret) return ret; - drm_fbdev_generic_setup(dev, 0); + drm_fbdev_generic_setup(dev, drm_format_info_bpp(sdev->format, 0)); return 0; } -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 6/7] drm/solomon: Set preferred color depth and bpp to the correct values
Set the preferred color depth to 24 bits and the fbdev bpp to 32 bits. This will signal XRGB8888 as default format to clients. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/solomon/ssd130x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 53464afc2b9ac..c3bf3a18302ea 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -876,7 +876,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) drm->mode_config.max_width = max_width; drm->mode_config.min_height = mode->vdisplay; drm->mode_config.max_height = max_height; - drm->mode_config.preferred_depth = 32; + drm->mode_config.preferred_depth = 24; drm->mode_config.funcs = &ssd130x_mode_config_funcs; /* Primary plane */ @@ -1006,7 +1006,7 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) if (ret) return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n")); - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_generic_setup(drm, 32); return ssd130x; } -- 2.38.1
Thomas Zimmermann
2022-Nov-23 11:53 UTC
[PATCH v2 7/7] drm/fb-helper: Don't use the preferred depth for the BPP default
If no preferred value for bits-per-pixel has been given, fall back to 32. Never use the preferred depth. The color depth is the number of color/alpha bits per pixel, while bpp is the overall number of bits in most cases. Most noteworthy, XRGB8888 has a depth of 24 and a bpp value of 32. Using depth for bpp would make the value 24 as well and format selection in fbdev helpers fails. Unfortunately XRGB8888 is the most common format and the old heuristic therefore fails for most of the drivers (unless they implement the 24-bit RGB888 format). Picking a bpp of 32 will later on result in a default depth of 24 and the format XRGB8888. As XRGB8888 is the default format for most of the current and legacy graphics stack, all drivers must support it. So it is the safe choice. v2: * fix commit-message typo (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/drm_fbdev_generic.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c index ab86956692795..0a4c160e0e58a 100644 --- a/drivers/gpu/drm/drm_fbdev_generic.c +++ b/drivers/gpu/drm/drm_fbdev_generic.c @@ -431,7 +431,6 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = { * drm_fbdev_generic_setup() - Setup generic fbdev emulation * @dev: DRM device * @preferred_bpp: Preferred bits per pixel for the device. - * @dev->mode_config.preferred_depth is used if this is zero. * * This function sets up generic fbdev emulation for drivers that supports * dumb buffers with a virtual address and that can be mmap'ed. @@ -475,12 +474,16 @@ void drm_fbdev_generic_setup(struct drm_device *dev, } /* - * FIXME: This mixes up depth with bpp, which results in a glorious - * mess, resulting in some drivers picking wrong fbdev defaults and - * others wrong preferred_depth defaults. + * Pick a preferred bpp of 32 if no value has been given. This + * will select XRGB8888 for the framebuffer formats. All drivers + * have to support XRGB8888 for backwards compatibility with legacy + * userspace, so it's the safe choice here. + * + * TODO: Replace struct drm_mode_config.preferred_depth and this + * bpp value with a preferred format that is given as struct + * drm_format_info. Then derive all other values from the + * format. */ - if (!preferred_bpp) - preferred_bpp = dev->mode_config.preferred_depth; if (!preferred_bpp) preferred_bpp = 32; fb_helper->preferred_bpp = preferred_bpp; -- 2.38.1