[PATCH v2 1/3] drm/mgag200: Consolidate VGA output
The various models have common code for the VGA output's encoder and connector. Move everything into a single shared source file. Remove some obsolete initializer macros. No functional changes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/Makefile | 3 +- drivers/gpu/drm/mgag200/mgag200_drv.h | 24 +++- drivers/gpu/drm/mgag200/mgag200_g200.c| 46 +-- drivers/gpu/drm/mgag200/mgag200_g200eh.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_g200er.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_g200ev.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_g200se.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_g200wb.c | 46 +-- drivers/gpu/drm/mgag200/mgag200_vga.c | 68 +++ 11 files changed, 95 insertions(+), 368 deletions(-) create mode 100644 drivers/gpu/drm/mgag200/mgag200_vga.c diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile index 0b919352046eb..d1b25f9f6586e 100644 --- a/drivers/gpu/drm/mgag200/Makefile +++ b/drivers/gpu/drm/mgag200/Makefile @@ -11,6 +11,7 @@ mgag200-y := \ mgag200_g200ew3.o \ mgag200_g200se.o \ mgag200_g200wb.o \ - mgag200_mode.o + mgag200_mode.o \ + mgag200_vga.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 20e3710e056b3..db89fddc26dcb 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -283,8 +283,12 @@ struct mga_device { struct drm_plane primary_plane; struct drm_crtc crtc; - struct drm_encoder encoder; - struct drm_connector connector; + struct { + struct { + struct drm_encoder encoder; + struct drm_connector connector; + } vga; + } output; }; static inline struct mga_device *to_mga_device(struct drm_device *dev) @@ -417,25 +421,15 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ .atomic_destroy_state = mgag200_crtc_atomic_destroy_state -#define MGAG200_DAC_ENCODER_FUNCS \ - .destroy = drm_encoder_cleanup - -#define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \ - .get_modes = drm_connector_helper_get_modes - -#define MGAG200_VGA_CONNECTOR_FUNCS \ - .reset = drm_atomic_helper_connector_reset, \ - .fill_modes = drm_helper_probe_single_connector_modes, \ - .destroy= drm_connector_cleanup, \ - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \ - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state - void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode); void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_info *format); void mgag200_enable_display(struct mga_device *mdev); void mgag200_init_registers(struct mga_device *mdev); int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_available); +/* mgag200_vga.c */ +int mgag200_vga_output_init(struct mga_device *mdev); + /* mgag200_bmc.c */ void mgag200_bmc_disable_vidrst(struct mga_device *mdev); void mgag200_bmc_enable_vidrst(struct mga_device *mdev); diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c index 39a29d8ffca6e..ff467b0f9cbf3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200.c @@ -9,7 +9,6 @@ #include #include -#include "mgag200_ddc.h" #include "mgag200_drv.h" static int mgag200_g200_init_pci_options(struct pci_dev *pdev) @@ -184,26 +183,11 @@ static const struct drm_crtc_funcs mgag200_g200_crtc_funcs = { MGAG200_CRTC_FUNCS, }; -static const struct drm_encoder_funcs mgag200_g200_dac_encoder_funcs = { - MGAG200_DAC_ENCODER_FUNCS, -}; - -static const struct drm_connector_helper_funcs mgag200_g200_vga_connector_helper_funcs = { - MGAG200_VGA_CONNECTOR_HELPER_FUNCS, -}; - -static const struct drm_connector_funcs mgag200_g200_vga_connector_funcs = { - MGAG200_VGA_CONNECTOR_FUNCS, -}; - static int mgag200_g200_pipeline_init(struct mga_device *mdev) { struct drm_device *dev = >base; struct drm_plane *primary_plane = >primary_plane; struct drm_crtc *crtc = >crtc; - struct drm_encoder *encoder = >encoder; - struct drm_connector *connector = >connector; - struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -231,35 +215,9 @@ static int mgag200_g200_pip
[PATCH v2 2/3] drm/mgag200: Add BMC output
The BMC output can be viewed via the BMC's web interface or a similar client. Represent it as virtual encoder and connector. It's attached to the same CRTC as the VGA connector. The connector's status depends on the physical connector's status. The BMC is only connected if the physical connector is not. This is necessary to support userspace clients that can only handle a single output per CRTC. The BMC is a server feature. Add a BMC output for all server chips, but not the desktop models. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_bmc.c | 107 ++ drivers/gpu/drm/mgag200/mgag200_drv.h | 10 ++ drivers/gpu/drm/mgag200/mgag200_g200eh.c | 4 + drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 4 + drivers/gpu/drm/mgag200/mgag200_g200er.c | 4 + drivers/gpu/drm/mgag200/mgag200_g200ev.c | 4 + drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 4 + drivers/gpu/drm/mgag200/mgag200_g200se.c | 4 + drivers/gpu/drm/mgag200/mgag200_g200wb.c | 4 + 9 files changed, 145 insertions(+) diff --git a/drivers/gpu/drm/mgag200/mgag200_bmc.c b/drivers/gpu/drm/mgag200/mgag200_bmc.c index 2ba2e3c5086a5..23ef85aa7e378 100644 --- a/drivers/gpu/drm/mgag200/mgag200_bmc.c +++ b/drivers/gpu/drm/mgag200/mgag200_bmc.c @@ -2,8 +2,18 @@ #include +#include +#include +#include +#include + #include "mgag200_drv.h" +static struct mgag200_bmc_connector *to_mgag200_bmc_connector(struct drm_connector *connector) +{ + return container_of(connector, struct mgag200_bmc_connector, base); +} + void mgag200_bmc_disable_vidrst(struct mga_device *mdev) { u8 tmp; @@ -97,3 +107,100 @@ void mgag200_bmc_enable_vidrst(struct mga_device *mdev) tmp &= ~0x10; WREG_DAC(MGA1064_GEN_IO_DATA, tmp); } + +static const struct drm_encoder_funcs mgag200_bmc_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static int mgag200_bmc_connector_helper_detect_ctx(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + bool force) +{ + struct mgag200_bmc_connector *bmc_connector = to_mgag200_bmc_connector(connector); + struct drm_connector *physical_connector = bmc_connector->physical_connector; + + /* +* Most user-space compositors cannot handle more than one connected +* connector per CRTC. Hence, we only mark the BMC as connected if the +* physical connector is disconnected. If the physical connector's status +* is connected or unknown, the BMC remains disconnected. This has no +* effect on the output of the BMC. +* +* FIXME: Remove this logic once user-space compositors can handle more +*than one connector per CRTC. The BMC should always be connected. +*/ + + if (physical_connector && physical_connector->status == connector_status_disconnected) + return connector_status_connected; + + return connector_status_disconnected; +} + +static int mgag200_bmc_connector_helper_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct mga_device *mdev = to_mga_device(dev); + const struct mgag200_device_info *minfo = mdev->info; + + return drm_add_modes_noedid(connector, minfo->max_hdisplay, minfo->max_vdisplay); +} + +static const struct drm_connector_helper_funcs mgag200_bmc_connector_helper_funcs = { + .get_modes = mgag200_bmc_connector_helper_get_modes, + .detect_ctx = mgag200_bmc_connector_helper_detect_ctx, +}; + +static const struct drm_connector_funcs mgag200_bmc_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int mgag200_bmc_connector_init(struct drm_device *dev, + struct mgag200_bmc_connector *bmc_connector, + struct drm_connector *physical_connector) +{ + struct drm_connector *connector = _connector->base; + int ret; + + ret = drm_connector_init(dev, connector, _bmc_connector_funcs, +DRM_MODE_CONNECTOR_VIRTUAL); + if (ret) + return ret; + drm_connector_helper_add(connector, _bmc_connector_helper_funcs); + + bmc_connector->physical_connector = physical_connector; + + return 0; +} + +int mgag200_bmc_output_init(struct mga_device *mdev, struct drm_connector *physical_connector) +{ + struct drm_device *dev = >base; + struct drm_crtc *crtc = >crtc; + struct drm_encoder *encoder; + struct mgag200_bmc_co
[PATCH v2 3/3] drm/mgag200: Set .detect_ctx() and enable connector polling
Set .detect_ctx() in struct drm_connector_helper_funcs to the common helper drm_connector_helper_detect_from_ddc() and enable polling for the connector. Mgag200 will now test for the monitor's presence by probing the DDC in regular intervals. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_g200.c| 1 + drivers/gpu/drm/mgag200/mgag200_g200eh.c | 1 + drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 1 + drivers/gpu/drm/mgag200/mgag200_g200er.c | 1 + drivers/gpu/drm/mgag200/mgag200_g200ev.c | 1 + drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 1 + drivers/gpu/drm/mgag200/mgag200_g200se.c | 1 + drivers/gpu/drm/mgag200/mgag200_g200wb.c | 1 + drivers/gpu/drm/mgag200/mgag200_vga.c | 6 +- 9 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c index ff467b0f9cbf3..f874e29498409 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200.c @@ -401,6 +401,7 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c index 6f31c5249f0b1..52bf49ead5c50 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c @@ -277,6 +277,7 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c index 5befe8da4beb2..e7f89b2a59fd0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c @@ -182,6 +182,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c index 55c275180cde2..4e8a1756138d7 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200er.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c @@ -316,6 +316,7 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c index 2466126140db6..d884f3cb0ec79 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c @@ -321,6 +321,7 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c index a52e60609c3de..839401e8b4654 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c @@ -202,6 +202,7 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c index 212770acdd477..a824bb8ad5791 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200se.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c @@ -521,6 +521,7 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c index cb6daa0426fbc..835df0f4fc13d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c @@ -326,6 +326,7 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru return ERR_PTR(ret); drm_mode_config_reset(dev); + drm_kms_helper_poll_init(dev); return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_vga.c b/drivers/gpu/drm/mgag200/mgag200_vga.c index 6d8982990c2c3..60568f32736dd 100644 --- a/drivers/gpu/drm/mgag200/mgag200_vga.c +++ b/drivers/gpu/drm/mgag200/mgag200_vga.c @@ -12,7 +12,8 @@ static const struct drm_encoder_funcs mgag200_dac_encoder_funcs = { }; static const struct drm_connector_helper_funcs mgag200_vga_connector_helper_funcs = { - .get_modes
[PATCH v2 0/3] drm/mgag200: Detect connector status
Detect the connector status by polling the DDC. Update the status at runtime. Add a dedicated BMC output to still display to the BMC while the VGA connector is not attached. This patchset fixes a long-standing problem where attaching the VGA display a runtime resulted in incorrect display modes. Tested on various Matrox hardware. v2: - move the DDC clean up into a separate patchset [1] - add dedicated BMC support (Jocelyn) [1] https://patchwork.freedesktop.org/series/133537/ Thomas Zimmermann (3): drm/mgag200: Consolidate VGA output drm/mgag200: Add BMC output drm/mgag200: Set .detect_ctx() and enable connector polling drivers/gpu/drm/mgag200/Makefile | 3 +- drivers/gpu/drm/mgag200/mgag200_bmc.c | 107 ++ drivers/gpu/drm/mgag200/mgag200_drv.h | 34 --- drivers/gpu/drm/mgag200/mgag200_g200.c| 47 +- drivers/gpu/drm/mgag200/mgag200_g200eh.c | 47 +- drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 47 +- drivers/gpu/drm/mgag200/mgag200_g200er.c | 47 +- drivers/gpu/drm/mgag200/mgag200_g200ev.c | 47 +- drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 47 +- drivers/gpu/drm/mgag200/mgag200_g200se.c | 47 +- drivers/gpu/drm/mgag200/mgag200_g200wb.c | 47 +- drivers/gpu/drm/mgag200/mgag200_vga.c | 72 +++ 12 files changed, 238 insertions(+), 354 deletions(-) create mode 100644 drivers/gpu/drm/mgag200/mgag200_vga.c base-commit: 2bea08bd31298d60d416b2a6ed346bb53dd28037 -- 2.45.2
Re: [PATCH] drm/edid: reduce DisplayID log spamming
Am 06.06.24 um 14:35 schrieb Jani Nikula: Debug printing at DisplayID validation leads to lots of log spamming as it's called at DisplayID iterators during EDID parsing. Remove it, and replace with a less noisy message at connector EDID update. Signed-off-by: Jani Nikula Acked-by: Thomas Zimmermann --- drivers/gpu/drm/drm_displayid.c | 3 --- drivers/gpu/drm/drm_edid.c | 5 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c index 9d01d762801f..b4fd43783c50 100644 --- a/drivers/gpu/drm/drm_displayid.c +++ b/drivers/gpu/drm/drm_displayid.c @@ -33,9 +33,6 @@ validate_displayid(const u8 *displayid, int length, int idx) if (IS_ERR(base)) return base; - DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", - base->rev, base->bytes, base->prod_id, base->ext_count); - /* +1 for DispID checksum */ dispid_length = sizeof(*base) + base->bytes + 1; if (dispid_length > length - idx) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f68a41eeb1fa..9fc7292f5382 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -6629,6 +6629,11 @@ static void update_displayid_info(struct drm_connector *connector, displayid_iter_edid_begin(drm_edid, ); displayid_iter_for_each(block, ) { + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] DisplayID extension version 0x%02x, primary use 0x%02x\n", + connector->base.id, connector->name, + displayid_version(), + displayid_primary_use()); if (displayid_version() == DISPLAY_ID_STRUCTURE_VER_20 && (displayid_primary_use() == PRIMARY_USE_HEAD_MOUNTED_VR || displayid_primary_use() == PRIMARY_USE_HEAD_MOUNTED_AR)) -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH] drm/managed: Simplify if condition
Am 05.06.24 um 13:50 schrieb Thorsten Blum: The if condition !A || A && B can be simplified to !A || B. Fixes the following Coccinelle/coccicheck warning reported by excluded_middle.cocci: WARNING !A || A && B is equivalent to !A || B Compile-tested only. Signed-off-by: Thorsten Blum Acked-by: Thomas Zimmermann --- drivers/gpu/drm/drm_managed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c index 7646f67bda4e..79ce86a5bd67 100644 --- a/drivers/gpu/drm/drm_managed.c +++ b/drivers/gpu/drm/drm_managed.c @@ -197,7 +197,7 @@ void drmm_release_action(struct drm_device *dev, spin_lock_irqsave(>managed.lock, flags); list_for_each_entry_reverse(dr, >managed.resources, node.entry) { if (dr->node.release == action) { - if (!data || (data && *(void **)dr->data == data)) { + if (!data || *(void **)dr->data == data) { dr_match = dr; del_dr(dev, dr_match); break; -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH] drm/fbdev-dma: fix getting smem_start
Hi Am 04.06.24 um 10:03 schrieb Peng Fan (OSS): From: Peng Fan If 'info->screen_buffer' locates in vmalloc address space, virt_to_page will not be able to get correct results. With CONFIG_DEBUG_VM and CONFIG_DEBUG_VIRTUAL enabled on ARM64, there is dump below: Which graphics driver triggers this bug? [3.536043] [ cut here ] [3.540716] virt_to_phys used for non-linear address: 7fc4f540 (0x800086001000) [3.552628] WARNING: CPU: 4 PID: 61 at arch/arm64/mm/physaddr.c:12 __virt_to_phys+0x68/0x98 [3.565455] Modules linked in: [3.568525] CPU: 4 PID: 61 Comm: kworker/u12:5 Not tainted 6.6.23-06226-g4986cc3e1b75-dirty #250 [3.577310] Hardware name: NXP i.MX95 19X19 board (DT) [3.582452] Workqueue: events_unbound deferred_probe_work_func [3.588291] pstate: 6049 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [3.595233] pc : __virt_to_phys+0x68/0x98 [3.599246] lr : __virt_to_phys+0x68/0x98 [3.603276] sp : 800083603990 [3.677939] Call trace: [3.680393] __virt_to_phys+0x68/0x98 [3.684067] drm_fbdev_dma_helper_fb_probe+0x138/0x238 [3.689214] __drm_fb_helper_initial_config_and_unlock+0x2b0/0x4c0 [3.695385] drm_fb_helper_initial_config+0x4c/0x68 [3.700264] drm_fbdev_dma_client_hotplug+0x8c/0xe0 [3.705161] drm_client_register+0x60/0xb0 [3.709269] drm_fbdev_dma_setup+0x94/0x148 So add a check 'is_vmalloc_addr'. Fixes: b79fe9abd58b ("drm/fbdev-dma: Implement fbdev emulation for GEM DMA helpers") Signed-off-by: Peng Fan Reviewed-by: Thomas Zimmermann Best regards Thomas --- drivers/gpu/drm/drm_fbdev_dma.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index 6c9427bb4053..9e2eddb6eb5c 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -130,7 +130,12 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, info->flags |= FBINFO_READS_FAST; /* signal caching */ info->screen_size = sizes->surface_height * fb->pitches[0]; info->screen_buffer = map.vaddr; - info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); + + if (is_vmalloc_addr(info->screen_buffer)) + info->fix.smem_start = page_to_phys(vmalloc_to_page(info->screen_buffer)); + else + info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); + info->fix.smem_len = info->screen_size; return 0; -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PULL] drm-misc-fixes
Hi Dave, Sima, this is the PR for drm-misc-fixes or this week. FYI I had to run dim pull-request with the -f option, so that it ignored the following error dim: 779aa4d74785 ("drm/nouveau/nvif: Avoid build error due to potential integer overflows"): Fixes: SHA1 in not pointing at an ancestor: dim: a61ddb4393ad ("drm: enable (most) W=1 warnings by default across the subsystem") dim: ERROR: issues in commits detected, aborting The commit a61ddb4393ad ("drm: enable (most) W=1 warnings by default across the subsystem") apparently got in before the commit it fixes. Best regards Thomas drm-misc-fixes-2024-05-30: Short summary of fixes pull: dma-buf: - sw-sync: Don't interfere with IRQ handling - Fix kthreads-handling error path gem-shmem: - Warn when trying to pin imported objects lima: - Fix dma_resv-related deadlock in object pin msm: - Remove build-time dependency on Python 3.9 nouveau: - nvif: Fix possible integer overflow panel: - lg-sw43408: Select DP helpers; Declare backlight ops as static - sitronix-st7789v: Various fixes for jt240mhqs_hwt_ek_e3 panel panfrost: - Fix dma_resv-related deadlock in object pin The following changes since commit 3e049b6b8f32f25c6967f4cffd8eac6e1e5316f6: Merge tag 'drm-misc-fixes-2024-05-23' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes (2024-05-27 13:47:14 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-05-30 for you to fetch changes up to bb195358806847217efba98de62b7decec3b371f: drm/msm: remove python 3.9 dependency for compiling msm (2024-05-30 18:49:23 +0200) Short summary of fixes pull: dma-buf: - sw-sync: Don't interfere with IRQ handling - Fix kthreads-handling error path gem-shmem: - Warn when trying to pin imported objects lima: - Fix dma_resv-related deadlock in object pin msm: - Remove build-time dependency on Python 3.9 nouveau: - nvif: Fix possible integer overflow panel: - lg-sw43408: Select DP helpers; Declare backlight ops as static - sitronix-st7789v: Various fixes for jt240mhqs_hwt_ek_e3 panel panfrost: - Fix dma_resv-related deadlock in object pin Abhinav Kumar (1): drm/msm: remove python 3.9 dependency for compiling msm Adrián Larumbe (3): drm/panfrost: Fix dma_resv deadlock at drm object pin time drm/lima: Fix dma_resv deadlock at drm object pin time drm/gem-shmem: Add import attachment warning to locked pin function Dmitry Baryshkov (2): drm/panel/lg-sw43408: select CONFIG_DRM_DISPLAY_DP_HELPER drm/panel/lg-sw43408: mark sw43408_backlight_ops as static Fedor Pchelkin (1): dma-buf: handle testing kthreads creation failure Gerald Loacker (3): drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 panel Guenter Roeck (1): drm/nouveau/nvif: Avoid build error due to potential integer overflows Maarten Lankhorst (1): Merge remote-tracking branch 'drm/drm-fixes' into drm-misc-fixes Tetsuo Handa (1): dma-buf/sw-sync: don't enable IRQ from sync_print_obj() drivers/dma-buf/st-dma-fence.c | 6 ++ drivers/dma-buf/sync_debug.c | 4 ++-- drivers/gpu/drm/drm_gem_shmem_helper.c | 2 ++ drivers/gpu/drm/lima/lima_gem.c| 2 +- drivers/gpu/drm/msm/registers/gen_header.py| 5 +++-- drivers/gpu/drm/nouveau/nvif/object.c | 24 ++-- drivers/gpu/drm/panel/Kconfig | 2 ++ drivers/gpu/drm/panel/panel-lg-sw43408.c | 2 +- drivers/gpu/drm/panel/panel-sitronix-st7789v.c | 16 drivers/gpu/drm/panfrost/panfrost_gem.c| 2 +- 10 files changed, 44 insertions(+), 21 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PULL] drm-misc-fixes
Hi Dave, Sima, here's the weekly PR for drm-misc-fixes. There's one important patch included, which fixes a kernel panic that can be triggered from userspace. Best regards Thomas drm-misc-fixes-2024-05-23: Short summary of fixes pull: buddy: - stop using PAGE_SIZE shmem-helper: - avoid kernel panic in mmap() tests: - buddy: fix PAGE_SIZE dependency The following changes since commit 6897204ea3df808d342c8e4613135728bc538bcd: drm/connector: Add \n to message about demoting connector force-probes (2024-05-07 09:17:07 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-05-23 for you to fetch changes up to 39bc27bd688066a63e56f7f64ad34fae03fbe3b8: drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE) (2024-05-21 14:38:51 +0200) Short summary of fixes pull: buddy: - stop using PAGE_SIZE shmem-helper: - avoid kernel panic in mmap() tests: - buddy: fix PAGE_SIZE dependency Matthew Auld (2): drm/buddy: stop using PAGE_SIZE drm/tests/buddy: stop using PAGE_SIZE Mohamed Ahmed (1): drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations Wachowski, Karol (1): drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE) drivers/gpu/drm/drm_buddy.c | 2 +- drivers/gpu/drm/drm_gem_shmem_helper.c | 3 +++ drivers/gpu/drm/nouveau/nouveau_abi16.c | 3 +++ drivers/gpu/drm/nouveau/nouveau_bo.c| 44 ++--- drivers/gpu/drm/tests/drm_buddy_test.c | 42 +++ include/drm/drm_buddy.h | 6 ++--- include/uapi/drm/nouveau_drm.h | 7 ++ 7 files changed, 57 insertions(+), 50 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v2 2/2] drm/mgag200: Add an option to disable Write-Combine
Hi Am 17.05.24 um 17:09 schrieb Jocelyn Falempe: Unfortunately, the G200 ioburst workaround doesn't work on some servers like Dell poweredge XR11, XR5610, or HPE XL260. In this case completely disabling WC is the only option to achieve low-latency. So this adds a new Kconfig option to disable WC mapping of the G200. Signed-off-by: Jocelyn Falempe Reviewed-by: Thomas Zimmermann Thanks a lot for the fix. Best regards Thomas --- drivers/gpu/drm/mgag200/Kconfig | 10 ++ drivers/gpu/drm/mgag200/mgag200_drv.c | 6 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index b28c5e4828f47..3096944a8f0ab 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -11,3 +11,13 @@ config DRM_MGAG200 MGA G200 desktop chips and the server variants. It requires 0.3.0 of the modesetting userspace driver, and a version of mga driver that will fail on KMS enabled devices. + +config DRM_MGAG200_DISABLE_WRITECOMBINE + bool "Disable Write Combine mapping of VRAM" + depends on DRM_MGAG200 && PREEMPT_RT + help + The VRAM of the G200 is mapped with Write-Combine to improve + performances. This can interfere with real-time tasks; even if they + are running on other CPU cores than the graphics output. + Enable this option only if you run realtime tasks on a server with a + Matrox G200. \ No newline at end of file diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 3883f25ca4d8b..62080cf0f2da4 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -146,12 +146,18 @@ int mgag200_device_preinit(struct mga_device *mdev) } mdev->vram_res = res; +#if defined(CONFIG_DRM_MGAG200_DISABLE_WRITECOMBINE) + mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res)); + if (!mdev->vram) + return -ENOMEM; +#else mdev->vram = devm_ioremap_wc(dev->dev, res->start, resource_size(res)); if (!mdev->vram) return -ENOMEM; /* Don't fail on errors, but performance might be reduced. */ devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res)); +#endif return 0; } -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH 2/2] drm/mgag200: Add an option to disable Write-Combine
Hi, just nits below. Am 16.05.24 um 18:17 schrieb Jocelyn Falempe: Unfortunately, the G200 ioburst workaround doesn't work on some servers like Dell poweredge XR11, XR5610, or HPE XL260 In this case completely disabling WC is the only option to achieve low-latency. So this adds a new Kconfig option, to disable WC mapping of the G200 The formatting look off. Maybe make this one single paragraph. No comma after 'option'. Signed-off-by: Jocelyn Falempe --- drivers/gpu/drm/mgag200/Kconfig | 10 ++ drivers/gpu/drm/mgag200/mgag200_drv.c | 7 +++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index b28c5e4828f47..73ab5730b74d9 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -11,3 +11,13 @@ config DRM_MGAG200 MGA G200 desktop chips and the server variants. It requires 0.3.0 of the modesetting userspace driver, and a version of mga driver that will fail on KMS enabled devices. + +config DRM_MGAG200_DISABLE_WRITECOMBINE + bool "Disable Write Combine mapping of VRAM" + depends on DRM_MGAG200 && PREEMPT_RT + help + The VRAM of the G200 is mapped with Write-Combine, to improve No comma after Write-Combine + performances. However this increases the system latency a lot, even Just say "This can interfere with real-time tasks; even if they are running on other CPU cores then the graphics output." + for realtime tasks running on other CPU cores. Typically 40us-80us + latencies are measured with hwlat when Write Combine is enabled. Leave out the next sentence: "Typically ..." The measureed numbers depend on the hardware and everyone is encouraged to test on their own system. You could mention the numbers in the commit description, as you already mention the affected systems there. + Recommended if you run realtime tasks on a server with a Matrox G200. I still think that we should not encourage anyone to use this option. Maybe say "Enable this option only if you run..." \ No newline at end of file diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 3883f25ca4d8b..7461e3f984eff 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -146,12 +146,19 @@ int mgag200_device_preinit(struct mga_device *mdev) } mdev->vram_res = res; +#if defined(CONFIG_DRM_MGAG200_DISABLE_WRITECOMBINE) + drm_info(dev, "Disable Write Combine\n"); I would not print this drm_info() here. The user has selected the config option, so they should know what happens. It's also listed in /proc/mtrr IIRC. Best regards Thomas + mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res)); + if (!mdev->vram) + return -ENOMEM; +#else mdev->vram = devm_ioremap_wc(dev->dev, res->start, resource_size(res)); if (!mdev->vram) return -ENOMEM; /* Don't fail on errors, but performance might be reduced. */ devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res)); +#endif return 0; } -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH 1/2] Revert "drm/mgag200: Add a workaround for low-latency"
Am 16.05.24 um 18:17 schrieb Jocelyn Falempe: This reverts commit bfa4437fd3938ae2e186e7664b2db65bb8775670. This workaround doesn't work reliably on all servers. I'll replace it with an option to disable Write-Combine, which has more impact on performance, but fix the latency issue on all hardware. Signed-off-by: Jocelyn Falempe Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/Kconfig| 12 drivers/gpu/drm/mgag200/mgag200_drv.c | 17 - drivers/gpu/drm/mgag200/mgag200_mode.c | 8 3 files changed, 37 deletions(-) diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index 5e4d48df4854c..b28c5e4828f47 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -11,15 +11,3 @@ config DRM_MGAG200 MGA G200 desktop chips and the server variants. It requires 0.3.0 of the modesetting userspace driver, and a version of mga driver that will fail on KMS enabled devices. - -config DRM_MGAG200_IOBURST_WORKAROUND - bool "Disable buffer caching" - depends on DRM_MGAG200 && PREEMPT_RT && X86 - help - Enable a workaround to avoid I/O bursts within the mgag200 driver at - the expense of overall display performance. - It restores the -#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND) -static struct drm_gem_object *mgag200_create_object(struct drm_device *dev, size_t size) -{ - struct drm_gem_shmem_object *shmem; - - shmem = kzalloc(sizeof(*shmem), GFP_KERNEL); - if (!shmem) - return NULL; - - shmem->map_wc = true; - return >base; -} -#endif - /* * DRM driver */ @@ -113,9 +99,6 @@ static const struct drm_driver mgag200_driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, -#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND) - .gem_create_object = mgag200_create_object, -#endif DRM_GEM_SHMEM_DRIVER_OPS, }; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index fc54851d3384d..d3d820f7a77d7 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -438,13 +437,6 @@ static void mgag200_handle_damage(struct mga_device *mdev, const struct iosys_ma iosys_map_incr(, drm_fb_clip_offset(fb->pitches[0], fb->format, clip)); drm_fb_memcpy(, fb->pitches, vmap, fb, clip); - - /* Flushing the cache greatly improves latency on x86_64 */ -#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND) - if (!vmap->is_iomem) - drm_clflush_virt_range(vmap->vaddr + clip->y1 * fb->pitches[0], - drm_rect_height(clip) * fb->pitches[0]); -#endif } /* -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PATCH] arch: Fix name collision with ACPI's video.o
Commit 2fd001cd3600 ("arch: Rename fbdev header and source files") renames the video source files under arch/ such that they do not refer to fbdev any longer. The new files named video.o conflict with ACPI's video.ko module. Modprobing the ACPI module can then fail with warnings about missing symbols, as shown below. (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol acpi_video_unregister (err -2) (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol acpi_video_register_backlight (err -2) (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol __acpi_video_get_backlight_type (err -2) (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol acpi_video_register (err -2) Fix the issue by renaming the architecture's video.o to video-common.o. Reported-by: Chaitanya Kumar Borah Closes: https://lore.kernel.org/intel-gfx/9dcac6e9-a3bf-4ace-bbdc-f697f767f...@suse.de/T/#t Signed-off-by: Thomas Zimmermann Fixes: 2fd001cd3600 ("arch: Rename fbdev header and source files") Cc: Arnd Bergmann Cc: linux-a...@vger.kernel.org Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- arch/sparc/video/Makefile| 2 +- arch/sparc/video/{video.c => video-common.c} | 0 arch/x86/video/Makefile | 2 +- arch/x86/video/{video.c => video-common.c} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename arch/sparc/video/{video.c => video-common.c} (100%) rename arch/x86/video/{video.c => video-common.c} (100%) diff --git a/arch/sparc/video/Makefile b/arch/sparc/video/Makefile index fdf83a408d750..dcfbe7a5912c0 100644 --- a/arch/sparc/video/Makefile +++ b/arch/sparc/video/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-y += video.o +obj-y += video-common.o diff --git a/arch/sparc/video/video.c b/arch/sparc/video/video-common.c similarity index 100% rename from arch/sparc/video/video.c rename to arch/sparc/video/video-common.c diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile index fdf83a408d750..dcfbe7a5912c0 100644 --- a/arch/x86/video/Makefile +++ b/arch/x86/video/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-y += video.o +obj-y += video-common.o diff --git a/arch/x86/video/video.c b/arch/x86/video/video-common.c similarity index 100% rename from arch/x86/video/video.c rename to arch/x86/video/video-common.c -- 2.45.0
Re: [PATCH] ACPI: video: Fix name collision with architecture's video.o
Hi Am 16.05.24 um 17:03 schrieb Hans de Goede: Hi, On 5/16/24 3:04 PM, Rafael J. Wysocki wrote: CC Hans who has been doing the majority of the ACPI video work. On Thu, May 16, 2024 at 2:43 PM Thomas Zimmermann wrote: Commit 2fd001cd3600 ("arch: Rename fbdev header and source files") renames the video source files under arch/ such that they does not refer to fbdev any longer. The new files named video.o conflict with ACPI's video.ko module. And surely nobody knew or was unable to check upfront that there was a video.ko already in the kernel. Sorry, but nack for this change. I very deliberately kept the module-name as video when renaming the actual .c file from video.c to acpi_video.c because many people pass drivers/video/acpi_video.c module arguments on the kernel commandline using video.param=val . Try e.g. doing a duckduckgo search for 1 off: "video.only_lcd" "video.allow_duplicates" "video.brightness_switch_enabled" Ok, that makes sense. I'll rename the other files. Best regards Thomas And you will find a lot of hits. The last one is even documented as being "video.brightness_switch_enabled" in the main kernel-parameters.txt as well as separately: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/kernel-parameters.txt#n39 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/kernel-parameters.txt#n7152 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/firmware-guide/acpi/video_extension.rst#n118 https://wiki.archlinux.org/title/Lenovo_ThinkPad_X1_Carbon#Brightness_control If you rename this module then peoples config will break for a whole lot of users. So lets not do that and lets rename the new module which is causing the conflict in the first place instead. Regards, Hans -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PATCH] ACPI: video: Fix name collision with architecture's video.o
Commit 2fd001cd3600 ("arch: Rename fbdev header and source files") renames the video source files under arch/ such that they does not refer to fbdev any longer. The new files named video.o conflict with ACPI's video.ko module. Modprobing the ACPI module can then fail with warnings about missing symbols, as shown below. (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol acpi_video_unregister (err -2) (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol acpi_video_register_backlight (err -2) (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol __acpi_video_get_backlight_type (err -2) (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol acpi_video_register (err -2) Fix this problem by renaming ACPI's video.ko to acpi_video.ko. Also rename a related source file and clean up the Makefile. Reported-by: Chaitanya Kumar Borah Closes: https://lore.kernel.org/intel-gfx/9dcac6e9-a3bf-4ace-bbdc-f697f767f...@suse.de/T/#t Tested-by: Chaitanya Kumar Borah Signed-off-by: Thomas Zimmermann Fixes: 2fd001cd3600 ("arch: Rename fbdev header and source files") Cc: Arnd Bergmann Cc: linux-a...@vger.kernel.org Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- drivers/acpi/Makefile| 5 +++-- drivers/acpi/{acpi_video.c => acpi_video_core.c} | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) rename drivers/acpi/{acpi_video.c => acpi_video_core.c} (99%) diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 8cc8c0d9c8732..fc9e11f7afbf7 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -84,7 +84,9 @@ obj-$(CONFIG_ACPI_FAN)+= fan.o fan-objs := fan_core.o fan-objs += fan_attr.o -obj-$(CONFIG_ACPI_VIDEO) += video.o +obj-$(CONFIG_ACPI_VIDEO) += acpi_video.o +acpi_video-objs+= acpi_video_core.o video_detect.o + obj-$(CONFIG_ACPI_TAD) += acpi_tad.o obj-$(CONFIG_ACPI_PCI_SLOT)+= pci_slot.o obj-$(CONFIG_ACPI_PROCESSOR) += processor.o @@ -124,7 +126,6 @@ obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o obj-y += pmic/ -video-objs += acpi_video.o video_detect.o obj-y += dptf/ obj-$(CONFIG_ARM64)+= arm64/ diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video_core.c similarity index 99% rename from drivers/acpi/acpi_video.c rename to drivers/acpi/acpi_video_core.c index 1fda303882973..32bf81c5773a4 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video_core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * video.c - ACPI Video Driver + * acpi_video_core.c - ACPI Video Driver * * Copyright (C) 2004 Luming Yu * Copyright (C) 2004 Bruno Ducrot -- 2.45.0
Re: [PATCH 00/10] drm/mgag200: Refactor DDC code
Hi Am 16.05.24 um 11:14 schrieb Jocelyn Falempe: Thanks for this refactor of mgag200. for the whole series: Reviewed-by: Jocelyn Falempe Thank you so much! Best regards Thomas -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PULL] drm-misc-fixes
Hi Dave, Sima there's only a single patch in this week's drm-misc-fixes PR. Best regards Thomas drm-misc-fixes-2024-05-16: Short summary of fixes pull: nouveau: - use tile_mode and pte_kind for VM_BIND bo allocations The following changes since commit 6897204ea3df808d342c8e4613135728bc538bcd: drm/connector: Add \n to message about demoting connector force-probes (2024-05-07 09:17:07 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-05-16 for you to fetch changes up to aed9a1a4f7106ff99a882ad06318cebfa71016a2: drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations (2024-05-13 22:17:58 +0200) Short summary of fixes pull: nouveau: - use tile_mode and pte_kind for VM_BIND bo allocations Mohamed Ahmed (1): drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations drivers/gpu/drm/nouveau/nouveau_abi16.c | 3 +++ drivers/gpu/drm/nouveau/nouveau_bo.c| 44 ++--- include/uapi/drm/nouveau_drm.h | 7 ++ 3 files changed, 29 insertions(+), 25 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH] drm/fbdev-dma: Clean up deferred I/O
Am 15.05.24 um 13:59 schrieb Javier Martinez Canillas: Thomas Zimmermann writes: Call fb_deferred_io_cleanup() upon destroying the framebuffer device. Releases the internal memory. Signed-off-by: Thomas Zimmermann Fixes: 808a40b69468 ("drm/fbdev-dma: Implement damage handling and deferred I/O") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard --- drivers/gpu/drm/drm_fbdev_dma.c | 1 + 1 file changed, 1 insertion(+) Reviewed-by: Javier Martinez Canillas Thanks a lot. I've pushed this patch and the other one to drm-misc-next. -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH 05/11] drm/hisilicon/hibmc: convert to struct drm_edid
Hi Am 15.05.24 um 14:34 schrieb Jani Nikula: On Tue, 14 May 2024, Thomas Zimmermann wrote: Hi Am 14.05.24 um 14:55 schrieb Jani Nikula: Prefer the struct drm_edid based functions for reading the EDID and updating the connector. Signed-off-by: Jani Nikula --- Cc: Xinliang Liu Cc: Tian Tao Cc: Xinwei Kong Cc: Sumit Semwal Cc: Yongqin Liu Cc: John Stultz Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann --- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c| 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 94e2c573a7af..409c551c92af 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -24,14 +24,16 @@ static int hibmc_connector_get_modes(struct drm_connector *connector) Could this function be replaced with a call to drm_connector_helper_get_modes()? With the patch, the only difference is the call to the _noedid() function, which the DRM core does automatically. There will still be a difference in the maximum resolution, but standardizing on 1024x768 seems preferable to me. Looks like it might work, but personally, I'm trying to shy away from any further cleanups than just switching to struct drm_edid. I've got my plate pretty full already. In that case Reviewed-by: Thomas Zimmermann for the current patch. Best regards Thomas BR, Jani. Best regards Thomas { - int count; - void *edid; struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); + const struct drm_edid *drm_edid; + int count; + + drm_edid = drm_edid_read_ddc(connector, _connector->adapter); - edid = drm_get_edid(connector, _connector->adapter); - if (edid) { - drm_connector_update_edid_property(connector, edid); - count = drm_add_edid_modes(connector, edid); + drm_edid_connector_update(connector, drm_edid); + + if (drm_edid) { + count = drm_edid_connector_add_modes(connector); if (count) goto out; } @@ -42,7 +44,8 @@ static int hibmc_connector_get_modes(struct drm_connector *connector) drm_set_preferred_mode(connector, 1024, 768); out: - kfree(edid); + drm_edid_free(drm_edid); + return count; } -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH 05/11] drm/hisilicon/hibmc: convert to struct drm_edid
Hi Am 14.05.24 um 14:55 schrieb Jani Nikula: Prefer the struct drm_edid based functions for reading the EDID and updating the connector. Signed-off-by: Jani Nikula --- Cc: Xinliang Liu Cc: Tian Tao Cc: Xinwei Kong Cc: Sumit Semwal Cc: Yongqin Liu Cc: John Stultz Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann --- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c| 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 94e2c573a7af..409c551c92af 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -24,14 +24,16 @@ static int hibmc_connector_get_modes(struct drm_connector *connector) Could this function be replaced with a call to drm_connector_helper_get_modes()? With the patch, the only difference is the call to the _noedid() function, which the DRM core does automatically. There will still be a difference in the maximum resolution, but standardizing on 1024x768 seems preferable to me. Best regards Thomas { - int count; - void *edid; struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector); + const struct drm_edid *drm_edid; + int count; + + drm_edid = drm_edid_read_ddc(connector, _connector->adapter); - edid = drm_get_edid(connector, _connector->adapter); - if (edid) { - drm_connector_update_edid_property(connector, edid); - count = drm_add_edid_modes(connector, edid); + drm_edid_connector_update(connector, drm_edid); + + if (drm_edid) { + count = drm_edid_connector_add_modes(connector); if (count) goto out; } @@ -42,7 +44,8 @@ static int hibmc_connector_get_modes(struct drm_connector *connector) drm_set_preferred_mode(connector, 1024, 768); out: - kfree(edid); + drm_edid_free(drm_edid); + return count; } -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: drm: Remove driver dependencies on FB_DEVICE
Hi Am 14.05.24 um 14:34 schrieb Manas Ghandat: Hi. I recently looked at the todos of drm and found the topic interesting. I wanted to get started with this issue but having some trouble identifying the devices. What would be the right approach to get started? Sorry, there's already someone working on that topic. Best regards Thomas Thanks, Manas -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH] drm/edid: remove drm_do_get_edid()
Am 13.05.24 um 22:27 schrieb Jani Nikula: All users of drm_do_get_edid() have been converted to drm_edid_read_custom(). Remove the unused function to prevent new users from creeping in. Signed-off-by: Jani Nikula Reviewed-by: Thomas Zimmermann --- Cc: Robert Foss Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann --- drivers/gpu/drm/drm_edid.c | 28 include/drm/drm_edid.h | 4 2 files changed, 32 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 4f54c91b31b2..0f7c4c5b14b9 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2464,34 +2464,6 @@ static struct edid *_drm_do_get_edid(struct drm_connector *connector, return NULL; } -/** - * drm_do_get_edid - get EDID data using a custom EDID block read function - * @connector: connector we're probing - * @read_block: EDID block read function - * @context: private data passed to the block read function - * - * When the I2C adapter connected to the DDC bus is hidden behind a device that - * exposes a different interface to read EDID blocks this function can be used - * to get EDID data using a custom block read function. - * - * As in the general case the DDC bus is accessible by the kernel at the I2C - * level, drivers must make all reasonable efforts to expose it as an I2C - * adapter and use drm_get_edid() instead of abusing this function. - * - * The EDID may be overridden using debugfs override_edid or firmware EDID - * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority - * order. Having either of them bypasses actual EDID reads. - * - * Return: Pointer to valid EDID or NULL if we couldn't find any. - */ -struct edid *drm_do_get_edid(struct drm_connector *connector, -read_block_fn read_block, -void *context) -{ - return _drm_do_get_edid(connector, read_block, context, NULL); -} -EXPORT_SYMBOL_GPL(drm_do_get_edid); - /** * drm_edid_raw - Get a pointer to the raw EDID data. * @drm_edid: drm_edid container diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index b085525e53e2..6bdfa254a1c1 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -423,10 +423,6 @@ static inline void drm_edid_decode_panel_id(u32 panel_id, char vend[4], u16 *pro } bool drm_probe_ddc(struct i2c_adapter *adapter); -struct edid *drm_do_get_edid(struct drm_connector *connector, - int (*get_edid_block)(void *data, u8 *buf, unsigned int block, - size_t len), - void *data); struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PATCH 04/10] drm/mgag200: Allocate instance of struct mga_i2c_chan dynamically
Allocate instances of struct mga_i2c_chan in mgag200_ddc_create() and return a pointer to the contained i2c adapter. The callers of the function are now independent from struct mga_i2c_chan. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_ddc.h | 11 +++ drivers/gpu/drm/mgag200/mgag200_drv.h | 4 drivers/gpu/drm/mgag200/mgag200_g200.c| 11 ++- drivers/gpu/drm/mgag200/mgag200_g200eh.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_g200er.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_g200ev.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_g200se.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_g200wb.c | 11 ++- drivers/gpu/drm/mgag200/mgag200_i2c.c | 20 +++- drivers/gpu/drm/mgag200/mgag200_mode.c| 1 + 12 files changed, 79 insertions(+), 45 deletions(-) create mode 100644 drivers/gpu/drm/mgag200/mgag200_ddc.h diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.h b/drivers/gpu/drm/mgag200/mgag200_ddc.h new file mode 100644 index 0..fa21d197cc783 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_ddc.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __MGAG200_DDC_H__ +#define __MGAG200_DDC_H__ + +struct i2c_adapter; +struct mga_device; + +struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev); + +#endif diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index c7d4047301bfb..3c834bfd82cf4 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -294,7 +294,6 @@ struct mga_device { struct drm_plane primary_plane; struct drm_crtc crtc; struct drm_encoder encoder; - struct mga_i2c_chan i2c; struct drm_connector connector; }; @@ -453,7 +452,4 @@ int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_avail void mgag200_bmc_disable_vidrst(struct mga_device *mdev); void mgag200_bmc_enable_vidrst(struct mga_device *mdev); - /* mgag200_i2c.c */ -int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c); - #endif /* __MGAG200_DRV_H__ */ diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c index bf5d7fe525a3f..39a29d8ffca6e 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200.c @@ -9,6 +9,7 @@ #include #include +#include "mgag200_ddc.h" #include "mgag200_drv.h" static int mgag200_g200_init_pci_options(struct pci_dev *pdev) @@ -201,8 +202,8 @@ static int mgag200_g200_pipeline_init(struct mga_device *mdev) struct drm_plane *primary_plane = >primary_plane; struct drm_crtc *crtc = >crtc; struct drm_encoder *encoder = >encoder; - struct mga_i2c_chan *i2c = >i2c; struct drm_connector *connector = >connector; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -238,16 +239,16 @@ static int mgag200_g200_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); drm_err(dev, "failed to add DDC bus: %d\n", ret); return ret; } ret = drm_connector_init_with_ddc(dev, connector, _g200_vga_connector_funcs, - DRM_MODE_CONNECTOR_VGA, - >adapter); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c index fad62453a91db..619fee7ffdf5e 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c @@ -9,6 +9,7 @@ #include #include +#include "mgag200_ddc.h" #include "mgag200_drv.h" void mgag200_g200eh_init_registers(struct mga_device *mdev) @@ -200,8 +201,8 @@ static int mgag200_g200eh_pipeline_init(struct mga_device *mdev) struct drm_plane *primary_plane = >primary_plane; struct drm_crtc *crtc = >crtc; struct drm_encoder *encoder = >encoder; - struct mga_i2c_chan *i2c = >i2c; struct drm_connector *connector = >connector; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -237,16 +238,16 @@ static int mgag200_g200e
[PATCH 06/10] drm/mgag200: Replace struct mga_i2c_chan with struct mgag200_ddc
Rename struct mga_i2c_chan to struct mgag200_ddc, define it in the source file mgag200_i2c.c, and reorder its fields. Rename all related variables from i2c to ddc. Also rename the i2c adapter accordingly. Using the term 'ddc' documents the purpose of the code clearly. The old term 'i2c' could refer to any functionality on an i2c bus. No functional changes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_drv.h | 10 - drivers/gpu/drm/mgag200/mgag200_i2c.c | 56 --- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 3c834bfd82cf4..008fdd5af09c8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -10,9 +10,6 @@ #ifndef __MGAG200_DRV_H__ #define __MGAG200_DRV_H__ -#include -#include - #include #include @@ -189,13 +186,6 @@ static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_s return container_of(base, struct mgag200_crtc_state, base); } -struct mga_i2c_chan { - struct i2c_adapter adapter; - struct mga_device *mdev; - struct i2c_algo_bit_data bit; - int data, clock; -}; - enum mga_type { G200_PCI, G200_AGP, diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index ba7aeca55fb40..73ff94c91ca36 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -36,6 +36,16 @@ #include "mgag200_ddc.h" #include "mgag200_drv.h" +struct mgag200_ddc { + struct mga_device *mdev; + + int data; + int clock; + + struct i2c_algo_bit_data bit; + struct i2c_adapter adapter; +}; + static int mga_i2c_read_gpio(struct mga_device *mdev) { WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA); @@ -63,62 +73,62 @@ static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state) static void mga_gpio_setsda(void *data, int state) { - struct mga_i2c_chan *i2c = data; + struct mgag200_ddc *ddc = data; - mga_i2c_set(i2c->mdev, i2c->data, state); + mga_i2c_set(ddc->mdev, ddc->data, state); } static void mga_gpio_setscl(void *data, int state) { - struct mga_i2c_chan *i2c = data; + struct mgag200_ddc *ddc = data; - mga_i2c_set(i2c->mdev, i2c->clock, state); + mga_i2c_set(ddc->mdev, ddc->clock, state); } static int mga_gpio_getsda(void *data) { - struct mga_i2c_chan *i2c = data; + struct mgag200_ddc *ddc = data; - return (mga_i2c_read_gpio(i2c->mdev) & i2c->data) ? 1 : 0; + return (mga_i2c_read_gpio(ddc->mdev) & ddc->data) ? 1 : 0; } static int mga_gpio_getscl(void *data) { - struct mga_i2c_chan *i2c = data; + struct mgag200_ddc *ddc = data; - return (mga_i2c_read_gpio(i2c->mdev) & i2c->clock) ? 1 : 0; + return (mga_i2c_read_gpio(ddc->mdev) & ddc->clock) ? 1 : 0; } -static void mgag200_i2c_release(struct drm_device *dev, void *res) +static void mgag200_ddc_release(struct drm_device *dev, void *res) { - struct mga_i2c_chan *i2c = res; + struct mgag200_ddc *ddc = res; - i2c_del_adapter(>adapter); + i2c_del_adapter(>adapter); } struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) { struct drm_device *dev = >base; const struct mgag200_device_info *info = mdev->info; - struct mga_i2c_chan *i2c; + struct mgag200_ddc *ddc; struct i2c_algo_bit_data *bit; struct i2c_adapter *adapter; int ret; - i2c = drmm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); - if (!i2c) + ddc = drmm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL); + if (!ddc) return ERR_PTR(-ENOMEM); WREG_DAC(MGA1064_GEN_IO_CTL2, 1); WREG_DAC(MGA1064_GEN_IO_DATA, 0xff); WREG_DAC(MGA1064_GEN_IO_CTL, 0); - i2c->mdev = mdev; - i2c->data = BIT(info->i2c.data_bit); - i2c->clock = BIT(info->i2c.clock_bit); + ddc->mdev = mdev; + ddc->data = BIT(info->i2c.data_bit); + ddc->clock = BIT(info->i2c.clock_bit); - bit = >bit; - bit->data = i2c; + bit = >bit; + bit->data = ddc; bit->setsda = mga_gpio_setsda; bit->setscl = mga_gpio_setscl; bit->getsda = mga_gpio_getsda; @@ -126,18 +136,18 @@ struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) bit->udelay = 10; bit->timeout = usecs_to_jiffies(2200); - adapter = >adapter; + adapter = >adapter; adapter->owner = THIS_MODULE; adapter->algo_data = bit; adapter->dev.parent = dev->dev; - snprintf(adapter->name, sizeof(adapter->name), "mga i2c"); -
[PATCH 08/10] drm/mgag200: Rename struct i2c_algo_bit_data callbacks
Align the names of the algo-bit helpers with mgag200's convention of using an mgag200 prefix plus the struct's name plus the callback's name for such function symbols. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_ddc.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.c b/drivers/gpu/drm/mgag200/mgag200_ddc.c index 73ff94c91ca36..3fa11b190943e 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ddc.c +++ b/drivers/gpu/drm/mgag200/mgag200_ddc.c @@ -71,28 +71,28 @@ static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state) mga_i2c_set_gpio(mdev, ~mask, state); } -static void mga_gpio_setsda(void *data, int state) +static void mgag200_ddc_algo_bit_data_setsda(void *data, int state) { struct mgag200_ddc *ddc = data; mga_i2c_set(ddc->mdev, ddc->data, state); } -static void mga_gpio_setscl(void *data, int state) +static void mgag200_ddc_algo_bit_data_setscl(void *data, int state) { struct mgag200_ddc *ddc = data; mga_i2c_set(ddc->mdev, ddc->clock, state); } -static int mga_gpio_getsda(void *data) +static int mgag200_ddc_algo_bit_data_getsda(void *data) { struct mgag200_ddc *ddc = data; return (mga_i2c_read_gpio(ddc->mdev) & ddc->data) ? 1 : 0; } -static int mga_gpio_getscl(void *data) +static int mgag200_ddc_algo_bit_data_getscl(void *data) { struct mgag200_ddc *ddc = data; @@ -129,10 +129,10 @@ struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) bit = >bit; bit->data = ddc; - bit->setsda = mga_gpio_setsda; - bit->setscl = mga_gpio_setscl; - bit->getsda = mga_gpio_getsda; - bit->getscl = mga_gpio_getscl; + bit->setsda = mgag200_ddc_algo_bit_data_setsda; + bit->setscl = mgag200_ddc_algo_bit_data_setscl; + bit->getsda = mgag200_ddc_algo_bit_data_getsda; + bit->getscl = mgag200_ddc_algo_bit_data_getscl; bit->udelay = 10; bit->timeout = usecs_to_jiffies(2200); -- 2.45.0
[PATCH 09/10] drm/mgag200: Acquire I/O-register lock in DDC code
The modeset lock protects the DDC code from concurrent modeset operations, which use the same registers. Move that code from the connector helpers into the DDC helpers .pre_xfer() and .post_xfer(). Both, .pre_xfer() and .post_xfer(), enclose the transfer of data blocks over the I2C channel in the internal I2C function bit_xfer(). Both calls are executed unconditionally if present. Invoking DDC transfers from any where within the driver now takes the lock. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_ddc.c | 24 drivers/gpu/drm/mgag200/mgag200_mode.c | 9 - 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.c b/drivers/gpu/drm/mgag200/mgag200_ddc.c index 3fa11b190943e..6d81ea8931e88 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ddc.c +++ b/drivers/gpu/drm/mgag200/mgag200_ddc.c @@ -99,6 +99,28 @@ static int mgag200_ddc_algo_bit_data_getscl(void *data) return (mga_i2c_read_gpio(ddc->mdev) & ddc->clock) ? 1 : 0; } +static int mgag200_ddc_algo_bit_data_pre_xfer(struct i2c_adapter *adapter) +{ + struct mgag200_ddc *ddc = i2c_get_adapdata(adapter); + struct mga_device *mdev = ddc->mdev; + + /* +* Protect access to I/O registers from concurrent modesetting +* by acquiring the I/O-register lock. +*/ + mutex_lock(>rmmio_lock); + + return 0; +} + +static void mgag200_ddc_algo_bit_data_post_xfer(struct i2c_adapter *adapter) +{ + struct mgag200_ddc *ddc = i2c_get_adapdata(adapter); + struct mga_device *mdev = ddc->mdev; + + mutex_unlock(>rmmio_lock); +} + static void mgag200_ddc_release(struct drm_device *dev, void *res) { struct mgag200_ddc *ddc = res; @@ -133,6 +155,8 @@ struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) bit->setscl = mgag200_ddc_algo_bit_data_setscl; bit->getsda = mgag200_ddc_algo_bit_data_getsda; bit->getscl = mgag200_ddc_algo_bit_data_getscl; + bit->pre_xfer = mgag200_ddc_algo_bit_data_pre_xfer; + bit->post_xfer = mgag200_ddc_algo_bit_data_post_xfer; bit->udelay = 10; bit->timeout = usecs_to_jiffies(2200); diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index cd1f48b2f9986..a04c2b550be02 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -743,23 +743,14 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector) { - struct mga_device *mdev = to_mga_device(connector->dev); const struct drm_edid *drm_edid; int count; - /* -* Protect access to I/O registers from concurrent modesetting -* by acquiring the I/O-register lock. -*/ - mutex_lock(>rmmio_lock); - drm_edid = drm_edid_read(connector); drm_edid_connector_update(connector, drm_edid); count = drm_edid_connector_add_modes(connector); drm_edid_free(drm_edid); - mutex_unlock(>rmmio_lock); - return count; } -- 2.45.0
[PATCH 00/10] drm/mgag200: Refactor DDC code
Clean up a the driver's DDC code, make it simpler, more robust, and mostly self contained. The patches in this patchset have previously been sent as part of rev 1 of [1]. Patches 1 and 2 fix long-standing problems in the DDC code. Patches 3 to 9 refactor the DDC code. The code then keeps its data structures internal, acquires locks automatically and is much more readable overall. Patch 10 replaces driver code with an equivalent helper. Tested on various Matrox hardware. [1] https://patchwork.freedesktop.org/series/131977/ Thomas Zimmermann (10): drm/mgag200: Set DDC timeout in milliseconds drm/mgag200: Bind I2C lifetime to DRM device drm/mgag200: Store pointer to struct mga_device in struct mga_i2c_chan drm/mgag200: Allocate instance of struct mga_i2c_chan dynamically drm/mgag200: Inline mgag200_i2c_init() drm/mgag200: Replace struct mga_i2c_chan with struct mgag200_ddc drm/mgag200: Rename mgag200_i2c.c to mgag200_ddc.c drm/mgag200: Rename struct i2c_algo_bit_data callbacks drm/mgag200: Acquire I/O-register lock in DDC code drm/mgag200: Use drm_connector_helper_get_modes() drivers/gpu/drm/mgag200/Makefile | 2 +- drivers/gpu/drm/mgag200/mgag200_ddc.c | 179 ++ drivers/gpu/drm/mgag200/mgag200_ddc.h | 11 ++ drivers/gpu/drm/mgag200/mgag200_drv.h | 18 +-- drivers/gpu/drm/mgag200/mgag200_g200.c| 11 +- drivers/gpu/drm/mgag200/mgag200_g200eh.c | 11 +- drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 11 +- drivers/gpu/drm/mgag200/mgag200_g200er.c | 11 +- drivers/gpu/drm/mgag200/mgag200_g200ev.c | 11 +- drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 11 +- drivers/gpu/drm/mgag200/mgag200_g200se.c | 11 +- drivers/gpu/drm/mgag200/mgag200_g200wb.c | 11 +- drivers/gpu/drm/mgag200/mgag200_i2c.c | 129 drivers/gpu/drm/mgag200/mgag200_mode.c| 27 +--- 14 files changed, 241 insertions(+), 213 deletions(-) create mode 100644 drivers/gpu/drm/mgag200/mgag200_ddc.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_ddc.h delete mode 100644 drivers/gpu/drm/mgag200/mgag200_i2c.c -- 2.45.0
[PATCH 02/10] drm/mgag200: Bind I2C lifetime to DRM device
Managed cleanup with devm_add_action_or_reset() will release the I2C adapter when the underlying Linux device goes away. But the connector still refers to it, so this cleanup leaves behind a stale pointer in struct drm_connector.ddc. Bind the lifetime of the I2C adapter to the connector's lifetime by using DRM's managed release. When the DRM device goes away (after the Linux device) DRM will first clean up the connector and then clean up the I2C adapter. Signed-off-by: Thomas Zimmermann Fixes: b279df242972 ("drm/mgag200: Switch I2C code to managed cleanup") Cc: Thomas Zimmermann Cc: Jocelyn Falempe Cc: Dave Airlie Cc: dri-devel@lists.freedesktop.org Cc: # v6.0+ --- drivers/gpu/drm/mgag200/mgag200_i2c.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 1029fef590f9b..4caeb68f3010c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -31,6 +31,8 @@ #include #include +#include + #include "mgag200_drv.h" static int mga_i2c_read_gpio(struct mga_device *mdev) @@ -86,7 +88,7 @@ static int mga_gpio_getscl(void *data) return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; } -static void mgag200_i2c_release(void *res) +static void mgag200_i2c_release(struct drm_device *dev, void *res) { struct mga_i2c_chan *i2c = res; @@ -125,5 +127,5 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) if (ret) return ret; - return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c); + return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c); } -- 2.45.0
[PATCH 05/10] drm/mgag200: Inline mgag200_i2c_init()
The function mgag200_i2c_init() is an internal helper that sets up the i2c data structure. Inline its code into the only caller. Rearrange the individual steps to separate among i2c algorithm, adapter and fields in struct mga_i2c_chan. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_i2c.c | 62 +-- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 46fa9f1b4e469..ba7aeca55fb40 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -96,54 +96,50 @@ static void mgag200_i2c_release(struct drm_device *dev, void *res) i2c_del_adapter(>adapter); } -static int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) +struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) { struct drm_device *dev = >base; const struct mgag200_device_info *info = mdev->info; + struct mga_i2c_chan *i2c; + struct i2c_algo_bit_data *bit; + struct i2c_adapter *adapter; int ret; + i2c = drmm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return ERR_PTR(-ENOMEM); + WREG_DAC(MGA1064_GEN_IO_CTL2, 1); WREG_DAC(MGA1064_GEN_IO_DATA, 0xff); WREG_DAC(MGA1064_GEN_IO_CTL, 0); + i2c->mdev = mdev; i2c->data = BIT(info->i2c.data_bit); i2c->clock = BIT(info->i2c.clock_bit); - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.dev.parent = dev->dev; - i2c->mdev = mdev; - i2c_set_adapdata(>adapter, i2c); - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c"); - - i2c->adapter.algo_data = >bit; - i2c->bit.udelay = 10; - i2c->bit.timeout = usecs_to_jiffies(2200); - i2c->bit.data = i2c; - i2c->bit.setsda = mga_gpio_setsda; - i2c->bit.setscl = mga_gpio_setscl; - i2c->bit.getsda = mga_gpio_getsda; - i2c->bit.getscl = mga_gpio_getscl; - - ret = i2c_bit_add_bus(>adapter); + bit = >bit; + bit->data = i2c; + bit->setsda = mga_gpio_setsda; + bit->setscl = mga_gpio_setscl; + bit->getsda = mga_gpio_getsda; + bit->getscl = mga_gpio_getscl; + bit->udelay = 10; + bit->timeout = usecs_to_jiffies(2200); + + adapter = >adapter; + adapter->owner = THIS_MODULE; + adapter->algo_data = bit; + adapter->dev.parent = dev->dev; + snprintf(adapter->name, sizeof(adapter->name), "mga i2c"); + i2c_set_adapdata(adapter, i2c); + + ret = i2c_bit_add_bus(adapter); if (ret) - return ret; - - return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c); -} - -struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) -{ - struct mga_i2c_chan *i2c; - struct drm_device *dev = >base; - int ret; - - i2c = drmm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); - if (!i2c) - return ERR_PTR(-ENOMEM); + return ERR_PTR(ret); - ret = mgag200_i2c_init(mdev, i2c); + ret = drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c); if (ret) return ERR_PTR(ret); - return >adapter; + return adapter; } -- 2.45.0
[PATCH 07/10] drm/mgag200: Rename mgag200_i2c.c to mgag200_ddc.c
Rename the source file according to its content. No functional changes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/Makefile | 2 +- drivers/gpu/drm/mgag200/{mgag200_i2c.c => mgag200_ddc.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/gpu/drm/mgag200/{mgag200_i2c.c => mgag200_ddc.c} (100%) diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile index 182e224c460dd..0b919352046eb 100644 --- a/drivers/gpu/drm/mgag200/Makefile +++ b/drivers/gpu/drm/mgag200/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only mgag200-y := \ mgag200_bmc.o \ + mgag200_ddc.o \ mgag200_drv.o \ mgag200_g200.o \ mgag200_g200eh.o \ @@ -10,7 +11,6 @@ mgag200-y := \ mgag200_g200ew3.o \ mgag200_g200se.o \ mgag200_g200wb.o \ - mgag200_i2c.o \ mgag200_mode.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_ddc.c similarity index 100% rename from drivers/gpu/drm/mgag200/mgag200_i2c.c rename to drivers/gpu/drm/mgag200/mgag200_ddc.c -- 2.45.0
[PATCH 01/10] drm/mgag200: Set DDC timeout in milliseconds
Compute the i2c timeout in jiffies from a value in milliseconds. The original values of 2 jiffies equals 2 milliseconds if HZ has been configured to a value of 1000. This corresponds to 2.2 milliseconds used by most other DRM drivers. Update mgag200 accordingly. Signed-off-by: Thomas Zimmermann Fixes: 414c45310625 ("mgag200: initial g200se driver (v2)") Cc: Dave Airlie Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: Jocelyn Falempe Cc: dri-devel@lists.freedesktop.org Cc: # v3.5+ --- drivers/gpu/drm/mgag200/mgag200_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 423eb302be7eb..1029fef590f9b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -114,7 +114,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) i2c->adapter.algo_data = >bit; i2c->bit.udelay = 10; - i2c->bit.timeout = 2; + i2c->bit.timeout = usecs_to_jiffies(2200); i2c->bit.data = i2c; i2c->bit.setsda = mga_gpio_setsda; i2c->bit.setscl = mga_gpio_setscl; -- 2.45.0
[PATCH 10/10] drm/mgag200: Use drm_connector_helper_get_modes()
Mgag200's .get_modes() function is identical to the common helper. Use the latter. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_drv.h | 4 +--- drivers/gpu/drm/mgag200/mgag200_mode.c | 17 - 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 008fdd5af09c8..20e3710e056b3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -420,10 +420,8 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st #define MGAG200_DAC_ENCODER_FUNCS \ .destroy = drm_encoder_cleanup -int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector); - #define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \ - .get_modes = mgag200_vga_connector_helper_get_modes + .get_modes = drm_connector_helper_get_modes #define MGAG200_VGA_CONNECTOR_FUNCS \ .reset = drm_atomic_helper_connector_reset, \ diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a04c2b550be02..d566e8476bf81 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -737,23 +737,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st kfree(mgag200_crtc_state); } -/* - * Connector - */ - -int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector) -{ - const struct drm_edid *drm_edid; - int count; - - drm_edid = drm_edid_read(connector); - drm_edid_connector_update(connector, drm_edid); - count = drm_edid_connector_add_modes(connector); - drm_edid_free(drm_edid); - - return count; -} - /* * Mode config */ -- 2.45.0
[PATCH 03/10] drm/mgag200: Store pointer to struct mga_device in struct mga_i2c_chan
Avoid upcasting to struct mga_device in i2c code by storing the pointer directly. No functional changes. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_drv.h | 2 +- drivers/gpu/drm/mgag200/mgag200_i2c.c | 18 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 58a0e62eaf183..c7d4047301bfb 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -191,7 +191,7 @@ static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_s struct mga_i2c_chan { struct i2c_adapter adapter; - struct drm_device *dev; + struct mga_device *mdev; struct i2c_algo_bit_data bit; int data, clock; }; diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 4caeb68f3010c..effd7c057fce0 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -63,29 +63,29 @@ static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state) static void mga_gpio_setsda(void *data, int state) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - mga_i2c_set(mdev, i2c->data, state); + + mga_i2c_set(i2c->mdev, i2c->data, state); } static void mga_gpio_setscl(void *data, int state) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - mga_i2c_set(mdev, i2c->clock, state); + + mga_i2c_set(i2c->mdev, i2c->clock, state); } static int mga_gpio_getsda(void *data) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - return (mga_i2c_read_gpio(mdev) & i2c->data) ? 1 : 0; + + return (mga_i2c_read_gpio(i2c->mdev) & i2c->data) ? 1 : 0; } static int mga_gpio_getscl(void *data) { struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; + + return (mga_i2c_read_gpio(i2c->mdev) & i2c->clock) ? 1 : 0; } static void mgag200_i2c_release(struct drm_device *dev, void *res) @@ -109,7 +109,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) i2c->clock = BIT(info->i2c.clock_bit); i2c->adapter.owner = THIS_MODULE; i2c->adapter.dev.parent = dev->dev; - i2c->dev = dev; + i2c->mdev = mdev; i2c_set_adapdata(>adapter, i2c); snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c"); -- 2.45.0
[PATCH v3 0/5] drm/udl: Convert to struct drm_edid
Convert udl to use struct drm_edid and its helpers. Also clean up a few things in the process. Patch 1 fixes a bug. Patches 2 to 4 convert the current EDID handling to struct drm_edid and its helpers. Patch 4 also separates the helpers for .get_modes() and .detect_ctx() from each other. Patch 5 removes the obsolete struct udl_connector. v3: - implement udl_probe_edid() with memchr_inv() (Jani) v2: - drop the generic EDID probing (Jani) - fixes Thomas Zimmermann (5): drm/udl: Remove DRM_CONNECTOR_POLL_HPD drm/udl: Move drm_dev_{enter,exit}() into udl_get_edid_block() drm/udl: Clean up Makefile drm/udl: Untangle .get_modes() and .detect_ctx() drm/udl: Remove struct udl_connector drivers/gpu/drm/udl/Makefile | 8 +- drivers/gpu/drm/udl/udl_drv.h | 12 +-- drivers/gpu/drm/udl/udl_edid.c| 80 + drivers/gpu/drm/udl/udl_edid.h| 15 drivers/gpu/drm/udl/udl_modeset.c | 138 +++--- 5 files changed, 132 insertions(+), 121 deletions(-) create mode 100644 drivers/gpu/drm/udl/udl_edid.c create mode 100644 drivers/gpu/drm/udl/udl_edid.h -- 2.44.0
[PATCH v3 3/5] drm/udl: Clean up Makefile
Clean up Makefile before listing new object files. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jani Nikula --- drivers/gpu/drm/udl/Makefile | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile index 3f6db179455d1..00690741db376 100644 --- a/drivers/gpu/drm/udl/Makefile +++ b/drivers/gpu/drm/udl/Makefile @@ -1,4 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only -udl-y := udl_drv.o udl_modeset.o udl_main.o udl_transfer.o + +udl-y := \ + udl_drv.o \ + udl_main.o \ + udl_modeset.o \ + udl_transfer.o obj-$(CONFIG_DRM_UDL) := udl.o -- 2.44.0
[PATCH v3 5/5] drm/udl: Remove struct udl_connector
Udl's struct udl_connector is an empty wrapper around struct drm_connector. Remove it. Allocate the connector as part of struct udl_device and inline the init function into its only caller. v2: - fix return value in udl_modeset_init() (Dan) Signed-off-by: Thomas Zimmermann Reviewed-by: Jani Nikula --- drivers/gpu/drm/udl/udl_drv.h | 10 +-- drivers/gpu/drm/udl/udl_modeset.c | 49 +++ 2 files changed, 11 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index f112cfb270f31..1eb716d9dad57 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -49,15 +49,6 @@ struct urb_list { size_t size; }; -struct udl_connector { - struct drm_connector connector; -}; - -static inline struct udl_connector *to_udl_connector(struct drm_connector *connector) -{ - return container_of(connector, struct udl_connector, connector); -} - struct udl_device { struct drm_device drm; struct device *dev; @@ -66,6 +57,7 @@ struct udl_device { struct drm_plane primary_plane; struct drm_crtc crtc; struct drm_encoder encoder; + struct drm_connector connector; struct mutex gem_lock; diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 4236ce57f5945..bbb04f98886a2 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -444,49 +444,14 @@ static const struct drm_connector_helper_funcs udl_connector_helper_funcs = { .detect_ctx = udl_connector_helper_detect_ctx, }; -static void udl_connector_destroy(struct drm_connector *connector) -{ - struct udl_connector *udl_connector = to_udl_connector(connector); - - drm_connector_cleanup(connector); - kfree(udl_connector); -} - static const struct drm_connector_funcs udl_connector_funcs = { .reset = drm_atomic_helper_connector_reset, .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = udl_connector_destroy, + .destroy = drm_connector_cleanup, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -struct drm_connector *udl_connector_init(struct drm_device *dev) -{ - struct udl_connector *udl_connector; - struct drm_connector *connector; - int ret; - - udl_connector = kzalloc(sizeof(*udl_connector), GFP_KERNEL); - if (!udl_connector) - return ERR_PTR(-ENOMEM); - - connector = _connector->connector; - ret = drm_connector_init(dev, connector, _connector_funcs, DRM_MODE_CONNECTOR_VGA); - if (ret) - goto err_kfree; - - drm_connector_helper_add(connector, _connector_helper_funcs); - - connector->polled = DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT; - - return connector; - -err_kfree: - kfree(udl_connector); - return ERR_PTR(ret); -} - /* * Modesetting */ @@ -556,9 +521,15 @@ int udl_modeset_init(struct drm_device *dev) return ret; encoder->possible_crtcs = drm_crtc_mask(crtc); - connector = udl_connector_init(dev); - if (IS_ERR(connector)) - return PTR_ERR(connector); + connector = >connector; + ret = drm_connector_init(dev, connector, _connector_funcs, DRM_MODE_CONNECTOR_VGA); + if (ret) + return ret; + drm_connector_helper_add(connector, _connector_helper_funcs); + + connector->polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; + ret = drm_connector_attach_encoder(connector, encoder); if (ret) return ret; -- 2.44.0
[PATCH v3 4/5] drm/udl: Untangle .get_modes() and .detect_ctx()
Provide separate implementations of .get_modes() and .detect_ctx() from struct drm_connector. Switch to struct drm_edid. Udl's .detect() helper used to fetch the EDID from the adapter and the .get_modes() helper provided display modes from the data. But this relied on the DRM helpers to call the functions in the correct order. When no EDID could be retrieved, .detect() regularly printed a warning to the kernel log. Switching to the new helpers around struct drm_edid separates both from each other. The .get_modes() helper now fetches the EDID by itself and the .detect_ctx() helper only tests for its presence. The patch does a number of things to implement this. - Move udl_get_edid_block() to udl_edid.c and rename it to udl_read_edid_block(). Then use the helper to implement probing in udl_probe_edid() and reading in udl_edid_read(). The latter helper is build on top of DRM helpers. - Replace the existing code in .get_modes() and .detect() with udl's new EDID helpers. The new code behaves like DRM's similar DDC-based helpers. Instead of .detect(), udl now implements .detect_ctx(). - Remove the edid data from struct udl_connector. The field cached the EDID data between calls to .detect() and .get_modes(), but is now unused. v3: - implement udl_probe_edid() with memchr_inv() (Jani) v2: - implement udl_probe_edid() within udl - reword commit description Signed-off-by: Thomas Zimmermann Reviewed-by: Jani Nikula --- drivers/gpu/drm/udl/Makefile | 1 + drivers/gpu/drm/udl/udl_drv.h | 2 - drivers/gpu/drm/udl/udl_edid.c| 80 +++ drivers/gpu/drm/udl/udl_edid.h| 15 ++ drivers/gpu/drm/udl/udl_modeset.c | 90 +++ 5 files changed, 115 insertions(+), 73 deletions(-) create mode 100644 drivers/gpu/drm/udl/udl_edid.c create mode 100644 drivers/gpu/drm/udl/udl_edid.h diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile index 00690741db376..43d69a16af183 100644 --- a/drivers/gpu/drm/udl/Makefile +++ b/drivers/gpu/drm/udl/Makefile @@ -2,6 +2,7 @@ udl-y := \ udl_drv.o \ + udl_edid.o \ udl_main.o \ udl_modeset.o \ udl_transfer.o diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 282ebd6c02fda..f112cfb270f31 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -51,8 +51,6 @@ struct urb_list { struct udl_connector { struct drm_connector connector; - /* last udl_detect edid */ - struct edid *edid; }; static inline struct udl_connector *to_udl_connector(struct drm_connector *connector) diff --git a/drivers/gpu/drm/udl/udl_edid.c b/drivers/gpu/drm/udl/udl_edid.c new file mode 100644 index 0..d67e6bf1f2aec --- /dev/null +++ b/drivers/gpu/drm/udl/udl_edid.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include +#include + +#include "udl_drv.h" +#include "udl_edid.h" + +static int udl_read_edid_block(void *data, u8 *buf, unsigned int block, size_t len) +{ + struct udl_device *udl = data; + struct drm_device *dev = >drm; + struct usb_device *udev = udl_to_usb_device(udl); + u8 *read_buff; + int idx, ret; + size_t i; + + read_buff = kmalloc(2, GFP_KERNEL); + if (!read_buff) + return -ENOMEM; + + if (!drm_dev_enter(dev, )) { + ret = -ENODEV; + goto err_kfree; + } + + for (i = 0; i < len; i++) { + int bval = (i + block * EDID_LENGTH) << 8; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0x02, (0x80 | (0x02 << 5)), bval, + 0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT); + if (ret < 0) { + drm_err(dev, "Read EDID byte %zu failed err %x\n", i, ret); + goto err_drm_dev_exit; + } else if (ret < 1) { + ret = -EIO; + drm_err(dev, "Read EDID byte %zu failed\n", i); + goto err_drm_dev_exit; + } + + buf[i] = read_buff[1]; + } + + drm_dev_exit(idx); + kfree(read_buff); + + return 0; + +err_drm_dev_exit: + drm_dev_exit(idx); +err_kfree: + kfree(read_buff); + return ret; +} + +bool udl_probe_edid(struct udl_device *udl) +{ + u8 hdr[8]; + int ret; + + ret = udl_read_edid_block(udl, hdr, 0, sizeof(hdr)); + if (ret) + return false; + + /* +* The adapter sends all-zeros if no monitor has been +* connected. We consider anything else a connection. +*/ + return !!memchr_inv(hdr, 0, sizeof(hdr)); +} + +const struct drm_edid *udl_edid_read(struct drm_connector *connector) +{ + struct udl_device *udl = to_udl(
[PATCH v3 1/5] drm/udl: Remove DRM_CONNECTOR_POLL_HPD
DisplayLink devices do not generate hotplug events. Remove the poll flag DRM_CONNECTOR_POLL_HPD, as it may not be specified together with DRM_CONNECTOR_POLL_CONNECT or DRM_CONNECTOR_POLL_DISCONNECT. Signed-off-by: Thomas Zimmermann Fixes: afdfc4c6f55f ("drm/udl: Fixed problem with UDL adpater reconnection") Reviewed-by: Jani Nikula Cc: Robert Tarasov Cc: Alex Deucher Cc: Dave Airlie Cc: Sean Paul Cc: Thomas Zimmermann Cc: dri-devel@lists.freedesktop.org Cc: # v4.15+ --- drivers/gpu/drm/udl/udl_modeset.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 7702359c90c22..751da3a294c44 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -527,8 +527,7 @@ struct drm_connector *udl_connector_init(struct drm_device *dev) drm_connector_helper_add(connector, _connector_helper_funcs); - connector->polled = DRM_CONNECTOR_POLL_HPD | - DRM_CONNECTOR_POLL_CONNECT | + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; return connector; -- 2.44.0
[PATCH v3 2/5] drm/udl: Move drm_dev_{enter, exit}() into udl_get_edid_block()
Protect the code in udl_get_edid_block() with drm_dev_enter() and drm_dev_exit(), so that all callers automatically invoke it. The function uses hardware resources, which can be hot-unplugged at any time. The other code in udl_connector_detect() does not use the resources of the hardware device and therefore does not require protection. This change will allow to use udl_get_edid_block() in various contexts easily. Signed-off-by: Thomas Zimmermann Reviewed-by: Jani Nikula --- drivers/gpu/drm/udl/udl_modeset.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 751da3a294c44..3df9fc38388b4 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -434,13 +434,18 @@ static int udl_get_edid_block(void *data, u8 *buf, unsigned int block, size_t le struct drm_device *dev = >drm; struct usb_device *udev = udl_to_usb_device(udl); u8 *read_buff; - int ret; + int idx, ret; size_t i; read_buff = kmalloc(2, GFP_KERNEL); if (!read_buff) return -ENOMEM; + if (!drm_dev_enter(dev, )) { + ret = -ENODEV; + goto err_kfree; + } + for (i = 0; i < len; i++) { int bval = (i + block * EDID_LENGTH) << 8; @@ -449,20 +454,23 @@ static int udl_get_edid_block(void *data, u8 *buf, unsigned int block, size_t le 0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT); if (ret < 0) { drm_err(dev, "Read EDID byte %zu failed err %x\n", i, ret); - goto err_kfree; + goto err_drm_dev_exit; } else if (ret < 1) { ret = -EIO; drm_err(dev, "Read EDID byte %zu failed\n", i); - goto err_kfree; + goto err_drm_dev_exit; } buf[i] = read_buff[1]; } + drm_dev_exit(idx); kfree(read_buff); return 0; +err_drm_dev_exit: + drm_dev_exit(idx); err_kfree: kfree(read_buff); return ret; @@ -474,21 +482,15 @@ static enum drm_connector_status udl_connector_detect(struct drm_connector *conn struct udl_device *udl = to_udl(dev); struct udl_connector *udl_connector = to_udl_connector(connector); enum drm_connector_status status = connector_status_disconnected; - int idx; /* cleanup previous EDID */ kfree(udl_connector->edid); udl_connector->edid = NULL; - if (!drm_dev_enter(dev, )) - return connector_status_disconnected; - udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl); if (udl_connector->edid) status = connector_status_connected; - drm_dev_exit(idx); - return status; } -- 2.44.0
Re: [PATCH v2 4/5] drm/udl: Untangle .get_modes() and .detect_ctx()
udl_connector_helper_funcs = { + .get_modes = udl_connector_helper_get_modes, + .detect_ctx = udl_connector_helper_detect_ctx, +}; static void udl_connector_destroy(struct drm_connector *connector) { struct udl_connector *udl_connector = to_udl_connector(connector); drm_connector_cleanup(connector); - kfree(udl_connector->edid); kfree(udl_connector); } static const struct drm_connector_funcs udl_connector_funcs = { .reset = drm_atomic_helper_connector_reset, - .detect = udl_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = udl_connector_destroy, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: simpledrm, running display servers, and drivers replacing simpledrm while the display server is running
Hi (This was discussed on #dri-devel, but I'll reiterate here as well). There are two problems at hand; one is the race condition during boot when the login screen (or whatever display server appears first) is launched with simpledrm, only some moments later having the real GPU driver appear. The other is general purpose GPU hotplugging, including the unplugging the GPU decided by the compositor to be the primary one. The situation of booting with simpledrm (problem 2) is a special case of problem 1. From the kernel's perspective, unloading simpledrm is the same as what you call general purpose GPU hotplugging. Even through there is not a full GPU, but a trivial scanout buffer. In userspace, you see the same sequence of events as in the general case. The latter is something that should be handled in userspace, by compositors, etc, I agree. The former, however, is not properly solved by userspace learning how to deal with primary GPU unplugging and switching to using a real GPU driver, as it'd break the booting and login experience. When it works, i.e. the race condition is not hit, is this: * System boots * Plymouth shows a "splash" screen * The login screen display server is launched with the real GPU driver * The login screen interface is smoothly animating using hardware accelerating, presenting "advanced" graphical content depending on hardware capabilities (e.g. high color bit depth, HDR, and so on) If the race condition is hit, with a compositor supporting primary GPU hotplugging, it'll work like this: * System boots * Plymouth shows a "splash" screen * The login screen display server is launched with simpledrm * Due to using simpldrm, the login screen interface is not animated and just plops up, and no "advanced" graphical content is enabled due to apparent missing hardware capabilities * The real GPU driver appears, the login screen now starts to become animated, and may suddenly change appearance due to capabilties having changed Thus, by just supporting hotplugging the primary GPU in userspace, we'll still end up with a glitchy boot experience, and it forces userspace to add things like sleep(10) to work around this. In other words, fixing userspace is *not* a correct solution to the problem, it's a work around (albeit a behaivor we want for other reasons) for the race condition. To really fix the flickering, you need to read the old DRM device's atomic state and apply it to the new device. Then tell the desktop and applications to re-init their rendering stack. Depending on the DRM driver and its hardware, it might be possible to do this without flickering. The key is to not loose the original scanout buffer, while not probing the new device driver. But that needs work in each individual DRM driver. Arguably, the only place a more educated guess about whether to wait or not, and if so how long, is the kernel. As I said before, driver modules come and go and hardware devices come and go. To detect if there might be a native driver waiting to be loaded, you can test for - 'nomodeset' on the command line -> no native driver - 'systemd-load-modules' not started -> maybe wait - look for drivers under /lib/modules//kernel/drivers/gpu/drm/ -> maybe wait - maybe udev can tell you more - it might for detection help that recently simpledrm devices refer to their parent PCI device - maybe systemd tracks the probed devices Best regards Thomas Jonas The next best solution is to keep the final DRM device open until a new one shows up. All DRM graphics drivers with hotplugging support are required to accept commands after their hardware has been unplugged. They simply won't display anything. Best regards Thomas Thanks -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: simpledrm, running display servers, and drivers replacing simpledrm while the display server is running
Hi Am 09.05.24 um 15:06 schrieb nerdopolis: Hi So I have been made aware of an apparent race condition of some drivers taking a bit longer to load, which could lead to a possible race condition of display servers/greeters using the simpledrm device, and then experiencing problems once the real driver loads, the simpledrm device that the display servers are using as their primary GPU goes away. For example Weston crashes, Xorg crashes, wlroots seems to stay running, but doesn't draw anything on the screen, kwin aborts, This is if you boot on a QEMU machine with the virtio card, with modprobe.blacklist=virtio_gpu, and then, when the display server is running, run sudo modprobe virtio-gpu Namely, it's been recently reported here: https://github.com/sddm/sddm/issues/1917 and here https://github.com/systemd/systemd/issues/32509 My thinking: Instead of simpledrm's /dev/dri/card0 device going away when the real driver loads, is it possible for simpledrm to instead simulate an unplug of the fake display/CRTC? To my knowledge, there's no hotplugging for CRTCs. That way in theory, the simpledrm device will now be useless for drawing for drawing to the screen at that point, since the real driver is now taken over, but this way here, at least the display server doesn't lose its handles to the /dev/dri/card0 device, (and then maybe only remove itself once the final handle to it closes?) Is something like this possible to do with the way simpledrm works with the low level video memory? Or is this not possible? Userspace needs to be prepared that graphics devices can do hotplugging. The correct solution is to make compositors work without graphics devices. The next best solution is to keep the final DRM device open until a new one shows up. All DRM graphics drivers with hotplugging support are required to accept commands after their hardware has been unplugged. They simply won't display anything. Best regards Thomas Thanks -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PULL] drm-misc-fixes
Hi Dave, Sima, this is the weekly drm-misc-fixes PR. Sorry for being late. Best regards Thomas drm-misc-fixes-2024-05-10: Short summary of fixes pull: core: - fix connector debugging output meson: - dw-hdmi: power-up fixes - dw-hdmi: add badngap setting for g12 The following changes since commit da85f0aaa9f21999753b01d45c0343f885a8f905: drm/panel: ili9341: Use predefined error codes (2024-05-02 09:41:27 +0200) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-05-10 for you to fetch changes up to 6897204ea3df808d342c8e4613135728bc538bcd: drm/connector: Add \n to message about demoting connector force-probes (2024-05-07 09:17:07 -0700) Short summary of fixes pull: core: - fix connector debugging output meson: - dw-hdmi: power-up fixes - dw-hdmi: add badngap setting for g12 Douglas Anderson (1): drm/connector: Add \n to message about demoting connector force-probes Jerome Brunet (2): drm/meson: dw-hdmi: power up phy on device init drm/meson: dw-hdmi: add bandgap setting for g12 drivers/gpu/drm/drm_connector.c | 2 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 70 --- 2 files changed, 32 insertions(+), 40 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH 11/11] drm/tegra: Use fbdev client helpers
Hi Am 07.05.24 um 23:03 schrieb Felix Kuehling: On 2024-05-07 07:58, Thomas Zimmermann wrote: Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/radeon/radeon_fbdev.c | 66 ++- Was radeon meant to be a separate patch? Indeed. It also _was_ a separate patch. This looks like a mistake during rebasing. Thanks for noticing. I'll fix that in v2. Best regards Thomas Regards, Felix drivers/gpu/drm/tegra/fbdev.c | 58 ++- 2 files changed, 6 insertions(+), 118 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c index 02bf25759059a..cf790922174ea 100644 --- a/drivers/gpu/drm/radeon/radeon_fbdev.c +++ b/drivers/gpu/drm/radeon/radeon_fbdev.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -293,71 +292,12 @@ static const struct drm_fb_helper_funcs radeon_fbdev_fb_helper_funcs = { }; /* - * Fbdev client and struct drm_client_funcs + * struct drm_client_funcs */ -static void radeon_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = fb_helper->dev; - struct radeon_device *rdev = dev->dev_private; - - if (fb_helper->info) { - vga_switcheroo_client_fb_set(rdev->pdev, NULL); - drm_helper_force_disable_all(dev); - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int radeon_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - vga_switcheroo_process_delayed_switch(); - - return 0; -} - -static int radeon_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; - struct radeon_device *rdev = dev->dev_private; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - vga_switcheroo_client_fb_set(rdev->pdev, fb_helper->info); - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup radeon fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs radeon_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = radeon_fbdev_client_unregister, - .restore = radeon_fbdev_client_restore, - .hotplug = radeon_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; void radeon_fbdev_setup(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c index db6eaac3d30e6..f9cc365cfed94 100644 --- a/drivers/gpu/drm/tegra/fbdev.c +++ b/drivers/gpu/drm/tegra/fbdev.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -150,63 +149,12 @@ static const struct drm_fb_helper_funcs tegra_fb_helper_funcs = { }; /* - * struct drm_client + * struct drm_client_funcs */ -static void tegra_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_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int tegra_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int tegra_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, &qu
Re: [PATCH 00/15] drm: struct drm_edid conversions
Hi Am 16.04.24 um 15:22 schrieb Jani Nikula: I've these laying in a branch for a while, maybe let's try to make some forward progress in this front. Could you take another look at the udl patches at [1]? The second iteration of the patches is self-contained within the driver. So the most-controversial points should be resolved now. Best regards Thomas [1] https://patchwork.freedesktop.org/series/132039/#rev2 Build tested only, on x86, arm, and arm64. BR, Jani. Jani Nikula (15): drm/panel: simple: switch to struct drm_edid drm/panel-samsung-atna33xc20: switch to struct drm_edid drm/panel-edp: switch to struct drm_edid drm/bridge/analogix/anx6345: switch to struct drm_edid drm/bridge/analogix/anx78xx: switch to struct drm_edid drm/sun4i: hdmi: switch to struct drm_edid drm/vc4: hdmi: switch to struct drm_edid drm/bridge: anx7625: use struct drm_edid more drm/gud: switch to struct drm_edid drm/i2c: tda998x: switch to struct drm_edid drm/bochs: switch to struct drm_edid drm/virtio: switch to struct drm_edid drm/rockchip: cdn-dp: switch to struct drm_edid drm/rockchip: inno_hdmi: switch to struct drm_edid drm/rockchip: rk3066_hdmi: switch to struct drm_edid .../drm/bridge/analogix/analogix-anx6345.c| 15 +++--- .../drm/bridge/analogix/analogix-anx78xx.c| 23 +- drivers/gpu/drm/bridge/analogix/anx7625.c | 26 +++ drivers/gpu/drm/bridge/analogix/anx7625.h | 10 +--- drivers/gpu/drm/gud/gud_connector.c | 12 ++--- drivers/gpu/drm/i2c/tda998x_drv.c | 19 drivers/gpu/drm/panel/panel-edp.c | 17 --- .../gpu/drm/panel/panel-samsung-atna33xc20.c | 13 -- drivers/gpu/drm/panel/panel-simple.c | 15 +++--- drivers/gpu/drm/rockchip/cdn-dp-core.c| 33 +++-- drivers/gpu/drm/rockchip/cdn-dp-core.h| 2 +- drivers/gpu/drm/rockchip/inno_hdmi.c | 12 ++--- drivers/gpu/drm/rockchip/rk3066_hdmi.c| 12 ++--- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c| 18 +--- drivers/gpu/drm/tiny/bochs.c | 23 -- drivers/gpu/drm/vc4/vc4_hdmi.c| 46 ++- drivers/gpu/drm/virtio/virtgpu_display.c | 10 ++-- drivers/gpu/drm/virtio/virtgpu_drv.h | 2 +- drivers/gpu/drm/virtio/virtgpu_vq.c | 12 ++--- 19 files changed, 167 insertions(+), 153 deletions(-) -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PATCH] drm/fbdev-shmem: Clean up deferred I/O
Call fb_deferred_io_cleanup() upon destroying the framebuffer device. Releases the internal memory. Signed-off-by: Thomas Zimmermann Fixes: 150f431a0831 ("drm/fbdev: Add fbdev-shmem") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/drm_fbdev_shmem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c index a85a8a8e2eb8b..0c785007f11b1 100644 --- a/drivers/gpu/drm/drm_fbdev_shmem.c +++ b/drivers/gpu/drm/drm_fbdev_shmem.c @@ -60,6 +60,7 @@ static void drm_fbdev_shmem_fb_destroy(struct fb_info *info) if (!fb_helper->dev) return; + fb_deferred_io_cleanup(info); drm_fb_helper_fini(fb_helper); drm_client_buffer_vunmap(fb_helper->buffer); -- 2.44.0
[PATCH] drm/fbdev-dma: Clean up deferred I/O
Call fb_deferred_io_cleanup() upon destroying the framebuffer device. Releases the internal memory. Signed-off-by: Thomas Zimmermann Fixes: 808a40b69468 ("drm/fbdev-dma: Implement damage handling and deferred I/O") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard --- drivers/gpu/drm/drm_fbdev_dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index 5eeb5164e9e2b..97ef6300d47e0 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -59,6 +59,7 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info) if (!fb_helper->dev) return; + fb_deferred_io_cleanup(info); drm_fb_helper_fini(fb_helper); drm_client_buffer_vunmap(fb_helper->buffer); -- 2.44.0
Re: [PATCH 08/11] drm/i915: Use drm_fbdev_helper_client_unregister()
Hi Am 07.05.24 um 14:25 schrieb Rodrigo Vivi: On Tue, May 07, 2024 at 01:58:29PM +0200, Thomas Zimmermann wrote: Implement struct drm_client_funcs.unregister with the helpers drm_fbdev_helper_client_unregister() and remove the custom code from the driver. The generic helper is equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/i915/display/intel_fbdev.c | 21 ++--- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index bda702c2cab8e..f1b4543bffc02 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include @@ -580,25 +579,9 @@ static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) } /* - * Fbdev client and struct drm_client_funcs + * struct drm_client_funcs */ -static void intel_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = fb_helper->dev; - struct pci_dev *pdev = to_pci_dev(dev->dev); - - if (fb_helper->info) { - vga_switcheroo_client_fb_set(pdev, NULL); - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_fb_helper_unprepare(fb_helper); - drm_client_release(_helper->client); The only real difference is that these 2 calls are inverted in the new drm_fbdev_helper_client_unregister. The condition in this if statement is different for some drivers, but not i915. The setup code first does a _prepare and then an _init+_register, hence the _release goes first and then comes the _unprepare. I feel that the releasing after the unprepare sounds more logical, but if there's no actual issue with that and it is working for everybody, let's do that. It should make no difference in practice, but doing the release first is the inverse of the setup; hence conceptually cleaner. Reviewed-by: Rodrigo Vivi Acked-by: Rodrigo Vivi (to get through drm-misc with everything else if you prefer) Thanks. Best regards Thomas - kfree(fb_helper); - } -} - static int intel_fbdev_client_restore(struct drm_client_dev *client) { struct drm_i915_private *dev_priv = to_i915(client->dev); @@ -644,7 +627,7 @@ static int intel_fbdev_client_hotplug(struct drm_client_dev *client) static const struct drm_client_funcs intel_fbdev_client_funcs = { .owner = THIS_MODULE, - .unregister = intel_fbdev_client_unregister, + .unregister = drm_fbdev_helper_client_unregister, .restore= intel_fbdev_client_restore, .hotplug= intel_fbdev_client_hotplug, }; -- 2.44.0 -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PATCH 11/11] drm/tegra: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/radeon/radeon_fbdev.c | 66 ++- drivers/gpu/drm/tegra/fbdev.c | 58 ++- 2 files changed, 6 insertions(+), 118 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c index 02bf25759059a..cf790922174ea 100644 --- a/drivers/gpu/drm/radeon/radeon_fbdev.c +++ b/drivers/gpu/drm/radeon/radeon_fbdev.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -293,71 +292,12 @@ static const struct drm_fb_helper_funcs radeon_fbdev_fb_helper_funcs = { }; /* - * Fbdev client and struct drm_client_funcs + * struct drm_client_funcs */ -static void radeon_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = fb_helper->dev; - struct radeon_device *rdev = dev->dev_private; - - if (fb_helper->info) { - vga_switcheroo_client_fb_set(rdev->pdev, NULL); - drm_helper_force_disable_all(dev); - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int radeon_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - vga_switcheroo_process_delayed_switch(); - - return 0; -} - -static int radeon_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; - struct radeon_device *rdev = dev->dev_private; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - vga_switcheroo_client_fb_set(rdev->pdev, fb_helper->info); - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup radeon fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs radeon_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = radeon_fbdev_client_unregister, - .restore= radeon_fbdev_client_restore, - .hotplug= radeon_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; void radeon_fbdev_setup(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c index db6eaac3d30e6..f9cc365cfed94 100644 --- a/drivers/gpu/drm/tegra/fbdev.c +++ b/drivers/gpu/drm/tegra/fbdev.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -150,63 +149,12 @@ static const struct drm_fb_helper_funcs tegra_fb_helper_funcs = { }; /* - * struct drm_client + * struct drm_client_funcs */ -static void tegra_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_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int tegra_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int tegra_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - retur
[PATCH 10/11] drm/omapdrm: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 55 ++-- 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 523be34682caf..f6c131932a756 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -280,60 +279,12 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi) } /* - * struct drm_client + * struct drm_client_funcs */ -static void omap_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_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int omap_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int omap_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs omap_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = omap_fbdev_client_unregister, - .restore= omap_fbdev_client_restore, - .hotplug= omap_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; void omap_fbdev_setup(struct drm_device *dev) -- 2.44.0
[PATCH 09/11] drm/msm: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/msm/msm_fbdev.c | 58 ++--- 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 030bedac632d0..86f87f55513d1 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -164,63 +163,12 @@ static const struct drm_fb_helper_funcs msm_fb_helper_funcs = { }; /* - * struct drm_client + * struct drm_client_funcs */ -static void msm_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_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int msm_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int msm_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs msm_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = msm_fbdev_client_unregister, - .restore= msm_fbdev_client_restore, - .hotplug= msm_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; /* initialize fbdev helper */ -- 2.44.0
[PATCH 08/11] drm/i915: Use drm_fbdev_helper_client_unregister()
Implement struct drm_client_funcs.unregister with the helpers drm_fbdev_helper_client_unregister() and remove the custom code from the driver. The generic helper is equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/i915/display/intel_fbdev.c | 21 ++--- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index bda702c2cab8e..f1b4543bffc02 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include @@ -580,25 +579,9 @@ static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv) } /* - * Fbdev client and struct drm_client_funcs + * struct drm_client_funcs */ -static void intel_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = fb_helper->dev; - struct pci_dev *pdev = to_pci_dev(dev->dev); - - if (fb_helper->info) { - vga_switcheroo_client_fb_set(pdev, NULL); - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_fb_helper_unprepare(fb_helper); - drm_client_release(_helper->client); - kfree(fb_helper); - } -} - static int intel_fbdev_client_restore(struct drm_client_dev *client) { struct drm_i915_private *dev_priv = to_i915(client->dev); @@ -644,7 +627,7 @@ static int intel_fbdev_client_hotplug(struct drm_client_dev *client) static const struct drm_client_funcs intel_fbdev_client_funcs = { .owner = THIS_MODULE, - .unregister = intel_fbdev_client_unregister, + .unregister = drm_fbdev_helper_client_unregister, .restore= intel_fbdev_client_restore, .hotplug= intel_fbdev_client_hotplug, }; -- 2.44.0
[PATCH 05/11] drm/armada: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/armada/armada_fbdev.c | 58 ++- 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index d223176912b63..68d4fc0e47268 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -131,63 +130,12 @@ static const struct drm_fb_helper_funcs armada_fb_helper_funcs = { }; /* - * Fbdev client and struct drm_client_funcs + * struct drm_client_funcs */ -static void armada_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fbh = drm_fb_helper_from_client(client); - - if (fbh->info) { - drm_fb_helper_unregister_info(fbh); - } else { - drm_client_release(>client); - drm_fb_helper_unprepare(fbh); - kfree(fbh); - } -} - -static int armada_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int armada_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fbh = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fbh); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fbh); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fbh); -err_drm_err: - drm_err(dev, "armada: Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs armada_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = armada_fbdev_client_unregister, - .restore= armada_fbdev_client_restore, - .hotplug= armada_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; void armada_fbdev_setup(struct drm_device *dev) -- 2.44.0
[PATCH 07/11] drm/gma500: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/gma500/fbdev.c | 58 ++ 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c index 98b44974d42dd..8a6cb47e83f8f 100644 --- a/drivers/gpu/drm/gma500/fbdev.c +++ b/drivers/gpu/drm/gma500/fbdev.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -252,63 +251,12 @@ static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = { }; /* - * struct drm_client_funcs and setup code + * struct drm_client_funcs */ -static void psb_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_fb_helper_unregister_info(fb_helper); - } else { - drm_fb_helper_unprepare(fb_helper); - drm_client_release(_helper->client); - kfree(fb_helper); - } -} - -static int psb_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int psb_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup gma500 fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs psb_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = psb_fbdev_client_unregister, - .restore= psb_fbdev_client_restore, - .hotplug= psb_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; void psb_fbdev_setup(struct drm_psb_private *dev_priv) -- 2.44.0
[PATCH 06/11] drm/exynos: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 58 ++- 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index a379c8ca435a3..982754008a803 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -10,7 +10,6 @@ #include -#include #include #include #include @@ -140,63 +139,12 @@ static const struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = { }; /* - * struct drm_client + * struct drm_client_funcs */ -static void exynos_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_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int exynos_drm_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int exynos_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs exynos_drm_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = exynos_drm_fbdev_client_unregister, - .restore= exynos_drm_fbdev_client_restore, - .hotplug= exynos_drm_fbdev_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; void exynos_drm_fbdev_setup(struct drm_device *dev) -- 2.44.0
[PATCH 00/11] drm: Provide common fbdev client helpers
All fbdev emulation has finally been converted to use struct drm_client. Put the common client code into shared helpers. There are three callbacks in struct drm_client_funcs, unregister, restore and hotplug, which have similar implementations among the various drivers. This can all be shared. i915 is slightly different, but can still use some of the helper code. Fbdev support for VGA switcheroo and non-atomic mode setting is now entirely implemented in the fbdev helpers. Thomas Zimmermann (11): drm/fb-helper: Add helpers for struct drm_client_funcs drm/fbdev-dma: Use fbdev client helpers drm/fbdev-shmem: Use fbdev client helpers drm/fbdev-ttm: Use fbdev client helpers drm/armada: Use fbdev client helpers drm/exynos: Use fbdev client helpers drm/gma500: Use fbdev client helpers drm/i915: Use drm_fbdev_helper_client_unregister() drm/msm: Use fbdev client helpers drm/omapdrm: Use fbdev client helpers drm/tegra: Use fbdev client helpers drivers/gpu/drm/armada/armada_fbdev.c | 58 +--- drivers/gpu/drm/drm_fb_helper.c| 103 + drivers/gpu/drm/drm_fbdev_dma.c| 56 +-- drivers/gpu/drm/drm_fbdev_shmem.c | 56 +-- drivers/gpu/drm/drm_fbdev_ttm.c| 58 +--- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 58 +--- drivers/gpu/drm/gma500/fbdev.c | 58 +--- drivers/gpu/drm/i915/display/intel_fbdev.c | 21 + drivers/gpu/drm/msm/msm_fbdev.c| 58 +--- drivers/gpu/drm/omapdrm/omap_fbdev.c | 55 +-- drivers/gpu/drm/radeon/radeon_fbdev.c | 66 + drivers/gpu/drm/tegra/fbdev.c | 58 +--- include/drm/drm_fb_helper.h| 19 13 files changed, 154 insertions(+), 570 deletions(-) base-commit: 980de4c8f9c4fc65bd51d355372e06dc576c3ea7 -- 2.44.0
[PATCH 01/11] drm/fb-helper: Add helpers for struct drm_client_funcs
Add default implementations for unregister, restore and hotplug of struct drm_client_funcs. The provided helpers are compatible with the requirements of most DRM drivers. The helpers handle support for VGA switcheroo automatically. With DRM drivers that don't implement VGA switcheroo, this does nothing. The helpers also support DRM drivers with non-atomic mode setting, which require additional steps to disable their modesetting pipeline. Compared to its current implementations in various drivers, there is one difference in drm_fbdev_helper_client_hotplug(). The custom functions perform hotpluging if struct drm_device.fb_helper has been set, while the custom helper tests for struct drm_fb_helper.info. Both fields signal the presence of an active fbdev emulation, but the former field is deprecated. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fb_helper.c | 103 include/drm/drm_fb_helper.h | 19 ++ 2 files changed, 122 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index e2e19f49342e1..005debf61a571 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -2013,3 +2014,105 @@ 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); + +/* + * struct drm_client_funcs + */ + +/** + * drm_fbdev_helper_client_unregister - Unregister callback for fbdev emulation + * @client: The fbdev client + * + * Implements struct drm_client_funcs.unregister for fbdev emulation. The + * helper destroys the framebuffer device and releases all resources. It + * further disables all outputs and clears the VGA switcheroo framebuffer + * info for PCI devices. + */ +void drm_fbdev_helper_client_unregister(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = fb_helper->dev; + + if (fb_helper->info) { + if (dev_is_pci(dev->dev)) + vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), NULL); + drm_fb_helper_unregister_info(fb_helper); + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_force_disable_all(dev); + } else { + drm_client_release(client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + } +} +EXPORT_SYMBOL(drm_fbdev_helper_client_unregister); + +/** + * drm_fbdev_helper_client_restore - Restore callback for fbdev emulation + * @client: The fbdev client + * + * Implements struct drm_client_funcs.restore for fbdev emulation. The + * helper restores the console output after the fbdev emulation's current + * configuration. It also informs VGA switcheroo about the change. + * + * Returns: + * 0 on success, or a negative errno code otherwise. + */ +int drm_fbdev_helper_client_restore(struct drm_client_dev *client) +{ + struct drm_device *dev = client->dev; + + drm_fb_helper_lastclose(dev); + + if (dev_is_pci(dev->dev)) + vga_switcheroo_process_delayed_switch(); + + return 0; +} +EXPORT_SYMBOL(drm_fbdev_helper_client_restore); + +/** + * drm_fbdev_helper_client_hotplug - Hotplug callback for fbdev emulation + * @client: The fbdev client + * + * Implements struct drm_client_funcs.hotplug for fbdev emulation. The + * helper handles the hotplugging event by restoring the display output. + * If no output has been established yet, it instead performs an initial + * display configuration. On successful configuration, it installs the + * framebuffer info VGA switcheroo for PCI devices. + * + * Returns: + * 0 on success, or a negative errno code otherwise. + */ +int drm_fbdev_helper_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; + + if (fb_helper->info) + return drm_fb_helper_hotplug_event(fb_helper); + + ret = drm_fb_helper_init(dev, fb_helper); + if (ret) + goto err_drm_err; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper); + if (ret) + goto err_drm_fb_helper_fini; + + if (dev_is_pci(dev->dev)) + vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), fb_helper->info); + + return 0; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(fb_helper); +err_drm_err: + drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); + return ret; +} +EXPORT_SYMBOL(drm_fbdev_helper_client_hotplug); diff --git a/include/drm/drm_f
[PATCH 04/11] drm/fbdev-ttm: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fbdev_ttm.c | 58 +++-- 1 file changed, 5 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_ttm.c b/drivers/gpu/drm/drm_fbdev_ttm.c index bb7898cd7dc63..b1c5ebe6b9588 100644 --- a/drivers/gpu/drm/drm_fbdev_ttm.c +++ b/drivers/gpu/drm/drm_fbdev_ttm.c @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -239,60 +238,13 @@ static const struct drm_fb_helper_funcs drm_fbdev_ttm_helper_funcs = { .fb_dirty = drm_fbdev_ttm_helper_fb_dirty, }; -static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_ttm_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret); - return ret; -} +/* + * struct drm_client_funcs + */ static const struct drm_client_funcs drm_fbdev_ttm_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_ttm_client_unregister, - .restore= drm_fbdev_ttm_client_restore, - .hotplug= drm_fbdev_ttm_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; /** -- 2.44.0
[PATCH 03/11] drm/fbdev-shmem: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fbdev_shmem.c | 56 ++- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c index a85a8a8e2eb8b..475e2c228d97f 100644 --- a/drivers/gpu/drm/drm_fbdev_shmem.c +++ b/drivers/gpu/drm/drm_fbdev_shmem.c @@ -2,7 +2,6 @@ #include -#include #include #include #include @@ -210,60 +209,9 @@ static const struct drm_fb_helper_funcs drm_fbdev_shmem_helper_funcs = { * struct drm_client_funcs */ -static void drm_fbdev_shmem_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_shmem_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev-shmem: Failed to setup emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs drm_fbdev_shmem_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_shmem_client_unregister, - .restore= drm_fbdev_shmem_client_restore, - .hotplug= drm_fbdev_shmem_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; /** -- 2.44.0
[PATCH 02/11] drm/fbdev-dma: Use fbdev client helpers
Implement struct drm_client_funcs with the respective helpers and remove the custom code from the emulation. The generic helpers are equivalent in functionality. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_fbdev_dma.c | 56 ++--- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index 5eeb5164e9e2b..7991e37f000e7 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -2,7 +2,6 @@ #include -#include #include #include #include @@ -189,60 +188,9 @@ static const struct drm_fb_helper_funcs drm_fbdev_dma_helper_funcs = { * struct drm_client_funcs */ -static void drm_fbdev_dma_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_dma_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_dma_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; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev-dma: Failed to setup generic emulation (ret=%d)\n", ret); - return ret; -} - static const struct drm_client_funcs drm_fbdev_dma_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_dma_client_unregister, - .restore= drm_fbdev_dma_client_restore, - .hotplug= drm_fbdev_dma_client_hotplug, + .owner = THIS_MODULE, + DRM_FBDEV_HELPER_CLIENT_FUNCS, }; /** -- 2.44.0
Re: [PATCH v2 12/12] fbdev/viafb: Make I2C terminology more inclusive
Am 03.05.24 um 20:13 schrieb Easwar Hariharan: I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave" with more appropriate terms. Inspired by and following on to Wolfram's series to fix drivers/i2c/[1], fix the terminology for users of I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists in the specification. Compile tested, no functionality changes intended [1]: https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/ Signed-off-by: Easwar Hariharan Acked-by: Thomas Zimmermann --- drivers/video/fbdev/via/chip.h| 8 drivers/video/fbdev/via/dvi.c | 24 drivers/video/fbdev/via/lcd.c | 6 +++--- drivers/video/fbdev/via/via_aux.h | 2 +- drivers/video/fbdev/via/via_i2c.c | 12 ++-- drivers/video/fbdev/via/vt1636.c | 6 +++--- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/video/fbdev/via/chip.h b/drivers/video/fbdev/via/chip.h index f0a19cbcb9e5..f81af13630e2 100644 --- a/drivers/video/fbdev/via/chip.h +++ b/drivers/video/fbdev/via/chip.h @@ -69,7 +69,7 @@ #define VT1632_TMDS 0x01 #define INTEGRATED_TMDS 0x42 -/* Definition TMDS Trasmitter I2C Slave Address */ +/* Definition TMDS Trasmitter I2C Target Address */ #define VT1632_TMDS_I2C_ADDR0x10 /**/ @@ -88,21 +88,21 @@ #define TX_DATA_DDR_MODE0x04 #define TX_DATA_SDR_MODE0x08 -/* Definition LVDS Trasmitter I2C Slave Address */ +/* Definition LVDS Trasmitter I2C Target Address */ #define VT1631_LVDS_I2C_ADDR0x70 #define VT3271_LVDS_I2C_ADDR0x80 #define VT1636_LVDS_I2C_ADDR0x80 struct tmds_chip_information { int tmds_chip_name; - int tmds_chip_slave_addr; + int tmds_chip_target_addr; int output_interface; int i2c_port; }; struct lvds_chip_information { int lvds_chip_name; - int lvds_chip_slave_addr; + int lvds_chip_target_addr; int output_interface; int i2c_port; }; diff --git a/drivers/video/fbdev/via/dvi.c b/drivers/video/fbdev/via/dvi.c index 13147e3066eb..27990a73bfa3 100644 --- a/drivers/video/fbdev/via/dvi.c +++ b/drivers/video/fbdev/via/dvi.c @@ -70,7 +70,7 @@ bool viafb_tmds_trasmitter_identify(void) /* Check for VT1632: */ viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; viaparinfo->chip_info-> - tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; + tmds_chip_info.tmds_chip_target_addr = VT1632_TMDS_I2C_ADDR; viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { /* @@ -128,14 +128,14 @@ bool viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info-> tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; viaparinfo->chip_info->tmds_chip_info. - tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; + tmds_chip_target_addr = VT1632_TMDS_I2C_ADDR; return false; } static void tmds_register_write(int index, u8 data) { viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, - viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr, index, data); } @@ -144,7 +144,7 @@ static int tmds_register_read(int index) u8 data; viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, - (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr, (u8) index, ); return data; } @@ -152,7 +152,7 @@ static int tmds_register_read(int index) static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) { viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port, - (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr, (u8) index, buff, buff_len); return 0; } @@ -256,14 +256,14 @@ static int viafb_dvi_query_EDID(void) DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n"); - restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; - viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; + restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr; + viaparinfo->chip_info->tmds_ch
Re: [PATCH v2 11/12] fbdev/smscufx: Make I2C terminology more inclusive
Am 03.05.24 um 20:13 schrieb Easwar Hariharan: I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave" with more appropriate terms. Inspired by and following on to Wolfram's series to fix drivers/i2c/[1], fix the terminology for users of I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists in the specification. Compile tested, no functionality changes intended [1]: https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/ Signed-off-by: Easwar Hariharan Acked-by: Thomas Zimmermann --- drivers/video/fbdev/smscufx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index 35d682b110c4..5f0dd01fd834 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -1292,7 +1292,7 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, struct fb_info *info) return 0; } -/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, master, +/* sets up DDC channel for 100 Kbps, std. speed, 7-bit addr, controller mode, * restart enabled, but no start byte, enable controller */ static int ufx_i2c_init(struct ufx_data *dev) { @@ -1321,7 +1321,7 @@ static int ufx_i2c_init(struct ufx_data *dev) /* 7-bit (not 10-bit) addressing */ tmp &= ~(0x10); - /* enable restart conditions and master mode */ + /* enable restart conditions and controller mode */ tmp |= 0x21; status = ufx_reg_write(dev, 0x1000, tmp); -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v3 0/3] arch: Remove fbdev dependency from video helpers
Am 03.05.24 um 17:29 schrieb Arnd Bergmann: On Fri, Apr 5, 2024, at 11:04, Thomas Zimmermann wrote: Hi, if there are no further comments, can this series be merged through asm-generic? Sorry for the delay, I've merged these for asm-generic now. Thank you so much! Arnd -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v1 12/12] fbdev/viafb: Make I2C terminology more inclusive
Hi Am 03.05.24 um 00:26 schrieb Easwar Hariharan: On 5/2/2024 3:46 AM, Thomas Zimmermann wrote: Am 30.04.24 um 19:38 schrieb Easwar Hariharan: I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave" with more appropriate terms. Inspired by and following on to Wolfram's series to fix drivers/i2c/[1], fix the terminology for users of I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists in the specification. Compile tested, no functionality changes intended [1]: https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/ Signed-off-by: Easwar Hariharan Acked-by: Thomas Zimmermann Thanks for the ack! I had been addressing feedback as I got it on the v0 series, and it seems I missed out on updating viafb and smscufx to spec-compliant controller/target terminology like the v0->v1 changelog calls out before posting v1. For smscufx, I feel phrasing the following line (as an example) -/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, host, +/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, *controller*, would actually impact readability negatively, so I propose to leave smscufx as is. Why? I don't see much of a difference. For viafb, I propose making it compliant with the spec using the controller/target terminology and posting a v2 respin (which I can send out as soon as you say) and ask you to review again. What do you think? I think we should adopt the spec's language everywhere. That makes it possible to grep the spec for terms used in the source code. Using 'host' in smscufx appears to introduce yet another term. If you are worried about using 'I2C controller' and 'controller' in the same sentence, you can replace 'I2C controller' with 'DDC channel'. That's even more precise about the purpose of this code. Best regards Thomas Thanks, Easwar --- drivers/video/fbdev/via/chip.h | 8 drivers/video/fbdev/via/dvi.c | 24 drivers/video/fbdev/via/lcd.c | 6 +++--- drivers/video/fbdev/via/via_aux.h | 2 +- drivers/video/fbdev/via/via_i2c.c | 12 ++-- drivers/video/fbdev/via/vt1636.c | 6 +++--- 6 files changed, 29 insertions(+), 29 deletions(-) -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PULL] drm-misc-fixes
Hi Dave, Sima, here's the PR for drm-misc-fixes for this week. Best regards Thomas drm-misc-fixes-2024-05-02: Short summary of fixes pull: imagination: - fix page-count macro nouveau: - avoid page-table allocation failures - fix firmware memory allocation panel: - ili9341: avoid OF for device properties; respect deferred probe; fix usage of errno codes ttm: - fix status output vmwgfx: - fix legacy display unit - fix read length in fence signalling The following changes since commit 78d9161d2bcd442d93d917339297ffa057dbee8c: fbdev: fix incorrect address computation in deferred IO (2024-04-24 15:03:37 +0200) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-05-02 for you to fetch changes up to da85f0aaa9f21999753b01d45c0343f885a8f905: drm/panel: ili9341: Use predefined error codes (2024-05-02 09:41:27 +0200) Short summary of fixes pull: imagination: - fix page-count macro nouveau: - avoid page-table allocation failures - fix firmware memory allocation panel: - ili9341: avoid OF for device properties; respect deferred probe; fix usage of errno codes ttm: - fix status output vmwgfx: - fix legacy display unit - fix read length in fence signalling Andy Shevchenko (3): drm/panel: ili9341: Correct use of device property APIs drm/panel: ili9341: Respect deferred probe drm/panel: ili9341: Use predefined error codes Ian Forbes (1): drm/vmwgfx: Fix Legacy Display Unit Lyude Paul (2): drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor() drm/nouveau/gsp: Use the sg allocator for level 2 of radix3 Matt Coster (1): drm/imagination: Ensure PVR_MIPS_PT_PAGE_COUNT is never zero Zack Rusin (2): drm/ttm: Print the memory decryption status just once drm/vmwgfx: Fix invalid reads in fence signaled events drivers/gpu/drm/imagination/pvr_fw_mips.h | 5 +- drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 4 +- drivers/gpu/drm/nouveau/nvkm/core/firmware.c | 19 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c| 77 +++ drivers/gpu/drm/panel/Kconfig | 2 +- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 13 ++-- drivers/gpu/drm/ttm/ttm_tt.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c| 1 + drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- 9 files changed, 80 insertions(+), 45 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v3 0/2] drm: Fix dma_resv deadlock at drm object pin time
Hi Am 02.05.24 um 14:00 schrieb Boris Brezillon: On Thu, 2 May 2024 13:59:41 +0200 Boris Brezillon wrote: Hi Thomas, On Thu, 2 May 2024 13:51:16 +0200 Thomas Zimmermann wrote: Hi, ignoring my r-b on patch 1, I'd like to rethink the current patches in general. I think drm_gem_shmem_pin() should become the locked version of _pin(), so that drm_gem_shmem_object_pin() can call it directly. The existing _pin_unlocked() would not be needed any longer. Same for the _unpin() functions. This change would also fix the consistency with the semantics of the shmem _vmap() functions, which never take reservation locks. There are only two external callers of drm_gem_shmem_pin(): the test case and panthor. These assume that drm_gem_shmem_pin() acquires the reservation lock. The test case should likely call drm_gem_pin() instead. That would acquire the reservation lock and the test would validate that shmem's pin helper integrates well into the overall GEM framework. The way panthor uses drm_gem_shmem_pin() looks wrong to me. For now, it could receive a wrapper that takes the lock and that's it. I do agree that the current inconsistencies in the naming is troublesome (sometimes _unlocked, sometimes _locked, with the version without any suffix meaning either _locked or _unlocked depending on what the suffixed version does), and that's the very reason I asked Dmitry to address that in his shrinker series [1]. So, ideally I'd prefer if patches from Dmitry's series were applied instead of trying to fix that here (IIRC, we had an ack from Maxime). With the link this time :-). [1]https://lore.kernel.org/lkml/20240105184624.508603-1-dmitry.osipe...@collabora.com/T/ Thanks. I remember these patches. Somehow I thought they would have been merged already. I wasn't super happy about the naming changes in patch 5, because the names of the GEM object callbacks do no longer correspond with their implementations. But anyway. If we go that direction, we should here simply push drm_gem_shmem_pin() and drm_gem_shmem_unpin() into panthor and update the shmem tests with drm_gem_pin(). Panfrost and lima would call drm_gem_shmem_pin_locked(). IMHO we should not promote the use of drm_gem_shmem_object_*() functions, as they are meant to be callbacks for struct drm_gem_object_funcs. (Auto-generating them would be nice.) Best regards Thomas Regards, Boris -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v3 0/2] drm: Fix dma_resv deadlock at drm object pin time
Hi, ignoring my r-b on patch 1, I'd like to rethink the current patches in general. I think drm_gem_shmem_pin() should become the locked version of _pin(), so that drm_gem_shmem_object_pin() can call it directly. The existing _pin_unlocked() would not be needed any longer. Same for the _unpin() functions. This change would also fix the consistency with the semantics of the shmem _vmap() functions, which never take reservation locks. There are only two external callers of drm_gem_shmem_pin(): the test case and panthor. These assume that drm_gem_shmem_pin() acquires the reservation lock. The test case should likely call drm_gem_pin() instead. That would acquire the reservation lock and the test would validate that shmem's pin helper integrates well into the overall GEM framework. The way panthor uses drm_gem_shmem_pin() looks wrong to me. For now, it could receive a wrapper that takes the lock and that's it. Best regards Thomas Am 01.05.24 um 08:55 schrieb Adrián Larumbe: This is v3 of https://lore.kernel.org/dri-devel/20240424090429.57de7...@collabora.com/ The goal of this patch series is fixing a deadlock upon locking the dma reservation of a DRM gem object when pinning it, at a prime import operation. Changes from v2: - Removed comment explaining reason why an already-locked pin function replaced the locked variant inside Panfrost's object pin callback. - Moved already-assigned attachment warning into generic already-locked gem object pin function Adrián Larumbe (2): drm/panfrost: Fix dma_resv deadlock at drm object pin time drm/gem-shmem: Add import attachment warning to locked pin function drivers/gpu/drm/drm_gem_shmem_helper.c | 2 ++ drivers/gpu/drm/lima/lima_gem.c | 2 +- drivers/gpu/drm/panfrost/panfrost_gem.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) base-commit: 75b68f22e39aafb22f3d8e3071e1aba73560788c -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v3 1/2] drm/panfrost: Fix dma_resv deadlock at drm object pin time
Hi Am 01.05.24 um 08:55 schrieb Adrián Larumbe: When Panfrost must pin an object that is being prepared a dma-buf attachment for on behalf of another driver, the core drm gem object pinning code already takes a lock on the object's dma reservation. However, Panfrost GEM object's pinning callback would eventually try taking the lock on the same dma reservation when delegating pinning of the object onto the shmem subsystem, which led to a deadlock. This can be shown by enabling CONFIG_DEBUG_WW_MUTEX_SLOWPATH, which throws the following recursive locking situation: weston/3440 is trying to acquire lock: 00e235a0 (reservation_ww_class_mutex){+.+.}-{3:3}, at: drm_gem_shmem_pin+0x34/0xb8 [drm_shmem_helper] but task is already holding lock: 00e235a0 (reservation_ww_class_mutex){+.+.}-{3:3}, at: drm_gem_pin+0x2c/0x80 [drm] Fix it by assuming the object's reservation had already been locked by the time we reach panfrost_gem_pin. Maybe say that the reservation lock has been taken in drm_gem_pin() Do the same thing for the Lima driver, as it most likely suffers from the same issue. Please split this patch into one for panfrost and one for lima. To each patch, you can add Reviewed-by: Thomas Zimmermann Best regards Thomas Cc: Thomas Zimmermann Cc: Dmitry Osipenko Cc: Boris Brezillon Cc: Steven Price Fixes: a78027847226 ("drm/gem: Acquire reservation lock in drm_gem_{pin/unpin}()") Signed-off-by: Adrián Larumbe --- drivers/gpu/drm/lima/lima_gem.c | 2 +- drivers/gpu/drm/panfrost/panfrost_gem.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c index 7ea244d876ca..c4e0f9faaa47 100644 --- a/drivers/gpu/drm/lima/lima_gem.c +++ b/drivers/gpu/drm/lima/lima_gem.c @@ -185,7 +185,7 @@ static int lima_gem_pin(struct drm_gem_object *obj) if (bo->heap_size) return -EINVAL; - return drm_gem_shmem_pin(>base); + return drm_gem_shmem_object_pin(obj); } static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index d47b40b82b0b..f268bd5c2884 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -192,7 +192,7 @@ static int panfrost_gem_pin(struct drm_gem_object *obj) if (bo->is_heap) return -EINVAL; - return drm_gem_shmem_pin(>base); + return drm_gem_shmem_object_pin(obj); } static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object *obj) -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v1 12/12] fbdev/viafb: Make I2C terminology more inclusive
Am 30.04.24 um 19:38 schrieb Easwar Hariharan: I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave" with more appropriate terms. Inspired by and following on to Wolfram's series to fix drivers/i2c/[1], fix the terminology for users of I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists in the specification. Compile tested, no functionality changes intended [1]: https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/ Signed-off-by: Easwar Hariharan Acked-by: Thomas Zimmermann --- drivers/video/fbdev/via/chip.h| 8 drivers/video/fbdev/via/dvi.c | 24 drivers/video/fbdev/via/lcd.c | 6 +++--- drivers/video/fbdev/via/via_aux.h | 2 +- drivers/video/fbdev/via/via_i2c.c | 12 ++-- drivers/video/fbdev/via/vt1636.c | 6 +++--- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/video/fbdev/via/chip.h b/drivers/video/fbdev/via/chip.h index f0a19cbcb9e5..1ea6d4ce79e7 100644 --- a/drivers/video/fbdev/via/chip.h +++ b/drivers/video/fbdev/via/chip.h @@ -69,7 +69,7 @@ #define VT1632_TMDS 0x01 #define INTEGRATED_TMDS 0x42 -/* Definition TMDS Trasmitter I2C Slave Address */ +/* Definition TMDS Trasmitter I2C Client Address */ #define VT1632_TMDS_I2C_ADDR0x10 /**/ @@ -88,21 +88,21 @@ #define TX_DATA_DDR_MODE0x04 #define TX_DATA_SDR_MODE0x08 -/* Definition LVDS Trasmitter I2C Slave Address */ +/* Definition LVDS Trasmitter I2C Client Address */ #define VT1631_LVDS_I2C_ADDR0x70 #define VT3271_LVDS_I2C_ADDR0x80 #define VT1636_LVDS_I2C_ADDR0x80 struct tmds_chip_information { int tmds_chip_name; - int tmds_chip_slave_addr; + int tmds_chip_client_addr; int output_interface; int i2c_port; }; struct lvds_chip_information { int lvds_chip_name; - int lvds_chip_slave_addr; + int lvds_chip_client_addr; int output_interface; int i2c_port; }; diff --git a/drivers/video/fbdev/via/dvi.c b/drivers/video/fbdev/via/dvi.c index 13147e3066eb..db7db26416c3 100644 --- a/drivers/video/fbdev/via/dvi.c +++ b/drivers/video/fbdev/via/dvi.c @@ -70,7 +70,7 @@ bool viafb_tmds_trasmitter_identify(void) /* Check for VT1632: */ viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; viaparinfo->chip_info-> - tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; + tmds_chip_info.tmds_chip_client_addr = VT1632_TMDS_I2C_ADDR; viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { /* @@ -128,14 +128,14 @@ bool viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info-> tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; viaparinfo->chip_info->tmds_chip_info. - tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; + tmds_chip_client_addr = VT1632_TMDS_I2C_ADDR; return false; } static void tmds_register_write(int index, u8 data) { viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, - viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr, index, data); } @@ -144,7 +144,7 @@ static int tmds_register_read(int index) u8 data; viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, - (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr, (u8) index, ); return data; } @@ -152,7 +152,7 @@ static int tmds_register_read(int index) static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) { viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port, - (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr, (u8) index, buff, buff_len); return 0; } @@ -256,14 +256,14 @@ static int viafb_dvi_query_EDID(void) DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n"); - restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; - viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; + restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr; + viaparinfo->chip_info->tmds_ch
Re: [PATCH v1 11/12] fbdev/smscufx: Make I2C terminology more inclusive
Am 30.04.24 um 19:38 schrieb Easwar Hariharan: I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave" with more appropriate terms. Inspired by and following on to Wolfram's series to fix drivers/i2c/[1], fix the terminology for users of I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists in the specification. Compile tested, no functionality changes intended [1]: https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/ Signed-off-by: Easwar Hariharan Acked-by: Thomas Zimmermann --- drivers/video/fbdev/smscufx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index 35d682b110c4..1c80c1a3d516 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -1292,7 +1292,7 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, struct fb_info *info) return 0; } -/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, master, +/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, host, * restart enabled, but no start byte, enable controller */ static int ufx_i2c_init(struct ufx_data *dev) { @@ -1321,7 +1321,7 @@ static int ufx_i2c_init(struct ufx_data *dev) /* 7-bit (not 10-bit) addressing */ tmp &= ~(0x10); - /* enable restart conditions and master mode */ + /* enable restart conditions and host mode */ tmp |= 0x21; status = ufx_reg_write(dev, 0x1000, tmp); -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v1 02/12] drm/gma500: Make I2C terminology more inclusive
Am 30.04.24 um 19:38 schrieb Easwar Hariharan: I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave" with more appropriate terms. Inspired by and following on to Wolfram's series to fix drivers/i2c/[1], fix the terminology for users of I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists in the specification. Compile tested, no functionality changes intended [1]: https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/ Signed-off-by: Easwar Hariharan Acked-by: Thomas Zimmermann --- drivers/gpu/drm/gma500/cdv_intel_lvds.c | 2 +- drivers/gpu/drm/gma500/intel_bios.c | 22 ++--- drivers/gpu/drm/gma500/intel_bios.h | 4 ++-- drivers/gpu/drm/gma500/intel_gmbus.c| 2 +- drivers/gpu/drm/gma500/psb_drv.h| 2 +- drivers/gpu/drm/gma500/psb_intel_drv.h | 2 +- drivers/gpu/drm/gma500/psb_intel_lvds.c | 4 ++-- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 26 - 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index f08a6803dc18..c7652a02b42e 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -565,7 +565,7 @@ void cdv_intel_lvds_init(struct drm_device *dev, dev->dev, "I2C bus registration failed.\n"); goto err_encoder_cleanup; } - gma_encoder->i2c_bus->slave_addr = 0x2C; + gma_encoder->i2c_bus->target_addr = 0x2C; dev_priv->lvds_i2c_bus = gma_encoder->i2c_bus; /* diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index 8245b5603d2c..d5924ca3ed05 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c @@ -14,8 +14,8 @@ #include "psb_intel_drv.h" #include "psb_intel_reg.h" -#define SLAVE_ADDR1 0x70 -#defineSLAVE_ADDR2 0x72 +#defineTARGET_ADDR10x70 +#defineTARGET_ADDR20x72 static void *find_section(struct bdb_header *bdb, int section_id) { @@ -357,10 +357,10 @@ parse_sdvo_device_mapping(struct drm_psb_private *dev_priv, /* skip the device block if device type is invalid */ continue; } - if (p_child->slave_addr != SLAVE_ADDR1 && - p_child->slave_addr != SLAVE_ADDR2) { + if (p_child->target_addr != TARGET_ADDR1 && + p_child->target_addr != TARGET_ADDR2) { /* -* If the slave address is neither 0x70 nor 0x72, +* If the target address is neither 0x70 nor 0x72, * it is not a SDVO device. Skip it. */ continue; @@ -371,22 +371,22 @@ parse_sdvo_device_mapping(struct drm_psb_private *dev_priv, DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n"); continue; } - DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on" + DRM_DEBUG_KMS("the SDVO device with target addr %2x is found on" " %s port\n", - p_child->slave_addr, + p_child->target_addr, (p_child->dvo_port == DEVICE_PORT_DVOB) ? "SDVOB" : "SDVOC"); p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]); if (!p_mapping->initialized) { p_mapping->dvo_port = p_child->dvo_port; - p_mapping->slave_addr = p_child->slave_addr; + p_mapping->target_addr = p_child->target_addr; p_mapping->dvo_wiring = p_child->dvo_wiring; p_mapping->ddc_pin = p_child->ddc_pin; p_mapping->i2c_pin = p_child->i2c_pin; p_mapping->initialized = 1; DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n", p_mapping->dvo_port, - p_mapping->slave_addr, + p_mapping->target_addr, p_mapping->dvo_wiring, p_mapping->ddc_pin, p_mapping->i2c_pin); @@ -394,10 +394,10 @@ parse_sdvo_device_mapping(struct drm_psb_private *dev_priv, DRM_DEBUG_KMS("Maybe one SDVO po
Re: [PATCH] drm/fb_dma: Add checks in drm_fb_dma_get_scanout_buffer()
Am 26.04.24 um 14:10 schrieb Jocelyn Falempe: plane->state and plane->state->fb can be NULL, so add a check before dereferencing them. Found by testing with the imx driver. Fixes: 879b3b6511fe9 ("drm/fb_dma: Add generic get_scanout_buffer() for drm_panic") Signed-off-by: Jocelyn Falempe --- drivers/gpu/drm/drm_fb_dma_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_dma_helper.c b/drivers/gpu/drm/drm_fb_dma_helper.c index 96e5ab960f12..d7bffde94cc5 100644 --- a/drivers/gpu/drm/drm_fb_dma_helper.c +++ b/drivers/gpu/drm/drm_fb_dma_helper.c @@ -167,6 +167,9 @@ int drm_fb_dma_get_scanout_buffer(struct drm_plane *plane, struct drm_gem_dma_object *dma_obj; struct drm_framebuffer *fb; + if (!plane->state || !plane->state->fb) + return -ENODEV; + It's EINVAL here. With that fixed, free free to add Reviewed-by: Thomas Zimmermann Best regards Thomas fb = plane->state->fb; /* Only support linear modifier */ if (fb->modifier != DRM_FORMAT_MOD_LINEAR) base-commit: 2e3f08a1ac99cb9a19a5cb151593d4f9df5cc6a7 -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: After suspend/resume cycle ASPEED VGA monitor suffers with "No Signal" state.
Hi Am 23.04.24 um 21:51 schrieb Cary Garrett: Hello, An Aspeed VGA monitor, in my case AST 2400, after a suspend/resume cycle suffers with a "No Signal" state. This is also true of a IPMI/BMC remote console. To restore the "Signal" state requires a reboot or the following workaround. To restore the "Signal" state without rebooting issue the following commands from a SSH session or serial console after every suspend/resume cycle: sudo modprobe -r ast sudo modprobe ast This a home media server which is updated infrequently, so I am unable offer any guidance as to when this issue started occurring. Just to clarify, suspend/resume did restore the display in earlier versions? Best regards Thomas Regards, Cary Garrett Current environment: uname -a: Linux xx-server 6.8.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 17 Apr 2024 15:20:28 + x86_64 GNU/Linux modinfo: filename: /lib/modules/6.8.7-arch1-1/kernel/drivers/gpu/drm/ast/ast.ko.zst license:GPL and additional rights description:AST author: Dave Airlie firmware: ast_dp501_fw.bin srcversion: 7E39455BCA2D11E968D8B2B alias: pci:v1A03d2010sv*sd*bc03sc*i* alias: pci:v1A03d2000sv*sd*bc03sc*i* depends:i2c-algo-bit retpoline: Y intree: Y name: ast vermagic: 6.8.7-arch1-1 SMP preempt mod_unload sig_id: PKCS#7 signer: Build time autogenerated kernel key sig_key:76:06:C7:84:BC:2F:C6:38:38:61:C1:6F:32:D5:6A:03:88:22:68:1C sig_hashalgo: sha512 signature: 30:66:02:31:00:AD:83:EB:D2:9B:91:E6:C3:9B:52:89:51:4B:BB:06: DE:D7:44:A6:6B:07:92:AA:75:2A:0B:20:26:73:58:09:DF:C3:86:C6: FC:B7:D4:13:5F:5D:35:4D:67:89:73:0E:C2:02:31:00:C3:98:99:67: B4:74:02:5C:6D:D3:81:13:D4:9F:B4:F4:CF:37:8A:7C:84:8C:73:BF: DF:4D:D5:34:B0:0A:CE:0E:59:67:28:98:07:BF:D7:FA:68:B3:37:43: 02:1C:59:3E parm: modeset:Disable/Enable modesetting (int) lspci: 04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 30) (prog-if 00 [VGA controller]) DeviceName: Onboard VGA Subsystem: Super Micro Computer Inc Device 0804 Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- SERR- -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PULL] drm-misc-fixes
Hi Dave, Sima, here's the PR for drm-misc-fixes. Best regards Thomas drm-misc-fixes-2024-04-25: Short summary of fixes pull: atomic-helpers: - Fix memory leak in drm_format_conv_state_copy() fbdev: - fbdefio: Fix address calculation gma500: - Fix crash during boot The following changes since commit 941c0bdbc176df825adf77052263b2d63db6fef7: drm/panel: novatek-nt36682e: don't unregister DSI device (2024-04-16 23:17:59 +0300) are available in the Git repository at: https://gitlab.freedesktop.org/drm/misc/kernel.git tags/drm-misc-fixes-2024-04-25 for you to fetch changes up to 78d9161d2bcd442d93d917339297ffa057dbee8c: fbdev: fix incorrect address computation in deferred IO (2024-04-24 15:03:37 +0200) Short summary of fixes pull: atomic-helpers: - Fix memory leak in drm_format_conv_state_copy() fbdev: - fbdefio: Fix address calculation gma500: - Fix crash during boot Lucas Stach (1): drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call Nam Cao (1): fbdev: fix incorrect address computation in deferred IO Patrik Jakobsson (1): drm/gma500: Remove lid code drivers/gpu/drm/drm_gem_atomic_helper.c | 4 +- drivers/gpu/drm/gma500/Makefile | 1 - drivers/gpu/drm/gma500/psb_device.c | 5 +-- drivers/gpu/drm/gma500/psb_drv.h| 9 drivers/gpu/drm/gma500/psb_lid.c| 80 - drivers/video/fbdev/core/fb_defio.c | 2 +- 6 files changed, 4 insertions(+), 97 deletions(-) delete mode 100644 drivers/gpu/drm/gma500/psb_lid.c -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v8 6/6] drm/{i915,xe}: Implement fbdev emulation as in-kernel client
Hi Am 23.04.24 um 13:36 schrieb Hogander, Jouni: On Tue, 2024-04-23 at 13:13 +0200, Thomas Zimmermann wrote: Hi Am 22.04.24 um 16:11 schrieb Hogander, Jouni: On Tue, 2024-04-09 at 10:04 +0200, Thomas Zimmermann wrote: Replace all code that initializes or releases fbdev emulation throughout the driver. Instead initialize the fbdev client by a single call to intel_fbdev_setup() after i915 has registered its DRM device. Just like similar code in other drivers, i915 fbdev emulation now acts like a regular DRM client. Do the same for xe. The fbdev client setup consists of the initial preparation and the hot-plugging of the display. The latter creates the fbdev device and sets up the fbdev framebuffer. The setup performs display hot-plugging once. If no display can be detected, DRM probe helpers re-run the detection on each hotplug event. A call to drm_client_dev_unregister() releases all in-kernel clients automatically. No further action is required within i915. If the fbdev framebuffer has been fully set up, struct fb_ops.fb_destroy implements the release. For partially initialized emulation, the fbdev client reverts the initial setup. Do the same for xe and remove its call to intel_fbdev_fini(). v8: - setup client in intel_display_driver_register (Jouni) - mention xe in commit message v7: - update xe driver - reword commit message v6: - use 'i915' for i915 device (Jouni) - remove unnecessary code for non-atomic mode setting (Jouni, Ville) - fix function name in commit message (Jouni) v3: - as before, silently ignore devices without displays v2: - let drm_client_register() handle initial hotplug - fix driver name in error message (Jani) - fix non-fbdev build (kernel test robot) Signed-off-by: Thomas Zimmermann Reviewed-by: Jouni Högander Thank you so much. All patches has R-bs. Can you add the series to the intel tree? Is it ok to merge patch 01/06 via intel tree as well? Sure, np. Best regards Thomas Rodrigo, This set is containing Xe display changes as well. Is it ok to push this via drm-intel? BR, Jouni Högander Best regards Thomas --- drivers/gpu/drm/i915/display/intel_display.c | 1 - .../drm/i915/display/intel_display_driver.c | 20 +- drivers/gpu/drm/i915/display/intel_fbdev.c | 177 --- - -- drivers/gpu/drm/i915/display/intel_fbdev.h | 20 +- drivers/gpu/drm/xe/display/xe_display.c | 2 - 5 files changed, 80 insertions(+), 140 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 614e60420a29a..161a5aabf6746 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -85,7 +85,6 @@ #include "intel_dvo.h" #include "intel_fb.h" #include "intel_fbc.h" -#include "intel_fbdev.h" #include "intel_fdi.h" #include "intel_fifo_underrun.h" #include "intel_frontbuffer.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index e5f052d4ff1cc..ed8589fa35448 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -514,10 +514,6 @@ int intel_display_driver_probe(struct drm_i915_private *i915) intel_overlay_setup(i915); - ret = intel_fbdev_init(>drm); - if (ret) - return ret; - /* Only enable hotplug handling once the fbdev is fully set up. */ intel_hpd_init(i915); @@ -544,16 +540,6 @@ void intel_display_driver_register(struct drm_i915_private *i915) intel_display_debugfs_register(i915); - /* - * Some ports require correctly set-up hpd registers for - * detection to work properly (leading to ghost connected - * connector status), e.g. VGA on gm45. Hence we can only set - * up the initial fbdev config after hpd irqs are fully - * enabled. We do it last so that the async config cannot run - * before the connectors are registered. - */ - intel_fbdev_initial_config_async(i915); - /* * We need to coordinate the hotplugs with the asynchronous * fbdev configuration, for which we use the @@ -562,6 +548,8 @@ void intel_display_driver_register(struct drm_i915_private *i915) drm_kms_helper_poll_init(>drm); intel_hpd_poll_disable(i915); + intel_fbdev_setup(i915); + intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i91 5), ); } @@ -597,9 +585,6 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915) */ intel_hpd_poll_fini(i915); - /* poll work can call into fbdev, hence clean that up afterwards */ - intel_fbdev_fini(i915); - intel_unregister_dsm_handl
Re: [PATCH v2] fbdev: fix incorrect address computation in deferred IO
Hi Am 23.04.24 um 13:50 schrieb Nam Cao: With deferred IO enabled, a page fault happens when data is written to the framebuffer device. Then driver determines which page is being updated by calculating the offset of the written virtual address within the virtual memory area, and uses this offset to get the updated page within the internal buffer. This page is later copied to hardware (thus the name "deferred IO"). This offset calculation is only correct if the virtual memory area is mapped to the beginning of the internal buffer. Otherwise this is wrong. For example, if users do: mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0xff000); Then the virtual memory area will mapped at offset 0xff000 within the internal buffer. This offset 0xff000 is not accounted for, and wrong page is updated. Correct the calculation by using vmf->pgoff instead. With this change, the variable "offset" will no longer hold the exact offset value, but it is rounded down to multiples of PAGE_SIZE. But this is still correct, because this variable is only used to calculate the page offset. Reported-by: Harshit Mogalapalli Closes: https://lore.kernel.org/linux-fbdev/271372d6-e665-4e7f-b088-dee5f4ab3...@oracle.com Fixes: 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct") Cc: Signed-off-by: Nam Cao Reviewed-by: Thomas Zimmermann Thank you so much. I'll take care of merging the patch later this week. Best regards Thomas --- v2: - simplify the patch by using vfg->pgoff - remove tested-by tag, as the patch is now different drivers/video/fbdev/core/fb_defio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 1ae1d35a5942..b9607d5a370d 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -196,7 +196,7 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info *info, unsigned long */ static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct vm_fault *vmf) { - unsigned long offset = vmf->address - vmf->vma->vm_start; + unsigned long offset = vmf->pgoff << PAGE_SHIFT; struct page *page = vmf->page; file_update_time(vmf->vma->vm_file); -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH] fbdev: fix incorrect address computation in deferred IO
Hi Am 23.04.24 um 11:55 schrieb Nam Cao: [...] Fix this by taking the mapping offset into account. Reported-and-tested-by: Harshit Mogalapalli Closes: https://lore.kernel.org/linux-fbdev/271372d6-e665-4e7f-b088-dee5f4ab3...@oracle.com Fixes: 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct") Cc: sta...@vger.kernel.org Signed-off-by: Nam Cao --- drivers/video/fbdev/core/fb_defio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index dae96c9f61cf..d5d6cd9e8b29 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -196,7 +196,8 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info *info, unsigned long */ static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct vm_fault *vmf) { - unsigned long offset = vmf->address - vmf->vma->vm_start; + unsigned long offset = vmf->address - vmf->vma->vm_start + + (vmf->vma->vm_pgoff << PAGE_SHIFT); The page-fault handler at [1] use vm_fault.pgoff to retrieve the page structure. Can we do the same here and avoid that computation? Yes, thanks for the suggestion. It will change things a bit: offset will not be the exact value anymore, but will be rounded down to multiple of PAGE_SIZE. But that doesn't matter, because it will only be used to calculate the page offset later on. We can clean this up and rename this "offset" to "pg_offset". But that's for another day. But can't we use struct vm_fault.pgoff directly? The page-fault handler has used it since forever. The look-up code for the pageref should probably do the same, because there's a 1:1 connection between the page and the pageref. The pageref structure only exists because we cannot store its data in struct page directly. AFAICT pgoff is exactly the value want to compute. See [1] and the calculation at [2]. [1] https://elixir.bootlin.com/linux/v6.8/source/mm/memory.c#L5222 [2] https://elixir.bootlin.com/linux/v6.8/source/include/linux/pagemap.h#L957 Best regards Thomas Best regards, Nam -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH v8 6/6] drm/{i915,xe}: Implement fbdev emulation as in-kernel client
Hi Am 22.04.24 um 16:11 schrieb Hogander, Jouni: On Tue, 2024-04-09 at 10:04 +0200, Thomas Zimmermann wrote: Replace all code that initializes or releases fbdev emulation throughout the driver. Instead initialize the fbdev client by a single call to intel_fbdev_setup() after i915 has registered its DRM device. Just like similar code in other drivers, i915 fbdev emulation now acts like a regular DRM client. Do the same for xe. The fbdev client setup consists of the initial preparation and the hot-plugging of the display. The latter creates the fbdev device and sets up the fbdev framebuffer. The setup performs display hot-plugging once. If no display can be detected, DRM probe helpers re-run the detection on each hotplug event. A call to drm_client_dev_unregister() releases all in-kernel clients automatically. No further action is required within i915. If the fbdev framebuffer has been fully set up, struct fb_ops.fb_destroy implements the release. For partially initialized emulation, the fbdev client reverts the initial setup. Do the same for xe and remove its call to intel_fbdev_fini(). v8: - setup client in intel_display_driver_register (Jouni) - mention xe in commit message v7: - update xe driver - reword commit message v6: - use 'i915' for i915 device (Jouni) - remove unnecessary code for non-atomic mode setting (Jouni, Ville) - fix function name in commit message (Jouni) v3: - as before, silently ignore devices without displays v2: - let drm_client_register() handle initial hotplug - fix driver name in error message (Jani) - fix non-fbdev build (kernel test robot) Signed-off-by: Thomas Zimmermann Reviewed-by: Jouni Högander Thank you so much. All patches has R-bs. Can you add the series to the intel tree? Best regards Thomas --- drivers/gpu/drm/i915/display/intel_display.c | 1 - .../drm/i915/display/intel_display_driver.c | 20 +- drivers/gpu/drm/i915/display/intel_fbdev.c | 177 -- drivers/gpu/drm/i915/display/intel_fbdev.h | 20 +- drivers/gpu/drm/xe/display/xe_display.c | 2 - 5 files changed, 80 insertions(+), 140 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 614e60420a29a..161a5aabf6746 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -85,7 +85,6 @@ #include "intel_dvo.h" #include "intel_fb.h" #include "intel_fbc.h" -#include "intel_fbdev.h" #include "intel_fdi.h" #include "intel_fifo_underrun.h" #include "intel_frontbuffer.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index e5f052d4ff1cc..ed8589fa35448 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -514,10 +514,6 @@ int intel_display_driver_probe(struct drm_i915_private *i915) intel_overlay_setup(i915); - ret = intel_fbdev_init(>drm); - if (ret) - return ret; - /* Only enable hotplug handling once the fbdev is fully set up. */ intel_hpd_init(i915); @@ -544,16 +540,6 @@ void intel_display_driver_register(struct drm_i915_private *i915) intel_display_debugfs_register(i915); - /* - * Some ports require correctly set-up hpd registers for - * detection to work properly (leading to ghost connected - * connector status), e.g. VGA on gm45. Hence we can only set - * up the initial fbdev config after hpd irqs are fully - * enabled. We do it last so that the async config cannot run - * before the connectors are registered. - */ - intel_fbdev_initial_config_async(i915); - /* * We need to coordinate the hotplugs with the asynchronous * fbdev configuration, for which we use the @@ -562,6 +548,8 @@ void intel_display_driver_register(struct drm_i915_private *i915) drm_kms_helper_poll_init(>drm); intel_hpd_poll_disable(i915); + intel_fbdev_setup(i915); + intel_display_device_info_print(DISPLAY_INFO(i915), DISPLAY_RUNTIME_INFO(i915), ); } @@ -597,9 +585,6 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915) */ intel_hpd_poll_fini(i915); - /* poll work can call into fbdev, hence clean that up afterwards */ - intel_fbdev_fini(i915); - intel_unregister_dsm_handler(); /* flush any delayed tasks or pending work */ @@ -640,7 +625,6 @@ void intel_display_driver_unregister(struct drm_i915_private *i915) drm_client_dev_unregister(>drm); - intel_fbdev_unregister(i915); /* * After flushing the fbdev (incl. a late async config which * will have de
Re: [PATCH] fbdev: fix incorrect address computation in deferred IO
Hi, thanks for following through with the bug and sending the patch Am 19.04.24 um 21:00 schrieb Nam Cao: With deferred IO enabled, a page fault happens when data is written to the framebuffer device. Then driver determines which page is being updated by calculating the offset of the written virtual address within the virtual memory area, and uses this offset to get the updated page within the internal buffer. This page is later copied to hardware (thus the name "deferred IO"). This calculation is only correct if the virtual memory area is mapped to the beginning of the internal buffer. Otherwise this is wrong. For example, if users do: mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0xff000); Then the virtual memory area will mapped at offset 0xff000 within the internal buffer. This offset 0xff000 is not accounted for, and wrong page is updated. This will lead to wrong pixels being updated on the device. However, it gets worse: if users do 2 mmap to the same virtual address, for example: int fd = open("/dev/fb0", O_RDWR, 0); char *ptr = (char *) 0x2000ul; mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0xff000); *ptr = 0; // write #1 mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0); *ptr = 0; // write #2 In this case, both write #1 and write #2 apply to the same virtual address (0x2000ul), and the driver mistakenly thinks the same page is being written to. When the second write happens, the driver thinks this is the same page as the last time, and reuse the page from write #1. The driver then lock_page() an incorrect page, and returns VM_FAULT_LOCKED with the correct page unlocked. It is unclear what will happen with memory management subsystem after that, but likely something terrible. Please tone down the drama. :) Fix this by taking the mapping offset into account. Reported-and-tested-by: Harshit Mogalapalli Closes: https://lore.kernel.org/linux-fbdev/271372d6-e665-4e7f-b088-dee5f4ab3...@oracle.com Fixes: 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct") Cc: sta...@vger.kernel.org Signed-off-by: Nam Cao --- drivers/video/fbdev/core/fb_defio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index dae96c9f61cf..d5d6cd9e8b29 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -196,7 +196,8 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info *info, unsigned long */ static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct vm_fault *vmf) { - unsigned long offset = vmf->address - vmf->vma->vm_start; + unsigned long offset = vmf->address - vmf->vma->vm_start + + (vmf->vma->vm_pgoff << PAGE_SHIFT); The page-fault handler at [1] use vm_fault.pgoff to retrieve the page structure. Can we do the same here and avoid that computation? Best regards Thomas [1] https://elixir.bootlin.com/linux/v6.8/source/drivers/video/fbdev/core/fb_defio.c#L100 struct page *page = vmf->page; file_update_time(vmf->vma->vm_file); -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Re: [PATCH] drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call
Hi, thanks for this fix. Am 04.04.24 um 10:17 schrieb Lucas Stach: Old and new state parameters are swapped, so the old state was cleared instead of the new duplicated state. Fixes: 903674588a48 ("drm/atomic-helper: Add format-conversion state to shadow-plane state") Signed-off-by: Lucas Stach Tested-by: Leonard Göhrs Reviewed-by: Thomas Zimmermann Please also add Cc: # v6.8+ Best regards Thomas --- drivers/gpu/drm/drm_gem_atomic_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index e440f458b663..93337543aac3 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -224,8 +224,8 @@ __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, __drm_atomic_helper_plane_duplicate_state(plane, _shadow_plane_state->base); - drm_format_conv_state_copy(_plane_state->fmtcnv_state, - _shadow_plane_state->fmtcnv_state); + drm_format_conv_state_copy(_shadow_plane_state->fmtcnv_state, + _plane_state->fmtcnv_state); } EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state); -- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
[PATCH v3 25/43] drm/ingenic: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by ingenic. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Paul Cercueil Acked-by: Paul Cercueil --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 0751235007a7e..39fa291f43dd1 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -1399,7 +1399,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) goto err_clk_notifier_unregister; } - drm_fbdev_generic_setup(drm, 32); + drm_fbdev_dma_setup(drm, 32); return 0; -- 2.44.0
[PATCH v3 00/43] drm: Provide fbdev emulation per memory manager
DRM provides 3 different memory managers with slightly different characteristics: DMA-based, SHMEM-based and TTM. This affects fbdev emulation as each requires different handling of mmap(). This series reworks fbdev emulation to provide an optimized emulation for each of the memory managers. Patch 1 fixes a minor bug in fbdev-generic. Patches 2 to 8 implement fbdev-shmem, which is optimized for drivers with SHMEM-based allocation. Patches 2 to 7 prepare deferred I/O to support driver-custom page lookups. When the mmap'ed framebuffer sees a pagefault, the deferred-I/O code can ask the graphics driver of the page (instead of trying to detect it by itself). Using this hook, patch 8 implements fbdev-shmem. The code is similar to fbdev-generic, but does not require an additional shadow buffer for mmap(). Mmap'ed pages are instead provided from the GEM buffer object. That saves a few MiB of framebuffer memory and copying between the internal buffers. Patches 9 to 20 convert SHMEM-based drivers to fbdev-shmem. Patch 21 adds damage handling and deferred I/O to fbdev-dma. Such code has been tested on the DMA-based omapdrm and can be adopted for all drivers. Patches 22 to 41 convert DMA-based drivers to fbdev-dma. These drivers could not use it because of the missing support for damage handling. Patch 42 renames fbdev-generic to fbdev-ttm. Only TTM-based drivers still use it, so building it can be linked to TTM as well. Patch 43 cleans up the documentation. Tested with simpledrm, vc4 and amdgpu. v3: - fbdev-dma: init fb_ops with DMAMEM initializer (Javier) - fbdev-shmem: clarify get_page usage (Javier) v2: - fbdev-shmem: use drm_driver_legacy_fb_format() (Geert) - fix a few typos Thomas Zimmermann (43): drm/fbdev-generic: Do not set physical framebuffer address fbdev/deferred-io: Move pageref setup into separate helper fbdev/deferred-io: Clean up pageref on lastclose fbdev/deferred-io: Test screen_buffer for vmalloc'ed memory fbdev/deferred-io: Test smem_start for I/O memory fbdev/deferred-io: Always call get_page() for framebuffer pages fbdev/deferred-io: Provide get_page hook in struct fb_deferred_io drm/fbdev: Add fbdev-shmem drm/ast: Use fbdev-shmem drm/gud: Use fbdev-shmem drm/hyperv: Use fbdev-shmem drm/mgag200: Use fbdev-shmem drm/solomon: Use fbdev-shmem drm/tiny/cirrus: Use fbdev-shmem drm/tiny/gm12u320: Use fbdev-shmem drm/tiny/ofdrm: Use fbdev-shmem drm/tiny/simpledrm: Use fbdev-shmem drm/udl: Use fbdev-shmem drm/virtio: Use fbdev-shmem drm/vkms: Use fbdev-shmem drm/fbdev-dma: Implement damage handling and deferred I/O drm/arm/komeda: Use fbdev-dma drm/hisilicon/kirin: Use fbdev-dma drm/imx/lcdc: Use fbdev-dma drm/ingenic: Use fbdev-dma drm/mediatek: Use fbdev-dma drm/panel/panel-ilitek-9341: Use fbdev-dma drm/renesas/rcar-du: Use fbdev-dma drm/renesas/rz-du: Use fbdev-dma drm/renesas/shmobile: Use fbdev-dma drm/rockchip: Use fbdev-dma drm/tiny/hx8357d: Use fbdev-dma drm/tiny/ili9163: Use fbdev-dma drm/tiny/ili9225: Use fbdev-dma drm/tiny/ili9341: Use fbdev-dma drm/tiny/ili9486: Use fbdev-dma drm/tiny/mi0283qt: Use fbdev-dma drm/tiny/panel-mipi-dbi: Use fbdev-dma drm/tiny/repaper: Use fbdev-dma drm/tiny/st7586: Use fbdev-dma drm/tiny/st7735r: Use fbdev-dma drm/fbdev-generic: Convert to fbdev-ttm drm/fbdev: Clean up fbdev documentation Documentation/gpu/drm-kms-helpers.rst | 12 +- Documentation/gpu/todo.rst| 13 - drivers/gpu/drm/Makefile | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 +- .../gpu/drm/arm/display/komeda/komeda_drv.c | 4 +- drivers/gpu/drm/ast/ast_drv.c | 4 +- drivers/gpu/drm/drm_drv.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 11 +- drivers/gpu/drm/drm_fbdev_dma.c | 65 +++- drivers/gpu/drm/drm_fbdev_shmem.c | 316 ++ .../{drm_fbdev_generic.c => drm_fbdev_ttm.c} | 81 +++-- drivers/gpu/drm/gud/gud_drv.c | 4 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 +- .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 4 +- drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 4 +- drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 4 +- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 +- drivers/gpu/drm/loongson/Kconfig | 1 + drivers/gpu/drm/loongson/lsdc_drv.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c| 4 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 6 +- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 4 +- drivers/gpu/drm/qxl/qxl_drv.c | 4 +- drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c | 4 +- drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 4 +- .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 +- drivers/gpu/
[PATCH v3 34/43] drm/tiny/ili9225: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by ili9225. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: David Lechner Acked-by: David Lechner --- drivers/gpu/drm/tiny/ili9225.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c index dd8b0a181be94..537df5f5b8a6e 100644 --- a/drivers/gpu/drm/tiny/ili9225.c +++ b/drivers/gpu/drm/tiny/ili9225.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -426,7 +426,7 @@ static int ili9225_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_dma_setup(drm, 0); return 0; } -- 2.44.0
[PATCH v3 24/43] drm/imx/lcdc: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by lcdc. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c index 43ddf3a9810b6..36668455aee8c 100644 --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -501,7 +501,7 @@ static int imx_lcdc_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "Cannot register device\n"); - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_dma_setup(drm, 0); return 0; } -- 2.44.0
[PATCH v3 17/43] drm/tiny/simpledrm: Use fbdev-shmem
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/tiny/simpledrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index 7ce1c46176750..3cb09ad5f7537 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -1026,7 +1026,7 @@ static int simpledrm_probe(struct platform_device *pdev) if (color_mode == 16) color_mode = sdev->format->depth; // can be 15 or 16 - drm_fbdev_generic_setup(dev, color_mode); + drm_fbdev_shmem_setup(dev, color_mode); return 0; } -- 2.44.0
[PATCH v3 37/43] drm/tiny/mi0283qt: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by mi0283qt. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: "Noralf Trønnes" Acked-by: Noralf Trønnes --- drivers/gpu/drm/tiny/mi0283qt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c index 01ff43c8ac3ff..e46581d74c257 100644 --- a/drivers/gpu/drm/tiny/mi0283qt.c +++ b/drivers/gpu/drm/tiny/mi0283qt.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -226,7 +226,7 @@ static int mi0283qt_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_dma_setup(drm, 0); return 0; } -- 2.44.0
[PATCH v3 20/43] drm/vkms: Use fbdev-shmem
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Rodrigo Siqueira Cc: Melissa Wen Cc: "Maíra Canal" Cc: Haneen Mohammed Cc: Daniel Vetter Reviewed-by: Javier Martinez Canillas Acked-by: Maíra Canal --- drivers/gpu/drm/vkms/vkms_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index dd0af086e7fa9..8dc9dc13896e9 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -223,7 +223,7 @@ static int vkms_create(struct vkms_config *config) if (ret) goto out_devres; - drm_fbdev_generic_setup(_device->drm, 0); + drm_fbdev_shmem_setup(_device->drm, 0); return 0; -- 2.44.0
[PATCH v3 15/43] drm/tiny/gm12u320: Use fbdev-shmem
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Hans de Goede Reviewed-by: Hans de Goede --- drivers/gpu/drm/tiny/gm12u320.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 0187539ff5eaa..8b4efd39d7c41 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -699,7 +699,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface, if (ret) goto err_put_device; - drm_fbdev_generic_setup(dev, 0); + drm_fbdev_shmem_setup(dev, 0); return 0; -- 2.44.0
[PATCH v3 19/43] drm/virtio: Use fbdev-shmem
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: David Airlie Cc: Gerd Hoffmann Cc: Gurchetan Singh Cc: Chia-I Wu Tested-by: Dmitry Osipenko Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/virtio/virtgpu_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 9539aa28937fa..3d626bbaab9e4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include "virtgpu_drv.h" @@ -103,7 +103,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev) if (ret) goto err_deinit; - drm_fbdev_generic_setup(vdev->priv, 32); + drm_fbdev_shmem_setup(vdev->priv, 32); return 0; err_deinit: -- 2.44.0
[PATCH v3 21/43] drm/fbdev-dma: Implement damage handling and deferred I/O
Add support for damage handling and deferred I/O to fbdev-dma. This enables fbdev-dma to support all DMA-memory-based DRM drivers, even such with a dirty callback in their framebuffers. The patch adds the code for deferred I/O and also sets a dedicated helper for struct fb_ops.fb_mmap that support coherent mappings. v3: - init fb_ops with FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS() (Javier) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/drm_fbdev_dma.c | 65 ++--- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index 6c9427bb4053b..5eeb5164e9e2b 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,22 @@ static int drm_fbdev_dma_fb_release(struct fb_info *info, int user) return 0; } +FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(drm_fbdev_dma, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area); + +static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_dma_object *dma = drm_fb_dma_get_gem_obj(fb, 0); + + if (!dma->map_noncoherent) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + return fb_deferred_io_mmap(info, vma); +} + static void drm_fbdev_dma_fb_destroy(struct fb_info *info) { struct drm_fb_helper *fb_helper = info->par; @@ -51,20 +68,13 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info) kfree(fb_helper); } -static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct drm_fb_helper *fb_helper = info->par; - - return drm_gem_prime_mmap(fb_helper->buffer->gem, vma); -} - static const struct fb_ops drm_fbdev_dma_fb_ops = { .owner = THIS_MODULE, .fb_open = drm_fbdev_dma_fb_open, .fb_release = drm_fbdev_dma_fb_release, - __FB_DEFAULT_DMAMEM_OPS_RDWR, + __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_dma), DRM_FB_HELPER_DEFAULT_OPS, - __FB_DEFAULT_DMAMEM_OPS_DRAW, + __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_dma), .fb_mmap = drm_fbdev_dma_fb_mmap, .fb_destroy = drm_fbdev_dma_fb_destroy, }; @@ -98,10 +108,6 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, dma_obj = to_drm_gem_dma_obj(buffer->gem); fb = buffer->fb; - if (drm_WARN_ON(dev, fb->funcs->dirty)) { - ret = -ENODEV; /* damage handling not supported; use generic emulation */ - goto err_drm_client_buffer_delete; - } ret = drm_client_buffer_vmap(buffer, ); if (ret) { @@ -112,7 +118,7 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, } fb_helper->buffer = buffer; - fb_helper->fb = buffer->fb; + fb_helper->fb = fb; info = drm_fb_helper_alloc_info(fb_helper); if (IS_ERR(info)) { @@ -133,8 +139,19 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); info->fix.smem_len = info->screen_size; + /* deferred I/O */ + fb_helper->fbdefio.delay = HZ / 20; + fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; + + info->fbdefio = _helper->fbdefio; + ret = fb_deferred_io_init(info); + if (ret) + goto err_drm_fb_helper_release_info; + return 0; +err_drm_fb_helper_release_info: + drm_fb_helper_release_info(fb_helper); err_drm_client_buffer_vunmap: fb_helper->fb = NULL; fb_helper->buffer = NULL; @@ -144,8 +161,28 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, return ret; } +static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper, +struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + static const struct drm_fb_helper_funcs drm_fbdev_dma_helper_funcs = { .fb_probe = drm_fbdev_dma_helper_fb_probe, + .fb_dirty = drm_fbdev_dma_helper_fb_dirty, }; /* -- 2.44.0
[PATCH v3 33/43] drm/tiny/ili9163: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by ili9163. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/tiny/ili9163.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c index bc4384d410fcc..86f9d88349015 100644 --- a/drivers/gpu/drm/tiny/ili9163.c +++ b/drivers/gpu/drm/tiny/ili9163.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -185,7 +185,7 @@ static int ili9163_probe(struct spi_device *spi) if (ret) return ret; - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_dma_setup(drm, 0); return 0; } -- 2.44.0
[PATCH v3 41/43] drm/tiny/st7735r: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by st7735r. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: David Lechner Acked-by: David Lechner --- drivers/gpu/drm/tiny/st7735r.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index 477eb36fbb70d..1676da00883d3 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -241,7 +241,7 @@ static int st7735r_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_dma_setup(drm, 0); return 0; } -- 2.44.0
[PATCH v3 43/43] drm/fbdev: Clean up fbdev documentation
Rewrite some docs that are not up-to-date any longer. Remove the TODO item for fbdev-generic conversion, as the helper has been replaced. Make documentation for DMA, SHMEM and TTM emulation available. Signed-off-by: Thomas Zimmermann Cc: Jonathan Corbet Reviewed-by: Javier Martinez Canillas --- Documentation/gpu/drm-kms-helpers.rst | 12 +--- Documentation/gpu/todo.rst| 13 - drivers/gpu/drm/drm_drv.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 11 ++- include/drm/drm_mode_config.h | 4 ++-- 5 files changed, 14 insertions(+), 28 deletions(-) diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index e46ab9b670acd..8435e8621cc08 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -110,15 +110,21 @@ fbdev Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :doc: fbdev helpers -.. kernel-doc:: include/drm/drm_fb_helper.h - :internal: +.. kernel-doc:: drivers/gpu/drm/drm_fbdev_dma.c + :export: -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c +.. kernel-doc:: drivers/gpu/drm/drm_fbdev_shmem.c :export: .. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c :export: +.. kernel-doc:: include/drm/drm_fb_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :export: + format Helper Functions Reference = diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index fb9ad120b1414..e2a0585915b32 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -243,19 +243,6 @@ Contact: Maintainer of the driver you plan to convert Level: Intermediate -Convert drivers to use drm_fbdev_generic_setup() - - -Most drivers can use drm_fbdev_generic_setup(). Driver have to implement -atomic modesetting and GEM vmap support. Historically, generic fbdev emulation -expected the framebuffer in system memory or system-like memory. By employing -struct iosys_map, drivers with frambuffers in I/O memory can be supported -as well. - -Contact: Maintainer of the driver you plan to convert - -Level: Intermediate - Reimplement functions in drm_fbdev_fb_ops without fbdev --- diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 243cacb3575c0..cfcd45480d326 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -345,7 +345,7 @@ void drm_minor_release(struct drm_minor *minor) * if (ret) * return ret; * - * drm_fbdev_generic_setup(drm, 32); + * drm_fbdev_{...}_setup(drm, 32); * * return 0; * } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d612133e2cf7e..e2e19f49342e1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -85,12 +85,8 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * The fb helper functions are useful to provide an fbdev on top of a drm kernel * mode setting driver. They can be used mostly independently from the crtc * helper functions used by many drivers to implement the kernel mode setting - * interfaces. - * - * Drivers that support a dumb buffer with a virtual address and mmap support, - * should try out the generic fbdev emulation using drm_fbdev_generic_setup(). - * It will automatically set up deferred I/O if the driver requires a shadow - * buffer. + * interfaces. Drivers that use one of the shared memory managers, TTM, SHMEM, + * DMA, should instead use the corresponding fbdev emulation. * * Existing fbdev implementations should restore the fbdev console by using * drm_fb_helper_lastclose() as their _driver.lastclose callback. @@ -126,9 +122,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io * callback it will also schedule dirty_work with the damage collected from the * mmap page writes. - * - * Deferred I/O is not compatible with SHMEM. Such drivers should request an - * fbdev shadow buffer and call drm_fbdev_generic_setup() instead. */ static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 9d8acf7a10eb8..77b8429e7b2b2 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -106,8 +106,8 @@ struct drm_mode_config_funcs { * Drivers implementing fbdev emulation use drm_kms_helper_hotplug_event() * to call this hook to inform the fbdev helper of output changes. * -* This hook is deprecated, drivers should instead use -* drm_fbdev_generic_setup() which takes care of any necessary +* This hook is deprecated, drivers should instead implement fbdev +* support with struct
[PATCH v3 29/43] drm/renesas/rz-du: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by rz-du. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Biju Das Tested-by: Biju Das Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c index 470d34da1d6c4..e5eca8691a331 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -149,7 +149,7 @@ static int rzg2l_du_probe(struct platform_device *pdev) drm_info(>ddev, "Device %s probed\n", dev_name(>dev)); - drm_fbdev_generic_setup(>ddev, 32); + drm_fbdev_dma_setup(>ddev, 32); return 0; -- 2.44.0
[PATCH v3 07/43] fbdev/deferred-io: Provide get_page hook in struct fb_deferred_io
Add a callback for drivers to provide framebuffer pages to fbdev's deferred-I/O helpers. Implementations need to acquire a reference on the page before returning it. Returning NULL generates a SIGBUS signal. This will be useful for DRM's fbdev emulation with GEM-shmem buffer objects. v2: - fix typo in commit message (Javier) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- drivers/video/fbdev/core/fb_defio.c | 4 include/linux/fb.h | 1 + 2 files changed, 5 insertions(+) diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 6e0bbcfdb01b5..51928ff7961a5 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -25,9 +25,13 @@ static struct page *fb_deferred_io_get_page(struct fb_info *info, unsigned long offs) { + struct fb_deferred_io *fbdefio = info->fbdefio; const void *screen_buffer = info->screen_buffer; struct page *page = NULL; + if (fbdefio->get_page) + return fbdefio->get_page(info, offs); + if (is_vmalloc_addr(screen_buffer + offs)) page = vmalloc_to_page(screen_buffer + offs); else if (info->fix.smem_start) diff --git a/include/linux/fb.h b/include/linux/fb.h index 3417103885e27..4eb6afa93737c 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -225,6 +225,7 @@ struct fb_deferred_io { struct mutex lock; /* mutex that protects the pageref list */ struct list_head pagereflist; /* list of pagerefs for touched pages */ /* callback */ + struct page *(*get_page)(struct fb_info *info, unsigned long offset); void (*deferred_io)(struct fb_info *info, struct list_head *pagelist); }; #endif -- 2.44.0
[PATCH v3 16/43] drm/tiny/ofdrm: Use fbdev-shmem
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/tiny/ofdrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index ab89b7fc7bf61..35996f7eedac0 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -1377,7 +1377,7 @@ static int ofdrm_probe(struct platform_device *pdev) if (color_mode == 16) color_mode = odev->format->depth; // can be 15 or 16 - drm_fbdev_generic_setup(dev, color_mode); + drm_fbdev_shmem_setup(dev, color_mode); return 0; } -- 2.44.0
[PATCH v3 36/43] drm/tiny/ili9486: Use fbdev-dma
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports damage handling, which is required by ili9486. Avoids the overhead of fbdev-generic's additional shadow buffering. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/tiny/ili9486.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index 938bceed59998..70d3662600410 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include @@ -247,7 +247,7 @@ static int ili9486_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_generic_setup(drm, 0); + drm_fbdev_dma_setup(drm, 0); return 0; } -- 2.44.0
[PATCH v3 08/43] drm/fbdev: Add fbdev-shmem
Add an fbdev emulation for SHMEM-based memory managers. The code is similar to fbdev-generic, but does not require an additional shadow buffer for mmap(). Fbdev-shmem operates directly on the buffer object's SHMEM pages. Fbdev's deferred-I/O mechanism updates the hardware state on write operations. The memory pages of GEM SHMEM cannot be detected by fbdefio. Therefore fbdev-shmem implements the .get_page() hook in struct fb_deferred_io. The fbdefio helpers call this hook to retrieve the page directly from fbdev-shmem instead of trying to detect it internally. v3: - clarify on get_page mechanism in commit description (Javier) v2: - use drm_driver_legacy_fb_format() (Geert) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_fbdev_shmem.c | 316 ++ include/drm/drm_fbdev_shmem.h | 15 ++ 3 files changed, 332 insertions(+) create mode 100644 drivers/gpu/drm/drm_fbdev_shmem.c create mode 100644 include/drm/drm_fbdev_shmem.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index a73c04d2d7a39..50a2f0cffdac2 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -107,6 +107,7 @@ drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_dma_helper.o obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o drm_shmem_helper-y := drm_gem_shmem_helper.o +drm_shmem_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_shmem.o obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o drm_suballoc_helper-y := drm_suballoc.o diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c new file mode 100644 index 0..a85a8a8e2eb8b --- /dev/null +++ b/drivers/gpu/drm/drm_fbdev_shmem.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: MIT + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* + * struct fb_ops + */ + +static int drm_fbdev_shmem_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_shmem_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; +} + +FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_shmem, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area); + +static int drm_fbdev_shmem_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0); + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + + if (shmem->map_wc) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + return fb_deferred_io_mmap(info, vma); +} + +static void drm_fbdev_shmem_fb_destroy(struct fb_info *info) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (!fb_helper->dev) + return; + + drm_fb_helper_fini(fb_helper); + + drm_client_buffer_vunmap(fb_helper->buffer); + drm_client_framebuffer_delete(fb_helper->buffer); + drm_client_release(_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); +} + +static const struct fb_ops drm_fbdev_shmem_fb_ops = { + .owner = THIS_MODULE, + .fb_open = drm_fbdev_shmem_fb_open, + .fb_release = drm_fbdev_shmem_fb_release, + __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_shmem), + DRM_FB_HELPER_DEFAULT_OPS, + __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_shmem), + .fb_mmap = drm_fbdev_shmem_fb_mmap, + .fb_destroy = drm_fbdev_shmem_fb_destroy, +}; + +static struct page *drm_fbdev_shmem_get_page(struct fb_info *info, unsigned long offset) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0); + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + unsigned int i = offset >> PAGE_SHIFT; + struct page *page; + + if (fb_WARN_ON_ONCE(info, offset > obj->size)) + return NULL; + + page = shmem->pages[i]; // protected by active vmap + if (page) + get_page(page); + fb_WARN_ON_ONCE(info, !page); + + return page; +} + +/* + * struct drm_fb_helper + */ + +static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper, + stru
[PATCH v3 42/43] drm/fbdev-generic: Convert to fbdev-ttm
Only TTM-based drivers use fbdev-generic. Rename it to fbdev-ttm and change the symbol infix from _generic_ to _ttm_. Link the source file into TTM helpers, so that it is only build if TTM-based drivers have been selected. Select DRM_TTM_HELPER for loongson. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- Documentation/gpu/drm-kms-helpers.rst | 2 +- drivers/gpu/drm/Makefile | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 +- .../{drm_fbdev_generic.c => drm_fbdev_ttm.c} | 80 +-- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 +- drivers/gpu/drm/loongson/Kconfig | 1 + drivers/gpu/drm/loongson/lsdc_drv.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 6 +- drivers/gpu/drm/qxl/qxl_drv.c | 4 +- drivers/gpu/drm/tiny/bochs.c | 4 +- drivers/gpu/drm/vboxvideo/vbox_drv.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 +- include/drm/drm_fbdev_generic.h | 15 include/drm/drm_fbdev_ttm.h | 15 14 files changed, 77 insertions(+), 77 deletions(-) rename drivers/gpu/drm/{drm_fbdev_generic.c => drm_fbdev_ttm.c} (76%) delete mode 100644 include/drm/drm_fbdev_generic.h create mode 100644 include/drm/drm_fbdev_ttm.h diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 59cfe8a7a8bac..e46ab9b670acd 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -116,7 +116,7 @@ fbdev Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :export: -.. kernel-doc:: drivers/gpu/drm/drm_fbdev_generic.c +.. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c :export: format Helper Functions Reference diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 50a2f0cffdac2..7bd4c525fd825 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -117,6 +117,7 @@ drm_vram_helper-y := drm_gem_vram_helper.o obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o drm_ttm_helper-y := drm_gem_ttm_helper.o +drm_ttm_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_ttm.o obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o # @@ -142,9 +143,7 @@ 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_fbdev_generic.o \ - drm_fb_helper.o +drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += 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 e4277298cf1aa..a4a63daab9e10 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -2318,9 +2318,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, !list_empty(_to_drm(adev)->mode_config.connector_list)) { /* select 8 bpp console on low vram cards */ if (adev->gmc.real_vram_size <= (32*1024*1024)) - drm_fbdev_generic_setup(adev_to_drm(adev), 8); + drm_fbdev_ttm_setup(adev_to_drm(adev), 8); else - drm_fbdev_generic_setup(adev_to_drm(adev), 32); + drm_fbdev_ttm_setup(adev_to_drm(adev), 32); } ret = amdgpu_debugfs_init(adev); diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_ttm.c similarity index 76% rename from drivers/gpu/drm/drm_fbdev_generic.c rename to drivers/gpu/drm/drm_fbdev_ttm.c index 97e579c33d84a..bb7898cd7dc63 100644 --- a/drivers/gpu/drm/drm_fbdev_generic.c +++ b/drivers/gpu/drm/drm_fbdev_ttm.c @@ -10,10 +10,10 @@ #include #include -#include +#include /* @user: 1=userspace, 0=fbcon */ -static int drm_fbdev_generic_fb_open(struct fb_info *info, int user) +static int drm_fbdev_ttm_fb_open(struct fb_info *info, int user) { struct drm_fb_helper *fb_helper = info->par; @@ -24,7 +24,7 @@ static int drm_fbdev_generic_fb_open(struct fb_info *info, int user) return 0; } -static int drm_fbdev_generic_fb_release(struct fb_info *info, int user) +static int drm_fbdev_ttm_fb_release(struct fb_info *info, int user) { struct drm_fb_helper *fb_helper = info->par; @@ -34,11 +34,11 @@ static int drm_fbdev_generic_fb_release(struct fb_info *info, int user) return 0; } -FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_generic, +FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_ttm, drm_fb_helper_damage_range, drm_fb_helper_damage_area); -static void drm_fbdev_generic_fb_destroy(struct fb_inf
[PATCH v3 01/43] drm/fbdev-generic: Do not set physical framebuffer address
Framebuffer memory is allocated via vzalloc() from non-contiguous physical pages. The physical framebuffer start address is therefore meaningless. Do not set it. The value is not used within the kernel and only exported to userspace on dedicated ARM configs. No functional change is expected. v2: - refer to vzalloc() in commit message (Javier) Signed-off-by: Thomas Zimmermann Fixes: a5b44c4adb16 ("drm/fbdev-generic: Always use shadow buffering") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Zack Rusin Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: # v6.4+ Reviewed-by: Javier Martinez Canillas Reviewed-by: Zack Rusin Reviewed-by: Sui Jingfeng Tested-by: Sui Jingfeng Acked-by: Maxime Ripard --- drivers/gpu/drm/drm_fbdev_generic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c index be357f926faec..97e579c33d84a 100644 --- a/drivers/gpu/drm/drm_fbdev_generic.c +++ b/drivers/gpu/drm/drm_fbdev_generic.c @@ -113,7 +113,6 @@ static int drm_fbdev_generic_helper_fb_probe(struct drm_fb_helper *fb_helper, /* screen */ info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; info->screen_buffer = screen_buffer; - info->fix.smem_start = page_to_phys(vmalloc_to_page(info->screen_buffer)); info->fix.smem_len = screen_size; /* deferred I/O */ -- 2.44.0