From 62aeaeaa1b267c5149abee6b45967a5df3feed58 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:03 +0200 Subject: drm/aperture: Remove primary argument Only really pci devices have a business setting this - it's for figuring out whether the legacy vga stuff should be nuked too. And with the preceding two patches those are all using the pci version of this. Which means for all other callers primary == false and we can remove it now. v2: - Reorder to avoid compile fail (Thomas) - Include gma500, which retained it's called to the non-pci version. v4: - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Deepak Rawat Cc: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl Cc: Thierry Reding Cc: Jonathan Hunter Cc: Emma Anholt Cc: Helge Deller Cc: David Airlie Cc: Daniel Vetter Cc: linux-hyperv@vger.kernel.org Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-tegra@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Acked-by: Martin Blumenstingl Acked-by: Thierry Reding Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-4-tzimmermann@suse.de --- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/msm/msm_fbdev.c') diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d26aa52217ce..16652a5a7018 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -155,7 +155,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) } /* the fw fb could be anywhere in memory */ - ret = drm_aperture_remove_framebuffers(false, dev->driver); + ret = drm_aperture_remove_framebuffers(dev->driver); if (ret) goto fini; -- cgit From b0c536d88ed260d75eb3076690ca9630cafd1b90 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 22 May 2023 21:17:01 +0200 Subject: drm/msm: Use struct fb_info.screen_buffer The fbdev framebuffer is in system memory. Store the address in the field 'screen_buffer'. Fixes the following sparse warning. ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: warning: incorrect type in assignment (different address spaces) ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: expected char [noderef] __iomem *screen_base ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: got void * Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230522191701.13406-1-tzimmermann@suse.de --- drivers/gpu/drm/msm/msm_fbdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/msm/msm_fbdev.c') diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 2ebc86381e1c..ce0ba6d1979a 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -121,9 +121,9 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, drm_fb_helper_fill_info(fbi, helper, sizes); - fbi->screen_base = msm_gem_get_vaddr(bo); - if (IS_ERR(fbi->screen_base)) { - ret = PTR_ERR(fbi->screen_base); + fbi->screen_buffer = msm_gem_get_vaddr(bo); + if (IS_ERR(fbi->screen_buffer)) { + ret = PTR_ERR(fbi->screen_buffer); goto fail; } fbi->screen_size = bo->size; -- cgit From 4a2262c121130026306a36888f74f0736fc3fb1c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 30 May 2023 17:12:26 +0200 Subject: drm/msm: Use regular fbdev I/O helpers Use the regular fbdev helpers for framebuffer I/O instead of DRM's helpers. Msm does not use damage handling, so DRM's fbdev helpers are mere wrappers around the fbdev code. By using fbdev helpers directly within each DRM fbdev emulation, we can eventually remove DRM's wrapper functions entirely. Msm's fbdev emulation has been incomplete as it didn't implement damage handling. Partilly fix this by implementing damage handling for write and draw operation. It is still missing for mmaped pages. v4: * use initializer macros for struct fb_ops * partially support damage handling v2: * use FB_SYS_HELPERS option Signed-off-by: Thomas Zimmermann Reviewed-by: Dmitry Baryshkov Acked-by: Sam Ravnborg Cc: Rob Clark Cc: Abhinav Kumar Cc: Dmitry Baryshkov Cc: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20230530151228.22979-12-tzimmermann@suse.de --- drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/msm_fbdev.c | 17 ++++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm/msm/msm_fbdev.c') diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 85f5ab1d552c..a78662bd6273 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -21,6 +21,7 @@ config DRM_MSM select DRM_BRIDGE select DRM_PANEL_BRIDGE select DRM_SCHED + select FB_SYS_HELPERS if DRM_FBDEV_EMULATION select SHMEM select TMPFS select QCOM_SCM diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index ce0ba6d1979a..fa9c1cbffae3 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -4,6 +4,8 @@ * Author: Rob Clark */ +#include + #include #include #include @@ -23,6 +25,10 @@ module_param(fbdev, bool, 0600); * fbdev funcs, to implement legacy fbdev interface on top of drm driver */ +FB_GEN_DEFAULT_DEFERRED_SYS_OPS(msm_fbdev, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area) + static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par; @@ -52,16 +58,9 @@ static void msm_fbdev_fb_destroy(struct fb_info *info) static const struct fb_ops msm_fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_DEFERRED_OPS_RDWR(msm_fbdev), DRM_FB_HELPER_DEFAULT_OPS, - - /* Note: to properly handle manual update displays, we wrap the - * basic fbdev ops which write to the framebuffer - */ - .fb_read = drm_fb_helper_sys_read, - .fb_write = drm_fb_helper_sys_write, - .fb_fillrect = drm_fb_helper_sys_fillrect, - .fb_copyarea = drm_fb_helper_sys_copyarea, - .fb_imageblit = drm_fb_helper_sys_imageblit, + __FB_DEFAULT_DEFERRED_OPS_DRAW(msm_fbdev), .fb_mmap = msm_fbdev_mmap, .fb_destroy = msm_fbdev_fb_destroy, }; -- cgit From fda520976ef49d3ab66f6157053b084721d86712 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 12 Jun 2023 06:16:15 +0300 Subject: drm/msm: provide fb_dirty implemenation Since commit 93e81e38e197 ("drm/fb_helper: Minimize damage-helper overhead") the drm_fb_helper_funcs::fb_dirty helper is required for proper dirty/damage processing. The drm/msm driver requires that to function to let CMD panels to work. Use simplified version of drm_fbdev_generic_helper_fb_dirty() to fix support for CMD mode panels. Reported-by: Degdag Mohamed Fixes: 93e81e38e197 ("drm/fb_helper: Minimize damage-helper overhead") Cc: Thomas Zimmermann Signed-off-by: Dmitry Baryshkov Reviewed-by: Thomas Zimmermann Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/542002/ Link: https://lore.kernel.org/r/20230612031616.3620134-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_fbdev.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu/drm/msm/msm_fbdev.c') diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index fa9c1cbffae3..b933a85420f6 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -139,8 +139,28 @@ fail: return ret; } +static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + static const struct drm_fb_helper_funcs msm_fb_helper_funcs = { .fb_probe = msm_fbdev_create, + .fb_dirty = msm_fbdev_fb_dirty, }; /* -- cgit From 27655b9bb9f0d9c32b8de8bec649b676898c52d5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 10 Jul 2023 11:10:17 +0200 Subject: drm/client: Send hotplug event after registering a client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generate a hotplug event after registering a client to allow the client to configure its display. Remove the hotplug calls from the existing clients for fbdev emulation. This change fixes a concurrency bug between registering a client and receiving events from the DRM core. The bug is present in the fbdev emulation of all drivers. The fbdev emulation currently generates a hotplug event before registering the client to the device. For each new output, the DRM core sends an additional hotplug event to each registered client. If the DRM core detects first output between sending the artificial hotplug and registering the device, the output's hotplug event gets lost. If this is the first output, the fbdev console display remains dark. This has been observed with amdgpu and fbdev-generic. Fix this by adding hotplug generation directly to the client's register helper drm_client_register(). Registering the client and receiving events are serialized by struct drm_device.clientlist_mutex. So an output is either configured by the initial hotplug event, or the client has already been registered. The bug was originally added in commit 6e3f17ee73f7 ("drm/fb-helper: generic: Call drm_client_add() after setup is done"), in which adding a client and receiving a hotplug event switched order. It was hidden, as most hardware and drivers have at least on static output configured. Other drivers didn't use the internal DRM client or still had struct drm_mode_config_funcs.output_poll_changed set. That callback handled hotplug events as well. After not setting the callback in amdgpu in commit 0e3172bac3f4 ("drm/amdgpu: Don't set struct drm_driver.output_poll_changed"), amdgpu did not show a framebuffer console if output events got lost. The bug got copy-pasted from fbdev-generic into the other fbdev emulation. Reported-by: Moritz Duge Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2649 Fixes: 6e3f17ee73f7 ("drm/fb-helper: generic: Call drm_client_add() after setup is done") Fixes: 8ab59da26bc0 ("drm/fb-helper: Move generic fbdev emulation into separate source file") Fixes: b79fe9abd58b ("drm/fbdev-dma: Implement fbdev emulation for GEM DMA helpers") Fixes: 63c381552f69 ("drm/armada: Implement fbdev emulation as in-kernel client") Fixes: 49953b70e7d3 ("drm/exynos: Implement fbdev emulation as in-kernel client") Fixes: 8f1aaccb04b7 ("drm/gma500: Implement client-based fbdev emulation") Fixes: 940b869c2f2f ("drm/msm: Implement fbdev emulation as in-kernel client") Fixes: 9e69bcd88e45 ("drm/omapdrm: Implement fbdev emulation as in-kernel client") Fixes: e317a69fe891 ("drm/radeon: Implement client-based fbdev emulation") Fixes: 71ec16f45ef8 ("drm/tegra: Implement fbdev emulation as in-kernel client") Fixes: 0e3172bac3f4 ("drm/amdgpu: Don't set struct drm_driver.output_poll_changed") Signed-off-by: Thomas Zimmermann Tested-by: Moritz Duge Tested-by: Torsten Krah Tested-by: Paul Schyska Cc: Daniel Vetter Cc: David Airlie Cc: Noralf Trønnes Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Javier Martinez Canillas Cc: Russell King Cc: Inki Dae Cc: Seung-Woo Kim Cc: Kyungmin Park Cc: Krzysztof Kozlowski Cc: Patrik Jakobsson Cc: Rob Clark Cc: Abhinav Kumar Cc: Dmitry Baryshkov Cc: Tomi Valkeinen Cc: Alex Deucher Cc: "Christian König" Cc: "Pan, Xinhui" Cc: Thierry Reding Cc: Mikko Perttunen Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: amd-gfx@lists.freedesktop.org Cc: linux-tegra@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: # v5.2+ Reviewed-by: Javier Martinez Canillas Reviewed-by: Dmitry Baryshkov # msm Link: https://patchwork.freedesktop.org/patch/msgid/20230710091029.27503-1-tzimmermann@suse.de --- drivers/gpu/drm/armada/armada_fbdev.c | 4 ---- drivers/gpu/drm/drm_client.c | 21 +++++++++++++++++++++ drivers/gpu/drm/drm_fbdev_dma.c | 4 ---- drivers/gpu/drm/drm_fbdev_generic.c | 4 ---- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 4 ---- drivers/gpu/drm/gma500/fbdev.c | 4 ---- drivers/gpu/drm/msm/msm_fbdev.c | 4 ---- drivers/gpu/drm/omapdrm/omap_fbdev.c | 4 ---- drivers/gpu/drm/radeon/radeon_fbdev.c | 4 ---- drivers/gpu/drm/tegra/fbdev.c | 4 ---- 10 files changed, 21 insertions(+), 36 deletions(-) (limited to 'drivers/gpu/drm/msm/msm_fbdev.c') diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index 3943e89cc06c..e40a95e51785 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -209,10 +209,6 @@ void armada_fbdev_setup(struct drm_device *dev) goto err_drm_client_init; } - ret = armada_fbdev_client_hotplug(&fbh->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&fbh->client); return; diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index f6292ba0e6fc..037e36f2049c 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -122,13 +122,34 @@ EXPORT_SYMBOL(drm_client_init); * drm_client_register() it is no longer permissible to call drm_client_release() * directly (outside the unregister callback), instead cleanup will happen * automatically on driver unload. + * + * Registering a client generates a hotplug event that allows the client + * to set up its display from pre-existing outputs. The client must have + * initialized its state to able to handle the hotplug event successfully. */ void drm_client_register(struct drm_client_dev *client) { struct drm_device *dev = client->dev; + int ret; mutex_lock(&dev->clientlist_mutex); list_add(&client->list, &dev->clientlist); + + if (client->funcs && client->funcs->hotplug) { + /* + * Perform an initial hotplug event to pick up the + * display configuration for the client. This step + * has to be performed *after* registering the client + * in the list of clients, or a concurrent hotplug + * event might be lost; leaving the display off. + * + * Hold the clientlist_mutex as for a regular hotplug + * event. + */ + ret = client->funcs->hotplug(client); + if (ret) + drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); + } mutex_unlock(&dev->clientlist_mutex); } EXPORT_SYMBOL(drm_client_register); diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index 76aa52b38a13..f353daff65e1 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -252,10 +252,6 @@ void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp) goto err_drm_client_init; } - ret = drm_fbdev_dma_client_hotplug(&fb_helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&fb_helper->client); return; diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c index 98ae703848a0..b9343fb6cf13 100644 --- a/drivers/gpu/drm/drm_fbdev_generic.c +++ b/drivers/gpu/drm/drm_fbdev_generic.c @@ -339,10 +339,6 @@ void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) goto err_drm_client_init; } - ret = drm_fbdev_generic_client_hotplug(&fb_helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&fb_helper->client); return; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index fdf65587f1fe..226310c765d8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -215,10 +215,6 @@ void exynos_drm_fbdev_setup(struct drm_device *dev) if (ret) goto err_drm_client_init; - ret = exynos_drm_fbdev_client_hotplug(&fb_helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&fb_helper->client); return; diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c index 955cbe9f05a7..054426549fc6 100644 --- a/drivers/gpu/drm/gma500/fbdev.c +++ b/drivers/gpu/drm/gma500/fbdev.c @@ -328,10 +328,6 @@ void psb_fbdev_setup(struct drm_psb_private *dev_priv) goto err_drm_fb_helper_unprepare; } - ret = psb_fbdev_client_hotplug(&fb_helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&fb_helper->client); return; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index b933a85420f6..bf1e17dc4550 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -246,10 +246,6 @@ void msm_fbdev_setup(struct drm_device *dev) goto err_drm_fb_helper_unprepare; } - ret = msm_fbdev_client_hotplug(&helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&helper->client); return; diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index b7ccce0704a3..fe6639c1cdf3 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -318,10 +318,6 @@ void omap_fbdev_setup(struct drm_device *dev) INIT_WORK(&fbdev->work, pan_worker); - ret = omap_fbdev_client_hotplug(&helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&helper->client); return; diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c index ab9c1abbac97..f941e2e7cae6 100644 --- a/drivers/gpu/drm/radeon/radeon_fbdev.c +++ b/drivers/gpu/drm/radeon/radeon_fbdev.c @@ -383,10 +383,6 @@ void radeon_fbdev_setup(struct radeon_device *rdev) goto err_drm_client_init; } - ret = radeon_fbdev_client_hotplug(&fb_helper->client); - if (ret) - drm_dbg_kms(rdev->ddev, "client hotplug ret=%d\n", ret); - drm_client_register(&fb_helper->client); return; diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c index e74d9be981c7..d042234e1807 100644 --- a/drivers/gpu/drm/tegra/fbdev.c +++ b/drivers/gpu/drm/tegra/fbdev.c @@ -225,10 +225,6 @@ void tegra_fbdev_setup(struct drm_device *dev) if (ret) goto err_drm_client_init; - ret = tegra_fbdev_client_hotplug(&helper->client); - if (ret) - drm_dbg_kms(dev, "client hotplug ret=%d\n", ret); - drm_client_register(&helper->client); return; -- cgit