From: Tomi Valkeinen tomi.valkeinen@ideasonboard.com
[ Upstream commit 942e54a372b44da3ffb0191b4d289d476256c861 ]
Add a call to drm_aperture_remove_framebuffers() to drop the possible early fb (simplefb).
Reviewed-by: Javier Martinez Canillas javierm@redhat.com Link: https://lore.kernel.org/r/20250416-tidss-splash-v1-2-4ff396eb5008@ideasonboa... Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
Why this is a bug fix that helps users - Removes firmware/early framebuffer (e.g., simplefb) so TIDSS can take over display cleanly. Without this, users can see takeover failures, flicker, or double-bound consoles when the SoC boots with a splash/firmware FB and then loads the real DRM driver. This is a common class of issues addressed in many DRM drivers.
What the change does - Adds `#include <linux/aperture.h>` to use the aperture helpers (drivers/gpu/drm/tidss/tidss_drv.c). - Calls `aperture_remove_all_conflicting_devices(tidss_driver.name)` after successful device registration and before setting up the DRM client/fbdev to explicitly drop early FBs (simplefb). In the posted diff this is placed after `drm_dev_register()` and before the fbdev/client setup call, matching the documented ordering for `drm_client_setup()`. - Adds an error path (`err_drm_dev_unreg:`) to unwind with `drm_dev_unregister(ddev)` if removal unexpectedly fails.
Evidence this is the right pattern - The kernel already provides standard helpers for this exact purpose and other SoC DRM drivers use them in probe/bind: - `drivers/gpu/drm/sun4i/sun4i_drv.c:101`: `drm_aperture_remove_framebuffers(&sun4i_drv_driver);` - `drivers/gpu/drm/rockchip/rockchip_drm_drv.c:148`: `drm_aperture_remove_framebuffers(&rockchip_drm_driver);` - `drivers/gpu/drm/stm/drv.c:191`, `drivers/gpu/drm/vc4/vc4_drv.c:359`, etc. - Aperture helpers are specifically designed to hot-unplug firmware fb drivers and prevent sysfb from re-registering them (drivers/video/aperture.c). The wrapper used here (`aperture_remove_all_conflicting_devices`) is equivalent in intent to `drm_aperture_remove_framebuffers()` and is safe even if CONFIG_APERTURE_HELPERS=n (it is a no-op stub that returns 0).
Scope, risk, and side effects - Small, localized to a single driver. No architectural changes. - Only affects takeover of early/firmware framebuffers; normal operation otherwise unchanged. - Error handling is conservative: on failure it unregisters the DRM device and unwinds. In practice, the current implementation of `aperture_remove_conflicting_devices()` for non-PCI platforms returns 0 (and performs the detach), so the new error path should not trigger. - This follows the long-standing DRM takeover model; many drivers rely on exactly this call to avoid conflicts with simplefb/efifb/vesafb.
Stable backport considerations - This is a classic stable-friendly fix: improves reliability of display takeover; minimal risk; contained to a driver; no new features. - The specific helper used in the patch (`aperture_remove_all_conflicting_devices`) lives in `include/linux/aperture.h` and exists in 6.1+; for older stable trees (e.g., 5.10/5.15), use the DRM helper instead: - `drm_aperture_remove_framebuffers(&tidss_driver);` (include `drm/drm_aperture.h`) - Placement must remain before the fbdev/client setup for the DRM device: - In current trees using `drm_client_setup()`: keep it after `drm_dev_register()` and before `drm_client_setup()`. - In older trees using `drm_fbdev_dma_setup()` (e.g., drivers/gpu/drm/tidss/tidss_drv.c:189): insert removal between `drm_dev_register()` (drivers/gpu/drm/tidss/tidss_drv.c:183) and fbdev setup (drivers/gpu/drm/tidss/tidss_drv.c:189). - The posted diff also shows `#include "tidss_oldi.h"` and a `tidss_oldi_deinit(tidss)` call in an error path; those appear to be from adjacent series and are not required to deliver the early-FB removal. For minimal-risk stable backports, restrict the change to adding the early FB removal call and associated include, and keep existing error handling as-is unless those oldi changes already exist in the target stable branch.
Conclusion - This is a low-risk, targeted fix that aligns TIDSS with standard DRM takeover practices, prevents conflicts with early/simplefb framebuffers, and improves user experience on TI SoCs that boot with a splash/firmware FB. It is suitable for stable backporting, with minor API adaptation on older series as noted.
drivers/gpu/drm/tidss/tidss_drv.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index a1b12e52aca47..27d9a8fd541fc 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -8,6 +8,7 @@ #include <linux/of.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/aperture.h>
#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic.h> @@ -192,12 +193,20 @@ static int tidss_probe(struct platform_device *pdev) goto err_irq_uninstall; }
+ /* Remove possible early fb before setting up the fbdev */ + ret = aperture_remove_all_conflicting_devices(tidss_driver.name); + if (ret) + goto err_drm_dev_unreg; + drm_client_setup(ddev, NULL);
dev_dbg(dev, "%s done\n", __func__);
return 0;
+err_drm_dev_unreg: + drm_dev_unregister(ddev); + err_irq_uninstall: tidss_irq_uninstall(ddev);