Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 00/23] drm/fb-helper: Untangle fbdev emulation and helpers
Separate generic fbdev emulation from the helper code that is shared among the various fbdev implementations within DRM. Affects many drivers. It has become apparent that our fully generic fbdev emulation will never produce optimal results for all drivers. In its current form, it is also hard to maintain. The goal of this patchset is to improve readability and streamline the fbdev helper code within DRM. In the long term, we want to get to a point where drivers or memory managers can pick and combine the various helpers for optimal fbdev support. Patches 1 to 8 start by preparing drivers. Setting struct drm_driver's lastclose and output_poll_changed is not required by generic fbdev emulation. Two drivers depend on fb helpers implicitly including other Linux header files. Fixing this in patches 9 and 10 allows to remove unnecesary include statements from the fb-helper header in patch 11. Do some renaming in patches 12 to 14. There are currently various implementation of the fbdev I/O helpers with varying feature sets. The fb helpers for fbdev I/O should all call fb_sync, which is what fbdev's internal implementation does. For DRM, damage handling needs to be performed after updating a framebuffer. The damage worker is part of the fb helpers, but the actual update logic only works with generic fbdev emulation. Separate the two, which also gives other drivers an option to set their own damage handling if neccessary. The full-featured I/O helpers can be moved under a shared implementation and called by all drivers. Patches 15 to 18 resolve these issues. Patch 19 changes fbdev disablement to work at the level of display detection. If disabled, generic fbdev emulation will be initialized, but no display will be detected. It can later be enabled by changing the parameter in sysfs and plugging in a connector. Patches 20 to 22 move the generic fbdev emulation into their own source and header files and clean up the include statements throughout DRM. Many drivers only call drm_fbdev_generic_setup() and can avoid including other Linux header files. Patch 23 is a documentation update. Built on x86-64, aarch64, arm, ppc64le. Tested with various combinations of bochs, i915, simpledrm. v3: * documentation fixes (Javier) * rename drm_fbdev.{c,h} to drm_fbdev_generic.{c,h} * keep drm_leak_fbdev_smem in drm_fb_helper.c * fix several include statements * rebases v2: * fixed commit descriptions (Christian, Sergey) Thomas Zimmermann (23): drm/komeda: Don't set struct drm_driver.lastclose drm/mcde: Don't set struct drm_driver.lastclose drm/vboxvideo: Don't set struct drm_driver.lastclose drm/amdgpu: Don't set struct drm_driver.output_poll_changed drm/imx/dcss: Don't set struct drm_driver.output_poll_changed drm/ingenic: Don't set struct drm_driver.output_poll_changed drm/logicvc: Don't set struct drm_driver.output_poll_changed drm/rockchip: Don't set struct drm_driver.output_poll_changed drm/panel-ili9341: Include <linux/backlight.h> drm/tve200: Include <linux/of.h> drm/fb-helper: Cleanup include statements in header file drm/fb_helper: Rename field fbdev to info in struct drm_fb_helper drm/fb-helper: Rename drm_fb_helper_alloc_fbi() to use _info postfix drm/fb-helper: Rename drm_fb_helper_unregister_fbi() to use _info postfix drm/fb-helper: Disconnect damage worker from update logic drm/fb-helper: Call fb_sync in I/O functions drm/fb-helper: Perform all fbdev I/O with the same implementation drm/fb_helper: Minimize damage-helper overhead drm/fb-helper: Always initialize generic fbdev emulation drm/fb-helper: Set flag in struct drm_fb_helper for leaking physical addresses drm/fb-helper: Move generic fbdev emulation into separate source file drm/fb-helper: Remove unnecessary include statements drm/fb-helper: Clarify use of last_close and output_poll_changed drivers/gpu/drm/Makefile | 4 +- .../gpu/drm/amd/amdgpu/amdgpu_connectors.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 1 - drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 1 + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 - .../gpu/drm/arm/display/komeda/komeda_drv.c | 2 +- .../gpu/drm/arm/display/komeda/komeda_kms.c | 2 - drivers/gpu/drm/arm/hdlcd_crtc.c | 1 - drivers/gpu/drm/arm/hdlcd_drv.c | 2 +- drivers/gpu/drm/arm/malidp_drv.c | 2 +- drivers/gpu/drm/armada/armada_fbdev.c | 6 +- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 2 +- drivers/gpu/drm/ast/ast_drv.c | 1 + drivers/gpu/drm/ast/ast_drv.h | 1 - drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +- drivers/gpu/drm/bridge/tc358762.c | 2 +- drivers/gpu/drm/drm_crtc_helper.c | 1 - drivers/gpu/drm/drm_fb_helper.c | 1008 ++++++----------- drivers/gpu/drm/drm_fbdev_generic.c | 493 ++++++++ drivers/gpu/drm/drm_gem_framebuffer_helper.c | 1 - drivers/gpu/drm/drm_probe_helper.c | 1 - drivers/gpu/drm/etnaviv/etnaviv_drv.h | 3 +- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 6 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 +- drivers/gpu/drm/gma500/framebuffer.c | 6 +- drivers/gpu/drm/gud/gud_drv.c | 2 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 1 + .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 - .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 2 +- drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 2 +- drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 1 - drivers/gpu/drm/i915/display/intel_fbdev.c | 8 +- drivers/gpu/drm/imx/dcss/dcss-kms.c | 3 +- drivers/gpu/drm/imx/imx-drm-core.c | 2 +- drivers/gpu/drm/imx/imx-ldb.c | 2 +- drivers/gpu/drm/imx/imx-tve.c | 1 - drivers/gpu/drm/imx/parallel-display.c | 2 +- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 3 +- drivers/gpu/drm/kmb/kmb_drv.c | 2 +- drivers/gpu/drm/kmb/kmb_plane.c | 1 - drivers/gpu/drm/logicvc/logicvc_drm.c | 2 +- drivers/gpu/drm/logicvc/logicvc_mode.c | 2 - drivers/gpu/drm/mcde/mcde_drv.c | 3 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 +- drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 1 + drivers/gpu/drm/mgag200/mgag200_drv.h | 1 - drivers/gpu/drm/msm/msm_fbdev.c | 4 +- drivers/gpu/drm/mxsfb/lcdif_drv.c | 2 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 27 +- drivers/gpu/drm/omapdrm/omap_fbdev.c | 6 +- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 3 +- drivers/gpu/drm/pl111/pl111_drv.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.c | 1 + drivers/gpu/drm/qxl/qxl_drv.h | 1 - drivers/gpu/drm/radeon/radeon_fb.c | 6 +- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 2 - drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + drivers/gpu/drm/solomon/ssd130x.c | 2 +- drivers/gpu/drm/sti/sti_drv.c | 2 +- drivers/gpu/drm/stm/drv.c | 2 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +- drivers/gpu/drm/tegra/fb.c | 8 +- drivers/gpu/drm/tidss/tidss_drv.c | 2 +- drivers/gpu/drm/tidss/tidss_kms.c | 1 - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +- drivers/gpu/drm/tiny/arcpgu.c | 2 +- drivers/gpu/drm/tiny/bochs.c | 2 +- drivers/gpu/drm/tiny/cirrus.c | 2 +- drivers/gpu/drm/tiny/gm12u320.c | 2 +- drivers/gpu/drm/tiny/hx8357d.c | 2 +- drivers/gpu/drm/tiny/ili9163.c | 2 +- drivers/gpu/drm/tiny/ili9225.c | 2 +- drivers/gpu/drm/tiny/ili9341.c | 2 +- drivers/gpu/drm/tiny/ili9486.c | 2 +- drivers/gpu/drm/tiny/mi0283qt.c | 2 +- drivers/gpu/drm/tiny/ofdrm.c | 2 +- drivers/gpu/drm/tiny/panel-mipi-dbi.c | 2 +- drivers/gpu/drm/tiny/repaper.c | 2 +- drivers/gpu/drm/tiny/simpledrm.c | 2 +- drivers/gpu/drm/tiny/st7586.c | 2 +- drivers/gpu/drm/tiny/st7735r.c | 2 +- drivers/gpu/drm/tve200/tve200_drv.c | 3 +- drivers/gpu/drm/udl/udl_drv.c | 2 +- drivers/gpu/drm/v3d/v3d_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_drv.c | 4 +- drivers/gpu/drm/vboxvideo/vbox_main.c | 1 - drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/vkms/vkms_drv.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- drivers/gpu/drm/xen/xen_drm_front_gem.c | 1 - drivers/gpu/drm/xlnx/zynqmp_kms.c | 2 +- include/drm/drm_fb_helper.h | 61 +- include/drm/drm_fbdev_generic.h | 15 + 107 files changed, 987 insertions(+), 835 deletions(-) create mode 100644 drivers/gpu/drm/drm_fbdev_generic.c create mode 100644 include/drm/drm_fbdev_generic.h base-commit: f5a9fb2d688dfc6efa1fd779a2d225048bfb10f9 prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24 prerequisite-patch-id: 3f204510fcbf9530d6540bd8e6128cce598988b6 prerequisite-patch-id: db1c43fc253bf3b55cfa09128a2d83d960599ead prerequisite-patch-id: 007fca7c89f5fe0e5279021fcac49fb621bf5708 -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 01/23] drm/komeda: Don't set struct drm_driver.lastclose
Don't set struct drm_driver.lastclose. It's used to restore the fbdev console. But as komeda uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the call to drm_client_dev_restore() in drm_lastclose(). Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 451746ebbe713..62dc64550793e 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -10,7 +10,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_managed.h> @@ -59,7 +58,6 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data) static const struct drm_driver komeda_kms_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - .lastclose = drm_fb_helper_lastclose, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(komeda_gem_dma_dumb_create), .fops = &komeda_cma_fops, .name = "komeda", -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 02/23] drm/mcde: Don't set struct drm_driver.lastclose
Don't set struct drm_driver.lastclose. It's used to restore the fbdev console. But as mcde uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the call to drm_client_dev_restore() in drm_lastclose(). Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/mcde/mcde_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 1c4482ad507d9..38c3907bb151a 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -203,7 +203,6 @@ DEFINE_DRM_GEM_DMA_FOPS(drm_fops); static const struct drm_driver mcde_drm_driver = { .driver_features DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, - .lastclose = drm_fb_helper_lastclose, .ioctls = NULL, .fops = &drm_fops, .name = "mcde", -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 03/23] drm/vboxvideo: Don't set struct drm_driver.lastclose
Don't set struct drm_driver.lastclose. It's used to restore the fbdev console. But as vboxvideo uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the call to drm_client_dev_restore() in drm_lastclose(). Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index f4f2bd79a7cb6..1cd716eb17a1c 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -178,8 +178,6 @@ static const struct drm_driver driver = { .driver_features DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, - .lastclose = drm_fb_helper_lastclose, - .fops = &vbox_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 04/23] drm/amdgpu: Don't set struct drm_driver.output_poll_changed
Don't set struct drm_driver.output_poll_changed. It's used to restore the fbdev console. But as amdgpu uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the functions drm_kms_helper_hotplug_event() and drm_kms_helper_connector_hotplug_event() in drm_probe_helper.c. v2: * fix commit description (Christian) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 1 - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 1a06b8d724f39..dd6f9ae6fbe9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -1214,7 +1214,6 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, const struct drm_mode_config_funcs amdgpu_mode_funcs = { .fb_create = amdgpu_display_user_framebuffer_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, }; static const struct drm_prop_enum_list amdgpu_underscan_enum_list[] diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3c072754738d2..d58dd916488a1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -82,7 +82,6 @@ #include <drm/drm_atomic_uapi.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_edid.h> #include <drm/drm_vblank.h> @@ -2810,7 +2809,6 @@ const struct amdgpu_ip_block_version dm_ip_block static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { .fb_create = amdgpu_display_user_framebuffer_create, .get_format_info = amd_get_format_info, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = amdgpu_dm_atomic_check, .atomic_commit = drm_atomic_helper_commit, }; -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 05/23] drm/imx/dcss: Don't set struct drm_driver.output_poll_changed
Don't set struct drm_driver.output_poll_changed. It's used to restore the fbdev console. But as DCSS uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the functions drm_kms_helper_hotplug_event() and drm_kms_helper_connector_hotplug_event() in drm_probe_helper.c. v2: * fix commit description (Christian) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/imx/dcss/dcss-kms.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index b4f82ebca5325..1defd6a40f11d 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -21,7 +21,6 @@ DEFINE_DRM_GEM_DMA_FOPS(dcss_cma_fops); static const struct drm_mode_config_funcs dcss_drm_mode_config_funcs = { .fb_create = drm_gem_fb_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 06/23] drm/ingenic: Don't set struct drm_driver.output_poll_changed
Don't set struct drm_driver.output_poll_changed. It's used to restore the fbdev console. But as ingenic uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the functions drm_kms_helper_hotplug_event() and drm_kms_helper_connector_hotplug_event() in drm_probe_helper.c. v2: * fix commit description (Christian, Sergey) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index ab0515d2c420a..99f86f1ba8bee 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -1018,7 +1018,6 @@ static const struct drm_bridge_funcs ingenic_drm_bridge_funcs = { static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = { .fb_create = ingenic_drm_gem_fb_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 07/23] drm/logicvc: Don't set struct drm_driver.output_poll_changed
Don't set struct drm_driver.output_poll_changed. It's used to restore the fbdev console. But as logicvc uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the functions drm_kms_helper_hotplug_event() and drm_kms_helper_connector_hotplug_event() in drm_probe_helper.c. v2: * fix commit description (Christian) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/logicvc/logicvc_mode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/logicvc/logicvc_mode.c b/drivers/gpu/drm/logicvc/logicvc_mode.c index d8207ffda1af9..9971950ebd4ee 100644 --- a/drivers/gpu/drm/logicvc/logicvc_mode.c +++ b/drivers/gpu/drm/logicvc/logicvc_mode.c @@ -10,7 +10,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_mode_config.h> @@ -26,7 +25,6 @@ static const struct drm_mode_config_funcs logicvc_mode_config_funcs = { .fb_create = drm_gem_fb_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 08/23] drm/rockchip: Don't set struct drm_driver.output_poll_changed
Don't set struct drm_driver.output_poll_changed. It's used to restore the fbdev console. But as rockchip uses generic fbdev emulation, the console is being restored by the DRM client helpers already. See the functions drm_kms_helper_hotplug_event() and drm_kms_helper_connector_hotplug_event() in drm_probe_helper.c. v2: * fix commit description (Christian) Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 092bf863110b7..7de64b0ad047f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -9,7 +9,6 @@ #include <drm/drm.h> #include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_framebuffer_helper.h> @@ -101,7 +100,6 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file, static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = { .fb_create = rockchip_fb_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 09/23] drm/panel-ili9341: Include <linux/backlight.h>
Include <linux/backlight.h> for devm_of_find_backlight(). Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index 39dc40cf681f0..b59472c29a40d 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -18,6 +18,7 @@ * Copyright 2018 David Lechner <david at lechnology.com> */ +#include <linux/backlight.h> #include <linux/bitops.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 10/23] drm/tve200: Include <linux/of.h>
Include <linux/of.h> for of_match_ptr(). Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/tve200/tve200_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c index 04db72e3fa9c2..611785e097576 100644 --- a/drivers/gpu/drm/tve200/tve200_drv.c +++ b/drivers/gpu/drm/tve200/tve200_drv.c @@ -32,6 +32,7 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/shmem_fs.h> #include <linux/slab.h> -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 11/23] drm/fb-helper: Cleanup include statements in header file
Only include what we have to. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- include/drm/drm_fb_helper.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index fddd0d1af6891..e923089522896 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -32,11 +32,9 @@ struct drm_fb_helper; -#include <drm/drm_client.h> -#include <drm/drm_crtc.h> -#include <drm/drm_device.h> #include <linux/fb.h> -#include <linux/kgdb.h> + +#include <drm/drm_client.h> enum mode_set_atomic { LEAVE_ATOMIC_MODE_SET, -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 12/23] drm/fb_helper: Rename field fbdev to info in struct drm_fb_helper
Rename struct drm_fb_helper.fbdev to info. The current name is misleading as it overlaps with generic fbdev naming conventions. Adapt to the usual naming in fbdev drivers by calling the field 'info'. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/drm_fb_helper.c | 40 +++++++++++----------- drivers/gpu/drm/i915/display/intel_fbdev.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 23 ++++++------- drivers/gpu/drm/omapdrm/omap_fbdev.c | 2 +- drivers/gpu/drm/tegra/fb.c | 2 +- include/drm/drm_fb_helper.h | 4 +-- 6 files changed, 36 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 71edb80fe0fb9..480bf4f568b7b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -368,7 +368,7 @@ static void drm_fb_helper_resume_worker(struct work_struct *work) resume_work); console_lock(); - fb_set_suspend(helper->fbdev, 0); + fb_set_suspend(helper->info, 0); console_unlock(); } @@ -401,7 +401,7 @@ static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper, break; } - src = fb_helper->fbdev->screen_buffer + offset; + src = fb_helper->info->screen_buffer + offset; iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ for (y = clip->y1; y < clip->y2; y++) { @@ -598,7 +598,7 @@ struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) goto err_free_cmap; } - fb_helper->fbdev = info; + fb_helper->info = info; info->skip_vt_switch = true; return info; @@ -621,8 +621,8 @@ EXPORT_SYMBOL(drm_fb_helper_alloc_fbi); */ void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) { - if (fb_helper && fb_helper->fbdev) - unregister_framebuffer(fb_helper->fbdev); + if (fb_helper && fb_helper->info) + unregister_framebuffer(fb_helper->info); } EXPORT_SYMBOL(drm_fb_helper_unregister_fbi); @@ -647,13 +647,13 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) cancel_work_sync(&fb_helper->resume_work); cancel_work_sync(&fb_helper->damage_work); - info = fb_helper->fbdev; + info = fb_helper->info; if (info) { if (info->cmap.len) fb_dealloc_cmap(&info->cmap); framebuffer_release(info); } - fb_helper->fbdev = NULL; + fb_helper->info = NULL; mutex_lock(&kernel_fb_helper_lock); if (!list_empty(&fb_helper->kernel_fb_list)) { @@ -914,8 +914,8 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); */ void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) { - if (fb_helper && fb_helper->fbdev) - fb_set_suspend(fb_helper->fbdev, suspend); + if (fb_helper && fb_helper->info) + fb_set_suspend(fb_helper->info, suspend); } EXPORT_SYMBOL(drm_fb_helper_set_suspend); @@ -938,20 +938,20 @@ EXPORT_SYMBOL(drm_fb_helper_set_suspend); void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend) { - if (!fb_helper || !fb_helper->fbdev) + if (!fb_helper || !fb_helper->info) return; /* make sure there's no pending/ongoing resume */ flush_work(&fb_helper->resume_work); if (suspend) { - if (fb_helper->fbdev->state != FBINFO_STATE_RUNNING) + if (fb_helper->info->state != FBINFO_STATE_RUNNING) return; console_lock(); } else { - if (fb_helper->fbdev->state == FBINFO_STATE_RUNNING) + if (fb_helper->info->state == FBINFO_STATE_RUNNING) return; if (!console_trylock()) { @@ -960,7 +960,7 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, } } - fb_set_suspend(fb_helper->fbdev, suspend); + fb_set_suspend(fb_helper->info, suspend); console_unlock(); } EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked); @@ -1850,7 +1850,7 @@ EXPORT_SYMBOL(drm_fb_helper_fill_info); /* * This is a continuation of drm_setup_crtcs() that sets up anything related * to the framebuffer. During initialization, drm_setup_crtcs() is called before - * the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev). + * the framebuffer has been allocated (fb_helper->fb and fb_helper->info). * So, any setup that touches those fields needs to be done here instead of in * drm_setup_crtcs(). */ @@ -1858,7 +1858,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) { struct drm_client_dev *client = &fb_helper->client; struct drm_connector_list_iter conn_iter; - struct fb_info *info = fb_helper->fbdev; + struct fb_info *info = fb_helper->info; unsigned int rotation, sw_rotations = 0; struct drm_connector *connector; struct drm_mode_set *modeset; @@ -1942,7 +1942,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, fb_helper->deferred_setup = false; - info = fb_helper->fbdev; + info = fb_helper->info; info->var.pixclock = 0; /* Shamelessly allow physical address leaking to userspace */ #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) @@ -2077,7 +2077,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) drm_setup_crtcs_fb(fb_helper); mutex_unlock(&fb_helper->lock); - drm_fb_helper_set_par(fb_helper->fbdev); + drm_fb_helper_set_par(fb_helper->info); return 0; } @@ -2135,7 +2135,7 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user) static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) { - struct fb_info *fbi = fb_helper->fbdev; + struct fb_info *fbi = fb_helper->info; void *shadow = NULL; if (!fb_helper->dev) @@ -2495,7 +2495,7 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client) { struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - if (fb_helper->fbdev) + if (fb_helper->info) /* drm_fbdev_fb_destroy() takes care of cleanup */ drm_fb_helper_unregister_fbi(fb_helper); else @@ -2546,7 +2546,7 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client) drm_fbdev_cleanup(fb_helper); err: fb_helper->dev = NULL; - fb_helper->fbdev = NULL; + fb_helper->info = NULL; drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index ab385d18ddcc3..d533ecd451025 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -627,7 +627,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous if (!ifbdev || !ifbdev->vma) goto set_suspend; - info = ifbdev->helper.fbdev; + info = ifbdev->helper.info; if (synchronous) { /* Flush any pending work to turn the console on, and then diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 3c7e0c9d6baf1..ac4bd529ae2e8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -231,9 +231,9 @@ void nouveau_fbcon_accel_save_disable(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon && drm->fbcon->helper.fbdev) { - drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags; - drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; + if (drm->fbcon && drm->fbcon->helper.info) { + drm->fbcon->saved_flags = drm->fbcon->helper.info->flags; + drm->fbcon->helper.info->flags |= FBINFO_HWACCEL_DISABLED; } } @@ -241,9 +241,8 @@ void nouveau_fbcon_accel_restore(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon && drm->fbcon->helper.fbdev) { - drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags; - } + if (drm->fbcon && drm->fbcon->helper.info) + drm->fbcon->helper.info->flags = drm->fbcon->saved_flags; } static void @@ -253,8 +252,8 @@ nouveau_fbcon_accel_fini(struct drm_device *dev) struct nouveau_fbdev *fbcon = drm->fbcon; if (fbcon && drm->channel) { console_lock(); - if (fbcon->helper.fbdev) - fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; + if (fbcon->helper.info) + fbcon->helper.info->flags |= FBINFO_HWACCEL_DISABLED; console_unlock(); nouveau_channel_idle(drm->channel); nvif_object_dtor(&fbcon->twod); @@ -272,7 +271,7 @@ nouveau_fbcon_accel_init(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_fbdev *fbcon = drm->fbcon; - struct fb_info *info = fbcon->helper.fbdev; + struct fb_info *info = fbcon->helper.info; int ret; if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) @@ -290,7 +289,7 @@ nouveau_fbcon_accel_init(struct drm_device *dev) static void nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon) { - struct fb_info *info = fbcon->helper.fbdev; + struct fb_info *info = fbcon->helper.info; struct fb_fillrect rect; /* Clear the entire fbcon. The drm will program every connector @@ -586,8 +585,8 @@ nouveau_fbcon_init(struct drm_device *dev) if (ret) goto fini; - if (fbcon->helper.fbdev) - fbcon->helper.fbdev->pixmap.buf_align = 4; + if (fbcon->helper.info) + fbcon->helper.info->pixmap.buf_align = 4; return 0; fini: diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index ed67dd25794c8..92d505be53e06 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -38,7 +38,7 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi); static void pan_worker(struct work_struct *work) { struct omap_fbdev *fbdev = container_of(work, struct omap_fbdev, work); - struct fb_info *fbi = fbdev->base.fbdev; + struct fb_info *fbi = fbdev->base.info; int npages; /* DMM roll shifts in 4K pages: */ diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index bce71c0ccc9ef..6fe24535d0e43 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -261,7 +261,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, fb = fbdev->fb; helper->fb = fb; - helper->fbdev = info; + helper->info = info; info->fbops = &tegra_fb_ops; diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index e923089522896..d83e2d8e92eb9 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -96,7 +96,7 @@ struct drm_fb_helper_funcs { * @fb: Scanout framebuffer object * @dev: DRM device * @funcs: driver callbacks for fb helper - * @fbdev: emulated fbdev device info struct + * @info: emulated fbdev device info struct * @pseudo_palette: fake palette of 16 colors * @damage_clip: clip rectangle used with deferred_io to accumulate damage to * the screen buffer @@ -127,7 +127,7 @@ struct drm_fb_helper { struct drm_framebuffer *fb; struct drm_device *dev; const struct drm_fb_helper_funcs *funcs; - struct fb_info *fbdev; + struct fb_info *info; u32 pseudo_palette[17]; struct drm_clip_rect damage_clip; spinlock_t damage_lock; -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 13/23] drm/fb-helper: Rename drm_fb_helper_alloc_fbi() to use _info postfix
Rename drm_fb_helper_alloc_fbi() to drm_fb_helper_alloc_info() as part of unifying the naming within fbdev helpers. Adapt drivers. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/armada/armada_fbdev.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 8 ++++---- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 2 +- drivers/gpu/drm/gma500/framebuffer.c | 2 +- drivers/gpu/drm/i915/display/intel_fbdev.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- drivers/gpu/drm/omapdrm/omap_fbdev.c | 2 +- drivers/gpu/drm/radeon/radeon_fb.c | 2 +- drivers/gpu/drm/tegra/fb.c | 2 +- include/drm/drm_fb_helper.h | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index 38f5170c0fea6..eaae98d9377ae 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -72,7 +72,7 @@ static int armada_fbdev_create(struct drm_fb_helper *fbh, if (IS_ERR(dfb)) return PTR_ERR(dfb); - info = drm_fb_helper_alloc_fbi(fbh); + info = drm_fb_helper_alloc_info(fbh); if (IS_ERR(info)) { ret = PTR_ERR(info); goto err_fballoc; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 480bf4f568b7b..881e6a04fa706 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -558,7 +558,7 @@ int drm_fb_helper_init(struct drm_device *dev, EXPORT_SYMBOL(drm_fb_helper_init); /** - * drm_fb_helper_alloc_fbi - allocate fb_info and some of its members + * drm_fb_helper_alloc_info - allocate fb_info and some of its members * @fb_helper: driver-allocated fbdev helper * * A helper to alloc fb_info and the members cmap and apertures. Called @@ -570,7 +570,7 @@ EXPORT_SYMBOL(drm_fb_helper_init); * fb_info pointer if things went okay, pointer containing error code * otherwise */ -struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) +struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) { struct device *dev = fb_helper->dev->dev; struct fb_info *info; @@ -609,7 +609,7 @@ struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) framebuffer_release(info); return ERR_PTR(ret); } -EXPORT_SYMBOL(drm_fb_helper_alloc_fbi); +EXPORT_SYMBOL(drm_fb_helper_alloc_info); /** * drm_fb_helper_unregister_fbi - unregister fb_info framebuffer device @@ -2440,7 +2440,7 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, fb_helper->fb = buffer->fb; fb = buffer->fb; - fbi = drm_fb_helper_alloc_fbi(fb_helper); + fbi = drm_fb_helper_alloc_info(fb_helper); if (IS_ERR(fbi)) return PTR_ERR(fbi); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 767afd2bfa822..8741eb0b1b604 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -63,7 +63,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, unsigned int size = fb->width * fb->height * fb->format->cpp[0]; unsigned long offset; - fbi = drm_fb_helper_alloc_fbi(helper); + fbi = drm_fb_helper_alloc_info(helper); if (IS_ERR(fbi)) { DRM_DEV_ERROR(to_dma_dev(helper->dev), "failed to allocate fb info.\n"); diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 5f502a0048ab8..6d0e3bf6435ee 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -268,7 +268,7 @@ static int psbfb_create(struct drm_fb_helper *fb_helper, memset(dev_priv->vram_addr + backing->offset, 0, size); - info = drm_fb_helper_alloc_fbi(fb_helper); + info = drm_fb_helper_alloc_info(fb_helper); if (IS_ERR(info)) { ret = PTR_ERR(info); goto err_drm_gem_object_put; diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index d533ecd451025..05b841343ea3e 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -254,7 +254,7 @@ static int intelfb_create(struct drm_fb_helper *helper, goto out_unlock; } - info = drm_fb_helper_alloc_fbi(helper); + info = drm_fb_helper_alloc_info(helper); if (IS_ERR(info)) { drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info); ret = PTR_ERR(info); diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index b373e30003203..4d9a0fcbf95b6 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -93,7 +93,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, goto fail; } - fbi = drm_fb_helper_alloc_fbi(helper); + fbi = drm_fb_helper_alloc_info(helper); if (IS_ERR(fbi)) { DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n"); ret = PTR_ERR(fbi); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ac4bd529ae2e8..fca40124fc17c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -362,7 +362,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, } } - info = drm_fb_helper_alloc_fbi(helper); + info = drm_fb_helper_alloc_info(helper); if (IS_ERR(info)) { ret = PTR_ERR(info); goto out_unlock; diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 92d505be53e06..ab30c64e97043 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -161,7 +161,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, goto fail; } - fbi = drm_fb_helper_alloc_fbi(helper); + fbi = drm_fb_helper_alloc_info(helper); if (IS_ERR(fbi)) { dev_err(dev->dev, "failed to allocate fb info\n"); ret = PTR_ERR(fbi); diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index cc6754d88b819..0c6a227929db2 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -243,7 +243,7 @@ static int radeonfb_create(struct drm_fb_helper *helper, rbo = gem_to_radeon_bo(gobj); /* okay we have an object now allocate the framebuffer */ - info = drm_fb_helper_alloc_fbi(helper); + info = drm_fb_helper_alloc_info(helper); if (IS_ERR(info)) { ret = PTR_ERR(info); goto out; diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 6fe24535d0e43..a09c071f35120 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -243,7 +243,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, if (IS_ERR(bo)) return PTR_ERR(bo); - info = drm_fb_helper_alloc_fbi(helper); + info = drm_fb_helper_alloc_info(helper); if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); drm_gem_object_put(&bo->gem); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index d83e2d8e92eb9..5ec9d9c68d144 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -222,7 +222,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); -struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper); +struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper); void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper); void drm_fb_helper_fill_info(struct fb_info *info, struct drm_fb_helper *fb_helper, @@ -320,7 +320,7 @@ drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) } static inline struct fb_info * -drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper) +drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) { return NULL; } -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 14/23] drm/fb-helper: Rename drm_fb_helper_unregister_fbi() to use _info postfix
Rename drm_fb_helper_unregister_fbi() to drm_fb_helper_unregister_info() as part of unifying the naming within fbdev helpers. Adapt drivers. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/armada/armada_fbdev.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 8 ++++---- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 2 +- drivers/gpu/drm/gma500/framebuffer.c | 2 +- drivers/gpu/drm/i915/display/intel_fbdev.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 2 +- drivers/gpu/drm/omapdrm/omap_fbdev.c | 2 +- drivers/gpu/drm/radeon/radeon_fb.c | 2 +- drivers/gpu/drm/tegra/fb.c | 2 +- include/drm/drm_fb_helper.h | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index eaae98d9377ae..f02f6a5ba8320 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -155,7 +155,7 @@ void armada_fbdev_fini(struct drm_device *dev) struct drm_fb_helper *fbh = priv->fbdev; if (fbh) { - drm_fb_helper_unregister_fbi(fbh); + drm_fb_helper_unregister_info(fbh); drm_fb_helper_fini(fbh); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 881e6a04fa706..bfbb2af144060 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -612,19 +612,19 @@ struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) EXPORT_SYMBOL(drm_fb_helper_alloc_info); /** - * drm_fb_helper_unregister_fbi - unregister fb_info framebuffer device + * drm_fb_helper_unregister_info - unregister fb_info framebuffer device * @fb_helper: driver-allocated fbdev helper, can be NULL * * A wrapper around unregister_framebuffer, to release the fb_info * framebuffer device. This must be called before releasing all resources for * @fb_helper by calling drm_fb_helper_fini(). */ -void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) +void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper) { if (fb_helper && fb_helper->info) unregister_framebuffer(fb_helper->info); } -EXPORT_SYMBOL(drm_fb_helper_unregister_fbi); +EXPORT_SYMBOL(drm_fb_helper_unregister_info); /** * drm_fb_helper_fini - finialize a &struct drm_fb_helper @@ -2497,7 +2497,7 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client) if (fb_helper->info) /* drm_fbdev_fb_destroy() takes care of cleanup */ - drm_fb_helper_unregister_fbi(fb_helper); + drm_fb_helper_unregister_info(fb_helper); else drm_fbdev_release(fb_helper); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 8741eb0b1b604..86c489d945849 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -201,7 +201,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev, drm_framebuffer_remove(fb); } - drm_fb_helper_unregister_fbi(fb_helper); + drm_fb_helper_unregister_info(fb_helper); drm_fb_helper_fini(fb_helper); } diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 6d0e3bf6435ee..6098d936e44b6 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -383,7 +383,7 @@ static int psb_fbdev_destroy(struct drm_device *dev, { struct drm_framebuffer *fb = fb_helper->fb; - drm_fb_helper_unregister_fbi(fb_helper); + drm_fb_helper_unregister_info(fb_helper); drm_fb_helper_fini(fb_helper); drm_framebuffer_unregister_private(fb); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 05b841343ea3e..1b576c859837b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -584,7 +584,7 @@ void intel_fbdev_unregister(struct drm_i915_private *dev_priv) if (!current_is_async()) intel_fbdev_sync(ifbdev); - drm_fb_helper_unregister_fbi(&ifbdev->helper); + drm_fb_helper_unregister_info(&ifbdev->helper); } void intel_fbdev_fini(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 4d9a0fcbf95b6..31e1e30cb52a2 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -182,7 +182,7 @@ void msm_fbdev_free(struct drm_device *dev) DBG(); - drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_unregister_info(helper); drm_fb_helper_fini(helper); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index fca40124fc17c..e87de7906f780 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -419,7 +419,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) struct drm_framebuffer *fb = fbcon->helper.fb; struct nouveau_bo *nvbo; - drm_fb_helper_unregister_fbi(&fbcon->helper); + drm_fb_helper_unregister_info(&fbcon->helper); drm_fb_helper_fini(&fbcon->helper); if (fb && fb->obj[0]) { diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index ab30c64e97043..98d8758048fc1 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -272,7 +272,7 @@ void omap_fbdev_fini(struct drm_device *dev) if (!helper) return; - drm_fb_helper_unregister_fbi(helper); + drm_fb_helper_unregister_info(helper); drm_fb_helper_fini(helper); diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 0c6a227929db2..f06fed2030a89 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -309,7 +309,7 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb { struct drm_framebuffer *fb = &rfbdev->fb; - drm_fb_helper_unregister_fbi(&rfbdev->helper); + drm_fb_helper_unregister_info(&rfbdev->helper); if (fb->obj[0]) { radeonfb_destroy_pinned_object(fb->obj[0]); diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index a09c071f35120..84b7f1dd9fb57 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -347,7 +347,7 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev, static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) { - drm_fb_helper_unregister_fbi(&fbdev->base); + drm_fb_helper_unregister_info(&fbdev->base); if (fbdev->fb) { struct tegra_bo *bo = tegra_fb_get_plane(fbdev->fb, 0); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 5ec9d9c68d144..edc697a2fde24 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -223,7 +223,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper); -void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper); +void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper); void drm_fb_helper_fill_info(struct fb_info *info, struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes); @@ -325,7 +325,7 @@ drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) return NULL; } -static inline void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper) +static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper) { } -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 15/23] drm/fb-helper: Disconnect damage worker from update logic
The fbdev helpers implement a damage worker that forwards fbdev updates to the DRM driver. The worker's update logic depends on the generic fbdev emulation. Separate the two via function pointer. The generic fbdev emulation sets struct drm_fb_helper_funcs.fb_dirty, a new callback that hides the update logic from the damage worker. It's not possible to use the generic logic with other fbdev emulation, because it contains additional code for the shadow buffering that the generic emulation employs. DRM drivers with internal fbdev emulation can set fb_dirty to their own implementation if they require damage handling; although no such drivers currently exist. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/drm_fb_helper.c | 75 ++++++++++++++++++++------------- include/drm/drm_fb_helper.h | 15 +++++++ 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index bfbb2af144060..f6d22cc4cd876 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -448,35 +448,24 @@ static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper, static void drm_fb_helper_damage_work(struct work_struct *work) { - struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, - damage_work); - struct drm_device *dev = helper->dev; + struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work); struct drm_clip_rect *clip = &helper->damage_clip; struct drm_clip_rect clip_copy; unsigned long flags; int ret; + if (!helper->funcs->fb_dirty) + return; + spin_lock_irqsave(&helper->damage_lock, flags); clip_copy = *clip; clip->x1 = clip->y1 = ~0; clip->x2 = clip->y2 = 0; spin_unlock_irqrestore(&helper->damage_lock, flags); - /* Call damage handlers only if necessary */ - if (!(clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2)) - return; - - if (helper->buffer) { - ret = drm_fb_helper_damage_blit(helper, &clip_copy); - if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) - goto err; - } - - if (helper->fb->funcs->dirty) { - ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1); - if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) - goto err; - } + ret = helper->funcs->fb_dirty(helper, &clip_copy); + if (ret) + goto err; return; @@ -670,16 +659,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_fini); -static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper) -{ - struct drm_device *dev = fb_helper->dev; - struct drm_framebuffer *fb = fb_helper->fb; - - return dev->mode_config.prefer_shadow_fbdev || - dev->mode_config.prefer_shadow || - fb->funcs->dirty; -} - static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, u32 width, u32 height) { @@ -687,7 +666,7 @@ static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, struct drm_clip_rect *clip = &helper->damage_clip; unsigned long flags; - if (!drm_fbdev_use_shadow_fb(helper)) + if (!helper->funcs->fb_dirty) return; spin_lock_irqsave(&helper->damage_lock, flags); @@ -2111,6 +2090,16 @@ void drm_fb_helper_output_poll_changed(struct drm_device *dev) } EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); +static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper) +{ + struct drm_device *dev = fb_helper->dev; + struct drm_framebuffer *fb = fb_helper->fb; + + return dev->mode_config.prefer_shadow_fbdev || + dev->mode_config.prefer_shadow || + fb->funcs->dirty; +} + /* @user: 1=userspace, 0=fbcon */ static int drm_fbdev_fb_open(struct fb_info *info, int user) { @@ -2487,8 +2476,36 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, return 0; } +static int drm_fbdev_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + if (!drm_fbdev_use_shadow_fb(helper)) + return 0; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->buffer) { + ret = drm_fb_helper_damage_blit(helper, clip); + if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) + return ret; + } + + 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 drm_fb_helper_generic_funcs = { .fb_probe = drm_fb_helper_generic_probe, + .fb_dirty = drm_fbdev_fb_dirty, }; static void drm_fbdev_client_unregister(struct drm_client_dev *client) diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index edc697a2fde24..3d7a3d68dab8a 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -30,6 +30,7 @@ #ifndef DRM_FB_HELPER_H #define DRM_FB_HELPER_H +struct drm_clip_rect; struct drm_fb_helper; #include <linux/fb.h> @@ -89,6 +90,20 @@ struct drm_fb_helper_funcs { */ int (*fb_probe)(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); + + /** + * @fb_dirty: + * + * Driver callback to update the framebuffer memory. If set, fbdev + * emulation will invoke this callback in regular intervals after + * the framebuffer has been written. + * + * This callback is optional. + * + * Returns: + * 0 on success, or an error code otherwise. + */ + int (*fb_dirty)(struct drm_fb_helper *helper, struct drm_clip_rect *clip); }; /** -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 16/23] drm/fb-helper: Call fb_sync in I/O functions
Call struct fb_ops.fb_sync in drm_fbdev_{read,write}() to mimic the behavior of fbdev. Fbdev implementations of fb_read and fb_write in struct fb_ops invoke fb_sync to synchronize with outstanding operations before I/O. Doing the same in DRM implementations will allow us to use them throughout DRM drivers. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/drm_fb_helper.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index f6d22cc4cd876..379e0d2f67198 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2246,6 +2246,9 @@ static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, if (total_size - count < pos) count = total_size - pos; + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + if (drm_fbdev_use_iomem(info)) ret = fb_read_screen_base(info, buf, count, pos); else @@ -2327,6 +2330,9 @@ static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, count = total_size - pos; } + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + /* * Copy to framebuffer even if we already logged an error. Emulates * the behavior of the original fbdev implementation. -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 17/23] drm/fb-helper: Perform all fbdev I/O with the same implementation
Implement the fbdev's read/write helpers with the same functions. Use the generic fbdev's code as template. Convert all drivers. DRM's fb helpers must implement regular I/O functionality in struct fb_ops and possibly perform a damage update. Handle all this in the same functions and convert drivers. The functionality has been used as part of the generic fbdev code for some time. The drivers don't set struct drm_fb_helper.fb_dirty, so they will not be affected by damage handling. For I/O memory, fb helpers now provide drm_fb_helper_cfb_read() and drm_fb_helper_cfb_write(). Several drivers require these. Until now tegra used I/O read and write, although the memory buffer appears to be in system memory. So use _sys_ helpers now. v3: * fix docs (Javier) v2: * rebase onto vmwgfx changes Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/armada/armada_fbdev.c | 2 + drivers/gpu/drm/drm_fb_helper.c | 383 ++++++++++++--------- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 2 + drivers/gpu/drm/gma500/framebuffer.c | 2 + drivers/gpu/drm/i915/display/intel_fbdev.c | 2 + drivers/gpu/drm/radeon/radeon_fb.c | 2 + drivers/gpu/drm/tegra/fb.c | 2 + include/drm/drm_fb_helper.h | 17 + 8 files changed, 254 insertions(+), 158 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index f02f6a5ba8320..584cee123bd8e 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -19,6 +19,8 @@ static const struct fb_ops armada_fb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, + .fb_read = drm_fb_helper_cfb_read, + .fb_write = drm_fb_helper_cfb_write, .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = drm_fb_helper_cfb_copyarea, .fb_imageblit = drm_fb_helper_cfb_imageblit, diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 379e0d2f67198..c7c0c0a8532b4 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -747,30 +747,132 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli } EXPORT_SYMBOL(drm_fb_helper_deferred_io); +typedef ssize_t (*drm_fb_helper_read_screen)(struct fb_info *info, char __user *buf, + size_t count, loff_t pos); + +static ssize_t __drm_fb_helper_read(struct fb_info *info, char __user *buf, size_t count, + loff_t *ppos, drm_fb_helper_read_screen read_screen) +{ + loff_t pos = *ppos; + size_t total_size; + ssize_t ret; + + if (info->screen_size) + total_size = info->screen_size; + else + total_size = info->fix.smem_len; + + if (pos >= total_size) + return 0; + if (count >= total_size) + count = total_size; + if (total_size - count < pos) + count = total_size - pos; + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + ret = read_screen(info, buf, count, pos); + if (ret > 0) + *ppos += ret; + + return ret; +} + +typedef ssize_t (*drm_fb_helper_write_screen)(struct fb_info *info, const char __user *buf, + size_t count, loff_t pos); + +static ssize_t __drm_fb_helper_write(struct fb_info *info, const char __user *buf, size_t count, + loff_t *ppos, drm_fb_helper_write_screen write_screen) +{ + loff_t pos = *ppos; + size_t total_size; + ssize_t ret; + int err = 0; + + if (info->screen_size) + total_size = info->screen_size; + else + total_size = info->fix.smem_len; + + if (pos > total_size) + return -EFBIG; + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + if (total_size - count < pos) { + if (!err) + err = -ENOSPC; + count = total_size - pos; + } + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + /* + * Copy to framebuffer even if we already logged an error. Emulates + * the behavior of the original fbdev implementation. + */ + ret = write_screen(info, buf, count, pos); + if (ret < 0) + return ret; /* return last error, if any */ + else if (!ret) + return err; /* return previous error, if any */ + + *ppos += ret; + + return ret; +} + +static ssize_t drm_fb_helper_read_screen_buffer(struct fb_info *info, char __user *buf, + size_t count, loff_t pos) +{ + const char *src = info->screen_buffer + pos; + + if (copy_to_user(buf, src, count)) + return -EFAULT; + + return count; +} + /** - * drm_fb_helper_sys_read - wrapper around fb_sys_read + * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory * @info: fb_info struct pointer * @buf: userspace buffer to read from framebuffer memory * @count: number of bytes to read from framebuffer memory * @ppos: read offset within framebuffer memory * - * A wrapper around fb_sys_read implemented by fbdev core + * Returns: + * The number of bytes read on success, or an error code otherwise. */ ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, size_t count, loff_t *ppos) { - return fb_sys_read(info, buf, count, ppos); + return __drm_fb_helper_read(info, buf, count, ppos, drm_fb_helper_read_screen_buffer); } EXPORT_SYMBOL(drm_fb_helper_sys_read); +static ssize_t drm_fb_helper_write_screen_buffer(struct fb_info *info, const char __user *buf, + size_t count, loff_t pos) +{ + char *dst = info->screen_buffer + pos; + + if (copy_from_user(dst, buf, count)) + return -EFAULT; + + return count; +} + /** - * drm_fb_helper_sys_write - wrapper around fb_sys_write + * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system memory * @info: fb_info struct pointer * @buf: userspace buffer to write to framebuffer memory * @count: number of bytes to write to framebuffer memory * @ppos: write offset within framebuffer memory * - * A wrapper around fb_sys_write implemented by fbdev core + * Returns: + * The number of bytes written on success, or an error code otherwise. */ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) @@ -779,7 +881,7 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, ssize_t ret; struct drm_rect damage_area; - ret = fb_sys_write(info, buf, count, ppos); + ret = __drm_fb_helper_write(info, buf, count, ppos, drm_fb_helper_write_screen_buffer); if (ret <= 0) return ret; @@ -837,6 +939,119 @@ void drm_fb_helper_sys_imageblit(struct fb_info *info, } EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); +static ssize_t fb_read_screen_base(struct fb_info *info, char __user *buf, size_t count, + loff_t pos) +{ + const char __iomem *src = info->screen_base + pos; + size_t alloc_size = min_t(size_t, count, PAGE_SIZE); + ssize_t ret = 0; + int err = 0; + char *tmp; + + tmp = kmalloc(alloc_size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + while (count) { + size_t c = min_t(size_t, count, alloc_size); + + memcpy_fromio(tmp, src, c); + if (copy_to_user(buf, tmp, c)) { + err = -EFAULT; + break; + } + + src += c; + buf += c; + ret += c; + count -= c; + } + + kfree(tmp); + + return ret ? ret : err; +} + +/** + * drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory + * @info: fb_info struct pointer + * @buf: userspace buffer to read from framebuffer memory + * @count: number of bytes to read from framebuffer memory + * @ppos: read offset within framebuffer memory + * + * Returns: + * The number of bytes read on success, or an error code otherwise. + */ +ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + return __drm_fb_helper_read(info, buf, count, ppos, fb_read_screen_base); +} +EXPORT_SYMBOL(drm_fb_helper_cfb_read); + +static ssize_t fb_write_screen_base(struct fb_info *info, const char __user *buf, size_t count, + loff_t pos) +{ + char __iomem *dst = info->screen_base + pos; + size_t alloc_size = min_t(size_t, count, PAGE_SIZE); + ssize_t ret = 0; + int err = 0; + u8 *tmp; + + tmp = kmalloc(alloc_size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + while (count) { + size_t c = min_t(size_t, count, alloc_size); + + if (copy_from_user(tmp, buf, c)) { + err = -EFAULT; + break; + } + memcpy_toio(dst, tmp, c); + + dst += c; + buf += c; + ret += c; + count -= c; + } + + kfree(tmp); + + return ret ? ret : err; +} + +/** + * drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory + * @info: fb_info struct pointer + * @buf: userspace buffer to write to framebuffer memory + * @count: number of bytes to write to framebuffer memory + * @ppos: write offset within framebuffer memory + * + * Returns: + * The number of bytes written on success, or an error code otherwise. + */ +ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + loff_t pos = *ppos; + ssize_t ret; + struct drm_rect damage_area; + + ret = __drm_fb_helper_write(info, buf, count, ppos, fb_write_screen_base); + if (ret <= 0) + return ret; + + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + + return ret; +} +EXPORT_SYMBOL(drm_fb_helper_cfb_write); + /** * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect * @info: fbdev registered by the helper @@ -2183,176 +2398,28 @@ static bool drm_fbdev_use_iomem(struct fb_info *info) return !drm_fbdev_use_shadow_fb(fb_helper) && buffer->map.is_iomem; } -static ssize_t fb_read_screen_base(struct fb_info *info, char __user *buf, size_t count, - loff_t pos) -{ - const char __iomem *src = info->screen_base + pos; - size_t alloc_size = min_t(size_t, count, PAGE_SIZE); - ssize_t ret = 0; - int err = 0; - char *tmp; - - tmp = kmalloc(alloc_size, GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - while (count) { - size_t c = min_t(size_t, count, alloc_size); - - memcpy_fromio(tmp, src, c); - if (copy_to_user(buf, tmp, c)) { - err = -EFAULT; - break; - } - - src += c; - buf += c; - ret += c; - count -= c; - } - - kfree(tmp); - - return ret ? ret : err; -} - -static ssize_t fb_read_screen_buffer(struct fb_info *info, char __user *buf, size_t count, - loff_t pos) -{ - const char *src = info->screen_buffer + pos; - - if (copy_to_user(buf, src, count)) - return -EFAULT; - - return count; -} - static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, size_t count, loff_t *ppos) { - loff_t pos = *ppos; - size_t total_size; ssize_t ret; - if (info->screen_size) - total_size = info->screen_size; - else - total_size = info->fix.smem_len; - - if (pos >= total_size) - return 0; - if (count >= total_size) - count = total_size; - if (total_size - count < pos) - count = total_size - pos; - - if (info->fbops->fb_sync) - info->fbops->fb_sync(info); - if (drm_fbdev_use_iomem(info)) - ret = fb_read_screen_base(info, buf, count, pos); + ret = drm_fb_helper_cfb_read(info, buf, count, ppos); else - ret = fb_read_screen_buffer(info, buf, count, pos); - - if (ret > 0) - *ppos += ret; + ret = drm_fb_helper_sys_read(info, buf, count, ppos); return ret; } -static ssize_t fb_write_screen_base(struct fb_info *info, const char __user *buf, size_t count, - loff_t pos) -{ - char __iomem *dst = info->screen_base + pos; - size_t alloc_size = min_t(size_t, count, PAGE_SIZE); - ssize_t ret = 0; - int err = 0; - u8 *tmp; - - tmp = kmalloc(alloc_size, GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - while (count) { - size_t c = min_t(size_t, count, alloc_size); - - if (copy_from_user(tmp, buf, c)) { - err = -EFAULT; - break; - } - memcpy_toio(dst, tmp, c); - - dst += c; - buf += c; - ret += c; - count -= c; - } - - kfree(tmp); - - return ret ? ret : err; -} - -static ssize_t fb_write_screen_buffer(struct fb_info *info, const char __user *buf, size_t count, - loff_t pos) -{ - char *dst = info->screen_buffer + pos; - - if (copy_from_user(dst, buf, count)) - return -EFAULT; - - return count; -} - static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { - loff_t pos = *ppos; - size_t total_size; ssize_t ret; - struct drm_rect damage_area; - int err = 0; - if (info->screen_size) - total_size = info->screen_size; - else - total_size = info->fix.smem_len; - - if (pos > total_size) - return -EFBIG; - if (count > total_size) { - err = -EFBIG; - count = total_size; - } - if (total_size - count < pos) { - if (!err) - err = -ENOSPC; - count = total_size - pos; - } - - if (info->fbops->fb_sync) - info->fbops->fb_sync(info); - - /* - * Copy to framebuffer even if we already logged an error. Emulates - * the behavior of the original fbdev implementation. - */ if (drm_fbdev_use_iomem(info)) - ret = fb_write_screen_base(info, buf, count, pos); + ret = drm_fb_helper_cfb_write(info, buf, count, ppos); else - ret = fb_write_screen_buffer(info, buf, count, pos); - - if (ret < 0) - return ret; /* return last error, if any */ - else if (!ret) - return err; /* return previous error, if any */ - - *ppos += ret; - - drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + ret = drm_fb_helper_sys_write(info, buf, count, ppos); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 86c489d945849..55c92372fca04 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -49,6 +49,8 @@ static const struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, .fb_mmap = exynos_drm_fb_mmap, + .fb_read = drm_fb_helper_cfb_read, + .fb_write = drm_fb_helper_cfb_write, .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = drm_fb_helper_cfb_copyarea, .fb_imageblit = drm_fb_helper_cfb_imageblit, diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 6098d936e44b6..8d5a37b8f1100 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -147,6 +147,8 @@ static const struct fb_ops psbfb_unaccel_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, .fb_setcolreg = psbfb_setcolreg, + .fb_read = drm_fb_helper_cfb_read, + .fb_write = drm_fb_helper_cfb_write, .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = drm_fb_helper_cfb_copyarea, .fb_imageblit = drm_fb_helper_cfb_imageblit, diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 1b576c859837b..5575d7abdc092 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -124,6 +124,8 @@ static const struct fb_ops intelfb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, .fb_set_par = intel_fbdev_set_par, + .fb_read = drm_fb_helper_cfb_read, + .fb_write = drm_fb_helper_cfb_write, .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = drm_fb_helper_cfb_copyarea, .fb_imageblit = drm_fb_helper_cfb_imageblit, diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index f06fed2030a89..c1710ed1cab83 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -80,6 +80,8 @@ static const struct fb_ops radeonfb_ops = { DRM_FB_HELPER_DEFAULT_OPS, .fb_open = radeonfb_open, .fb_release = radeonfb_release, + .fb_read = drm_fb_helper_cfb_read, + .fb_write = drm_fb_helper_cfb_write, .fb_fillrect = drm_fb_helper_cfb_fillrect, .fb_copyarea = drm_fb_helper_cfb_copyarea, .fb_imageblit = drm_fb_helper_cfb_imageblit, diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 84b7f1dd9fb57..a900300ae5bdc 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -206,6 +206,8 @@ static int tegra_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) static const struct fb_ops tegra_fb_ops = { .owner = THIS_MODULE, DRM_FB_HELPER_DEFAULT_OPS, + .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, diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 3d7a3d68dab8a..6581183618b89 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -257,6 +257,11 @@ void drm_fb_helper_sys_copyarea(struct fb_info *info, void drm_fb_helper_sys_imageblit(struct fb_info *info, const struct fb_image *image); +ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); + void drm_fb_helper_cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); void drm_fb_helper_cfb_copyarea(struct fb_info *info, @@ -402,6 +407,18 @@ static inline void drm_fb_helper_sys_imageblit(struct fb_info *info, { } +static inline ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + return -ENODEV; +} + +static inline ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + return -ENODEV; +} + static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 18/23] drm/fb_helper: Minimize damage-helper overhead
Pull the test for fb_dirty into the caller to avoid extra work if no callback has been set. In this case no damage handling is required and no damage area needs to be computed. Print a warning if the damage worker runs without getting an fb_dirty callback. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/drm_fb_helper.c | 90 ++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index c7c0c0a8532b4..3dfda1e3830b3 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -449,12 +449,13 @@ static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper, static void drm_fb_helper_damage_work(struct work_struct *work) { struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work); + struct drm_device *dev = helper->dev; struct drm_clip_rect *clip = &helper->damage_clip; struct drm_clip_rect clip_copy; unsigned long flags; int ret; - if (!helper->funcs->fb_dirty) + if (drm_WARN_ON_ONCE(dev, !helper->funcs->fb_dirty)) return; spin_lock_irqsave(&helper->damage_lock, flags); @@ -659,16 +660,12 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_fini); -static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, +static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y, u32 width, u32 height) { - struct drm_fb_helper *helper = info->par; struct drm_clip_rect *clip = &helper->damage_clip; unsigned long flags; - if (!helper->funcs->fb_dirty) - return; - spin_lock_irqsave(&helper->damage_lock, flags); clip->x1 = min_t(u32, clip->x1, x); clip->y1 = min_t(u32, clip->y1, y); @@ -718,6 +715,7 @@ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, */ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist) { + struct drm_fb_helper *helper = info->par; unsigned long start, end, min_off, max_off; struct fb_deferred_io_pageref *pageref; struct drm_rect damage_area; @@ -733,17 +731,19 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli if (min_off >= max_off) return; - /* - * As we can only track pages, we might reach beyond the end - * of the screen and account for non-existing scanlines. Hence, - * keep the covered memory area within the screen buffer. - */ - max_off = min(max_off, info->screen_size); + if (helper->funcs->fb_dirty) { + /* + * As we can only track pages, we might reach beyond the end + * of the screen and account for non-existing scanlines. Hence, + * keep the covered memory area within the screen buffer. + */ + max_off = min(max_off, info->screen_size); - drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + } } EXPORT_SYMBOL(drm_fb_helper_deferred_io); @@ -877,6 +877,7 @@ static ssize_t drm_fb_helper_write_screen_buffer(struct fb_info *info, const cha ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { + struct drm_fb_helper *helper = info->par; loff_t pos = *ppos; ssize_t ret; struct drm_rect damage_area; @@ -885,10 +886,12 @@ ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, if (ret <= 0) return ret; - drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + if (helper->funcs->fb_dirty) { + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + } return ret; } @@ -904,8 +907,12 @@ EXPORT_SYMBOL(drm_fb_helper_sys_write); void drm_fb_helper_sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { + struct drm_fb_helper *helper = info->par; + sys_fillrect(info, rect); - drm_fb_helper_damage(info, rect->dx, rect->dy, rect->width, rect->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, rect->height); } EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); @@ -919,8 +926,12 @@ EXPORT_SYMBOL(drm_fb_helper_sys_fillrect); void drm_fb_helper_sys_copyarea(struct fb_info *info, const struct fb_copyarea *area) { + struct drm_fb_helper *helper = info->par; + sys_copyarea(info, area); - drm_fb_helper_damage(info, area->dx, area->dy, area->width, area->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, area->dx, area->dy, area->width, area->height); } EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); @@ -934,8 +945,12 @@ EXPORT_SYMBOL(drm_fb_helper_sys_copyarea); void drm_fb_helper_sys_imageblit(struct fb_info *info, const struct fb_image *image) { + struct drm_fb_helper *helper = info->par; + sys_imageblit(info, image); - drm_fb_helper_damage(info, image->dx, image->dy, image->width, image->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, image->dx, image->dy, image->width, image->height); } EXPORT_SYMBOL(drm_fb_helper_sys_imageblit); @@ -1035,6 +1050,7 @@ static ssize_t fb_write_screen_base(struct fb_info *info, const char __user *buf ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { + struct drm_fb_helper *helper = info->par; loff_t pos = *ppos; ssize_t ret; struct drm_rect damage_area; @@ -1043,10 +1059,12 @@ ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, if (ret <= 0) return ret; - drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); - drm_fb_helper_damage(info, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + if (helper->funcs->fb_dirty) { + drm_fb_helper_memory_range_to_clip(info, pos, ret, &damage_area); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); + } return ret; } @@ -1062,8 +1080,12 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_write); void drm_fb_helper_cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { + struct drm_fb_helper *helper = info->par; + cfb_fillrect(info, rect); - drm_fb_helper_damage(info, rect->dx, rect->dy, rect->width, rect->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, rect->height); } EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); @@ -1077,8 +1099,12 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect); void drm_fb_helper_cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { + struct drm_fb_helper *helper = info->par; + cfb_copyarea(info, area); - drm_fb_helper_damage(info, area->dx, area->dy, area->width, area->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, area->dx, area->dy, area->width, area->height); } EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); @@ -1092,8 +1118,12 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea); void drm_fb_helper_cfb_imageblit(struct fb_info *info, const struct fb_image *image) { + struct drm_fb_helper *helper = info->par; + cfb_imageblit(info, image); - drm_fb_helper_damage(info, image->dx, image->dy, image->width, image->height); + + if (helper->funcs->fb_dirty) + drm_fb_helper_damage(helper, image->dx, image->dy, image->width, image->height); } EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 19/23] drm/fb-helper: Always initialize generic fbdev emulation
Initialize the generic fbdev emulation even if it has been disabled on the kernel command line. The hotplug and mode initialization will fail accordingly. The kernel parameter can still be changed at runtime and the emulation will initialize after hotplugging the connector. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/drm_fb_helper.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3dfda1e3830b3..95f389433c4a6 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -526,11 +526,6 @@ int drm_fb_helper_init(struct drm_device *dev, { int ret; - if (!drm_fbdev_emulation) { - dev->fb_helper = fb_helper; - return 0; - } - /* * If this is not the generic fbdev client, initialize a drm_client * without callbacks so we can use the modesets. @@ -2716,9 +2711,6 @@ void drm_fbdev_generic_setup(struct drm_device *dev, drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - if (!drm_fbdev_emulation) - return; - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); if (!fb_helper) { drm_err(dev, "Failed to allocate fb_helper\n"); -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 20/23] drm/fb-helper: Set flag in struct drm_fb_helper for leaking physical addresses
Uncouple the parameter drm_leak_fbdev_smem from the implementation by setting a flag in struct drm_fb_helper. This will help to move the generic fbdev emulation into its own source file, while keeping the parameter in drm_fb_helper.c. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- drivers/gpu/drm/drm_fb_helper.c | 10 +++++++--- include/drm/drm_fb_helper.h | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 95f389433c4a6..105d9c8fe3250 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -74,7 +74,7 @@ MODULE_PARM_DESC(drm_fbdev_overalloc, * considered as a broken and legacy behaviour from a modern fbdev device. */ #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) -static bool drm_leak_fbdev_smem = false; +static bool drm_leak_fbdev_smem; module_param_unsafe(drm_leak_fbdev_smem, bool, 0600); MODULE_PARM_DESC(drm_leak_fbdev_smem, "Allow unsafe leaking fbdev physical smem address [default=false]"); @@ -1968,6 +1968,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, sizes.surface_height = config->max_height; } +#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) + fb_helper->hint_leak_smem_start = drm_leak_fbdev_smem; +#endif + /* push down into drivers */ ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); if (ret < 0) @@ -2165,7 +2169,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, info->var.pixclock = 0; /* Shamelessly allow physical address leaking to userspace */ #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) - if (!drm_leak_fbdev_smem) + if (!fb_helper->hint_leak_smem_start) #endif /* don't leak any physical addresses to userspace */ info->flags |= FBINFO_HIDE_SMEM_START; @@ -2564,7 +2568,7 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, * case. */ #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) - if (drm_leak_fbdev_smem && fbi->fix.smem_start == 0 && + if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 && !drm_WARN_ON_ONCE(dev, map.is_iomem)) fbi->fix.smem_start page_to_phys(virt_to_page(fbi->screen_buffer)); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 6581183618b89..3dfb5d1093871 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -199,6 +199,8 @@ struct drm_fb_helper { * See also: @deferred_setup */ int preferred_bpp; + + bool hint_leak_smem_start; }; static inline struct drm_fb_helper * -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 21/23] drm/fb-helper: Move generic fbdev emulation into separate source file
Move the generic fbdev implementation into its own source and header file. Adapt drivers. No functional changes, but some of the internal helpers have been renamed to fit into the drm_fbdev_ naming scheme. v3: * rename drm_fbdev.{c,h} to drm_fbdev_generic.{c,h} * rebase onto vmwgfx changes * rebase onto xlnx changes * fix include statements in amdgpu Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/Makefile | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + .../gpu/drm/arm/display/komeda/komeda_drv.c | 2 +- drivers/gpu/drm/arm/hdlcd_drv.c | 2 +- drivers/gpu/drm/arm/malidp_drv.c | 2 +- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 2 +- drivers/gpu/drm/ast/ast_drv.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 498 +----------------- drivers/gpu/drm/drm_fbdev_generic.c | 493 +++++++++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 2 +- drivers/gpu/drm/gud/gud_drv.c | 2 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 1 + .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 2 +- drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 2 +- drivers/gpu/drm/imx/dcss/dcss-kms.c | 2 +- drivers/gpu/drm/imx/imx-drm-core.c | 2 +- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 2 +- drivers/gpu/drm/kmb/kmb_drv.c | 2 +- drivers/gpu/drm/logicvc/logicvc_drm.c | 2 +- drivers/gpu/drm/mcde/mcde_drv.c | 2 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 +- drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 1 + drivers/gpu/drm/mxsfb/lcdif_drv.c | 2 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 2 +- drivers/gpu/drm/pl111/pl111_drv.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.c | 1 + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- drivers/gpu/drm/solomon/ssd130x.c | 2 +- drivers/gpu/drm/sti/sti_drv.c | 2 +- drivers/gpu/drm/stm/drv.c | 2 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +- drivers/gpu/drm/tidss/tidss_drv.c | 2 +- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +- drivers/gpu/drm/tiny/arcpgu.c | 2 +- drivers/gpu/drm/tiny/bochs.c | 2 +- drivers/gpu/drm/tiny/cirrus.c | 2 +- drivers/gpu/drm/tiny/gm12u320.c | 2 +- drivers/gpu/drm/tiny/hx8357d.c | 2 +- drivers/gpu/drm/tiny/ili9163.c | 2 +- drivers/gpu/drm/tiny/ili9225.c | 2 +- drivers/gpu/drm/tiny/ili9341.c | 2 +- drivers/gpu/drm/tiny/ili9486.c | 2 +- drivers/gpu/drm/tiny/mi0283qt.c | 2 +- drivers/gpu/drm/tiny/ofdrm.c | 2 +- drivers/gpu/drm/tiny/panel-mipi-dbi.c | 2 +- drivers/gpu/drm/tiny/repaper.c | 2 +- drivers/gpu/drm/tiny/simpledrm.c | 2 +- drivers/gpu/drm/tiny/st7586.c | 2 +- drivers/gpu/drm/tiny/st7735r.c | 2 +- drivers/gpu/drm/tve200/tve200_drv.c | 2 +- drivers/gpu/drm/udl/udl_drv.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_drv.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + drivers/gpu/drm/vkms/vkms_drv.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- drivers/gpu/drm/xlnx/zynqmp_kms.c | 2 +- include/drm/drm_fb_helper.h | 9 - include/drm/drm_fbdev_generic.h | 15 + 63 files changed, 571 insertions(+), 558 deletions(-) create mode 100644 drivers/gpu/drm/drm_fbdev_generic.c create mode 100644 include/drm/drm_fbdev_generic.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 6e55c47288e42..c44a54cadb618 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -117,7 +117,9 @@ drm_kms_helper-y := \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o -drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o +drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \ + drm_fbdev_generic.o \ + drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o # diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 3c9fecdd6b2f3..ca96ee2c2c962 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -25,6 +25,7 @@ #include <drm/amdgpu_drm.h> #include <drm/drm_aperture.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem.h> #include <drm/drm_vblank.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c index 9fce4239d4ad4..3f4e719eebd85 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -9,7 +9,7 @@ #include <linux/platform_device.h> #include <linux/component.h> #include <linux/pm_runtime.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_module.h> #include <drm/drm_of.h> #include "komeda_dev.h" diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index a032003c340cc..3219cc33d7f69 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -26,7 +26,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_modeset_helper.h> diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index 1d0b0c54ccc74..b734dbdcc5773 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c @@ -19,7 +19,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index a94f1a9e8f409..718119e168a69 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -16,7 +16,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_device.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index bbeb5defc8f5c..420fc75c240e4 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -33,6 +33,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_module.h> #include <drm/drm_probe_helper.h> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index f7e7f4e919c77..a2bb5b9162352 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -19,7 +19,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 105d9c8fe3250..5eb2f0d4bf8d4 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -30,24 +30,17 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/console.h> -#include <linux/dma-buf.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> #include <linux/sysrq.h> -#include <linux/vmalloc.h> #include <drm/drm_atomic.h> -#include <drm/drm_crtc.h> -#include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> +#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_print.h> #include <drm/drm_vblank.h> -#include "drm_crtc_helper_internal.h" #include "drm_internal.h" static bool drm_fbdev_emulation = true; @@ -372,80 +365,6 @@ static void drm_fb_helper_resume_worker(struct work_struct *work) console_unlock(); } -static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper, - struct drm_clip_rect *clip, - struct iosys_map *dst) -{ - struct drm_framebuffer *fb = fb_helper->fb; - size_t offset = clip->y1 * fb->pitches[0]; - size_t len = clip->x2 - clip->x1; - unsigned int y; - void *src; - - switch (drm_format_info_bpp(fb->format, 0)) { - case 1: - offset += clip->x1 / 8; - len = DIV_ROUND_UP(len + clip->x1 % 8, 8); - break; - case 2: - offset += clip->x1 / 4; - len = DIV_ROUND_UP(len + clip->x1 % 4, 4); - break; - case 4: - offset += clip->x1 / 2; - len = DIV_ROUND_UP(len + clip->x1 % 2, 2); - break; - default: - offset += clip->x1 * fb->format->cpp[0]; - len *= fb->format->cpp[0]; - break; - } - - src = fb_helper->info->screen_buffer + offset; - iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ - - for (y = clip->y1; y < clip->y2; y++) { - iosys_map_memcpy_to(dst, 0, src, len); - iosys_map_incr(dst, fb->pitches[0]); - src += fb->pitches[0]; - } -} - -static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper, - struct drm_clip_rect *clip) -{ - struct drm_client_buffer *buffer = fb_helper->buffer; - struct iosys_map map, dst; - int ret; - - /* - * We have to pin the client buffer to its current location while - * flushing the shadow buffer. In the general case, concurrent - * modesetting operations could try to move the buffer and would - * fail. The modeset has to be serialized by acquiring the reservation - * object of the underlying BO here. - * - * For fbdev emulation, we only have to protect against fbdev modeset - * operations. Nothing else will involve the client buffer's BO. So it - * is sufficient to acquire struct drm_fb_helper.lock here. - */ - mutex_lock(&fb_helper->lock); - - ret = drm_client_buffer_vmap(buffer, &map); - if (ret) - goto out; - - dst = map; - drm_fb_helper_damage_blit_real(fb_helper, clip, &dst); - - drm_client_buffer_vunmap(buffer); - -out: - mutex_unlock(&fb_helper->lock); - - return ret; -} - static void drm_fb_helper_damage_work(struct work_struct *work) { struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work); @@ -2326,423 +2245,10 @@ EXPORT_SYMBOL(drm_fb_helper_lastclose); * * This function can be used as the * &drm_mode_config_funcs.output_poll_changed callback for drivers that only - * need to call drm_fb_helper_hotplug_event(). + * need to call drm_fbdev.hotplug_event(). */ void drm_fb_helper_output_poll_changed(struct drm_device *dev) { drm_fb_helper_hotplug_event(dev->fb_helper); } EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); - -static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper) -{ - struct drm_device *dev = fb_helper->dev; - struct drm_framebuffer *fb = fb_helper->fb; - - return dev->mode_config.prefer_shadow_fbdev || - dev->mode_config.prefer_shadow || - fb->funcs->dirty; -} - -/* @user: 1=userspace, 0=fbcon */ -static int drm_fbdev_fb_open(struct fb_info *info, int user) -{ - struct drm_fb_helper *fb_helper = info->par; - - /* No need to take a ref for fbcon because it unbinds on unregister */ - if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) - return -ENODEV; - - return 0; -} - -static int drm_fbdev_fb_release(struct fb_info *info, int user) -{ - struct drm_fb_helper *fb_helper = info->par; - - if (user) - module_put(fb_helper->dev->driver->fops->owner); - - return 0; -} - -static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) -{ - struct fb_info *fbi = fb_helper->info; - void *shadow = NULL; - - if (!fb_helper->dev) - return; - - if (fbi) { - if (fbi->fbdefio) - fb_deferred_io_cleanup(fbi); - if (drm_fbdev_use_shadow_fb(fb_helper)) - shadow = fbi->screen_buffer; - } - - drm_fb_helper_fini(fb_helper); - - if (shadow) - vfree(shadow); - else if (fb_helper->buffer) - drm_client_buffer_vunmap(fb_helper->buffer); - - drm_client_framebuffer_delete(fb_helper->buffer); -} - -static void drm_fbdev_release(struct drm_fb_helper *fb_helper) -{ - drm_fbdev_cleanup(fb_helper); - drm_client_release(&fb_helper->client); - kfree(fb_helper); -} - -/* - * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of - * unregister_framebuffer() or fb_release(). - */ -static void drm_fbdev_fb_destroy(struct fb_info *info) -{ - drm_fbdev_release(info->par); -} - -static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct drm_fb_helper *fb_helper = info->par; - - if (drm_fbdev_use_shadow_fb(fb_helper)) - return fb_deferred_io_mmap(info, vma); - else if (fb_helper->dev->driver->gem_prime_mmap) - return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma); - else - return -ENODEV; -} - -static bool drm_fbdev_use_iomem(struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_client_buffer *buffer = fb_helper->buffer; - - return !drm_fbdev_use_shadow_fb(fb_helper) && buffer->map.is_iomem; -} - -static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, - size_t count, loff_t *ppos) -{ - ssize_t ret; - - if (drm_fbdev_use_iomem(info)) - ret = drm_fb_helper_cfb_read(info, buf, count, ppos); - else - ret = drm_fb_helper_sys_read(info, buf, count, ppos); - - return ret; -} - -static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) -{ - ssize_t ret; - - if (drm_fbdev_use_iomem(info)) - ret = drm_fb_helper_cfb_write(info, buf, count, ppos); - else - ret = drm_fb_helper_sys_write(info, buf, count, ppos); - - return ret; -} - -static void drm_fbdev_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - if (drm_fbdev_use_iomem(info)) - drm_fb_helper_cfb_fillrect(info, rect); - else - drm_fb_helper_sys_fillrect(info, rect); -} - -static void drm_fbdev_fb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - if (drm_fbdev_use_iomem(info)) - drm_fb_helper_cfb_copyarea(info, area); - else - drm_fb_helper_sys_copyarea(info, area); -} - -static void drm_fbdev_fb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - if (drm_fbdev_use_iomem(info)) - drm_fb_helper_cfb_imageblit(info, image); - else - drm_fb_helper_sys_imageblit(info, image); -} - -static const struct fb_ops drm_fbdev_fb_ops = { - .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, - .fb_open = drm_fbdev_fb_open, - .fb_release = drm_fbdev_fb_release, - .fb_destroy = drm_fbdev_fb_destroy, - .fb_mmap = drm_fbdev_fb_mmap, - .fb_read = drm_fbdev_fb_read, - .fb_write = drm_fbdev_fb_write, - .fb_fillrect = drm_fbdev_fb_fillrect, - .fb_copyarea = drm_fbdev_fb_copyarea, - .fb_imageblit = drm_fbdev_fb_imageblit, -}; - -static struct fb_deferred_io drm_fbdev_defio = { - .delay = HZ / 20, - .deferred_io = drm_fb_helper_deferred_io, -}; - -/* - * This function uses the client API to create a framebuffer backed by a dumb buffer. - * - * The _sys_ versions are used for &fb_ops.fb_read, fb_write, fb_fillrect, - * fb_copyarea, fb_imageblit. - */ -static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_client_dev *client = &fb_helper->client; - struct drm_device *dev = fb_helper->dev; - struct drm_client_buffer *buffer; - struct drm_framebuffer *fb; - struct fb_info *fbi; - u32 format; - struct iosys_map map; - int ret; - - drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); - - format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); - buffer = drm_client_framebuffer_create(client, sizes->surface_width, - sizes->surface_height, format); - if (IS_ERR(buffer)) - return PTR_ERR(buffer); - - fb_helper->buffer = buffer; - fb_helper->fb = buffer->fb; - fb = buffer->fb; - - fbi = drm_fb_helper_alloc_info(fb_helper); - if (IS_ERR(fbi)) - return PTR_ERR(fbi); - - fbi->fbops = &drm_fbdev_fb_ops; - fbi->screen_size = sizes->surface_height * fb->pitches[0]; - fbi->fix.smem_len = fbi->screen_size; - fbi->flags = FBINFO_DEFAULT; - - drm_fb_helper_fill_info(fbi, fb_helper, sizes); - - if (drm_fbdev_use_shadow_fb(fb_helper)) { - fbi->screen_buffer = vzalloc(fbi->screen_size); - if (!fbi->screen_buffer) - return -ENOMEM; - fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; - - fbi->fbdefio = &drm_fbdev_defio; - fb_deferred_io_init(fbi); - } else { - /* buffer is mapped for HW framebuffer */ - ret = drm_client_buffer_vmap(fb_helper->buffer, &map); - if (ret) - return ret; - if (map.is_iomem) { - fbi->screen_base = map.vaddr_iomem; - } else { - fbi->screen_buffer = map.vaddr; - fbi->flags |= FBINFO_VIRTFB; - } - - /* - * Shamelessly leak the physical address to user-space. As - * page_to_phys() is undefined for I/O memory, warn in this - * case. - */ -#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) - if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 && - !drm_WARN_ON_ONCE(dev, map.is_iomem)) - fbi->fix.smem_start - page_to_phys(virt_to_page(fbi->screen_buffer)); -#endif - } - - return 0; -} - -static int drm_fbdev_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) -{ - struct drm_device *dev = helper->dev; - int ret; - - if (!drm_fbdev_use_shadow_fb(helper)) - return 0; - - /* Call damage handlers only if necessary */ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->buffer) { - ret = drm_fb_helper_damage_blit(helper, clip); - if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) - return ret; - } - - 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 drm_fb_helper_generic_funcs = { - .fb_probe = drm_fb_helper_generic_probe, - .fb_dirty = drm_fbdev_fb_dirty, -}; - -static void drm_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) - /* drm_fbdev_fb_destroy() takes care of cleanup */ - drm_fb_helper_unregister_info(fb_helper); - else - drm_fbdev_release(fb_helper); -} - -static int drm_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - /* Setup is not retried if it has failed */ - if (!fb_helper->dev && fb_helper->funcs) - return 0; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - if (!dev->mode_config.num_connector) { - drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n"); - return 0; - } - - drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp); - if (ret) - goto err_cleanup; - - return 0; - -err_cleanup: - drm_fbdev_cleanup(fb_helper); -err: - fb_helper->dev = NULL; - fb_helper->info = NULL; - - drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); - - return ret; -} - -static const struct drm_client_funcs drm_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_client_unregister, - .restore = drm_fbdev_client_restore, - .hotplug = drm_fbdev_client_hotplug, -}; - -/** - * 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. - * drm_fbdev_generic_setup() shall be called after the DRM driver registered - * the new DRM device with drm_dev_register(). - * - * Restore, hotplug events and teardown are all taken care of. Drivers that do - * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. - * Simple drivers might use drm_mode_config_helper_suspend(). - * - * Drivers that set the dirty callback on their framebuffer will get a shadow - * fbdev buffer that is blitted onto the real buffer. This is done in order to - * make deferred I/O work with all kinds of buffers. A shadow buffer can be - * requested explicitly by setting struct drm_mode_config.prefer_shadow or - * struct drm_mode_config.prefer_shadow_fbdev to true beforehand. This is - * required to use generic fbdev emulation with SHMEM helpers. - * - * This function is safe to call even when there are no connectors present. - * Setup will be retried on the next hotplug event. - * - * The fbdev is destroyed by drm_dev_unregister(). - */ -void drm_fbdev_generic_setup(struct drm_device *dev, - unsigned int preferred_bpp) -{ - struct drm_fb_helper *fb_helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) { - drm_err(dev, "Failed to allocate fb_helper\n"); - return; - } - - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); - if (ret) { - kfree(fb_helper); - drm_err(dev, "Failed to register client: %d\n", ret); - return; - } - - /* - * 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. - */ - if (!preferred_bpp) - preferred_bpp = dev->mode_config.preferred_depth; - if (!preferred_bpp) - preferred_bpp = 32; - fb_helper->preferred_bpp = preferred_bpp; - - ret = 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); -} -EXPORT_SYMBOL(drm_fbdev_generic_setup); diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c new file mode 100644 index 0000000000000..2d6083ad2e3c7 --- /dev/null +++ b/drivers/gpu/drm/drm_fbdev_generic.c @@ -0,0 +1,493 @@ +// SPDX-License-Identifier: MIT + +#include <linux/moduleparam.h> + +#include <drm/drm_crtc_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_print.h> + +#include <drm/drm_fbdev_generic.h> + +static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper) +{ + struct drm_device *dev = fb_helper->dev; + struct drm_framebuffer *fb = fb_helper->fb; + + return dev->mode_config.prefer_shadow_fbdev || + dev->mode_config.prefer_shadow || + fb->funcs->dirty; +} + +/* @user: 1=userspace, 0=fbcon */ +static int drm_fbdev_fb_open(struct fb_info *info, int user) +{ + struct drm_fb_helper *fb_helper = info->par; + + /* No need to take a ref for fbcon because it unbinds on unregister */ + if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) + return -ENODEV; + + return 0; +} + +static int drm_fbdev_fb_release(struct fb_info *info, int user) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (user) + module_put(fb_helper->dev->driver->fops->owner); + + return 0; +} + +static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) +{ + struct fb_info *fbi = fb_helper->info; + void *shadow = NULL; + + if (!fb_helper->dev) + return; + + if (fbi) { + if (fbi->fbdefio) + fb_deferred_io_cleanup(fbi); + if (drm_fbdev_use_shadow_fb(fb_helper)) + shadow = fbi->screen_buffer; + } + + drm_fb_helper_fini(fb_helper); + + if (shadow) + vfree(shadow); + else if (fb_helper->buffer) + drm_client_buffer_vunmap(fb_helper->buffer); + + drm_client_framebuffer_delete(fb_helper->buffer); +} + +static void drm_fbdev_release(struct drm_fb_helper *fb_helper) +{ + drm_fbdev_cleanup(fb_helper); + drm_client_release(&fb_helper->client); + kfree(fb_helper); +} + +/* + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of + * unregister_framebuffer() or fb_release(). + */ +static void drm_fbdev_fb_destroy(struct fb_info *info) +{ + drm_fbdev_release(info->par); +} + +static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (drm_fbdev_use_shadow_fb(fb_helper)) + return fb_deferred_io_mmap(info, vma); + else if (fb_helper->dev->driver->gem_prime_mmap) + return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, vma); + else + return -ENODEV; +} + +static bool drm_fbdev_use_iomem(struct fb_info *info) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_client_buffer *buffer = fb_helper->buffer; + + return !drm_fbdev_use_shadow_fb(fb_helper) && buffer->map.is_iomem; +} + +static ssize_t drm_fbdev_fb_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + ssize_t ret; + + if (drm_fbdev_use_iomem(info)) + ret = drm_fb_helper_cfb_read(info, buf, count, ppos); + else + ret = drm_fb_helper_sys_read(info, buf, count, ppos); + + return ret; +} + +static ssize_t drm_fbdev_fb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + ssize_t ret; + + if (drm_fbdev_use_iomem(info)) + ret = drm_fb_helper_cfb_write(info, buf, count, ppos); + else + ret = drm_fb_helper_sys_write(info, buf, count, ppos); + + return ret; +} + +static void drm_fbdev_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + if (drm_fbdev_use_iomem(info)) + drm_fb_helper_cfb_fillrect(info, rect); + else + drm_fb_helper_sys_fillrect(info, rect); +} + +static void drm_fbdev_fb_copyarea(struct fb_info *info, + const struct fb_copyarea *area) +{ + if (drm_fbdev_use_iomem(info)) + drm_fb_helper_cfb_copyarea(info, area); + else + drm_fb_helper_sys_copyarea(info, area); +} + +static void drm_fbdev_fb_imageblit(struct fb_info *info, + const struct fb_image *image) +{ + if (drm_fbdev_use_iomem(info)) + drm_fb_helper_cfb_imageblit(info, image); + else + drm_fb_helper_sys_imageblit(info, image); +} + +static const struct fb_ops drm_fbdev_fb_ops = { + .owner = THIS_MODULE, + DRM_FB_HELPER_DEFAULT_OPS, + .fb_open = drm_fbdev_fb_open, + .fb_release = drm_fbdev_fb_release, + .fb_destroy = drm_fbdev_fb_destroy, + .fb_mmap = drm_fbdev_fb_mmap, + .fb_read = drm_fbdev_fb_read, + .fb_write = drm_fbdev_fb_write, + .fb_fillrect = drm_fbdev_fb_fillrect, + .fb_copyarea = drm_fbdev_fb_copyarea, + .fb_imageblit = drm_fbdev_fb_imageblit, +}; + +static struct fb_deferred_io drm_fbdev_defio = { + .delay = HZ / 20, + .deferred_io = drm_fb_helper_deferred_io, +}; + +/* + * This function uses the client API to create a framebuffer backed by a dumb buffer. + */ +static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; + struct drm_client_buffer *buffer; + struct drm_framebuffer *fb; + struct fb_info *fbi; + u32 format; + struct iosys_map map; + int ret; + + drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); + + format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); + buffer = drm_client_framebuffer_create(client, sizes->surface_width, + sizes->surface_height, format); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); + + fb_helper->buffer = buffer; + fb_helper->fb = buffer->fb; + fb = buffer->fb; + + fbi = drm_fb_helper_alloc_info(fb_helper); + if (IS_ERR(fbi)) + return PTR_ERR(fbi); + + fbi->fbops = &drm_fbdev_fb_ops; + fbi->screen_size = sizes->surface_height * fb->pitches[0]; + fbi->fix.smem_len = fbi->screen_size; + fbi->flags = FBINFO_DEFAULT; + + drm_fb_helper_fill_info(fbi, fb_helper, sizes); + + if (drm_fbdev_use_shadow_fb(fb_helper)) { + fbi->screen_buffer = vzalloc(fbi->screen_size); + if (!fbi->screen_buffer) + return -ENOMEM; + fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; + + fbi->fbdefio = &drm_fbdev_defio; + fb_deferred_io_init(fbi); + } else { + /* buffer is mapped for HW framebuffer */ + ret = drm_client_buffer_vmap(fb_helper->buffer, &map); + if (ret) + return ret; + if (map.is_iomem) { + fbi->screen_base = map.vaddr_iomem; + } else { + fbi->screen_buffer = map.vaddr; + fbi->flags |= FBINFO_VIRTFB; + } + + /* + * Shamelessly leak the physical address to user-space. As + * page_to_phys() is undefined for I/O memory, warn in this + * case. + */ +#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) + if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 && + !drm_WARN_ON_ONCE(dev, map.is_iomem)) + fbi->fix.smem_start + page_to_phys(virt_to_page(fbi->screen_buffer)); +#endif + } + + return 0; +} + +static void drm_fbdev_damage_blit_real(struct drm_fb_helper *fb_helper, + struct drm_clip_rect *clip, + struct iosys_map *dst) +{ + struct drm_framebuffer *fb = fb_helper->fb; + size_t offset = clip->y1 * fb->pitches[0]; + size_t len = clip->x2 - clip->x1; + unsigned int y; + void *src; + + switch (drm_format_info_bpp(fb->format, 0)) { + case 1: + offset += clip->x1 / 8; + len = DIV_ROUND_UP(len + clip->x1 % 8, 8); + break; + case 2: + offset += clip->x1 / 4; + len = DIV_ROUND_UP(len + clip->x1 % 4, 4); + break; + case 4: + offset += clip->x1 / 2; + len = DIV_ROUND_UP(len + clip->x1 % 2, 2); + break; + default: + offset += clip->x1 * fb->format->cpp[0]; + len *= fb->format->cpp[0]; + break; + } + + src = fb_helper->info->screen_buffer + offset; + iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ + + for (y = clip->y1; y < clip->y2; y++) { + iosys_map_memcpy_to(dst, 0, src, len); + iosys_map_incr(dst, fb->pitches[0]); + src += fb->pitches[0]; + } +} + +static int drm_fbdev_damage_blit(struct drm_fb_helper *fb_helper, + struct drm_clip_rect *clip) +{ + struct drm_client_buffer *buffer = fb_helper->buffer; + struct iosys_map map, dst; + int ret; + + /* + * We have to pin the client buffer to its current location while + * flushing the shadow buffer. In the general case, concurrent + * modesetting operations could try to move the buffer and would + * fail. The modeset has to be serialized by acquiring the reservation + * object of the underlying BO here. + * + * For fbdev emulation, we only have to protect against fbdev modeset + * operations. Nothing else will involve the client buffer's BO. So it + * is sufficient to acquire struct drm_fb_helper.lock here. + */ + mutex_lock(&fb_helper->lock); + + ret = drm_client_buffer_vmap(buffer, &map); + if (ret) + goto out; + + dst = map; + drm_fbdev_damage_blit_real(fb_helper, clip, &dst); + + drm_client_buffer_vunmap(buffer); + +out: + mutex_unlock(&fb_helper->lock); + + return ret; +} + +static int drm_fbdev_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + if (!drm_fbdev_use_shadow_fb(helper)) + return 0; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->buffer) { + ret = drm_fbdev_damage_blit(helper, clip); + if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) + return ret; + } + + 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 drm_fb_helper_generic_funcs = { + .fb_probe = drm_fbdev_fb_probe, + .fb_dirty = drm_fbdev_fb_dirty, +}; + +static void drm_fbdev_client_unregister(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (fb_helper->info) + /* drm_fbdev_fb_destroy() takes care of cleanup */ + drm_fb_helper_unregister_info(fb_helper); + else + drm_fbdev_release(fb_helper); +} + +static int drm_fbdev_client_restore(struct drm_client_dev *client) +{ + drm_fb_helper_lastclose(client->dev); + + return 0; +} + +static int drm_fbdev_client_hotplug(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = client->dev; + int ret; + + /* Setup is not retried if it has failed */ + if (!fb_helper->dev && fb_helper->funcs) + return 0; + + if (dev->fb_helper) + return drm_fb_helper_hotplug_event(dev->fb_helper); + + if (!dev->mode_config.num_connector) { + drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n"); + return 0; + } + + drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs); + + ret = drm_fb_helper_init(dev, fb_helper); + if (ret) + goto err; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp); + if (ret) + goto err_cleanup; + + return 0; + +err_cleanup: + drm_fbdev_cleanup(fb_helper); +err: + fb_helper->dev = NULL; + fb_helper->info = NULL; + + drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); + + return ret; +} + +static const struct drm_client_funcs drm_fbdev_client_funcs = { + .owner = THIS_MODULE, + .unregister = drm_fbdev_client_unregister, + .restore = drm_fbdev_client_restore, + .hotplug = drm_fbdev_client_hotplug, +}; + +/** + * 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. + * drm_fbdev_generic_setup() shall be called after the DRM driver registered + * the new DRM device with drm_dev_register(). + * + * Restore, hotplug events and teardown are all taken care of. Drivers that do + * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. + * Simple drivers might use drm_mode_config_helper_suspend(). + * + * Drivers that set the dirty callback on their framebuffer will get a shadow + * fbdev buffer that is blitted onto the real buffer. This is done in order to + * make deferred I/O work with all kinds of buffers. A shadow buffer can be + * requested explicitly by setting struct drm_mode_config.prefer_shadow or + * struct drm_mode_config.prefer_shadow_fbdev to true beforehand. This is + * required to use generic fbdev emulation with SHMEM helpers. + * + * This function is safe to call even when there are no connectors present. + * Setup will be retried on the next hotplug event. + * + * The fbdev is destroyed by drm_dev_unregister(). + */ +void drm_fbdev_generic_setup(struct drm_device *dev, + unsigned int preferred_bpp) +{ + struct drm_fb_helper *fb_helper; + int ret; + + drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); + drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); + + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) + return; + + ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); + if (ret) { + kfree(fb_helper); + drm_err(dev, "Failed to register client: %d\n", ret); + return; + } + + /* + * 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. + */ + if (!preferred_bpp) + preferred_bpp = dev->mode_config.preferred_depth; + if (!preferred_bpp) + preferred_bpp = 32; + fb_helper->preferred_bpp = preferred_bpp; + + ret = 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); +} +EXPORT_SYMBOL(drm_fbdev_generic_setup); diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index b4acc3422ba45..8579c7629f5e1 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -20,7 +20,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_modeset_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index 8d1630b8edac1..d57dab104358b 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -18,7 +18,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 5a2e1cac06b2e..22053c613644a 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -17,6 +17,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_vram_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 73ee7f25f7346..9c5d49bf40c97 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -19,7 +19,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index ca127ff797f75..427c20ba34045 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -11,7 +11,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_simple_kms_helper.h> diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index 1defd6a40f11d..18df3888b7f94 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -7,7 +7,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge_connector.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 8dd8b0f912af6..e060fa6cbcb92 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -16,7 +16,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 99f86f1ba8bee..fc9de7e373ae3 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -32,7 +32,7 @@ #include <drm/drm_encoder.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c index 2382ccb3ee99d..d29c678f6c912 100644 --- a/drivers/gpu/drm/kmb/kmb_drv.c +++ b/drivers/gpu/drm/kmb/kmb_drv.c @@ -15,7 +15,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c index cc9a4e965f779..9de24d9f0c963 100644 --- a/drivers/gpu/drm/logicvc/logicvc_drm.c +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c @@ -17,7 +17,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_print.h> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 38c3907bb151a..4aedb050d2a59 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -69,7 +69,7 @@ #include <drm/drm_bridge.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 91f58db5915f5..39a42dc8fb851 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -17,7 +17,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem.h> #include <drm/drm_gem_dma_helper.h> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 3b24a924b7b97..79bfe3938d3c6 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -18,7 +18,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_modeset_helper_vtables.h> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ece6cd102dbb1..976f0ab2006b5 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -11,6 +11,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c index 075002ed6fb09..cc2ceb301b96d 100644 --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c @@ -16,7 +16,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_mode_config.h> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index b29b332ed3814..810edea0a31e5 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -20,7 +20,7 @@ #include <drm/drm_bridge.h> #include <drm/drm_connector.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index b59472c29a40d..384a724f2822e 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -31,7 +31,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index eb25eedb5ee00..00deba0b72716 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -48,7 +48,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 3044ca948ce22..a3b83f89e0616 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -37,6 +37,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_gem_ttm_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index a2776f1d6f2c2..d003e8d9e7a26 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -20,7 +20,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> #include <drm/drm_probe_helper.h> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 813f9f8c86982..6e0788d14c10f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -17,7 +17,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_of.h> #include <drm/drm_probe_helper.h> diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index f2795f90ea693..53464afc2b9ac 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -23,7 +23,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_format_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index 7abf010a32935..ef6a4e63198f5 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -14,7 +14,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index d7914f5122dff..50410bd99dfe1 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -18,7 +18,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index d06ffd99d86e1..cc94efbbf2d4e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -17,7 +17,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_module.h> #include <drm/drm_of.h> diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index 15cd9b91b7e2a..07d94b1e80895 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -14,7 +14,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index f72755b8ea14c..80615ecdae0b2 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -16,7 +16,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c index bb302a3fd6b5f..611bbee150719 100644 --- a/drivers/gpu/drm/tiny/arcpgu.c +++ b/drivers/gpu/drm/tiny/arcpgu.c @@ -12,7 +12,7 @@ #include <drm/drm_drv.h> #include <drm/drm_edid.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_dma_helper.h> diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 04682f831544c..024346054c70e 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -7,7 +7,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 354d5e854a6f0..678c2ef1cae70 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -30,7 +30,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_format_helper.h> #include <drm/drm_fourcc.h> diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 7441d992a5d7a..130fd07a967d8 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -12,7 +12,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_format_helper.h> #include <drm/drm_fourcc.h> diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c index 48c24aa8c28a1..9f634f720817b 100644 --- a/drivers/gpu/drm/tiny/hx8357d.c +++ b/drivers/gpu/drm/tiny/hx8357d.c @@ -18,7 +18,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c index 9a1a5943bee01..ca0451f799625 100644 --- a/drivers/gpu/drm/tiny/ili9163.c +++ b/drivers/gpu/drm/tiny/ili9163.c @@ -9,7 +9,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_mipi_dbi.h> diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c index a79da2b4af647..815bab2858231 100644 --- a/drivers/gpu/drm/tiny/ili9225.c +++ b/drivers/gpu/drm/tiny/ili9225.c @@ -20,7 +20,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c index 69b265e78096b..420f6005a9568 100644 --- a/drivers/gpu/drm/tiny/ili9341.c +++ b/drivers/gpu/drm/tiny/ili9341.c @@ -17,7 +17,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index c80028bb1d110..1bb847466b107 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -16,7 +16,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c index bc522fb3d94d1..47df2b5a3048f 100644 --- a/drivers/gpu/drm/tiny/mi0283qt.c +++ b/drivers/gpu/drm/tiny/mi0283qt.c @@ -15,7 +15,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index 0e1cc2369afcc..cee626f730e79 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -11,7 +11,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_device.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_format_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c index 955a61d628e7c..03a7d569cd568 100644 --- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c @@ -16,7 +16,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index e62f4d16b2c6b..c2677d081a7b6 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -26,7 +26,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_format_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index cbb100753154e..162eb44dcba89 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -15,7 +15,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_device.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_format_helper.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c index b6f620b902e6d..ce57fa9917e51 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/tiny/st7586.c @@ -16,7 +16,7 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_format_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index c36ba08acda18..15d9cf283c66a 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -18,7 +18,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c index 611785e097576..0d05c386d3030 100644 --- a/drivers/gpu/drm/tve200/tve200_drv.c +++ b/drivers/gpu/drm/tve200/tve200_drv.c @@ -40,7 +40,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 91effdcefb6d5..e81352126a0f2 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -7,7 +7,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index 1cd716eb17a1c..b450f449a3aba 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -14,7 +14,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 2027063fdc309..b66bf7aea6327 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -33,7 +33,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_vblank.h> #include <soc/bcm2835/raspberrypi-firmware.h> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 0035affc3e590..ae97b98750b6d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -35,6 +35,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include "virtgpu_drv.h" diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 0ffe5f0e33f75..293dbca50c316 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -17,7 +17,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_ioctl.h> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 63496773f7142..bd02cb0e6837f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -35,7 +35,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_gem_ttm_helper.h> #include <drm/drm_ioctl.h> #include <drm/drm_module.h> diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c index 1847792cf13db..776ef54802064 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c @@ -19,7 +19,7 @@ #include <drm/drm_device.h> #include <drm/drm_drv.h> #include <drm/drm_encoder.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_generic.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_dma_helper.h> diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 3dfb5d1093871..ecfcd2c56d95a 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -287,9 +287,6 @@ int drm_fb_helper_debug_leave(struct fb_info *info); void drm_fb_helper_lastclose(struct drm_device *dev); void drm_fb_helper_output_poll_changed(struct drm_device *dev); - -void drm_fbdev_generic_setup(struct drm_device *dev, - unsigned int preferred_bpp); #else static inline void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, @@ -474,12 +471,6 @@ static inline void drm_fb_helper_lastclose(struct drm_device *dev) static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev) { } - -static inline void -drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ -} - #endif #endif diff --git a/include/drm/drm_fbdev_generic.h b/include/drm/drm_fbdev_generic.h new file mode 100644 index 0000000000000..75799342098dc --- /dev/null +++ b/include/drm/drm_fbdev_generic.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_FBDEV_GENERIC_H +#define DRM_FBDEV_GENERIC_H + +struct drm_device; + +#ifdef CONFIG_DRM_FBDEV_EMULATION +void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp); +#else +static inline void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) +{ } +#endif + +#endif -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 22/23] drm/fb-helper: Remove unnecessary include statements
Remove include statements for <drm/drm_fb_helper.h> where it is not required (i.e., most of them). In a few places include other header files that are required by the source code. v3: * fix amdgpu include statements * fix rockchip include statements Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 1 - drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c | 1 - drivers/gpu/drm/ast/ast_drv.h | 1 - drivers/gpu/drm/bridge/tc358762.c | 2 +- drivers/gpu/drm/drm_crtc_helper.c | 1 - drivers/gpu/drm/drm_gem_framebuffer_helper.c | 1 - drivers/gpu/drm/drm_probe_helper.c | 1 - drivers/gpu/drm/etnaviv/etnaviv_drv.h | 3 ++- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 - drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 1 - drivers/gpu/drm/imx/imx-ldb.c | 2 +- drivers/gpu/drm/imx/imx-tve.c | 1 - drivers/gpu/drm/imx/parallel-display.c | 2 +- drivers/gpu/drm/kmb/kmb_plane.c | 1 - drivers/gpu/drm/mgag200/mgag200_drv.h | 1 - drivers/gpu/drm/qxl/qxl_drv.h | 1 - drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + drivers/gpu/drm/tidss/tidss_kms.c | 1 - drivers/gpu/drm/v3d/v3d_drv.c | 1 - drivers/gpu/drm/vboxvideo/vbox_main.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/xen/xen_drm_front_gem.c | 1 - 31 files changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 491d4846fc02c..e1320edfc5274 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -26,7 +26,6 @@ #include <drm/display/drm_dp_helper.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_probe_helper.h> #include <drm/amdgpu_drm.h> #include "amdgpu.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ddaecb2610c94..56a031a2e087e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -37,6 +37,7 @@ #include <linux/pci-p2pdma.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_probe_helper.h> #include <drm/amdgpu_drm.h> #include <linux/vgaarb.h> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index dd6f9ae6fbe9f..311a8ea6f0654 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -39,8 +39,8 @@ #include <linux/pm_runtime.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_edid.h> -#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_fb_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_vblank.h> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index bf1ff8f0e7120..e3a18f069ce5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -29,6 +29,7 @@ #include "amdgpu.h" #include <drm/amdgpu_drm.h> #include <drm/drm_drv.h> +#include <drm/drm_fb_helper.h> #include "amdgpu_uvd.h" #include "amdgpu_vce.h" #include "atom.h" diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 37322550d7508..8a39300b1a845 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -36,7 +36,6 @@ #include <drm/drm_encoder.h> #include <drm/drm_fixed.h> #include <drm/drm_crtc_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_probe_helper.h> #include <linux/i2c.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 05051d5d2ec31..90f87b2d985b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -21,6 +21,7 @@ * */ +#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_vblank.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index c928bc9eb2026..0352de72c886a 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -21,6 +21,7 @@ * */ +#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_vblank.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index 62315fd5a05f2..07bd16e820461 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -23,6 +23,7 @@ #include <linux/pci.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_vblank.h> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 87d5e4c21cb37..d73df100f2b3b 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -21,6 +21,7 @@ * */ +#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_vblank.h> diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 7030339fa2323..ddbe1dd2d44ef 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -19,7 +19,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_of.h> diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 74f41282444f6..d51b81fea9c80 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -38,7 +38,6 @@ #include <drm/drm_encoder.h> #include <drm/drm_mode.h> #include <drm/drm_framebuffer.h> -#include <drm/drm_fb_helper.h> #define DRIVER_AUTHOR "Dave Airlie" diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c index 7f4fce1aa9988..0b6a284368859 100644 --- a/drivers/gpu/drm/bridge/tc358762.c +++ b/drivers/gpu/drm/bridge/tc358762.c @@ -11,6 +11,7 @@ */ #include <linux/delay.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/of_graph.h> #include <linux/regulator/consumer.h> @@ -19,7 +20,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f5fb22e0d0337..a209659a996c7 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -43,7 +43,6 @@ #include <drm/drm_drv.h> #include <drm/drm_edid.h> #include <drm/drm_encoder.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_print.h> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index e35e224e6303a..e93533b86037f 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -9,7 +9,6 @@ #include <linux/module.h> #include <drm/drm_damage_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem.h> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 2fc21df709bcb..bcd9611dabfd9 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -36,7 +36,6 @@ #include <drm/drm_client.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_print.h> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index f32f4771dada7..2bb4c25565dcb 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -6,13 +6,14 @@ #ifndef __ETNAVIV_DRV_H__ #define __ETNAVIV_DRV_H__ +#include <linux/io.h> #include <linux/list.h> #include <linux/mm_types.h> #include <linux/sizes.h> #include <linux/time64.h> #include <linux/types.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_drv.h> #include <drm/drm_gem.h> #include <drm/etnaviv_drm.h> #include <drm/gpu_scheduler.h> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 4a0cd22c10e21..f957552c6c507 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -19,7 +19,6 @@ #include <linux/i2c.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_framebuffer.h> struct hibmc_connector { diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c index 28e732f94bf2f..6c6b572987973 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c @@ -8,7 +8,6 @@ #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_format_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 41799011f73b6..c45fc8f4744d0 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -7,6 +7,7 @@ #include <linux/clk.h> #include <linux/component.h> +#include <linux/i2c.h> #include <linux/media-bus-format.h> #include <linux/mfd/syscon.h> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> @@ -23,7 +24,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 6b34fac3f73a0..d64ebd2cf15e8 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -19,7 +19,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_managed.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 06723b2e9b847..0fa0b590830b6 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -8,6 +8,7 @@ #include <linux/component.h> #include <linux/media-bus-format.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/videodev2.h> @@ -16,7 +17,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_edid.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> diff --git a/drivers/gpu/drm/kmb/kmb_plane.c b/drivers/gpu/drm/kmb/kmb_plane.c index a42f63f6f9573..d172a302f9024 100644 --- a/drivers/gpu/drm/kmb/kmb_plane.c +++ b/drivers/gpu/drm/kmb/kmb_plane.c @@ -9,7 +9,6 @@ #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_dma_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_dma_helper.h> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index f0c2349404b46..9e604dbb8e448 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -18,7 +18,6 @@ #include <drm/drm_connector.h> #include <drm/drm_crtc.h> #include <drm/drm_encoder.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_gem.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_plane.h> diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 432758ad39a35..76f060810f634 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -38,7 +38,6 @@ #include <drm/drm_crtc.h> #include <drm/drm_encoder.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_gem_ttm_helper.h> #include <drm/drm_ioctl.h> #include <drm/drm_gem.h> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 1641440837af5..aeb03a57240fd 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -9,10 +9,10 @@ #ifndef _ROCKCHIP_DRM_DRV_H #define _ROCKCHIP_DRM_DRV_H -#include <drm/drm_fb_helper.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_gem.h> +#include <linux/i2c.h> #include <linux/module.h> #include <linux/component.h> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index da8a69953706d..6edb7c52cb3dc 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -9,6 +9,7 @@ #include <linux/vmalloc.h> #include <drm/drm.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_gem.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_prime.h> diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index afb2879980c6c..345bcc3011e4f 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -10,7 +10,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_crtc_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index e8c975b815859..478f1f0f60dec 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -22,7 +22,6 @@ #include <linux/reset.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_managed.h> #include <uapi/drm/v3d_drm.h> diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c index c9e8b3a63c621..3b83e550f4df5 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -11,7 +11,6 @@ #include <linux/pci.h> #include <linux/vbox_err.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 9b98470593b06..b7a64c7dcc2c9 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -35,7 +35,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_drv.h> #include <drm/drm_encoder.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem.h> diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c index e31554d7139f1..4c95ebcdcc2d3 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -12,7 +12,6 @@ #include <linux/scatterlist.h> #include <linux/shmem_fs.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_gem.h> #include <drm/drm_prime.h> #include <drm/drm_probe_helper.h> -- 2.38.0
Thomas Zimmermann
2022-Nov-03 15:14 UTC
[Nouveau] [PATCH v3 23/23] drm/fb-helper: Clarify use of last_close and output_poll_changed
Clarify documentation in the use of struct drm_driver.last_close and struct drm_mode_config_funcs.output_poll_changed. Those callbacks should not be said for fbdev implementations on top of struct drm_client_funcs. Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> --- drivers/gpu/drm/drm_fb_helper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5eb2f0d4bf8d4..e0384f967c0b3 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -89,11 +89,13 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * It will automatically set up deferred I/O if the driver requires a shadow * buffer. * - * At runtime drivers should restore the fbdev console by using + * Existing fbdev implementations should restore the fbdev console by using * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback. * They should also notify the fb helper code from updates to the output * configuration by using drm_fb_helper_output_poll_changed() as their - * &drm_mode_config_funcs.output_poll_changed callback. + * &drm_mode_config_funcs.output_poll_changed callback. New implementations + * of fbdev should be build on top of struct &drm_client_funcs, which handles + * this automatically. Setting the old callbacks should be avoided. * * For suspend/resume consider using drm_mode_config_helper_suspend() and * drm_mode_config_helper_resume() which takes care of fbdev as well. -- 2.38.0
Javier Martinez Canillas
2022-Nov-04 10:37 UTC
[Nouveau] [PATCH v3 20/23] drm/fb-helper: Set flag in struct drm_fb_helper for leaking physical addresses
On 11/3/22 16:14, Thomas Zimmermann wrote:> Uncouple the parameter drm_leak_fbdev_smem from the implementation by > setting a flag in struct drm_fb_helper. This will help to move the > generic fbdev emulation into its own source file, while keeping the > parameter in drm_fb_helper.c. No functional changes. > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > ---Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> -- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Javier Martinez Canillas
2022-Nov-04 10:38 UTC
[Nouveau] [PATCH v3 23/23] drm/fb-helper: Clarify use of last_close and output_poll_changed
On 11/3/22 16:14, Thomas Zimmermann wrote:> Clarify documentation in the use of struct drm_driver.last_close and > struct drm_mode_config_funcs.output_poll_changed. Those callbacks should > not be said for fbdev implementations on top of struct drm_client_funcs. > > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de> > ---Reviewed-by: Javier Martinez Canillas <javierm at redhat.com> -- Best regards, Javier Martinez Canillas Core Platforms Red Hat