Re: [PATCH v4] drm/ast: Fixed CVE for DP501
return false; + + /* dummy read */ + offset = 0x; + data = readl(ast->dp501_fw_buf + offset); + + /* validate FW version */ + offset = AST_DP501_GBL_VERSION; + data = readl(ast->dp501_fw_buf + offset); + if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) + return false; + + /* validate PnP Monitor */ + offset = AST_DP501_PNPMONITOR; + data = readl(ast->dp501_fw_buf + offset); + if (!(data & AST_DP501_PNP_CONNECTED)) + return false; + + /* Read EDID */ + offset = AST_DP501_EDID_DATA; + for (i = 0; i < 128; i += 4) { + data = readl(ast->dp501_fw_buf + offset + i); + pEDIDidx = (u32 *)(ediddata + i); + *pEDIDidx = data; + } } return true; diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index e82ab8628..911f9f414 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -150,6 +150,7 @@ struct ast_private { void __iomem *regs; void __iomem *ioregs; + void __iomem *dp501_fw_buf; enum ast_chip chip; bool vga2_clone; @@ -325,6 +326,17 @@ int ast_mode_config_init(struct ast_private *ast); #define AST_MM_ALIGN_SHIFT 4 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) +#define AST_DP501_FW_VERSION_MASK GENMASK(7, 4) +#define AST_DP501_FW_VERSION_1 BIT(4) +#define AST_DP501_PNP_CONNECTEDBIT(1) + +#define AST_DP501_DEFAULT_DCLK 65 + +#define AST_DP501_GBL_VERSION 0xf000 +#define AST_DP501_PNPMONITOR 0xf010 +#define AST_DP501_LINKRATE 0xf014 +#define AST_DP501_EDID_DATA0xf020 + int ast_mm_init(struct ast_private *ast); /* ast post */ diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 0ac3c2039..dbf5224ab 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -450,6 +450,14 @@ struct ast_private *ast_device_create(const struct drm_driver *drv, if (ret) return ERR_PTR(ret); + /* map reserved buffer */ + ast->dp501_fw_buf = NULL; + if (dev->vram_mm->vram_size < pci_resource_len(dev->pdev, 0)) { + ast->dp501_fw_buf = pci_iomap_range(dev->pdev, 0, dev->vram_mm->vram_size, 0); + if (!ast->dp501_fw_buf) + drm_info(dev, "failed to map reserved buffer!\n"); + } + ret = ast_mode_config_init(ast); if (ret) return ERR_PTR(ret); -- 2.18.4 -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [syzbot] general protection fault in drm_client_buffer_vunmap
#syz fix: drm/fb-helper: only unmap if buffer not null Am 11.04.21 um 14:01 schrieb syzbot: #syz fix: drm/fb-helper: only unmap if buffer not null -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v4 2/6] drm/sprd: add Unisoc's drm kms master
Hi Am 09.04.21 um 15:50 schrieb Kevin Tang: > +static int __init sprd_drm_init(void) > +{ > + int ret; I think ret should just go away. Like this? "return platform_register_drivers(sprd_drm_drivers, ARRAY_SIZE(sprd_drm_drivers));" Sure. Best regards Thomas if so, i will fix it, thks. Acked-by: Thomas Zimmermann mailto:tzimmerm...@suse.de>> > + > + ret = platform_register_drivers(sprd_drm_drivers, > + ARRAY_SIZE(sprd_drm_drivers)); > + return ret; > +} > + > +static void __exit sprd_drm_exit(void) > +{ > + platform_unregister_drivers(sprd_drm_drivers, > + ARRAY_SIZE(sprd_drm_drivers)); > +} > + > +module_init(sprd_drm_init); > +module_exit(sprd_drm_exit); > + > +MODULE_AUTHOR("Leon He mailto:leon...@unisoc.com>>"); > +MODULE_AUTHOR("Kevin Tang mailto:kevin.t...@unisoc.com>>"); > +MODULE_DESCRIPTION("Unisoc DRM KMS Master Driver"); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/gpu/drm/sprd/sprd_drm.h b/drivers/gpu/drm/sprd/sprd_drm.h > new file mode 100644 > index 0..9781fd591 > --- /dev/null > +++ b/drivers/gpu/drm/sprd/sprd_drm.h > @@ -0,0 +1,16 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2020 Unisoc Inc. > + */ > + > +#ifndef _SPRD_DRM_H_ > +#define _SPRD_DRM_H_ > + > +#include > +#include > + > +struct sprd_drm { > + struct drm_device drm; > +}; > + > +#endif /* _SPRD_DRM_H_ */ > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v4 4/6] drm/sprd: add Unisoc's drm display controller driver
dev_err(dev, "failed to register dpu irq handler\n"); + return ret; + } + + init_waitqueue_head(>wait_queue); + + return 0; +} + +static int sprd_dpu_bind(struct device *dev, struct device *master, void *data) +{ + struct drm_device *drm = data; + struct sprd_dpu *dpu; + struct sprd_plane *plane; + int ret; + + plane = sprd_plane_init(drm); + if (IS_ERR(plane)) + return PTR_ERR(plane); + + dpu = sprd_crtc_init(drm, >base); + if (IS_ERR(dpu)) + return PTR_ERR(dpu); + + dpu->drm = drm; + dev_set_drvdata(dev, dpu); + + ret = sprd_dpu_context_init(dpu, dev); + if (ret) + return ret; + + return 0; +} + +static const struct component_ops dpu_component_ops = { + .bind = sprd_dpu_bind, +}; + +static const struct of_device_id dpu_match_table[] = { + { .compatible = "sprd,sharkl3-dpu" }, + { /* sentinel */ }, +}; + +static int sprd_dpu_probe(struct platform_device *pdev) +{ + return component_add(>dev, _component_ops); +} + +static int sprd_dpu_remove(struct platform_device *pdev) +{ + component_del(>dev, _component_ops); + + return 0; +} + +struct platform_driver sprd_dpu_driver = { + .probe = sprd_dpu_probe, + .remove = sprd_dpu_remove, + .driver = { + .name = "sprd-dpu-drv", + .of_match_table = dpu_match_table, + }, +}; + +MODULE_AUTHOR("Leon He "); +MODULE_AUTHOR("Kevin Tang "); +MODULE_DESCRIPTION("Unisoc Display Controller Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/sprd/sprd_dpu.h b/drivers/gpu/drm/sprd/sprd_dpu.h new file mode 100644 index 0..157a78f24 --- /dev/null +++ b/drivers/gpu/drm/sprd/sprd_dpu.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Unisoc Inc. + */ + +#ifndef __SPRD_DPU_H__ +#define __SPRD_DPU_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* DPU Layer registers offset */ +#define DPU_LAY_REG_OFFSET 0x30 + +enum { + SPRD_DPU_IF_DPI, + SPRD_DPU_IF_EDPI, + SPRD_DPU_IF_LIMIT +}; + +/** + * Sprd DPU context structure + * + * @base: DPU controller base address + * @irq: IRQ number to install the handler for + * @if_type: The type of DPI interface, default is DPI mode. + * @vm: videomode structure to use for DPU and DPI initialization + * @stopped: indicates whether DPU are stopped + * @wait_queue: wait queue, used to wait for DPU shadow register update done and + * DPU stop register done interrupt signal. + * @evt_update: wait queue condition for DPU shadow register + * @evt_stop: wait queue condition for DPU stop register + */ +struct dpu_context { + void __iomem *base; + int irq; + u8 if_type; + struct videomode vm; + bool stopped; + wait_queue_head_t wait_queue; + bool evt_update; + bool evt_stop; +}; + +/** + * Sprd DPU device structure + * + * @crtc: crtc object + * @drm: A point to drm device + * @ctx: DPU's implementation specific context object + */ +struct sprd_dpu { + struct drm_crtc base; + struct drm_device *drm; + struct dpu_context ctx; +}; + +static inline struct sprd_dpu *to_sprd_crtc(struct drm_crtc *crtc) +{ + return container_of(crtc, struct sprd_dpu, base); +} + +static inline void +dpu_reg_set(struct dpu_context *ctx, u32 offset, u32 set_bits) +{ + u32 bits = readl_relaxed(ctx->base + offset); + + writel(bits | set_bits, ctx->base + offset); +} + +static inline void +dpu_reg_clr(struct dpu_context *ctx, u32 offset, u32 clr_bits) +{ + u32 bits = readl_relaxed(ctx->base + offset); + + writel(bits & ~clr_bits, ctx->base + offset); +} + +static inline u32 +layer_reg_rd(struct dpu_context *ctx, u32 offset, int index) +{ + u32 layer_offset = offset + index * DPU_LAY_REG_OFFSET; + + return readl(ctx->base + layer_offset); +} + +static inline void +layer_reg_wr(struct dpu_context *ctx, u32 offset, u32 cfg_bits, int index) +{ + u32 layer_offset = offset + index * DPU_LAY_REG_OFFSET; + + writel(cfg_bits, ctx->base + layer_offset); +} + +void sprd_dpu_run(struct sprd_dpu *dpu); +void sprd_dpu_stop(struct sprd_dpu *dpu); + +#endif diff --git a/drivers/gpu/drm/sprd/sprd_drm.c b/drivers/gpu/drm/sprd/sprd_drm.c index a1d3ed655..c626c6caf 100644 --- a/drivers/gpu/drm/sprd/sprd_drm.c +++ b/drivers/gpu/drm/sprd/sprd_drm.c @@ -191,6 +191,7 @@ static struct platform_driver sprd_drm_driver = { static struct platform_driver *sprd_drm_drivers[] = { _drm_driver, + _dpu_driver, }; static int __init sprd_drm_init(void) diff --git a/drivers/gpu/drm/sprd/sprd_drm.h b/drivers/gpu/drm/sprd/sprd_drm.h index 9781fd591..85d4a8b9f 100644 --- a/drivers/gpu/drm/sprd/sprd_drm.h +++ b/drivers/gpu/drm/sprd/sprd_drm.h @@ -13,4 +13,6 @@ struct sprd_drm { struct drm_device drm; }; +extern struct platform_driver sprd_dpu_driver; + #endif /* _SPRD_DRM_H_ */ -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v4 2/6] drm/sprd: add Unisoc's drm kms master
+ +static int sprd_drm_bind(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct drm_device *drm; + struct sprd_drm *sprd; + int ret; + + sprd = devm_drm_dev_alloc(dev, _drm_drv, struct sprd_drm, drm); + if (IS_ERR(sprd)) + return PTR_ERR(sprd); + + drm = >drm; + platform_set_drvdata(pdev, drm); + + ret = drmm_mode_config_init(drm); + if (ret) + return ret; + + sprd_drm_mode_config_init(drm); + + /* bind and init sub drivers */ + ret = component_bind_all(drm->dev, drm); + if (ret) { + drm_err(drm, "failed to bind all component.\n"); + return ret; + } + + /* vblank init */ + ret = drm_vblank_init(drm, drm->mode_config.num_crtc); + if (ret) { + drm_err(drm, "failed to initialize vblank.\n"); + goto err_unbind_all; + } + /* with irq_enabled = true, we can use the vblank feature. */ + drm->irq_enabled = true; + + /* reset all the states of crtc/plane/encoder/connector */ + drm_mode_config_reset(drm); + + /* init kms poll for handling hpd */ + drm_kms_helper_poll_init(drm); + + ret = drm_dev_register(drm, 0); + if (ret < 0) + goto err_kms_helper_poll_fini; + + return 0; + +err_kms_helper_poll_fini: + drm_kms_helper_poll_fini(drm); +err_unbind_all: + component_unbind_all(drm->dev, drm); + return ret; +} + +static void sprd_drm_unbind(struct device *dev) +{ + struct drm_device *drm = dev_get_drvdata(dev); + + drm_dev_unregister(drm); + + drm_kms_helper_poll_fini(drm); + + component_unbind_all(drm->dev, drm); +} + +static const struct component_master_ops drm_component_ops = { + .bind = sprd_drm_bind, + .unbind = sprd_drm_unbind, +}; + +static int compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static int sprd_drm_probe(struct platform_device *pdev) +{ + struct device *dev = >dev; + int ret; + + ret = dma_set_mask_and_coherent(dev, ~0UL); + if (ret) { + dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); + return ret; + } + + return drm_of_component_probe(dev, compare_of, _component_ops); +} + +static int sprd_drm_remove(struct platform_device *pdev) +{ + component_master_del(>dev, _component_ops); + return 0; +} + +static void sprd_drm_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + + if (!drm) { + drm_warn(drm, "drm device is not available, no shutdown\n"); + return; + } + + drm_atomic_helper_shutdown(drm); +} + +static const struct of_device_id drm_match_table[] = { + { .compatible = "sprd,display-subsystem", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, drm_match_table); + +static struct platform_driver sprd_drm_driver = { + .probe = sprd_drm_probe, + .remove = sprd_drm_remove, + .shutdown = sprd_drm_shutdown, + .driver = { + .name = "sprd-drm-drv", + .of_match_table = drm_match_table, + }, +}; + +static struct platform_driver *sprd_drm_drivers[] = { + _drm_driver, +}; + +static int __init sprd_drm_init(void) +{ + int ret; I think ret should just go away. Acked-by: Thomas Zimmermann + + ret = platform_register_drivers(sprd_drm_drivers, + ARRAY_SIZE(sprd_drm_drivers)); + return ret; +} + +static void __exit sprd_drm_exit(void) +{ + platform_unregister_drivers(sprd_drm_drivers, + ARRAY_SIZE(sprd_drm_drivers)); +} + +module_init(sprd_drm_init); +module_exit(sprd_drm_exit); + +MODULE_AUTHOR("Leon He "); +MODULE_AUTHOR("Kevin Tang "); +MODULE_DESCRIPTION("Unisoc DRM KMS Master Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/sprd/sprd_drm.h b/drivers/gpu/drm/sprd/sprd_drm.h new file mode 100644 index 0..9781fd591 --- /dev/null +++ b/drivers/gpu/drm/sprd/sprd_drm.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Unisoc Inc. + */ + +#ifndef _SPRD_DRM_H_ +#define _SPRD_DRM_H_ + +#include +#include + +struct sprd_drm { + struct drm_device drm; +}; + +#endif /* _SPRD_DRM_H_ */ -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH V3] drm/ast: Disable fast reset after DRAM initial
Hi Am 31.03.21 um 08:56 schrieb Kuo-Hsiang Chou: Message-ID: <20201228030823.294147-1-kuohsiang_c...@aspeedtech.com> -Original Message- From: Thomas Zimmermann [mailto:tzimmerm...@suse.de] Sent: Monday, March 29, 2021 5:17 PM To: Kuo-Hsiang Chou ; dri-de...@lists.freedesktop.org; linux-kernel@vger.kernel.org Subject: Re: [PATCH V3] drm/ast: Disable fast reset after DRAM initial Hi, I cannot apply this patch. The error is shown below. Which tree do you use? Can you please move to drm-misc-next? Applying: drm/ast: Disable fast reset after DRAM initial error: sha1 information is lacking or useless (drivers/gpu/drm/ast/ast_drv.h). error: could not build fake ancestor Patch failed at 0001 drm/ast: Disable fast reset after DRAM initial hint: Use 'git am --show-current-patch=diff' to see the failed patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". dim: ERROR: git apply-mbox failed Hi, Thomas, Thanks for the comments, I still use kernel_5.9. Yes, I will move to the latest version of drm-misc-next. The errors seem to be caused by a pending patch(Message-ID: <20201228030823.294147-1-kuohsiang_c...@aspeedtech.com>). And I submitted current patch before reviewer result of pending patch(Message-ID: <20201228030823.294147-1-kuohsiang_c...@aspeedtech.com>). Please give an instruction how to works to next step. Continue waiting for the reviewer result, or move to kernel_5.12-rc1 and submit the pending patch again? Or other suggestions? The official Linux kernel tree is always behind with new features. So for development, you'll need a tree for the rsp topic. For DRM graphics, this would usually be drm-misc-next. [1] I already wanted to apply the patch as it is in v3. I suggest to simply rebase it on top of drm-misc-next and resubmit to the mailing list. When you create the patch file, 'git format-patch' and 'git am' support the --base option. It allows to set an upstream commit id. This can be helpful when git tries to apply the patch file later on. Several of our automated tests also use the base ref when they test patchsets. See the manpage of 'git format-patch' for a description of --base. [2] Best regards Thomas [1] git://anongit.freedesktop.org/drm/drm-misc [2] https://git-scm.com/docs/git-format-patch Thanks! Best Regards, Kuo-Hsiang Chou Best regards Thomas Am 19.03.21 um 10:23 schrieb KuoHsiang Chou: [Bug][AST2500] V1: When AST2500 acts as stand-alone VGA so that DRAM and DVO initialization have to be achieved by VGA driver with P2A (PCI to AHB) enabling. However, HW suggests disable Fast reset mode after DRAM initializaton, because fast reset mode is mainly designed for ARM ICE debugger. Once Fast reset is checked as enabling, WDT (Watch Dog Timer) should be first enabled to avoid system deadlock before disable fast reset mode. V2: Use to_pci_dev() to get revision of PCI configuration. V3: If SCU00 is not unlocked, just enter its password again. It is unnecessary to clear AHB lock condition and restore WDT default setting again, before Fast-reset clearing. Signed-off-by: KuoHsiang Chou --- drivers/gpu/drm/ast/ast_drv.h | 1 + drivers/gpu/drm/ast/ast_main.c | 5 +++ drivers/gpu/drm/ast/ast_post.c | 68 +- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index da6dfb677540..a2cf5fef2399 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -320,6 +320,7 @@ bool ast_is_vga_enabled(struct drm_device *dev); void ast_post_gpu(struct drm_device *dev); u32 ast_mindwm(struct ast_private *ast, u32 r); void ast_moutdwm(struct ast_private *ast, u32 r, u32 v); +void ast_patch_ahb_2500(struct ast_private *ast); /* ast dp501 */ void ast_set_dp501_video_output(struct drm_device *dev, u8 mode); bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 3775fe26f792..0e4dfcc25623 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -69,6 +69,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) { struct device_node *np = dev->pdev->dev.of_node; struct ast_private *ast = to_ast_private(dev); + struct pci_dev *pdev = to_pci_dev(dev->dev); uint32_t data, jregd0, jregd1; /* Defaults */ @@ -96,6 +97,10 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { + /* Patc
Re: [PATCH V3] drm/ast: Disable fast reset after DRAM initial
if ((reg & 0xC0) == 0) {/* vga only */ /* Clear bus lock condition */ - ast_moutdwm(ast, 0x1e60, 0xAEED1A03); - ast_moutdwm(ast, 0x1e600084, 0x0001); - ast_moutdwm(ast, 0x1e600088, 0x); - ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8); - ast_write32(ast, 0xf004, 0x1e6e); - ast_write32(ast, 0xf000, 0x1); - ast_write32(ast, 0x12000, 0x1688a8a8); - while (ast_read32(ast, 0x12000) != 0x1) - ; - - ast_write32(ast, 0x1, 0xfc600309); - while (ast_read32(ast, 0x1) != 0x1) - ; + ast_patch_ahb_2500(ast); + + /* Disable watchdog */ + ast_moutdwm(ast, 0x1E78502C, 0x); + ast_moutdwm(ast, 0x1E78504C, 0x); + /* Reset USB port */ + ast_moutdwm(ast, 0x1E6E2090, 0x2000); + ast_moutdwm(ast, 0x1E6E2094, 0x4000); + if (ast_mindwm(ast, 0x1E6E2070) & 0x0080) { + ast_moutdwm(ast, 0x1E6E207C, 0x0080); + mdelay(100); + ast_moutdwm(ast, 0x1E6E2070, 0x0080); + } + /* Modify eSPI reset pin */ + temp = ast_mindwm(ast, 0x1E6E2070); + if (temp & 0x0200) + ast_moutdwm(ast, 0x1E6E207C, 0x4000); /* Slow down CPU/AHB CLK in VGA only mode */ temp = ast_read32(ast, 0x12008); temp |= 0x73; ast_write32(ast, 0x12008, temp); - /* Reset USB port to patch USB unknown device issue */ - ast_moutdwm(ast, 0x1e6e2090, 0x2000); - temp = ast_mindwm(ast, 0x1e6e2094); - temp |= 0x4000; - ast_moutdwm(ast, 0x1e6e2094, temp); - temp = ast_mindwm(ast, 0x1e6e2070); - if (temp & 0x0080) { - ast_moutdwm(ast, 0x1e6e207c, 0x0080); - mdelay(100); - ast_moutdwm(ast, 0x1e6e2070, 0x0080); - } - if (!ast_dram_init_2500(ast)) drm_err(dev, "DRAM init failed !\n"); -- 2.18.4 ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 4/5] drm: Add and export function drm_gem_cma_sync_data
Hi Am 11.03.21 um 13:33 schrieb Paul Cercueil: Le jeu. 11 mars 2021 à 12:28, Christoph Hellwig a écrit : On Sun, Mar 07, 2021 at 08:28:34PM +, Paul Cercueil wrote: + drm_atomic_for_each_plane_damage(, ) { + for (i = 0; i < finfo->num_planes; i++) { + daddr = drm_fb_cma_get_gem_addr(state->fb, state, i); + + /* Ignore x1/x2 values, invalidate complete lines */ + offset = clip.y1 * state->fb->pitches[i]; + + dma_sync_single_for_device(dev, daddr + offset, + (clip.y2 - clip.y1) * state->fb->pitches[i], + DMA_TO_DEVICE); Are these helpers only ever used to transfer data to the device and never from it? If so please clearly document that. Yes. In the DRM world, are there cases where we transfer data from the device? I assume these cases are handled by v4l2 instead. Software rendering (i.e., anything wrt dumb buffers) likely reads back framebuffer content during blit operations. For devices where this is a slow operation (e.g., PCI read) we set struct drm_mode_config.prefer_shadow to hint renderers to use shadow buffering. Best regards Thomas -Paul -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 0/5] Add option to mmap GEM buffers cached
Hi Am 10.03.21 um 20:02 schrieb Paul Cercueil: Hi Thomas, Le lun. 8 mars 2021 à 9:41, Thomas Zimmermann a écrit : Hi Paul, having individual functions for each mode only makes sense if the decision is at compile time. But in patch 5, you're working around your earlier design by introducing in-driver helpers that select the correct CMA function. In SHMEM helpers we have the flag map_wc in the GEM structure that selects the pages caching mode (wc vs uncached). I think CMA should Re-reading this, it should rather be WC and cached. use this design as well. Have a map_noncoherent flag in the CMA GEM object and set it from the driver's implementation of gem_create_object. Is that a new addition? That severely reduces the patchset size, which is perfect. It was added a few months ago, around the time you send the first version of the patches at hand. Originally, SHMEM uses write combining by default. And several drivers used default mapping flags instead (so usually cached). IIRC I streamlined everything and flipped the default. Most drivers can use cached mappings and only some require WC. Recently there was also a patchset that added support for cached video RAM (or something like that). So at some point we could store these flags in drm_gem_object. For now, I'd just put a flag into drm_gem_cma_object. I'll send a V3 then. Great! Best regards Thomas Cheers, -Paul And in the long run, we could try to consolidate all drivers/helpers mapping flags in struct drm_gem_object. Best regards Thomas Am 07.03.21 um 21:28 schrieb Paul Cercueil: Rework of my previous patchset which added support for GEM buffers backed by non-coherent memory to the ingenic-drm driver. Having GEM buffers backed by non-coherent memory is interesting in the particular case where it is faster to render to a non-coherent buffer then sync the data cache, than to render to a write-combine buffer, and (by extension) much faster than using a shadow buffer. This is true for instance on some Ingenic SoCs, where even simple blits (e.g. memcpy) are about three times faster using this method. For the record, the previous patchset was accepted for 5.10 then had to be reverted, as it conflicted with some changes made to the DMA API. This new patchset is pretty different as it adds the functionality to the DRM core. The first three patches add variants to existing functions but with the "non-coherent memory" twist, exported as GPL symbols. The fourth patch adds a function to be used with the damage helpers. Finally, the last patch adds support for non-coherent GEM buffers to the ingenic-drm driver. The functionality is enabled through a module parameter, and is disabled by default. Cheers, -Paul Paul Cercueil (5): drm: Add and export function drm_gem_cma_create_noncoherent drm: Add and export function drm_gem_cma_dumb_create_noncoherent drm: Add and export function drm_gem_cma_mmap_noncoherent drm: Add and export function drm_gem_cma_sync_data drm/ingenic: Add option to alloc cached GEM buffers drivers/gpu/drm/drm_gem_cma_helper.c | 223 +++--- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 49 - drivers/gpu/drm/ingenic/ingenic-drm.h | 4 + drivers/gpu/drm/ingenic/ingenic-ipu.c | 14 +- include/drm/drm_gem_cma_helper.h | 13 ++ 5 files changed, 273 insertions(+), 30 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 0/5] Add option to mmap GEM buffers cached
Hi Paul, having individual functions for each mode only makes sense if the decision is at compile time. But in patch 5, you're working around your earlier design by introducing in-driver helpers that select the correct CMA function. In SHMEM helpers we have the flag map_wc in the GEM structure that selects the pages caching mode (wc vs uncached). I think CMA should use this design as well. Have a map_noncoherent flag in the CMA GEM object and set it from the driver's implementation of gem_create_object. And in the long run, we could try to consolidate all drivers/helpers mapping flags in struct drm_gem_object. Best regards Thomas Am 07.03.21 um 21:28 schrieb Paul Cercueil: Rework of my previous patchset which added support for GEM buffers backed by non-coherent memory to the ingenic-drm driver. Having GEM buffers backed by non-coherent memory is interesting in the particular case where it is faster to render to a non-coherent buffer then sync the data cache, than to render to a write-combine buffer, and (by extension) much faster than using a shadow buffer. This is true for instance on some Ingenic SoCs, where even simple blits (e.g. memcpy) are about three times faster using this method. For the record, the previous patchset was accepted for 5.10 then had to be reverted, as it conflicted with some changes made to the DMA API. This new patchset is pretty different as it adds the functionality to the DRM core. The first three patches add variants to existing functions but with the "non-coherent memory" twist, exported as GPL symbols. The fourth patch adds a function to be used with the damage helpers. Finally, the last patch adds support for non-coherent GEM buffers to the ingenic-drm driver. The functionality is enabled through a module parameter, and is disabled by default. Cheers, -Paul Paul Cercueil (5): drm: Add and export function drm_gem_cma_create_noncoherent drm: Add and export function drm_gem_cma_dumb_create_noncoherent drm: Add and export function drm_gem_cma_mmap_noncoherent drm: Add and export function drm_gem_cma_sync_data drm/ingenic: Add option to alloc cached GEM buffers drivers/gpu/drm/drm_gem_cma_helper.c | 223 +++--- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 49 - drivers/gpu/drm/ingenic/ingenic-drm.h | 4 + drivers/gpu/drm/ingenic/ingenic-ipu.c | 14 +- include/drm/drm_gem_cma_helper.h | 13 ++ 5 files changed, 273 insertions(+), 30 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/stm: ltdc: Use simple encoder
Hi, shall I merge this patch? Am 02.03.21 um 18:57 schrieb Jagan Teki: STM ltdc driver uses an empty implementation for its encoder. Replace the code with the generic simple encoder. Signed-off-by: Jagan Teki --- drivers/gpu/drm/stm/ltdc.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 7812094f93d6..aeeb43524ca0 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -1020,14 +1021,6 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) return ret; } -/* - * DRM_ENCODER - */ - -static const struct drm_encoder_funcs ltdc_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - static void ltdc_encoder_disable(struct drm_encoder *encoder) { struct drm_device *ddev = encoder->dev; @@ -1088,8 +1081,7 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge) encoder->possible_crtcs = CRTC_MASK; encoder->possible_clones = 0;/* No cloning support */ - drm_encoder_init(ddev, encoder, _encoder_funcs, -DRM_MODE_ENCODER_DPI, NULL); + drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI); drm_encoder_helper_add(encoder, _encoder_helper_funcs); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: drm/ttm: ttm_bo_release called without lock
186.091417] hardirqs last enabled at (619761): [] console_unlock+0x45b/0x570 [ 186.091421] hardirqs last disabled at (619766): [] vprintk_emit+0x23c/0x2c0 [ 186.091423] softirqs last enabled at (617742): [] __do_softirq+0x30f/0x432 [ 186.091425] softirqs last disabled at (617737): [] irq_exit_rcu+0xea/0xf0 [ 186.091427] ---[ end trace ac74376b06d2036c ]--- Tke kernel is based on Linus' tree and the last commit f69d02e37a85645aa90d1 ("Merge tag 'misc-5.12-2021-03-02' of git://git.kernel.dk/linux-block"). Best Regards, Petr ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/stm: ltdc: Use simple encoder
Am 02.03.21 um 18:57 schrieb Jagan Teki: STM ltdc driver uses an empty implementation for its encoder. Replace the code with the generic simple encoder. Signed-off-by: Jagan Teki Acked-by: Thomas Zimmermann --- drivers/gpu/drm/stm/ltdc.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 7812094f93d6..aeeb43524ca0 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -1020,14 +1021,6 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) return ret; } -/* - * DRM_ENCODER - */ - -static const struct drm_encoder_funcs ltdc_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - static void ltdc_encoder_disable(struct drm_encoder *encoder) { struct drm_device *ddev = encoder->dev; @@ -1088,8 +1081,7 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge) encoder->possible_crtcs = CRTC_MASK; encoder->possible_clones = 0;/* No cloning support */ - drm_encoder_init(ddev, encoder, _encoder_funcs, -DRM_MODE_ENCODER_DPI, NULL); + drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI); drm_encoder_helper_add(encoder, _encoder_helper_funcs); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/fb-helper: only unmap if buffer not null
Hi Am 02.03.21 um 04:29 schrieb Tong Zhang: Hi Tomas, I think the issue could be possibly caused by the following, Please correct me if I'm wrong. drm_fb_helper_single_fb_probe() can fail with "Cannot find any crtc or sizes" which will cause fb_helper->funcs->fb_probe not being called, thus fb_helper->buffer remains NULL -- Since there could be the case that the fb_probe is never called, a subsequent modprobe -r will cause the following drm_client_buffer_vunmap(NULL) in drm_fbdev_cleanup() Thanks! I added Fixes tags to your patch and merged it into drm-misc-fixes. Best regards Thomas Best, - Tong On Mon, Mar 1, 2021 at 3:26 AM Thomas Zimmermann wrote: Hi Am 28.02.21 um 05:46 schrieb Tong Zhang: drm_fbdev_cleanup() can be called when fb_helper->buffer is null, hence fb_helper->buffer should be checked before calling drm_client_buffer_vunmap(). This buffer is also checked in drm_client_framebuffer_delete(), so we should also do the same thing for drm_client_buffer_vunmap(). I think a lot of drivers are affected by this problem; probably most of the ones that use the generic fbdev code. How did you produce the error? What I'm more concerned about is why the buffer is NULL. Was ther eno hotplug event? Do you have a display attached? Best regards Thomas [ 199.128742] RIP: 0010:drm_client_buffer_vunmap+0xd/0x20 [ 199.129031] Code: 43 18 48 8b 53 20 49 89 45 00 49 89 55 08 5b 44 89 e0 41 5c 41 5d 41 5e 5d c3 0f 1f 00 53 48 89 fb 48 8d 7f 10 e8 73 7d a1 ff <48> 8b 7b 10 48 8d 73 18 5b e9 75 53 fc ff 0 f 1f 44 00 00 48 b8 00 [ 199.130041] RSP: 0018:888103f3fc88 EFLAGS: 00010282 [ 199.130329] RAX: 0001 RBX: RCX: 8214d46d [ 199.130733] RDX: 1079c6b9 RSI: 0246 RDI: 83ce35c8 [ 199.131119] RBP: 888103d25458 R08: 0001 R09: fbfff0791761 [ 199.131505] R10: 83c8bb07 R11: fbfff0791760 R12: [ 199.131891] R13: 888103d25468 R14: 888103d25418 R15: 888103f18120 [ 199.132277] FS: 7f36fdcbb6a0() GS:88815b40() knlGS: [ 199.132721] CS: 0010 DS: ES: CR0: 80050033 [ 199.133033] CR2: 0010 CR3: 000103d26000 CR4: 06f0 [ 199.133420] DR0: DR1: DR2: [ 199.133807] DR3: DR6: fffe0ff0 DR7: 0400 [ 199.134195] Call Trace: [ 199.134333] drm_fbdev_cleanup+0x179/0x1a0 [ 199.134562] drm_fbdev_client_unregister+0x2b/0x40 [ 199.134828] drm_client_dev_unregister+0xa8/0x180 [ 199.135088] drm_dev_unregister+0x61/0x110 [ 199.135315] mgag200_pci_remove+0x38/0x52 [mgag200] [ 199.135586] pci_device_remove+0x62/0xe0 [ 199.135806] device_release_driver_internal+0x148/0x270 [ 199.136094] driver_detach+0x76/0xe0 [ 199.136294] bus_remove_driver+0x7e/0x100 [ 199.136521] pci_unregister_driver+0x28/0xf0 [ 199.136759] __x64_sys_delete_module+0x268/0x300 [ 199.137016] ? __ia32_sys_delete_module+0x300/0x300 [ 199.137285] ? call_rcu+0x3e4/0x580 [ 199.137481] ? fpregs_assert_state_consistent+0x4d/0x60 [ 199.137767] ? exit_to_user_mode_prepare+0x2f/0x130 [ 199.138037] do_syscall_64+0x33/0x40 [ 199.138237] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 199.138517] RIP: 0033:0x7f36fdc3dcf7 Signed-off-by: Tong Zhang --- drivers/gpu/drm/drm_fb_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index b9a616737c0e..f6baa2046124 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2048,7 +2048,7 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) if (shadow) vfree(shadow); - else + else if (fb_helper->buffer) drm_client_buffer_vunmap(fb_helper->buffer); drm_client_framebuffer_delete(fb_helper->buffer); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/fb-helper: only unmap if buffer not null
Hi Am 28.02.21 um 05:46 schrieb Tong Zhang: drm_fbdev_cleanup() can be called when fb_helper->buffer is null, hence fb_helper->buffer should be checked before calling drm_client_buffer_vunmap(). This buffer is also checked in drm_client_framebuffer_delete(), so we should also do the same thing for drm_client_buffer_vunmap(). I think a lot of drivers are affected by this problem; probably most of the ones that use the generic fbdev code. How did you produce the error? What I'm more concerned about is why the buffer is NULL. Was ther eno hotplug event? Do you have a display attached? Best regards Thomas [ 199.128742] RIP: 0010:drm_client_buffer_vunmap+0xd/0x20 [ 199.129031] Code: 43 18 48 8b 53 20 49 89 45 00 49 89 55 08 5b 44 89 e0 41 5c 41 5d 41 5e 5d c3 0f 1f 00 53 48 89 fb 48 8d 7f 10 e8 73 7d a1 ff <48> 8b 7b 10 48 8d 73 18 5b e9 75 53 fc ff 0 f 1f 44 00 00 48 b8 00 [ 199.130041] RSP: 0018:888103f3fc88 EFLAGS: 00010282 [ 199.130329] RAX: 0001 RBX: RCX: 8214d46d [ 199.130733] RDX: 1079c6b9 RSI: 0246 RDI: 83ce35c8 [ 199.131119] RBP: 888103d25458 R08: 0001 R09: fbfff0791761 [ 199.131505] R10: 83c8bb07 R11: fbfff0791760 R12: [ 199.131891] R13: 888103d25468 R14: 888103d25418 R15: 888103f18120 [ 199.132277] FS: 7f36fdcbb6a0() GS:88815b40() knlGS: [ 199.132721] CS: 0010 DS: ES: CR0: 80050033 [ 199.133033] CR2: 0010 CR3: 000103d26000 CR4: 06f0 [ 199.133420] DR0: DR1: DR2: [ 199.133807] DR3: DR6: fffe0ff0 DR7: 0400 [ 199.134195] Call Trace: [ 199.134333] drm_fbdev_cleanup+0x179/0x1a0 [ 199.134562] drm_fbdev_client_unregister+0x2b/0x40 [ 199.134828] drm_client_dev_unregister+0xa8/0x180 [ 199.135088] drm_dev_unregister+0x61/0x110 [ 199.135315] mgag200_pci_remove+0x38/0x52 [mgag200] [ 199.135586] pci_device_remove+0x62/0xe0 [ 199.135806] device_release_driver_internal+0x148/0x270 [ 199.136094] driver_detach+0x76/0xe0 [ 199.136294] bus_remove_driver+0x7e/0x100 [ 199.136521] pci_unregister_driver+0x28/0xf0 [ 199.136759] __x64_sys_delete_module+0x268/0x300 [ 199.137016] ? __ia32_sys_delete_module+0x300/0x300 [ 199.137285] ? call_rcu+0x3e4/0x580 [ 199.137481] ? fpregs_assert_state_consistent+0x4d/0x60 [ 199.137767] ? exit_to_user_mode_prepare+0x2f/0x130 [ 199.138037] do_syscall_64+0x33/0x40 [ 199.138237] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 199.138517] RIP: 0033:0x7f36fdc3dcf7 Signed-off-by: Tong Zhang --- drivers/gpu/drm/drm_fb_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index b9a616737c0e..f6baa2046124 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2048,7 +2048,7 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) if (shadow) vfree(shadow); - else + else if (fb_helper->buffer) drm_client_buffer_vunmap(fb_helper->buffer); drm_client_framebuffer_delete(fb_helper->buffer); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: udldrm does not recover from powersave? Re: udldrmfb: causes WARN in i915 on X60 (x86-32)
Hi Am 25.02.21 um 10:53 schrieb Pavel Machek: Hi! This is in -next, but I get same behaviour on 5.11; and no, udl does Thanks for reporting. We are in the process of fixing the issue. The latest patch is at [1]. Thank you, that fixes the DMA issue, and I can use the udl. ...for a while. Then screensaver blanks laptop screen, udl screen blanks too. Upon hitting a key, internal screen shows up, udl does not. I try rerunning xrandr ... --auto, but could not recover it. Any ideas? Seems unrelated. I tested for the issue with the last good revision and with the latest fix applied. I use Gnome/X11. With both kernels, the udl adapter's display came back after suspending. So I'd attribute the problem to something else. Best regards Thomas Best regards, Pavel ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: udldrm does not recover from powersave? Re: udldrmfb: causes WARN in i915 on X60 (x86-32)
Hi Am 25.02.21 um 10:53 schrieb Pavel Machek: Hi! This is in -next, but I get same behaviour on 5.11; and no, udl does Thanks for reporting. We are in the process of fixing the issue. The latest patch is at [1]. Thank you, that fixes the DMA issue, and I can use the udl. ...for a while. Then screensaver blanks laptop screen, udl screen blanks too. Upon hitting a key, internal screen shows up, udl does not. I try rerunning xrandr ... --auto, but could not recover it. Any ideas? Did it work before the regression? For testing, could you please remove the fix and then do git revert 6eb0233ec2d0 This would restore the old version. Please report back on the results. Best regards Thomas Best regards, Pavel ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: udldrmfb: causes WARN in i915 on X60 (x86-32)
Hi Am 24.02.21 um 21:09 schrieb Pavel Machek: Hi! This is in -next, but I get same behaviour on 5.11; and no, udl does Thanks for reporting. We are in the process of fixing the issue. The latest patch is at [1]. Best regards Thomas [1] https://lore.kernel.org/dri-devel/b44307cf-25f9-acd0-eb35-92e871620...@suse.de/T/#m74795744a58836dcba055fdcd6a0697811b8c14b not work, but monitor is detected: pavel@amd:~/g/tui/crashled$ xrandr Screen 0: minimum 320 x 200, current 1024 x 768, maximum 4096 x 4096 LVDS1 connected 1024x768+0+0 (normal left inverted right x axis y axis) 246mm x 185mm 1024x768 50.00*+ 60.0040.00 800x600 60.3256.25 640x480 59.94 VGA1 disconnected (normal left inverted right x axis y axis) DVI-1-0 connected 1024x768+0+0 304mm x 228mm 1024x768 60.00*+ 75.03 800x600 75.0060.32 640x480 75.0059.94 720x400 70.08 1024x768 (0x45) 65.000MHz -HSync -VSync h: width 1024 start 1048 end 1184 total 1344 skew0 clock 48.36KHz v: height 768 start 771 end 777 total 806 clock 60.00Hz 800x600 (0x47) 40.000MHz +HSync +VSync h: width 800 start 840 end 968 total 1056 skew0 clock 37.88KHz v: height 600 start 601 end 605 total 628 clock 60.32Hz 640x480 (0x49) 25.175MHz -HSync -VSync h: width 640 start 656 end 752 total 800 skew0 clock 31.47KHz v: height 480 start 490 end 492 total 525 clock 59.94Hz pavel@amd:~/g/tui/crashled$ [13957.499755] wlan0: associated [13962.906368] udl 1-5:1.0: [drm] fb1: udldrmfb frame buffer device [13972.585101] [ cut here ] [13972.585117] WARNING: CPU: 0 PID: 3159 at kernel/dma/mapping.c:192 dma_map_sg_attrs+0x38/0x50 [13972.585137] Modules linked in: [13972.585149] CPU: 0 PID: 3159 Comm: Xorg Not tainted 5.11.0-next-20210223+ #176 [13972.585158] Hardware name: LENOVO 17097HU/17097HU, BIOS 7BETD8WW (2.19 ) 03/31/2011 [13972.585166] EIP: dma_map_sg_attrs+0x38/0x50 [13972.585176] Code: f0 01 00 00 00 74 23 ff 75 0c 53 e8 72 1b 00 00 5a 59 85 c0 78 1c 8b 5d fc c9 c3 8d b4 26 00 00 00 00 0f 0b 8d b6 00 00 00 00 <0f> 0b 31 c0 eb e6 66 90 0f 0b 8d b4 26 00 00 00 00 8d b4 26 00 00 [13972.585186] EAX: c296c41c EBX: ECX: 0055 EDX: dbbc4800 [13972.585194] ESI: c69f9ea0 EDI: d2c313c0 EBP: c5cbdda8 ESP: c5cbdda4 [13972.585202] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00210246 [13972.585211] CR0: 80050033 CR2: b6b99000 CR3: 05d42000 CR4: 06b0 [13972.585219] Call Trace: [13972.585227] i915_gem_map_dma_buf+0xee/0x160 [13972.585240] dma_buf_map_attachment+0xb8/0x140 [13972.585251] drm_gem_prime_import_dev.part.0+0x33/0xc0 [13972.585262] ? drm_gem_shmem_create+0x10/0x10 [13972.585271] drm_gem_prime_import_dev+0x22/0x70 [13972.585280] drm_gem_prime_fd_to_handle+0x186/0x1c0 [13972.585289] ? drm_gem_prime_import_dev+0x70/0x70 [13972.585298] ? drm_prime_destroy_file_private+0x20/0x20 [13972.585307] drm_prime_fd_to_handle_ioctl+0x1c/0x30 [13972.585315] drm_ioctl_kernel+0x8e/0xe0 [13972.585325] ? drm_prime_destroy_file_private+0x20/0x20 [13972.585334] drm_ioctl+0x1fd/0x380 [13972.585343] ? drm_prime_destroy_file_private+0x20/0x20 [13972.585352] ? ksys_write+0x5c/0xd0 [13972.585363] ? vfs_write+0xeb/0x3f0 [13972.585371] ? drm_ioctl_kernel+0xe0/0xe0 [13972.585380] __ia32_sys_ioctl+0x369/0x7d0 [13972.585389] ? exit_to_user_mode_prepare+0x4e/0x170 [13972.585398] do_int80_syscall_32+0x2c/0x40 [13972.585409] entry_INT80_32+0x111/0x111 [13972.585419] EIP: 0xb7f68092 [13972.585427] Code: 00 00 00 e9 90 ff ff ff ff a3 24 00 00 00 68 30 00 00 00 e9 80 ff ff ff ff a3 e8 ff ff ff 66 90 00 00 00 00 00 00 00 00 cd 80 8d b4 26 00 00 00 00 8d b6 00 00 00 00 8b 1c 24 c3 8d b4 26 00 [13972.585436] EAX: ffda EBX: 0030 ECX: c00c642e EDX: bfaeda30 [13972.585444] ESI: 00915790 EDI: c00c642e EBP: 0030 ESP: bfaed9e4 [13972.585452] DS: 007b ES: 007b FS: GS: 0033 SS: 007b EFLAGS: 00200296 [13972.585461] ? asm_exc_nmi+0xcc/0x2bc [13972.585470] ---[ end trace 46a21fad0595bc89 ]--- pavel@amd:~/g/tui/crashled$ Any ideas? Best regards, Pavel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 01/11] drm/atomic: Pass the full state to planes async atomic check and update
Hi Maxime, for the whole series: Acked-by: Thomas Zimmermann Am 19.02.21 um 13:00 schrieb Maxime Ripard: The current atomic helpers have either their object state being passed as an argument or the full atomic state. The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed. Let's start convert all the remaining helpers to provide a consistent interface, starting with the planes atomic_async_check and atomic_async_update. The conversion was done using the coccinelle script below, built tested on all the drivers. @@ identifier plane, plane_state; symbol state; @@ struct drm_plane_helper_funcs { ... int (*atomic_async_check)(struct drm_plane *plane, - struct drm_plane_state *plane_state); + struct drm_atomic_state *state); ... } @@ identifier plane, plane_state; symbol state; @@ struct drm_plane_helper_funcs { ... void (*atomic_async_update)(struct drm_plane *plane, - struct drm_plane_state *plane_state); + struct drm_atomic_state *state); ... } @ plane_atomic_func @ identifier helpers; identifier func; @@ ( static const struct drm_plane_helper_funcs helpers = { ..., .atomic_async_check = func, ..., }; | static const struct drm_plane_helper_funcs helpers = { ..., .atomic_async_update = func, ..., }; ) @@ struct drm_plane_helper_funcs *FUNCS; identifier f; identifier dev; identifier plane, plane_state, state; @@ f(struct drm_device *dev, struct drm_atomic_state *state) { <+... - FUNCS->atomic_async_check(plane, plane_state) + FUNCS->atomic_async_check(plane, state) ...+> } @@ struct drm_plane_helper_funcs *FUNCS; identifier f; identifier dev; identifier plane, plane_state, state; @@ f(struct drm_device *dev, struct drm_atomic_state *state) { <+... - FUNCS->atomic_async_update(plane, plane_state) + FUNCS->atomic_async_update(plane, state) ...+> } @@ identifier mtk_plane_atomic_async_update; identifier plane; symbol new_state, state; expression e; @@ void mtk_plane_atomic_async_update(struct drm_plane *plane, struct drm_plane_state *new_state) { ... - struct mtk_plane_state *state = e; + struct mtk_plane_state *new_plane_state = e; <+... - state + new_plane_state ...+> } @@ identifier plane_atomic_func.func; identifier plane; symbol state; @@ func(struct drm_plane *plane, -struct drm_plane_state *state) +struct drm_plane_state *new_plane_state) { <... - state + new_plane_state ...> } @ ignores_new_state @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { ... when != new_plane_state } @ adds_new_state depends on plane_atomic_func && !ignores_new_state @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); ... } @ depends on plane_atomic_func @ identifier plane_atomic_func.func; identifier plane, plane_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *plane_state + struct drm_atomic_state *state ) { ... } @ include depends on adds_new_state @ @@ #include @ no_include depends on !include && adds_new_state @ @@ + #include #include @@ identifier plane_atomic_func.func; identifier plane, state; identifier plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); <+... - plane_state->state + state ...+> } Acked-by: Thomas Zimmermann Signed-off-by: Maxime Ripard --- Changes from v1: - Updated the comment according to Thomas suggestions --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++- drivers/gpu/drm/drm_atomic_helper.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 26 + drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c| 33 ++- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 16 -- drivers/gpu/drm/vc4/vc4_plane.c | 56 ++- include/drm/drm_modeset_helper_vtables.h | 18 +++--- 7 files changed, 89 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 6ed96633425f..63f839679a0a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgp
Re: [PATCH] drm/ast: fix memory leak when unload the driver
Am 22.02.21 um 03:33 schrieb Tong Zhang: a connector is leaked upon module unload, it seems that we should do similar to sample driver as suggested in drm_drv.c. Adding drm_atomic_helper_shutdown() in ast_pci_remove to prevent leaking. [ 153.822134] WARNING: CPU: 0 PID: 173 at drivers/gpu/drm/drm_mode_config.c:504 drm_mode_config_cle0 [ 153.822698] Modules linked in: ast(-) drm_vram_helper drm_ttm_helper ttm [last unloaded: ttm] [ 153.823197] CPU: 0 PID: 173 Comm: modprobe Tainted: GW 5.11.0-03615-g55f62bc873474 [ 153.823708] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda519-4 [ 153.824333] RIP: 0010:drm_mode_config_cleanup+0x418/0x470 [ 153.824637] Code: 0c 00 00 00 00 48 8b 84 24 a8 00 00 00 65 48 33 04 25 28 00 00 00 75 65 48 81 c0 [ 153.825668] RSP: 0018:888103c9fb70 EFLAGS: 00010212 [ 153.825962] RAX: 888102b0d100 RBX: 888102b0c298 RCX: 818d8b2b [ 153.826356] RDX: dc00 RSI: 7fff RDI: 888102b0c298 [ 153.826748] RBP: 888103c9fba0 R08: 0001 R09: ed1020561857 [ 153.827146] R10: 888102b0c2b7 R11: ed1020561856 R12: 888102b0c000 [ 153.827538] R13: 888102b0c2d8 R14: 888102b0c2d8 R15: 111020793f70 [ 153.827935] FS: 7f24bff456a0() GS:88815b40() knlGS: [ 153.828380] CS: 0010 DS: ES: CR0: 80050033 [ 153.828697] CR2: 01c39018 CR3: 000103c9 CR4: 06f0 [ 153.829096] DR0: DR1: DR2: [ 153.829486] DR3: DR6: fffe0ff0 DR7: 0400 [ 153.829883] Call Trace: [ 153.830024] ? drmm_mode_config_init+0x930/0x930 [ 153.830281] ? cpumask_next+0x16/0x20 [ 153.830488] ? mnt_get_count+0x66/0x80 [ 153.830699] ? drm_mode_config_cleanup+0x470/0x470 [ 153.830972] drm_managed_release+0xed/0x1c0 [ 153.831208] drm_dev_release+0x3a/0x50 [ 153.831420] release_nodes+0x39e/0x410 [ 153.831631] ? devres_release+0x40/0x40 [ 153.831852] device_release_driver_internal+0x158/0x270 [ 153.832143] driver_detach+0x76/0xe0 [ 153.832344] bus_remove_driver+0x7e/0x100 [ 153.832568] pci_unregister_driver+0x28/0xf0 [ 153.832821] __x64_sys_delete_module+0x268/0x300 [ 153.833086] ? __ia32_sys_delete_module+0x300/0x300 [ 153.833357] ? call_rcu+0x372/0x4f0 [ 153.833553] ? fpregs_assert_state_consistent+0x4d/0x60 [ 153.833840] ? exit_to_user_mode_prepare+0x2f/0x130 [ 153.834118] do_syscall_64+0x33/0x40 [ 153.834317] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 153.834597] RIP: 0033:0x7f24bfec7cf7 [ 153.834797] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d6 41 [ 153.835812] RSP: 002b:7fff72e6cb58 EFLAGS: 0202 ORIG_RAX: 00b0 [ 153.836234] RAX: ffda RBX: 7f24bff45690 RCX: 7f24bfec7cf7 [ 153.836623] RDX: RSI: 0080 RDI: 01c2fb10 [ 153.837018] RBP: 01c2fac0 R08: 2f2f2f2f2f2f2f2f R09: 01c2fac0 [ 153.837408] R10: fefefefefefefeff R11: 0202 R12: 01c2fac0 [ 153.837798] R13: 01c2f9d0 R14: R15: 0001 [ 153.838194] ---[ end trace b92031513bbe596c ]--- [ 153.838441] [drm:drm_mode_config_cleanup] *ERROR* connector VGA-1 leaked! Signed-off-by: Tong Zhang I've added the patch to drm-misc-next. Thanks a lot! Best regards Thomas --- drivers/gpu/drm/ast/ast_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 667b450606ef..b047c0ea43e8 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -138,6 +139,7 @@ static void ast_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); drm_dev_unregister(dev); + drm_atomic_helper_shutdown(dev); } static int ast_drm_freeze(struct drm_device *dev) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 06/11] drm: Use state helper instead of plane state pointer in atomic_check
Am 19.02.21 um 13:00 schrieb Maxime Ripard: Many drivers reference the plane->state pointer in order to get the current plane state in their atomic_check hook, which would be the old plane state in the global atomic state since _swap_state hasn't happened when atomic_check is run. Use the drm_atomic_get_old_plane_state helper to get that state to make it more obvious. This was made using the coccinelle script below: @ plane_atomic_func @ identifier helpers; identifier func; @@ static struct drm_plane_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @ replaces_old_state @ identifier plane_atomic_func.func; identifier plane, state, plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... - struct drm_plane_state *plane_state = plane->state; + struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane); ... } @@ identifier plane_atomic_func.func; identifier plane, state, plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane); <... - plane->state + plane_state ...> } @ adds_old_state @ identifier plane_atomic_func.func; identifier plane, state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); <... - plane->state + old_plane_state ...> } @ include depends on adds_old_state || replaces_old_state @ @@ #include @ no_include depends on !include && (adds_old_state || replaces_old_state) @ @@ + #include #include Reviewed-by: Ville Syrjälä Signed-off-by: Maxime Ripard Acked-by: Thomas Zimmermann However, I find 'old plane state' somewhat confusing in this context, because it's actually the current plane state. Would it make sense to use drm_atomic_get_existing_plane_state() instead? Best regards Thomas --- Changes from v2: - s/.../<.../ in the coccinelle script as suggested by Ville --- drivers/gpu/drm/imx/ipuv3-plane.c | 3 ++- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 16 +--- drivers/gpu/drm/ingenic/ingenic-ipu.c | 8 +--- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 4 +++- drivers/gpu/drm/tilcdc/tilcdc_plane.c | 3 ++- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index b5f6123850bb..6484592e3f86 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -341,7 +341,8 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, { struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane); - struct drm_plane_state *old_state = plane->state; + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); struct drm_crtc_state *crtc_state; struct device *dev = plane->dev->dev; struct drm_framebuffer *fb = new_state->fb; diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index e6d7d0a04ddb..c022d9f1e737 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -361,11 +361,13 @@ static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc, static int ingenic_drm_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, + plane); struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); struct ingenic_drm *priv = drm_device_get_priv(plane->dev); struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc = new_plane_state->crtc ?: plane->state->crtc; + struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc; int ret; if (!crtc) @@ -399,12 +401,12 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane *plane, * its position, size or depth. */ if (priv->soc_info->has_osd && - (!plane->state->fb || !new_plane_state->fb || -plane->state->crtc_x != new_plane_state->crtc_x || -plane->state->crtc_y != new_plane_state->crtc_y || -plane->state->crtc_w != new_plane_state->crtc
Re: [PATCH v3 05/11] drm: Use the state pointer directly in planes atomic_check
Am 19.02.21 um 13:00 schrieb Maxime Ripard: Now that atomic_check takes the global atomic state as a parameter, we don't need to go through the pointer in the plane state. This was done using the following coccinelle script: @ plane_atomic_func @ identifier helpers; identifier func; @@ static struct drm_plane_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @@ identifier plane_atomic_func.func; identifier plane, state; identifier plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... - struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); <... when != plane_state - plane_state->state + state ...> } @@ identifier plane_atomic_func.func; identifier plane, state; identifier plane_state; @@ func(struct drm_plane *plane, struct drm_atomic_state *state) { ... struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); <... - plane_state->state + state ...> } Reviewed-by: Laurent Pinchart Signed-off-by: Maxime Ripard Acked-by: Thomas Zimmermann --- Changes from v1: - Fixed the formatting in zynqmp_disp --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 2 +- drivers/gpu/drm/arm/hdlcd_crtc.c | 2 +- drivers/gpu/drm/armada/armada_plane.c | 4 ++-- drivers/gpu/drm/ast/ast_mode.c| 4 ++-- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +- drivers/gpu/drm/drm_simple_kms_helper.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c| 2 +- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/imx/dcss/dcss-plane.c | 2 +- drivers/gpu/drm/imx/ipuv3-plane.c | 2 +- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 2 +- drivers/gpu/drm/ingenic/ingenic-ipu.c | 2 +- drivers/gpu/drm/kmb/kmb_plane.c | 2 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 +- drivers/gpu/drm/meson/meson_overlay.c | 2 +- drivers/gpu/drm/meson/meson_plane.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c| 2 +- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 2 +- drivers/gpu/drm/omapdrm/omap_plane.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- drivers/gpu/drm/sti/sti_cursor.c | 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun8i_ui_layer.c| 2 +- drivers/gpu/drm/sun4i/sun8i_vi_layer.c| 2 +- drivers/gpu/drm/tidss/tidss_plane.c | 2 +- drivers/gpu/drm/tilcdc/tilcdc_plane.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 8 drivers/gpu/drm/virtio/virtgpu_plane.c| 2 +- drivers/gpu/drm/vkms/vkms_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/gpu/drm/xlnx/zynqmp_disp.c| 3 +-- drivers/gpu/drm/zte/zx_plane.c| 4 ++-- 35 files changed, 41 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 1cdff048b0c0..22124f76d0b5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6451,7 +6451,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane, return 0; new_crtc_state = - drm_atomic_get_new_crtc_state(new_plane_state->state, + drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); if (!new_crtc_state) return -EINVAL; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index 96a6fe95a4e7..13582c174bbb 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -84,7 +84,7 @@ komeda_plane_atomic_check(struct drm_plane *plane, if (!new_plane_state->crtc || !new_plane_state->fb) return 0; - crtc_st = drm_atomic_get_crtc_state(new_plane_state->state, + crtc_st = drm_atomic_get_crtc_state(state, new_plane_state->crtc); if (IS_ERR(crtc_st) || !crtc_st->enable) { DRM_DEBUG_ATOMIC("Cannot update plane on a disabled CRTC.\n"); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 9da9d0581ce9..028ec39c8484 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -244,7 +244,7 @@ static int
Re: [PATCH v3 02/11] drm: Rename plane atomic_check state names
Am 19.02.21 um 16:12 schrieb Maxime Ripard: Hi Thomas, Thanks for your review! On Fri, Feb 19, 2021 at 03:49:22PM +0100, Thomas Zimmermann wrote: diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 075508051b5f..1873a155bb26 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -337,12 +337,12 @@ static const struct drm_plane_funcs ipu_plane_funcs = { }; static int ipu_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_plane_state *new_state) This function uses a different naming convention then the others? { struct drm_plane_state *old_state = plane->state; So, the function already had a variable named old_state, so I was actually trying to make the drivers consistent here: having one variable with old_state and new_plane_state felt weird. The heuristic is thus to use the convention of the driver if one exists already, and if there's none pick new_plane_state. It makes it indeed inconsistent across drivers, but it felt more natural to be consistent within a single driver. Makes sense. Maxime -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 04/11] drm/atomic: Pass the full state to planes atomic_check
Am 19.02.21 um 13:00 schrieb Maxime Ripard: The current atomic helpers have either their object state being passed as an argument or the full atomic state. The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed. Let's convert all the remaining helpers to provide a consistent interface, starting with the planes atomic_check. The conversion was done using the coccinelle script below plus some manual changes for vmwgfx, built tested on all the drivers. @@ identifier plane, plane_state; symbol state; @@ struct drm_plane_helper_funcs { ... int (*atomic_check)(struct drm_plane *plane, - struct drm_plane_state *plane_state); + struct drm_atomic_state *state); ... } @ plane_atomic_func @ identifier helpers; identifier func; @@ static const struct drm_plane_helper_funcs helpers = { ..., .atomic_check = func, ..., }; @@ struct drm_plane_helper_funcs *FUNCS; identifier f; identifier dev; identifier plane, plane_state, state; @@ f(struct drm_device *dev, struct drm_atomic_state *state) { <+... - FUNCS->atomic_check(plane, plane_state) + FUNCS->atomic_check(plane, state) ...+> } @ ignores_new_state @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { ... when != new_plane_state } @ adds_new_state depends on plane_atomic_func && !ignores_new_state @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); ... } @ depends on plane_atomic_func @ identifier plane_atomic_func.func; identifier plane, new_plane_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *new_plane_state + struct drm_atomic_state *state ) { ... } @ include depends on adds_new_state @ @@ #include @ no_include depends on !include && adds_new_state @ @@ + #include #include Reviewed-by: Laurent Pinchart Signed-off-by: Maxime Ripard Acked-by: Thomas Zimmermann --- Changes from v1: - Rewording and removal of a coccinelle rule suggested by Laurent --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 4 +++- drivers/gpu/drm/arm/hdlcd_crtc.c | 4 +++- drivers/gpu/drm/arm/malidp_planes.c | 4 +++- drivers/gpu/drm/armada/armada_plane.c | 4 +++- drivers/gpu/drm/armada/armada_plane.h | 2 +- drivers/gpu/drm/ast/ast_mode.c| 8 ++-- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 ++- drivers/gpu/drm/drm_atomic_helper.c | 2 +- drivers/gpu/drm/drm_simple_kms_helper.c | 4 +++- drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 +++- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 5 - drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c| 4 +++- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 4 +++- drivers/gpu/drm/imx/dcss/dcss-plane.c | 4 +++- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +++- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 +++- drivers/gpu/drm/ingenic/ingenic-ipu.c | 4 +++- drivers/gpu/drm/kmb/kmb_plane.c | 4 +++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 4 +++- drivers/gpu/drm/meson/meson_overlay.c | 4 +++- drivers/gpu/drm/meson/meson_plane.c | 4 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 - drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c| 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c| 4 +++- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 4 +++- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 5 - drivers/gpu/drm/omapdrm/omap_plane.c | 4 +++- drivers/gpu/drm/qxl/qxl_display.c | 4 +++- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +++- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 5 - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +++- drivers/gpu/drm/sti/sti_cursor.c | 4 +++- drivers/gpu/drm/sti/sti_gdp.c | 4 +++- drivers/gpu/drm/sti/sti_hqvdp.c | 4 +++- drivers/gpu/drm/stm/ltdc.c| 4 +++- drivers/gpu/drm/sun4i/sun8i_ui_layer.c| 4 +++- drivers/gpu/drm/sun4i/sun8i_vi_layer.c| 4 +++- drivers/gpu/drm/tegra/dc.c| 8 ++-- drivers/gpu/drm/tegra/hub.c | 4 +++- drivers/gpu/drm/tidss/tidss_plane.c | 4 +++- drivers/gpu/drm/tilcdc/tilcdc_plane.c
Re: [PATCH] efifb: Ensure graphics device for efifb stays at PCI D0
Hi Am 22.02.21 um 08:08 schrieb Kai-Heng Feng: On Mon, Feb 1, 2021 at 11:21 PM Alex Deucher wrote: On Sat, Jan 30, 2021 at 6:27 AM Kai-Heng Feng wrote: We are seeing root ports on some desktop boards support D3cold for discrete graphics card. So when efifb is in use while graphics device isn't bound to a driver, PCI and ACPI will put the graphics to D3cold when runtime suspend kicks in, makes efifb stop working. So ensure the graphics device won't be runtime suspended, to keep efifb work all the time. Signed-off-by: Kai-Heng Feng Reviewed-by: Alex Deucher A gentle ping... Thanks for your patch. I've added it to drm-misc-next. Best regards Thomas --- drivers/video/fbdev/efifb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index e57c00824965..19edd7206409 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include /* For drm_get_panel_orientation_quirk */ @@ -575,6 +576,7 @@ static int efifb_probe(struct platform_device *dev) goto err_fb_dealoc; } fb_info(info, "%s frame buffer device\n", info->fix.id); + pm_runtime_get_sync(_pci_dev->dev); return 0; err_fb_dealoc: @@ -601,6 +603,7 @@ static int efifb_remove(struct platform_device *pdev) unregister_framebuffer(info); sysfs_remove_groups(>dev.kobj, efifb_groups); framebuffer_release(info); + pm_runtime_put(_pci_dev->dev); return 0; } -- 2.29.2 ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 02/11] drm: Rename plane atomic_check state names
Am 19.02.21 um 13:00 schrieb Maxime Ripard: Most drivers call the argument to the plane atomic_check hook simply state, which is going to conflict with the global atomic state in a later rework. Let's rename it to new_plane_state (or new_state depending on the convention used in the driver). This was done using the coccinelle script below, and built tested: @ plane_atomic_func @ identifier helpers; identifier func; @@ static const struct drm_plane_helper_funcs helpers = { .atomic_check = func, }; @ has_old_state @ identifier plane_atomic_func.func; identifier plane; expression e; symbol old_state; symbol state; @@ func(struct drm_plane *plane, struct drm_plane_state *state) { ... struct drm_plane_state *old_state = e; ... } @ depends on has_old_state @ identifier plane_atomic_func.func; identifier plane; symbol old_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *state + struct drm_plane_state *new_state ) { <+... - state + new_state ...+> } @ has_state @ identifier plane_atomic_func.func; identifier plane; symbol state; @@ func(struct drm_plane *plane, struct drm_plane_state *state) { ... } @ depends on has_state @ identifier plane_atomic_func.func; identifier plane; symbol old_state; @@ func(struct drm_plane *plane, - struct drm_plane_state *state + struct drm_plane_state *new_plane_state ) { <+... - state + new_plane_state ...+> } Reviewed-by: Laurent Pinchart Signed-off-by: Maxime Ripard --- Changes from v1: - Updated the variable name in the comment in omapdrm --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 +++--- .../gpu/drm/arm/display/komeda/komeda_plane.c | 11 ++--- drivers/gpu/drm/arm/hdlcd_crtc.c | 18 drivers/gpu/drm/arm/malidp_planes.c | 36 drivers/gpu/drm/armada/armada_plane.c | 41 ++- drivers/gpu/drm/ast/ast_mode.c| 26 ++-- drivers/gpu/drm/exynos/exynos_drm_plane.c | 6 +-- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 6 +-- .../gpu/drm/hisilicon/hibmc/hibmc_drm_de.c| 22 +- .../gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 24 +-- drivers/gpu/drm/imx/dcss/dcss-plane.c | 26 ++-- drivers/gpu/drm/imx/ipuv3-plane.c | 31 +++--- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 27 ++-- drivers/gpu/drm/ingenic/ingenic-ipu.c | 30 +++--- drivers/gpu/drm/kmb/kmb_plane.c | 22 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 16 drivers/gpu/drm/meson/meson_overlay.c | 10 +++-- drivers/gpu/drm/meson/meson_plane.c | 10 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 35 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c| 9 ++-- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 5 ++- drivers/gpu/drm/omapdrm/omap_plane.c | 21 +- drivers/gpu/drm/qxl/qxl_display.c | 6 +-- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 7 ++-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 7 ++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 27 ++-- drivers/gpu/drm/sti/sti_cursor.c | 22 +- drivers/gpu/drm/sti/sti_gdp.c | 26 ++-- drivers/gpu/drm/sti/sti_hqvdp.c | 24 +-- drivers/gpu/drm/stm/ltdc.c| 10 ++--- drivers/gpu/drm/sun4i/sun8i_ui_layer.c| 10 +++-- drivers/gpu/drm/sun4i/sun8i_vi_layer.c| 10 +++-- drivers/gpu/drm/tegra/dc.c| 38 - drivers/gpu/drm/tegra/hub.c | 18 drivers/gpu/drm/tidss/tidss_plane.c | 34 --- drivers/gpu/drm/tilcdc/tilcdc_plane.c | 24 +-- drivers/gpu/drm/vc4/vc4_plane.c | 10 ++--- drivers/gpu/drm/virtio/virtgpu_plane.c| 9 ++-- drivers/gpu/drm/vkms/vkms_plane.c | 11 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 13 +++--- drivers/gpu/drm/xlnx/zynqmp_disp.c| 10 +++-- 41 files changed, 403 insertions(+), 358 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 63f839679a0a..906fa4ae25c9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6432,7 +6432,7 @@ static int dm_plane_helper_check_state(struct drm_plane_state *state, } static int dm_plane_atomic_check(struct drm_plane *plane, -struct drm_plane_state *state) +struct drm_plane_state *new_plane_state) { struct amdgpu_device *adev = drm_to_adev(plane->dev); struct dc *dc = adev->dm.dc; @@
Re: Regression: 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB devices")
Hi Am 18.02.21 um 16:07 schrieb Christoph Hellwig: On Thu, Feb 18, 2021 at 03:56:00PM +0100, Thomas Zimmermann wrote: I only have udl devices, but I expect that other DRM USB adapters are also affected. Find where the driver calls dma_map_* itself instead of using the USB wrappers and fix that.. Sure, it's at [1]. For udl, the dmabuf would need to be in system memory. The driver creates urbs from the framebuffer content and sends them to the device for displaying. My question is more: what's the best interface to do this? Is there example code somewhere? Best regards Thomas [1] https://elixir.bootlin.com/linux/v5.11/source/drivers/gpu/drm/drm_prime.c#L630 -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Regression: 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB devices")
Hi, commit 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB devices") creates a regression with the udl driver. udl is a DRM driver for USB-based DisplayLink adapters. It's no long possible to join/mirror displays in X. STR and an error log is shown below. STR: * use internal GFX card (radeon, i915) * attach udl adapter * start Gnome/x11 via startx * try to configure joined/mirrored screens Expected Result: * both adapters show the Gnome desktop Actual result: * the udl-driven display remains dark * error in the dmesg log I only have udl devices, but I expect that other DRM USB adapters are also affected. How to fix this? Best regards Thomas [ 60.050199] [ cut here ] [ 60.055092] WARNING: CPU: 0 PID: 1403 at kernel/dma/mapping.c:190 dma_map_sg_attrs+0x8f/0xc0 [ 60.064331] Modules linked in: af_packet(E) rfkill(E) dmi_sysfs(E) intel_rapl_msr(E) intel_rapl_common(E) snd_hda_codec_realtek(E) snd_hda_codec_generic(E) ledtrig_audio(E) snd_hda_codec_hdmi(E) x86_pkg_temp_thermal(E) intel_powerclam) [ 60.064801] wmi(E) video(E) btrfs(E) blake2b_generic(E) libcrc32c(E) crc32c_intel(E) xor(E) raid6_pq(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) msr(E) efivarfs(E) [ 60.170778] CPU: 0 PID: 1403 Comm: Xorg.bin Tainted: GE 5.11.0-rc5-1-default+ #747 [ 60.179841] Hardware name: Dell Inc. OptiPlex 9020/0N4YC8, BIOS A24 10/24/2018 [ 60.187145] RIP: 0010:dma_map_sg_attrs+0x8f/0xc0 [ 60.191822] Code: 4d 85 ff 75 2b 49 89 d8 44 89 e1 44 89 f2 4c 89 ee 48 89 ef e8 62 30 00 00 85 c0 78 36 5b 5d 41 5c 41 5d 41 5e 41 5f c3 0f 0b <0f> 0b 31 c0 eb ed 49 8d 7f 50 e8 72 f5 2a 00 49 8b 47 50 49 89 d8 [ 60.210770] RSP: 0018:c90001d6fc18 EFLAGS: 00010246 [ 60.216062] RAX: RBX: 0020 RCX: b31e677b [ 60.223274] RDX: dc00 RSI: 888212c10600 RDI: 8881b08a9488 [ 60.230501] RBP: 8881b08a9030 R08: 0020 R09: 888212c10600 [ 60.237710] R10: ed10425820df R11: 0001 R12: [ 60.244939] R13: 888212c10600 R14: 0008 R15: [ 60.252155] FS: 7f08ac2b2f00() GS:8887cbe0() knlGS: [ 60.260333] CS: 0010 DS: ES: CR0: 80050033 [ 60.266150] CR2: 55831c899be8 CR3: 00015372e006 CR4: 001706f0 [ 60.273369] Call Trace: [ 60.275845] drm_gem_map_dma_buf+0xb4/0x120 [ 60.280089] dma_buf_map_attachment+0x15d/0x1e0 [ 60.284688] drm_gem_prime_import_dev.part.0+0x5d/0x140 [ 60.289984] drm_gem_prime_fd_to_handle+0x213/0x280 [ 60.294931] ? drm_prime_destroy_file_private+0x30/0x30 [ 60.300224] drm_ioctl_kernel+0x131/0x180 [ 60.304291] ? drm_setversion+0x230/0x230 [ 60.308366] ? drm_prime_destroy_file_private+0x30/0x30 [ 60.313659] drm_ioctl+0x2f1/0x500 [ 60.317118] ? drm_version+0x150/0x150 [ 60.320903] ? lock_downgrade+0xa0/0xa0 [ 60.324806] ? do_vfs_ioctl+0x5f4/0x680 [ 60.328694] ? __fget_files+0x13e/0x210 [ 60.332591] ? ioctl_fiemap.isra.0+0x1a0/0x1a0 [ 60.337102] ? __fget_files+0x15d/0x210 [ 60.340990] __x64_sys_ioctl+0xb9/0xf0 [ 60.344795] do_syscall_64+0x33/0x80 [ 60.348427] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 60.353542] RIP: 0033:0x7f08ac7b53cb [ 60.357168] Code: 89 d8 49 8d 3c 1c 48 f7 d8 49 39 c4 72 b5 e8 1c ff ff ff 85 c0 78 ba 4c 89 e0 5b 5d 41 5c c3 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 75 ba 0c 00 f7 d8 64 89 01 48 [ 60.376108] RSP: 002b:7ffeabc89fc8 EFLAGS: 0246 ORIG_RAX: 0010 [ 60.383758] RAX: ffda RBX: 7ffeabc8a00c RCX: 7f08ac7b53cb [ 60.390970] RDX: 7ffeabc8a00c RSI: c00c642e RDI: 000d [ 60.398221] RBP: c00c642e R08: 55831c691d00 R09: 55831b2ec010 [ 60.405446] R10: 7f08acf6ada0 R11: 0246 R12: 55831c691d00 [ 60.412667] R13: 000d R14: 007e9000 R15: [ 60.419903] irq event stamp: 672893 [ 60.423441] hardirqs last enabled at (672913): [] console_unlock+0x44d/0x500 [ 60.432230] hardirqs last disabled at (672922): [] console_unlock+0x443/0x500 [ 60.441021] softirqs last enabled at (672940): [] __do_softirq+0x3dd/0x554 [ 60.449634] softirqs last disabled at (672931): [] asm_call_irq_on_stack+0x12/0x20 [ 60.458871] ---[ end trace f2f88696eb17806c ]--- -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 08/11] drm/qxl: fix monitors object vmap
Am 17.02.21 um 13:32 schrieb Gerd Hoffmann: Use the correct vmap variant. We don't hold a reservation here, so we can't use the _locked variant. We can drop the pin because qxl_bo_vmap will do that for us. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann I simply forgot to ack this patch. --- drivers/gpu/drm/qxl/qxl_display.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index bfcc93089a94..f106da917863 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1159,12 +1159,10 @@ int qxl_create_monitors_object(struct qxl_device *qdev) } qdev->monitors_config_bo = gem_to_qxl_bo(gobj); - ret = qxl_bo_pin(qdev->monitors_config_bo); + ret = qxl_bo_vmap(qdev->monitors_config_bo, ); if (ret) return ret; - qxl_bo_vmap_locked(qdev->monitors_config_bo, ); - qdev->monitors_config = qdev->monitors_config_bo->kptr; qdev->ram_header->monitors_config = qxl_bo_physical_address(qdev, qdev->monitors_config_bo, 0); @@ -1189,8 +1187,7 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) qdev->monitors_config = NULL; qdev->ram_header->monitors_config = 0; - qxl_bo_vunmap_locked(qdev->monitors_config_bo); - ret = qxl_bo_unpin(qdev->monitors_config_bo); + ret = qxl_bo_vunmap(qdev->monitors_config_bo); if (ret) return ret; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 10/11] drm/qxl: rework cursor plane
Hi Am 18.02.21 um 12:50 schrieb Gerd Hoffmann: Hi, I'm still trying to wrap my head around the qxl cursor code. Getting vmap out of the commit tail is good, but I feel like this isn't going in the right direction overall. In ast, these helper functions were only good when converting the drvier to atomic modesetting. So I removed them in the latst patchset and did all the updates in the plane helpers directly. I see the helper functions more as a way to get some structure into the code flow. The callbacks are easier to read if they just call helper functions for stuff which needs more than a handful lines of code (patch 9/11 exists for the same reason). The helpers also make it easier move work from one callback to another, but that is just a useful side-effect. I had considered making that two separate patches, one factor out code into functions and one moving the calls. Turned out to not be that easy though, because the old qxl_cursor_atomic_update() code was a rather hairy mix of qxl_create_cursor() + qxl_primary_apply_cursor() + qxl_primary_move_cursor(). For cursor_bo itself, it seems to be transitional state that is only used during the plane update and crtc update . It should probably be stored in a plane-state structure. Some of the primary plane's functions seem to deal with cursor handling. What's the role of the primary plane in cursor handling? It's a quirk. The qxl device will forget the cursor state on qxl_io_create_primary(), so I have to remember the cursor state and re-establish it by calling qxl_primary_apply_cursor() again. So I'm not sure sticking this into plane state would work. Because of the quirk this is more than just a handover from prepare to commit. For now, I suggest to merge patch 1 to 8 and 11; and move the cursor patches into a new patchset. I can merge 1-8, but 11 has to wait until the cursor is sorted. There is a reason why 11 is last in the series ;) I'd like ot hear Daniel's opinion on this. Do you have further plans here? Well. I suspect I could easily spend a month cleaning up and party redesign the qxl driver (specifically qxl_draw.c + qxl_image.c). I'm not sure I'll find the time to actually do that anytime soon. I have plenty of other stuff on my TODO list, and given that the world is transitioning to virtio-gpu the priority for qxl isn't that high. Well, in that case: Acked-by: Thomas Zimmermann for patches 9 and 10. Having the vmap calls fixed is at least worth it. Best regards Thomas So, no, I have no short-term plans for qxl beyond fixing pins + reservations + lockdep. take care, Gerd ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 10/11] drm/qxl: rework cursor plane
rsor_bo); - qxl_bo_vunmap_locked(user_bo); - - cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); - cmd->u.set.visible = 1; - cmd->u.set.shape = qxl_bo_physical_address(qdev, - cursor_bo, 0); - cmd->type = QXL_CURSOR_SET; - - old_cursor_bo = qcrtc->cursor_bo; - qcrtc->cursor_bo = cursor_bo; - cursor_bo = NULL; + qxl_primary_apply_cursor(qdev, plane->state); } else { - - ret = qxl_release_reserve_list(release, true); - if (ret) - goto out_free_release; - - cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); - cmd->type = QXL_CURSOR_MOVE; + qxl_primary_move_cursor(qdev, plane->state); } - - cmd->u.position.x = plane->state->crtc_x + fb->hot_x; - cmd->u.position.y = plane->state->crtc_y + fb->hot_y; - - qxl_release_unmap(qdev, release, >release_info); - qxl_release_fence_buffer_objects(release); - qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); - - if (old_cursor_bo != NULL) - qxl_bo_unpin(old_cursor_bo); - qxl_bo_unref(_cursor_bo); - qxl_bo_unref(_bo); - - return; - -out_backoff: - qxl_release_backoff_reserve_list(release); -out_unpin: - qxl_bo_unpin(cursor_bo); -out_free_bo: - qxl_bo_unref(_bo); -out_kunmap: - qxl_bo_vunmap_locked(user_bo); -out_free_release: - qxl_release_free(qdev, release); - return; - } static void qxl_cursor_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { struct qxl_device *qdev = to_qxl(plane->dev); + struct qxl_crtc *qcrtc; struct qxl_release *release; struct qxl_cursor_cmd *cmd; int ret; @@ -714,6 +717,10 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane, qxl_release_fence_buffer_objects(release); qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); + + qcrtc = to_qxl_crtc(old_state->crtc); + qxl_free_cursor(qcrtc->cursor_bo); + qcrtc->cursor_bo = NULL; } static void qxl_update_dumb_head(struct qxl_device *qdev, @@ -822,6 +829,17 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, qxl_prepare_shadow(qdev, user_bo, new_state->crtc->index); } + if (plane->type == DRM_PLANE_TYPE_CURSOR && + plane->state->fb != new_state->fb) { + struct qxl_crtc *qcrtc = to_qxl_crtc(new_state->crtc); + struct qxl_bo *old_cursor_bo = qcrtc->cursor_bo; + + qcrtc->cursor_bo = qxl_create_cursor(qdev, user_bo, + new_state->fb->hot_x, +new_state->fb->hot_y); + qxl_free_cursor(old_cursor_bo); + } + return qxl_bo_pin(user_bo); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 05/11] drm/qxl: rename qxl_bo_kmap -> qxl_bo_vmap_locked
Am 17.02.21 um 13:32 schrieb Gerd Hoffmann: Append _locked to Make clear that these functions should be called with reserved bo's only. While being at it also rename kmap -> vmap. No functional change. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_object.h | 4 ++-- drivers/gpu/drm/qxl/qxl_display.c | 14 +++--- drivers/gpu/drm/qxl/qxl_draw.c| 8 drivers/gpu/drm/qxl/qxl_image.c | 2 +- drivers/gpu/drm/qxl/qxl_object.c | 8 drivers/gpu/drm/qxl/qxl_prime.c | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index dc1659e717f1..2495e5cdf353 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -64,8 +64,8 @@ extern int qxl_bo_create(struct qxl_device *qdev, u32 priority, struct qxl_surface *surf, struct qxl_bo **bo_ptr); -extern int qxl_bo_kmap(struct qxl_bo *bo, struct dma_buf_map *map); -extern void qxl_bo_kunmap(struct qxl_bo *bo); +int qxl_bo_vmap_locked(struct qxl_bo *bo, struct dma_buf_map *map); +void qxl_bo_vunmap_locked(struct qxl_bo *bo); void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset); void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, void *map); extern struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index a1b5cc5918bc..bfcc93089a94 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -600,7 +600,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, user_bo = gem_to_qxl_bo(obj); /* pinning is done in the prepare/cleanup framevbuffer */ - ret = qxl_bo_kmap(user_bo, _map); + ret = qxl_bo_vmap_locked(user_bo, _map); if (ret) goto out_free_release; user_ptr = user_map.vaddr; /* TODO: Use mapping abstraction properly */ @@ -619,7 +619,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, if (ret) goto out_unpin; - ret = qxl_bo_kmap(cursor_bo, _map); + ret = qxl_bo_vmap_locked(cursor_bo, _map); if (ret) goto out_backoff; if (cursor_map.is_iomem) /* TODO: Use mapping abstraction properly */ @@ -638,8 +638,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, cursor->chunk.prev_chunk = 0; cursor->chunk.data_size = size; memcpy(cursor->chunk.data, user_ptr, size); - qxl_bo_kunmap(cursor_bo); - qxl_bo_kunmap(user_bo); + qxl_bo_vunmap_locked(cursor_bo); + qxl_bo_vunmap_locked(user_bo); cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); cmd->u.set.visible = 1; @@ -681,7 +681,7 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, out_free_bo: qxl_bo_unref(_bo); out_kunmap: - qxl_bo_kunmap(user_bo); + qxl_bo_vunmap_locked(user_bo); out_free_release: qxl_release_free(qdev, release); return; @@ -1163,7 +1163,7 @@ int qxl_create_monitors_object(struct qxl_device *qdev) if (ret) return ret; - qxl_bo_kmap(qdev->monitors_config_bo, ); + qxl_bo_vmap_locked(qdev->monitors_config_bo, ); qdev->monitors_config = qdev->monitors_config_bo->kptr; qdev->ram_header->monitors_config = @@ -1189,7 +1189,7 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) qdev->monitors_config = NULL; qdev->ram_header->monitors_config = 0; - qxl_bo_kunmap(qdev->monitors_config_bo); + qxl_bo_vunmap_locked(qdev->monitors_config_bo); ret = qxl_bo_unpin(qdev->monitors_config_bo); if (ret) return ret; diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c index 7b7acb910780..7d27891e87fa 100644 --- a/drivers/gpu/drm/qxl/qxl_draw.c +++ b/drivers/gpu/drm/qxl/qxl_draw.c @@ -48,7 +48,7 @@ static struct qxl_rect *drawable_set_clipping(struct qxl_device *qdev, struct qxl_clip_rects *dev_clips; int ret; - ret = qxl_bo_kmap(clips_bo, ); + ret = qxl_bo_vmap_locked(clips_bo, ); if (ret) return NULL; dev_clips = map.vaddr; /* TODO: Use mapping abstraction properly */ @@ -202,7 +202,7 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, if (ret) goto out_release_backoff; - ret = qxl_bo_kmap(bo, _map); + ret = qxl_bo_vmap_locked(bo, _map); if (ret) goto out_release_backoff; surface_base = surface_map.vaddr; /
Re: [PATCH v2 06/11] drm/qxl: add qxl_bo_vmap/qxl_bo_vunmap
Am 17.02.21 um 13:32 schrieb Gerd Hoffmann: Add vmap/vunmap variants which reserve (and pin) the bo. They can be used in case the caller doesn't hold a reservation for the bo. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_object.h | 2 ++ drivers/gpu/drm/qxl/qxl_object.c | 36 2 files changed, 38 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 2495e5cdf353..ee9c29de4d3d 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -64,7 +64,9 @@ extern int qxl_bo_create(struct qxl_device *qdev, u32 priority, struct qxl_surface *surf, struct qxl_bo **bo_ptr); +int qxl_bo_vmap(struct qxl_bo *bo, struct dma_buf_map *map); int qxl_bo_vmap_locked(struct qxl_bo *bo, struct dma_buf_map *map); +int qxl_bo_vunmap(struct qxl_bo *bo); void qxl_bo_vunmap_locked(struct qxl_bo *bo); void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset); void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, void *map); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index f4a015381a7f..82c3bf195ad6 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -29,6 +29,9 @@ #include "qxl_drv.h" #include "qxl_object.h" +static int __qxl_bo_pin(struct qxl_bo *bo); +static void __qxl_bo_unpin(struct qxl_bo *bo); + static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo) { struct qxl_bo *bo; @@ -179,6 +182,25 @@ int qxl_bo_vmap_locked(struct qxl_bo *bo, struct dma_buf_map *map) return 0; } +int qxl_bo_vmap(struct qxl_bo *bo, struct dma_buf_map *map) +{ + int r; + + r = qxl_bo_reserve(bo); + if (r) + return r; + + r = __qxl_bo_pin(bo); + if (r) { + qxl_bo_unreserve(bo); + return r; + } + + r = qxl_bo_vmap_locked(bo, map); + qxl_bo_unreserve(bo); + return r; +} + void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset) { @@ -223,6 +245,20 @@ void qxl_bo_vunmap_locked(struct qxl_bo *bo) ttm_bo_vunmap(>tbo, >map); } +int qxl_bo_vunmap(struct qxl_bo *bo) +{ + int r; + + r = qxl_bo_reserve(bo); + if (r) + return r; + + qxl_bo_vunmap_locked(bo); + __qxl_bo_unpin(bo); + qxl_bo_unreserve(bo); + return 0; +} + void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, void *pmap) { -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 04/11] drm/qxl: fix lockdep issue in qxl_alloc_release_reserved
Am 17.02.21 um 13:32 schrieb Gerd Hoffmann: Call qxl_bo_unpin (which does a reservation) without holding the release_mutex lock. Fixes lockdep (correctly) warning on a possible deadlock. Fixes: 65ffea3c6e73 ("drm/qxl: unpin release objects") Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_release.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 716d706ca7f0..f5845c96d414 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -283,7 +283,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, int type, struct qxl_release **release, struct qxl_bo **rbo) { - struct qxl_bo *bo; + struct qxl_bo *bo, *free_bo = NULL; int idr_ret; int ret = 0; union qxl_release_info *info; @@ -315,8 +315,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, mutex_lock(>release_mutex); if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { - qxl_bo_unpin(qdev->current_release_bo[cur_idx]); - qxl_bo_unref(>current_release_bo[cur_idx]); + free_bo = qdev->current_release_bo[cur_idx]; qdev->current_release_bo_offset[cur_idx] = 0; qdev->current_release_bo[cur_idx] = NULL; } @@ -324,6 +323,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, ret = qxl_release_bo_alloc(qdev, >current_release_bo[cur_idx], priority); if (ret) { mutex_unlock(>release_mutex); + if (free_bo) { + qxl_bo_unpin(free_bo); + qxl_bo_unref(_bo); + } qxl_release_free(qdev, *release); return ret; } @@ -339,6 +342,10 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, *rbo = bo; mutex_unlock(>release_mutex); + if (free_bo) { + qxl_bo_unpin(free_bo); + qxl_bo_unref(_bo); + } ret = qxl_release_list_add(*release, bo); qxl_bo_unref(); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2 03/11] drm/qxl: use ttm bo priorities
Am 17.02.21 um 13:32 schrieb Gerd Hoffmann: Allow to set priorities for buffer objects. Use priority 1 for surface and cursor command releases. Use priority 0 for drawing command releases. That way the short-living drawing commands are first in line when it comes to eviction, making it *much* less likely that ttm_bo_mem_force_space() picks something which can't be evicted and throws an error after waiting a while without success. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_object.h | 1 + drivers/gpu/drm/qxl/qxl_cmd.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 4 ++-- drivers/gpu/drm/qxl/qxl_gem.c | 2 +- drivers/gpu/drm/qxl/qxl_object.c | 5 +++-- drivers/gpu/drm/qxl/qxl_release.c | 18 -- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index e60a8f88e226..dc1659e717f1 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -61,6 +61,7 @@ static inline u64 qxl_bo_mmap_offset(struct qxl_bo *bo) extern int qxl_bo_create(struct qxl_device *qdev, unsigned long size, bool kernel, bool pinned, u32 domain, +u32 priority, struct qxl_surface *surf, struct qxl_bo **bo_ptr); extern int qxl_bo_kmap(struct qxl_bo *bo, struct dma_buf_map *map); diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 7e22a81bfb36..7b00c955cd82 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -269,7 +269,7 @@ int qxl_alloc_bo_reserved(struct qxl_device *qdev, int ret; ret = qxl_bo_create(qdev, size, false /* not kernel - device */, - false, QXL_GEM_DOMAIN_VRAM, NULL, ); + false, QXL_GEM_DOMAIN_VRAM, 0, NULL, ); if (ret) { DRM_ERROR("failed to allocate VRAM BO\n"); return ret; diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index ec50d2cfd4e1..a1b5cc5918bc 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -799,8 +799,8 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, qdev->dumb_shadow_bo = NULL; } qxl_bo_create(qdev, surf.height * surf.stride, - true, true, QXL_GEM_DOMAIN_SURFACE, , - >dumb_shadow_bo); + true, true, QXL_GEM_DOMAIN_SURFACE, 0, + , >dumb_shadow_bo); } if (user_bo->shadow != qdev->dumb_shadow_bo) { if (user_bo->shadow) { diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c index 48e096285b4c..a08da0bd9098 100644 --- a/drivers/gpu/drm/qxl/qxl_gem.c +++ b/drivers/gpu/drm/qxl/qxl_gem.c @@ -55,7 +55,7 @@ int qxl_gem_object_create(struct qxl_device *qdev, int size, /* At least align on page size */ if (alignment < PAGE_SIZE) alignment = PAGE_SIZE; - r = qxl_bo_create(qdev, size, kernel, false, initial_domain, surf, ); + r = qxl_bo_create(qdev, size, kernel, false, initial_domain, 0, surf, ); if (r) { if (r != -ERESTARTSYS) DRM_ERROR( diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 705b51535492..7eada4ad217b 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -103,8 +103,8 @@ static const struct drm_gem_object_funcs qxl_object_funcs = { .print_info = drm_gem_ttm_print_info, }; -int qxl_bo_create(struct qxl_device *qdev, - unsigned long size, bool kernel, bool pinned, u32 domain, +int qxl_bo_create(struct qxl_device *qdev, unsigned long size, + bool kernel, bool pinned, u32 domain, u32 priority, struct qxl_surface *surf, struct qxl_bo **bo_ptr) { @@ -137,6 +137,7 @@ int qxl_bo_create(struct qxl_device *qdev, qxl_ttm_placement_from_domain(bo, domain); + bo->tbo.priority = priority; r = ttm_bo_init_reserved(>mman.bdev, >tbo, size, type, >placement, 0, , NULL, NULL, _ttm_bo_destroy); diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 579c6de10c8e..716d706ca7f0 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -160,11 +160,12 @@ qxl_release_free(struct qxl_device *qdev, } static int qxl_release_bo_alloc(struct qxl_device *qdev, - struct qxl_bo **bo) +
Re: [PATCH v2 02/11] drm/qxl: more fence wait rework
Am 17.02.21 um 13:32 schrieb Gerd Hoffmann: Move qxl_io_notify_oom() call into wait condition. That way the driver will call it again if one call wasn't enough. Also allows to remove the extra dma_fence_is_signaled() check and the goto. Fixes: 5a838e5d5825 ("drm/qxl: simplify qxl_fence_wait") Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_release.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 6ed673d75f9f..579c6de10c8e 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -62,16 +62,12 @@ static long qxl_fence_wait(struct dma_fence *fence, bool intr, qdev = container_of(fence->lock, struct qxl_device, release_lock); - if (dma_fence_is_signaled(fence)) - goto signaled; - - qxl_io_notify_oom(qdev); if (!wait_event_timeout(qdev->release_event, - dma_fence_is_signaled(fence), + (dma_fence_is_signaled(fence) || +(qxl_io_notify_oom(qdev), 0)), timeout)) return 0; -signaled: cur = jiffies; if (time_after(cur, end)) return 0; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v9 0/4] Add %p4cc printk modifier for V4L2 and DRM fourcc codes
Hi Am 16.02.21 um 16:57 schrieb Sakari Ailus: Hi all, On merging --- it would seem everyone is happy with merging this through the drm-misc tree. The last patch should wait until all users are gone for sure, probably to the next kernel release. There are no users of drm_get_format_name() in linux-next currently after the 3rd patch. I've merged patches 1 to 3 into drm-misc-next. Patch 4 (and maybe some final fix-up patch) will land when all DRM trees have catched up the changes. Best regards Thomas This set adds support for %p4cc printk modifier for printing V4L2 and DRM fourcc codes. The codes are cumbersome to print manually and by adding the modifier, this task is saved from the V4L2 and DRM frameworks as well as related drivers. DRM actually had it handled in a way (see 3rd patch) but the printk modifier makes printing the format easier even there. On V4L2 side it saves quite a few lines of repeating different implementations of printing the 4cc codes. Further work will include converting the V4L2 drivers doing the same. I left these out from this version since individual drivers are easier changed without dealing with multiple trees. Since v8: - Reduce ternary conditionals in intel_plane_uapi_info(). - Wrap a long line in intel_plane_hw_info(). Since v7: - Add more examples, one with big endian and another with a space. - Add Y10 test format. - Use "0123" in the size string for temporary buffer. - Added acks. - Split the 3rd patch into two: driver changes and removal of drm_get_format_name(). Since v6: - Don't drop spaces in fourcc codes. - Print unprintable characters as dot ('.') instead of hexadecimal number in parentheses. - Convert DRM from drm_get_format_name() to %p4cc. I wonder if this should be merged through the DRM tree, albeit it's probably unlikely to conflict with other changes. Further use of the function could be a problem. - Make tests more realistic. Since v5: - Added V4L2 core conversion to %p4cc, as well as change the DRM fourcc printing function to use %p4cc. - Add missing checkpatch.pl checks for %p4cc modifier. Sakari Ailus (4): lib/vsprintf: Add support for printing V4L2 and DRM fourccs v4l: ioctl: Use %p4cc printk modifier to print FourCC codes drm: Switch to %p4cc format modifier drm: Remove drm_get_format_name() Documentation/core-api/printk-formats.rst | 18 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 5 +- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 5 +- drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 5 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +- .../arm/display/komeda/komeda_format_caps.h | 11 --- .../arm/display/komeda/komeda_framebuffer.c | 4 +- .../gpu/drm/arm/display/komeda/komeda_plane.c | 6 +- drivers/gpu/drm/arm/malidp_mw.c | 7 +- drivers/gpu/drm/drm_atomic.c | 8 +- drivers/gpu/drm/drm_crtc.c| 7 +- drivers/gpu/drm/drm_fourcc.c | 25 -- drivers/gpu/drm/drm_framebuffer.c | 11 +-- drivers/gpu/drm/drm_mipi_dbi.c| 5 +- drivers/gpu/drm/drm_plane.c | 8 +- .../gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 5 +- drivers/gpu/drm/i915/display/intel_display.c | 14 +-- .../drm/i915/display/intel_display_debugfs.c | 19 ++--- drivers/gpu/drm/i915/display/intel_sprite.c | 6 +- drivers/gpu/drm/mcde/mcde_display.c | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 +- drivers/gpu/drm/nouveau/nouveau_display.c | 9 +- drivers/gpu/drm/radeon/atombios_crtc.c| 10 +-- drivers/gpu/drm/sun4i/sun4i_backend.c | 6 +- drivers/gpu/drm/vkms/vkms_writeback.c | 7 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 15 ++-- drivers/media/v4l2-core/v4l2-ioctl.c | 85 +-- include/drm/drm_fourcc.h | 1 - lib/test_printf.c | 18 lib/vsprintf.c| 39 + scripts/checkpatch.pl | 6 +- 32 files changed, 164 insertions(+), 223 deletions(-) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 09/10] drm/qxl: map/unmap framebuffers in prepare_fb+cleanup_fb callbacks.
Hi Am 17.02.21 um 11:02 schrieb Gerd Hoffmann: On Tue, Feb 16, 2021 at 02:46:21PM +0100, Thomas Zimmermann wrote: Am 16.02.21 um 14:27 schrieb Thomas Zimmermann: Hi this is a shadow-buffered plane. Did you consider using the new helpers for shadow-buffered planes? They will map the user BO for you and provide the mapping in the plane state. From there, you should implement your own plane state on top of struct drm_shadow_plane_state, and also move all the other allocations and vmaps into prepare_fb and cleanup_fb. Most of this is not actually allowed in commit tails. All we'd have to do is to export the reset, duplicate and destroy code; similar to what __drm_atomic_helper_plane_reset() does. AFAICT the cursor_bo is used to implement double buffering for the cursor image. Ideally, you can do what ast does: pre-allocate/vmap 2 BOs at the end of the vram. Then pageflip between them in atomic_update(). Resolves all the allocation and mapping headaches. Just waded through the ast patches. I just received your ack. Thanks a lot for looking at the ast patches. It is not that simple for qxl. You have to send a command to the virtualization host and take care of the host accessing that memory when processing the command, so you can't reuse the memory until the host signals it is fine to do so. But, yes, it should be possible to handle cursor_bo creation in prepare_fb without too much effort. I've been thinking about this issue and here's an idea: If you take the ast code as a blueprint, you'd store two cursor bo in a cursor-plane structure. Aditionally each of these BOs would have a pointer to a fence associated with it. One idea for the fencing code would be to allocate each new fence in prepare_fb and store it in the cursor plane state. In atomic_update, pick the unused BO in the cursor plane and wait on its fence. This should guarantee that the BO is available. (?) Then swap the BO's fence with the one in the cursor plane state. Setup the new fence for synchronization with the host. Next time you pick this cursor BO, the fence will be there for synchronization. The old fence from the cursor BO will now be stored in the cursor-plane state and can be freed in cleanup_fb(). My main interest here is to move all fail-able/locking calls out of the atomic_update function. I might be missing some crucial corner case, but this should resolve the issue. (?) In any case, it's maybe worth a separate patchset. Best regards Thomas take care, Gerd ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 09/10] drm/qxl: map/unmap framebuffers in prepare_fb+cleanup_fb callbacks.
Am 16.02.21 um 14:27 schrieb Thomas Zimmermann: Hi this is a shadow-buffered plane. Did you consider using the new helpers for shadow-buffered planes? They will map the user BO for you and provide the mapping in the plane state. From there, you should implement your own plane state on top of struct drm_shadow_plane_state, and also move all the other allocations and vmaps into prepare_fb and cleanup_fb. Most of this is not actually allowed in commit tails. All we'd have to do is to export the reset, duplicate and destroy code; similar to what __drm_atomic_helper_plane_reset() does. AFAICT the cursor_bo is used to implement double buffering for the cursor image. Ideally, you can do what ast does: pre-allocate/vmap 2 BOs at the end of the vram. Then pageflip between them in atomic_update(). Resolves all the allocation and mapping headaches. Best regards Thomas Best regards Thomas Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: We don't have to map in atomic_update callback then, making locking a bit less complicated. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 14 +- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 7500560db8e4..39b8c5116d34 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -584,7 +584,6 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, struct drm_gem_object *obj; struct qxl_bo *cursor_bo = NULL, *user_bo = NULL, *old_cursor_bo = NULL; int ret; - struct dma_buf_map user_map; struct dma_buf_map cursor_map; void *user_ptr; int size = 64*64*4; @@ -599,11 +598,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, obj = fb->obj[0]; user_bo = gem_to_qxl_bo(obj); - /* pinning is done in the prepare/cleanup framevbuffer */ - ret = qxl_bo_kmap_locked(user_bo, _map); - if (ret) - goto out_free_release; - user_ptr = user_map.vaddr; /* TODO: Use mapping abstraction properly */ + /* mapping is done in the prepare/cleanup framevbuffer */ + user_ptr = user_bo->map.vaddr; /* TODO: Use mapping abstraction properly */ ret = qxl_alloc_bo_reserved(qdev, release, sizeof(struct qxl_cursor) + size, @@ -639,7 +635,6 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, cursor->chunk.data_size = size; memcpy(cursor->chunk.data, user_ptr, size); qxl_bo_kunmap_locked(cursor_bo); - qxl_bo_kunmap_locked(user_bo); cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); cmd->u.set.visible = 1; @@ -778,6 +773,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, struct drm_gem_object *obj; struct qxl_bo *user_bo; struct qxl_surface surf; + struct dma_buf_map unused; if (!new_state->fb) return 0; @@ -815,7 +811,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, } } - return qxl_bo_pin(user_bo); + return qxl_bo_kmap(user_bo, ); } static void qxl_plane_cleanup_fb(struct drm_plane *plane, @@ -834,7 +830,7 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, obj = old_state->fb->obj[0]; user_bo = gem_to_qxl_bo(obj); - qxl_bo_unpin(user_bo); + qxl_bo_kunmap(user_bo); if (old_state->fb != plane->state->fb && user_bo->shadow) { qxl_bo_unpin(user_bo->shadow); ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 10/10] drm/qxl: add lock asserts to qxl_bo_kmap_locked + qxl_bo_kunmap_locked
Hi Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: Try avoid re-introducing locking bugs. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann IMHO this should eventually be done in the rsp TTM functions. But so far, I'd expect this to break some drivers. Best regards Thomas --- drivers/gpu/drm/qxl/qxl_object.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 22748b9566af..90d5e5b7f927 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -162,6 +162,8 @@ int qxl_bo_kmap_locked(struct qxl_bo *bo, struct dma_buf_map *map) { int r; + dma_resv_assert_held(bo->tbo.base.resv); + if (bo->kptr) { bo->map_count++; goto out; @@ -236,6 +238,8 @@ void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, void qxl_bo_kunmap_locked(struct qxl_bo *bo) { + dma_resv_assert_held(bo->tbo.base.resv); + if (bo->kptr == NULL) return; bo->map_count--; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 09/10] drm/qxl: map/unmap framebuffers in prepare_fb+cleanup_fb callbacks.
Hi this is a shadow-buffered plane. Did you consider using the new helpers for shadow-buffered planes? They will map the user BO for you and provide the mapping in the plane state. From there, you should implement your own plane state on top of struct drm_shadow_plane_state, and also move all the other allocations and vmaps into prepare_fb and cleanup_fb. Most of this is not actually allowed in commit tails. All we'd have to do is to export the reset, duplicate and destroy code; similar to what __drm_atomic_helper_plane_reset() does. Best regards Thomas Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: We don't have to map in atomic_update callback then, making locking a bit less complicated. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 14 +- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 7500560db8e4..39b8c5116d34 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -584,7 +584,6 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, struct drm_gem_object *obj; struct qxl_bo *cursor_bo = NULL, *user_bo = NULL, *old_cursor_bo = NULL; int ret; - struct dma_buf_map user_map; struct dma_buf_map cursor_map; void *user_ptr; int size = 64*64*4; @@ -599,11 +598,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, obj = fb->obj[0]; user_bo = gem_to_qxl_bo(obj); - /* pinning is done in the prepare/cleanup framevbuffer */ - ret = qxl_bo_kmap_locked(user_bo, _map); - if (ret) - goto out_free_release; - user_ptr = user_map.vaddr; /* TODO: Use mapping abstraction properly */ + /* mapping is done in the prepare/cleanup framevbuffer */ + user_ptr = user_bo->map.vaddr; /* TODO: Use mapping abstraction properly */ ret = qxl_alloc_bo_reserved(qdev, release, sizeof(struct qxl_cursor) + size, @@ -639,7 +635,6 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, cursor->chunk.data_size = size; memcpy(cursor->chunk.data, user_ptr, size); qxl_bo_kunmap_locked(cursor_bo); - qxl_bo_kunmap_locked(user_bo); cmd = (struct qxl_cursor_cmd *) qxl_release_map(qdev, release); cmd->u.set.visible = 1; @@ -778,6 +773,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, struct drm_gem_object *obj; struct qxl_bo *user_bo; struct qxl_surface surf; + struct dma_buf_map unused; if (!new_state->fb) return 0; @@ -815,7 +811,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, } } - return qxl_bo_pin(user_bo); + return qxl_bo_kmap(user_bo, ); } static void qxl_plane_cleanup_fb(struct drm_plane *plane, @@ -834,7 +830,7 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, obj = old_state->fb->obj[0]; user_bo = gem_to_qxl_bo(obj); - qxl_bo_unpin(user_bo); + qxl_bo_kunmap(user_bo); if (old_state->fb != plane->state->fb && user_bo->shadow) { qxl_bo_unpin(user_bo->shadow); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 08/10] drm/qxl: fix monitors object kmap
Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: Use the correct kmap variant. We don't hold a reservation here, so we can't use the _locked variant. We can drop the pin because qxl_bo_kmap will do that for us. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_display.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 8672385a1caf..7500560db8e4 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1159,12 +1159,10 @@ int qxl_create_monitors_object(struct qxl_device *qdev) } qdev->monitors_config_bo = gem_to_qxl_bo(gobj); - ret = qxl_bo_pin(qdev->monitors_config_bo); + ret = qxl_bo_kmap(qdev->monitors_config_bo, ); if (ret) return ret; - qxl_bo_kmap_locked(qdev->monitors_config_bo, ); - qdev->monitors_config = qdev->monitors_config_bo->kptr; qdev->ram_header->monitors_config = qxl_bo_physical_address(qdev, qdev->monitors_config_bo, 0); @@ -1189,8 +1187,7 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) qdev->monitors_config = NULL; qdev->ram_header->monitors_config = 0; - qxl_bo_kunmap_locked(qdev->monitors_config_bo); - ret = qxl_bo_unpin(qdev->monitors_config_bo); + ret = qxl_bo_kunmap(qdev->monitors_config_bo); if (ret) return ret; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 06/10] drm/qxl: add qxl_bo_kmap/qxl_bo_kunmap
Hi Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: Add kmap/kunmap variants which reserve (and pin) the bo. They can be used in case the caller doesn't hold a reservation for the bo. Again, these functions should rather be called vmap/vunamp. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_object.h | 2 ++ drivers/gpu/drm/qxl/qxl_object.c | 36 2 files changed, 38 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 5bd33650183f..360972ae4869 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -64,7 +64,9 @@ extern int qxl_bo_create(struct qxl_device *qdev, u32 priority, struct qxl_surface *surf, struct qxl_bo **bo_ptr); +extern int qxl_bo_kmap(struct qxl_bo *bo, struct dma_buf_map *map); extern int qxl_bo_kmap_locked(struct qxl_bo *bo, struct dma_buf_map *map); +extern int qxl_bo_kunmap(struct qxl_bo *bo); extern void qxl_bo_kunmap_locked(struct qxl_bo *bo); void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset); void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, void *map); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index b56d4dfc28cb..22748b9566af 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -29,6 +29,9 @@ #include "qxl_drv.h" #include "qxl_object.h" +static int __qxl_bo_pin(struct qxl_bo *bo); +static void __qxl_bo_unpin(struct qxl_bo *bo); + static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo) { struct qxl_bo *bo; @@ -179,6 +182,25 @@ int qxl_bo_kmap_locked(struct qxl_bo *bo, struct dma_buf_map *map) return 0; } +int qxl_bo_kmap(struct qxl_bo *bo, struct dma_buf_map *map) +{ + int r; + + r = qxl_bo_reserve(bo); + if (r) + return r; + + r = __qxl_bo_pin(bo); + if (r) { + qxl_bo_unreserve(bo); + return r; + } + + r = qxl_bo_kmap_locked(bo, map); + qxl_bo_unreserve(bo); + return r; +} + void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset) { @@ -223,6 +245,20 @@ void qxl_bo_kunmap_locked(struct qxl_bo *bo) ttm_bo_vunmap(>tbo, >map); } +int qxl_bo_kunmap(struct qxl_bo *bo) +{ + int r; + + r = qxl_bo_reserve(bo); + if (r) + return r; + + qxl_bo_kunmap_locked(bo); + __qxl_bo_unpin(bo); + qxl_bo_unreserve(bo); + return 0; +} + void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, void *pmap) { -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 07/10] drm/qxl: fix prime kmap
Hi Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: Use the correct kmap variant. We don't have a reservation here, so we can't use the _locked version. I'd merge this change into patch 6. So the new functions come with a caller. Best regards Thomas Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_prime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_prime.c b/drivers/gpu/drm/qxl/qxl_prime.c index dc295b2e2b52..4aa949799446 100644 --- a/drivers/gpu/drm/qxl/qxl_prime.c +++ b/drivers/gpu/drm/qxl/qxl_prime.c @@ -59,7 +59,7 @@ int qxl_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) struct qxl_bo *bo = gem_to_qxl_bo(obj); int ret; - ret = qxl_bo_kmap_locked(bo, map); + ret = qxl_bo_kmap(bo, map); if (ret < 0) return ret; @@ -71,7 +71,7 @@ void qxl_gem_prime_vunmap(struct drm_gem_object *obj, { struct qxl_bo *bo = gem_to_qxl_bo(obj); - qxl_bo_kunmap_locked(bo); + qxl_bo_kunmap(bo); } int qxl_gem_prime_mmap(struct drm_gem_object *obj, -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 05/10] drm/qxl: rename qxl_bo_kmap -> qxl_bo_kmap_locked
surface_base = surface_map.vaddr; /* TODO: Use mapping abstraction properly */ @@ -210,7 +210,7 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, ret = qxl_image_init(qdev, release, dimage, surface_base, left - dumb_shadow_offset, top, width, height, depth, stride); - qxl_bo_kunmap(bo); + qxl_bo_kunmap_locked(bo); if (ret) goto out_release_backoff; @@ -247,7 +247,7 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, rects[i].top= clips_ptr->y1; rects[i].bottom = clips_ptr->y2; } - qxl_bo_kunmap(clips_bo); + qxl_bo_kunmap_locked(clips_bo); qxl_release_fence_buffer_objects(release); qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); diff --git a/drivers/gpu/drm/qxl/qxl_image.c b/drivers/gpu/drm/qxl/qxl_image.c index 60ab7151b84d..d4db21ca1d5d 100644 --- a/drivers/gpu/drm/qxl/qxl_image.c +++ b/drivers/gpu/drm/qxl/qxl_image.c @@ -186,7 +186,7 @@ qxl_image_init_helper(struct qxl_device *qdev, } } } - qxl_bo_kunmap(chunk_bo); + qxl_bo_kunmap_locked(chunk_bo); image_bo = dimage->bo; ptr = qxl_bo_kmap_atomic_page(qdev, image_bo, 0); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 7eada4ad217b..b56d4dfc28cb 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -155,7 +155,7 @@ int qxl_bo_create(struct qxl_device *qdev, unsigned long size, return 0; } -int qxl_bo_kmap(struct qxl_bo *bo, struct dma_buf_map *map) +int qxl_bo_kmap_locked(struct qxl_bo *bo, struct dma_buf_map *map) { int r; @@ -203,7 +203,7 @@ void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, return rptr; } - ret = qxl_bo_kmap(bo, _map); + ret = qxl_bo_kmap_locked(bo, _map); if (ret) return NULL; rptr = bo_map.vaddr; /* TODO: Use mapping abstraction properly */ @@ -212,7 +212,7 @@ void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, return rptr; } -void qxl_bo_kunmap(struct qxl_bo *bo) +void qxl_bo_kunmap_locked(struct qxl_bo *bo) { if (bo->kptr == NULL) return; @@ -233,7 +233,7 @@ void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, io_mapping_unmap_atomic(pmap); return; fallback: - qxl_bo_kunmap(bo); + qxl_bo_kunmap_locked(bo); } void qxl_bo_unref(struct qxl_bo **bo) diff --git a/drivers/gpu/drm/qxl/qxl_prime.c b/drivers/gpu/drm/qxl/qxl_prime.c index 4aa949799446..dc295b2e2b52 100644 --- a/drivers/gpu/drm/qxl/qxl_prime.c +++ b/drivers/gpu/drm/qxl/qxl_prime.c @@ -59,7 +59,7 @@ int qxl_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) struct qxl_bo *bo = gem_to_qxl_bo(obj); int ret; - ret = qxl_bo_kmap(bo, map); + ret = qxl_bo_kmap_locked(bo, map); if (ret < 0) return ret; @@ -71,7 +71,7 @@ void qxl_gem_prime_vunmap(struct drm_gem_object *obj, { struct qxl_bo *bo = gem_to_qxl_bo(obj); - qxl_bo_kunmap(bo); + qxl_bo_kunmap_locked(bo); } int qxl_gem_prime_mmap(struct drm_gem_object *obj, -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 01/10] drm/qxl: properly handle device init failures
Am 16.02.21 um 12:37 schrieb Gerd Hoffmann: Specifically do not try release resources which where not allocated in the first place. I still think this should eventually be resolved by using managed code. But for now Acked-by: Thomas Zimmermann Cc: Tong Zhang Tested-by: Tong Zhang Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 3 +++ drivers/gpu/drm/qxl/qxl_kms.c | 4 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index c326412136c5..ec50d2cfd4e1 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1183,6 +1183,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) { int ret; + if (!qdev->monitors_config_bo) + return 0; + qdev->monitors_config = NULL; qdev->ram_header->monitors_config = 0; diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 66d74aaaee06..4dc5ad13f12c 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -288,6 +288,10 @@ void qxl_device_fini(struct qxl_device *qdev) { int cur_idx; + /* check if qxl_device_init() was successful (gc_work is initialized last) */ + if (!qdev->gc_work.func) + return; + for (cur_idx = 0; cur_idx < 3; cur_idx++) { if (!qdev->current_release_bo[cur_idx]) continue; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v7 3/3] drm: Switch to %p4cc format modifier
Hi Am 15.02.21 um 12:40 schrieb Sakari Ailus: Switch DRM drivers from drm_get_format_name() to %p4cc. This gets rid of a large number of temporary variables at the same time. Signed-off-by: Sakari Ailus --- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 5 ++-- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 5 ++-- drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 5 ++-- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 5 ++-- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++-- .../arm/display/komeda/komeda_format_caps.h | 11 .../arm/display/komeda/komeda_framebuffer.c | 4 +-- .../gpu/drm/arm/display/komeda/komeda_plane.c | 6 ++--- drivers/gpu/drm/arm/malidp_mw.c | 7 ++ drivers/gpu/drm/drm_atomic.c | 8 ++ drivers/gpu/drm/drm_crtc.c| 7 ++ drivers/gpu/drm/drm_fourcc.c | 25 --- drivers/gpu/drm/drm_framebuffer.c | 11 +++- drivers/gpu/drm/drm_mipi_dbi.c| 5 ++-- drivers/gpu/drm/drm_plane.c | 8 ++ .../gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 5 ++-- drivers/gpu/drm/i915/display/intel_display.c | 14 +++ .../drm/i915/display/intel_display_debugfs.c | 19 ++ drivers/gpu/drm/i915/display/intel_sprite.c | 6 ++--- drivers/gpu/drm/mcde/mcde_display.c | 6 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++--- drivers/gpu/drm/nouveau/nouveau_display.c | 9 +++ drivers/gpu/drm/radeon/atombios_crtc.c| 10 +++- drivers/gpu/drm/sun4i/sun4i_backend.c | 6 ++--- drivers/gpu/drm/vkms/vkms_writeback.c | 7 ++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 15 +-- include/drm/drm_fourcc.h | 1 - 27 files changed, 64 insertions(+), 157 deletions(-) This is a nice patchset. For the driver-related changes: Acked-by: Thomas Zimmermann But landing this patch will certainly give us build errors. There are at least 3 git trees involved: drm-misc-next, amd and i915. I'd expect at least one of them to have additional changes that still require drm_get_format_name(). IMHO we should remove drm_get_format_name() in a later patch. Please remove the changes in drm_fourcc.{c,h} from this patch and maybe add a TODO comment to the declaration that the function is supposed to be removed. I would merge the patchset through drm-misc-next. And the final removal patch during the next cycle. Ok? Best regard Thomas diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 7944781e1086..ea825b4f8ee8 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -1862,7 +1862,6 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, u32 tmp, viewport_w, viewport_h; int r; bool bypass_lut = false; - struct drm_format_name_buf format_name; /* no fb bound */ if (!atomic && !crtc->primary->fb) { @@ -1981,8 +1980,8 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, #endif break; default: - DRM_ERROR("Unsupported screen format %s\n", - drm_get_format_name(target_fb->format->format, _name)); + DRM_ERROR("Unsupported screen format %p4cc\n", + _fb->format->format); return -EINVAL; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 1b6ff0470011..a360a6dec198 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -1904,7 +1904,6 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, u32 tmp, viewport_w, viewport_h; int r; bool bypass_lut = false; - struct drm_format_name_buf format_name; /* no fb bound */ if (!atomic && !crtc->primary->fb) { @@ -2023,8 +2022,8 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, #endif break; default: - DRM_ERROR("Unsupported screen format %s\n", - drm_get_format_name(target_fb->format->format, _name)); + DRM_ERROR("Unsupported screen format %p4cc\n", + _fb->format->format); return -EINVAL; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index 83a88385b762..ef124ac853b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -1820,7 +1820,6 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc, u32 viewport_w, viewport_h; int r; bool bypass_lut = false; - struct drm_format_name_buf format_na
Re: [RFC v3 10/10] drm/dp: Extract i915's eDP backlight code into DRM helpers
t a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index edffd1dcca3e..1eca0b42fc45 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1790,6 +1790,24 @@ drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) DP_MSA_TIMING_PAR_IGNORED; } +/** + * drm_edp_backlight_supported() - Check an eDP DPCD for VESA backlight support + * @edp_dpcd: The DPCD to check + * + * Note that currently this function will return %false for panels which support various DPCD + * backlight features but which require the brightness be set through PWM, and don't support setting + * the brightness level via the DPCD. This is a TODO. + * + * Returns: %True if @edp_dpcd indicates that VESA backlight controls are supported, %false + * otherwise + */ +static inline bool +drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]) +{ + return (edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP) && + (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP); +} + /* * DisplayPort AUX channel */ @@ -2089,6 +2107,36 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk) return desc->quirks & BIT(quirk); } +/** + * struct drm_edp_backlight_info - Probed eDP backlight info struct + * @pwmgen_bit_count: The pwmgen bit count + * @pwm_freq_pre_divider: The PWM frequency pre-divider value being used for this backlight, if any + * @max: The maximum backlight level that may be set + * @lsb_reg_used: Do we also write values to the DP_EDP_BACKLIGHT_BRIGHTNESS_LSB register? + * @aux_enable: Does the panel support the AUX enable cap? + * + * This structure contains various data about an eDP backlight, which can be populated by using + * drm_edp_backlight_init(). + */ +struct drm_edp_backlight_info { + u8 pwmgen_bit_count; + u8 pwm_freq_pre_divider; + u16 max; + + bool lsb_reg_used : 1; + bool aux_enable : 1; +}; + +int +drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, + u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], + u16 *current_level, u8 *current_mode); +int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, + u16 level); +int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, + u16 level); +int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl); + #ifdef CONFIG_DRM_DP_CEC void drm_dp_cec_irq(struct drm_dp_aux *aux); void drm_dp_cec_register_connector(struct drm_dp_aux *aux, -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: DMA-buf and uncached system memory
Hi Am 15.02.21 um 10:49 schrieb Thomas Zimmermann: Hi Am 15.02.21 um 09:58 schrieb Christian König: Hi guys, we are currently working an Freesync and direct scan out from system memory on AMD APUs in A+A laptops. On problem we stumbled over is that our display hardware needs to scan out from uncached system memory and we currently don't have a way to communicate that through DMA-buf. Re-reading this paragrah, it sounds more as if you want to let the exporter know where to move the buffer. Is this another case of the missing-pin-flag problem? Best regards Thomas For our specific use case at hand we are going to implement something driver specific, but the question is should we have something more generic for this? For vmap operations, we return the address as struct dma_buf_map, which contains additional information about the memory buffer. In vram helpers, we have the interface drm_gem_vram_offset() that returns the offset of the GPU device memory. Would it be feasible to combine both concepts into a dma-buf interface that returns the device-memory offset plus the additional caching flag? There'd be a structure and a getter function returning the structure. struct dma_buf_offset { bool cached; u64 address; }; // return offset in *off int dma_buf_offset(struct dma_buf *buf, struct dma_buf_off *off); Whatever settings are returned by dma_buf_offset() are valid while the dma_buf is pinned. Best regards Thomas After all the system memory access pattern is a PCIe extension and as such something generic. Regards, Christian. ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: DMA-buf and uncached system memory
Hi Am 15.02.21 um 09:58 schrieb Christian König: Hi guys, we are currently working an Freesync and direct scan out from system memory on AMD APUs in A+A laptops. On problem we stumbled over is that our display hardware needs to scan out from uncached system memory and we currently don't have a way to communicate that through DMA-buf. For our specific use case at hand we are going to implement something driver specific, but the question is should we have something more generic for this? For vmap operations, we return the address as struct dma_buf_map, which contains additional information about the memory buffer. In vram helpers, we have the interface drm_gem_vram_offset() that returns the offset of the GPU device memory. Would it be feasible to combine both concepts into a dma-buf interface that returns the device-memory offset plus the additional caching flag? There'd be a structure and a getter function returning the structure. struct dma_buf_offset { bool cached; u64 address; }; // return offset in *off int dma_buf_offset(struct dma_buf *buf, struct dma_buf_off *off); Whatever settings are returned by dma_buf_offset() are valid while the dma_buf is pinned. Best regards Thomas After all the system memory access pattern is a PCIe extension and as such something generic. Regards, Christian. ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3] kcmp: Support selection of SYS_kcmp without CHECKPOINT_RESTORE
Hi Am 05.02.21 um 23:00 schrieb Chris Wilson: Userspace has discovered the functionality offered by SYS_kcmp and has started to depend upon it. In particular, Mesa uses SYS_kcmp for os_same_file_description() in order to identify when two fd (e.g. device or dmabuf) point to the same struct file. Since they depend on it for core functionality, lift SYS_kcmp out of the non-default CONFIG_CHECKPOINT_RESTORE into the selectable syscall category. Rasmus Villemoes also pointed out that systemd uses SYS_kcmp to deduplicate the per-service file descriptor store. This helps a lot with transactional programming in userspace system code. So FWIW Acked-by: Thomas Zimmermann Note that some distributions such as Ubuntu are already enabling CHECKPOINT_RESTORE in their configs and so, by extension, SYS_kcmp. References: https://gitlab.freedesktop.org/drm/intel/-/issues/3046 Signed-off-by: Chris Wilson Cc: Kees Cook Cc: Andy Lutomirski Cc: Will Drewry Cc: Andrew Morton Cc: Dave Airlie Cc: Daniel Vetter Cc: Lucas Stach Cc: Rasmus Villemoes Cc: Cyrill Gorcunov Cc: sta...@vger.kernel.org Acked-by: Daniel Vetter # DRM depends on kcmp Acked-by: Rasmus Villemoes # systemd uses kcmp --- v2: - Default n. - Borrrow help message from man kcmp. - Export get_epoll_tfile_raw_ptr() for CONFIG_KCMP v3: - Select KCMP for CONFIG_DRM --- drivers/gpu/drm/Kconfig | 3 +++ fs/eventpoll.c| 4 ++-- include/linux/eventpoll.h | 2 +- init/Kconfig | 11 +++ kernel/Makefile | 2 +- tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 0973f408d75f..af6c6d214d91 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -15,6 +15,9 @@ menuconfig DRM select I2C_ALGOBIT select DMA_SHARED_BUFFER select SYNC_FILE +# gallium uses SYS_kcmp for os_same_file_description() to de-duplicate +# device and dmabuf fd. Let's make sure that is available for our userspace. + select KCMP help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/fs/eventpoll.c b/fs/eventpoll.c index a829af074eb5..3196474cbe24 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -979,7 +979,7 @@ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd) return epir; } -#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_KCMP static struct epitem *ep_find_tfd(struct eventpoll *ep, int tfd, unsigned long toff) { struct rb_node *rbp; @@ -1021,7 +1021,7 @@ struct file *get_epoll_tfile_raw_ptr(struct file *file, int tfd, return file_raw; } -#endif /* CONFIG_CHECKPOINT_RESTORE */ +#endif /* CONFIG_KCMP */ /** * Adds a new entry to the tail of the list in a lockless way, i.e. diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index 0350393465d4..593322c946e6 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h @@ -18,7 +18,7 @@ struct file; #ifdef CONFIG_EPOLL -#ifdef CONFIG_CHECKPOINT_RESTORE +#ifdef CONFIG_KCMP struct file *get_epoll_tfile_raw_ptr(struct file *file, int tfd, unsigned long toff); #endif diff --git a/init/Kconfig b/init/Kconfig index b77c60f8b963..9cc7436b2f73 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1194,6 +1194,7 @@ endif # NAMESPACES config CHECKPOINT_RESTORE bool "Checkpoint/restore support" select PROC_CHILDREN + select KCMP default n help Enables additional kernel features in a sake of checkpoint/restore. @@ -1737,6 +1738,16 @@ config ARCH_HAS_MEMBARRIER_CALLBACKS config ARCH_HAS_MEMBARRIER_SYNC_CORE bool +config KCMP + bool "Enable kcmp() system call" if EXPERT + help + Enable the kernel resource comparison system call. It provides + user-space with the ability to compare two processes to see if they + share a common resource, such as a file descriptor or even virtual + memory space. + + If unsure, say N. + config RSEQ bool "Enable rseq() system call" if EXPERT default y diff --git a/kernel/Makefile b/kernel/Makefile index aa7368c7eabf..320f1f3941b7 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -51,7 +51,7 @@ obj-y += livepatch/ obj-y += dma/ obj-y += entry/ -obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o +obj-$(CONFIG_KCMP) += kcmp.o obj-$(CONFIG_FREEZER) += freezer.o obj-$(CONFIG_PROFILING) += profile.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 26c72f2b61b1..1b6c7d33c4ff 100644 --- a/t
Re: [RFC v3 10/10] drm/dp: Extract i915's eDP backlight code into DRM helpers
_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) - panel->backlight.edp.vesa.lsb_reg_used = true; - - panel->backlight.max = intel_dp_aux_vesa_calc_max_backlight(connector); - if (!panel->backlight.max) - return -ENODEV; + ret = drm_edp_backlight_init(_dp->aux, >backlight.edp.vesa.info, +i915->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, +_level, _mode); + if (ret < 0) + return ret; + panel->backlight.max = panel->backlight.edp.vesa.info.max; panel->backlight.min = 0; - panel->backlight.level = intel_dp_aux_vesa_get_backlight(connector, pipe); - panel->backlight.enabled = intel_dp_aux_vesa_backlight_dpcd_mode(connector) && - panel->backlight.level != 0; + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { + panel->backlight.level = current_level; + panel->backlight.enabled = panel->backlight.level != 0; + } else { + panel->backlight.level = panel->backlight.max; + panel->backlight.enabled = false; + } return 0; } @@ -559,16 +340,12 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) struct intel_dp *intel_dp = intel_attached_dp(connector); struct drm_i915_private *i915 = dp_to_i915(intel_dp); - /* Check the eDP Display control capabilities registers to determine if -* the panel can support backlight control over the aux channel. -* -* TODO: We currently only support AUX only backlight configurations, not backlights which + /* TODO: We currently only support AUX only backlight configurations, not backlights which * require a mix of PWM and AUX controls to work. In the mean time, these machines typically * work just fine using normal PWM controls anyway. */ - if (intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP && - (intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) && - (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) { + if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) && + drm_edp_backlight_supported(intel_dp->edp_dpcd)) { drm_dbg_kms(>drm, "AUX Backlight Control Supported!\n"); return true; } diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index edffd1dcca3e..1eca0b42fc45 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1790,6 +1790,24 @@ drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) DP_MSA_TIMING_PAR_IGNORED; } +/** + * drm_edp_backlight_supported() - Check an eDP DPCD for VESA backlight support + * @edp_dpcd: The DPCD to check + * + * Note that currently this function will return %false for panels which support various DPCD + * backlight features but which require the brightness be set through PWM, and don't support setting + * the brightness level via the DPCD. This is a TODO. + * + * Returns: %True if @edp_dpcd indicates that VESA backlight controls are supported, %false + * otherwise + */ +static inline bool +drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]) +{ + return (edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP) && + (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP); +} + /* * DisplayPort AUX channel */ @@ -2089,6 +2107,36 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk) return desc->quirks & BIT(quirk); } +/** + * struct drm_edp_backlight_info - Probed eDP backlight info struct + * @pwmgen_bit_count: The pwmgen bit count + * @pwm_freq_pre_divider: The PWM frequency pre-divider value being used for this backlight, if any + * @max: The maximum backlight level that may be set + * @lsb_reg_used: Do we also write values to the DP_EDP_BACKLIGHT_BRIGHTNESS_LSB register? + * @aux_enable: Does the panel support the AUX enable cap? + * + * This structure contains various data about an eDP backlight, which can be populated by using + * drm_edp_backlight_init(). + */ +struct drm_edp_backlight_info { + u8 pwmgen_bit_count; + u8 pwm_freq_pre_divider; + u16 max; + + bool lsb_reg_used : 1; + bool aux_enable : 1; +}; + +int +drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl, + u16 driver_pwm_freq_hz, const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE], + u16 *current_level, u8 *current_mode); +int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, + u16 level); +int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, +u16 level); +int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl); + #ifdef CONFIG_DRM_DP_CEC void drm_dp_cec_irq(struct drm_dp_aux *aux); void drm_dp_cec_register_connector(struct drm_dp_aux *aux, -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH][V2] drm/mgag200: make a const array static, makes object smaller
Merged. Am 04.02.21 um 20:11 schrieb Colin King: From: Colin Ian King Don't populate the const array m_div_val on the stack but instead make it static. Makes the object code smaller by 29 bytes: Before: text data bss dechex filename 34736 4552 0 39288 9978 drivers/gpu/drm/mgag200/mgag200_mode.o After: text data bss dechex filename 34625 4616 0 39241 9949 drivers/gpu/drm/mgag200/mgag200_mode.o (gcc version 10.2.0) Signed-off-by: Colin Ian King Reviewed-by: Thomas Zimmermann --- V2: move static declaration to the top of the declarations --- drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 1dfc42170059..c3dfde8cad25 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -706,13 +706,13 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) static int mga_g200er_set_plls(struct mga_device *mdev, long clock) { + static const unsigned int m_div_val[] = { 1, 2, 4, 8 }; unsigned int vcomax, vcomin, pllreffreq; unsigned int delta, tmpdelta; int testr, testn, testm, testo; unsigned int p, m, n; unsigned int computed, vco; int tmp; - const unsigned int m_div_val[] = { 1, 2, 4, 8 }; m = n = p = 0; vcomax = 1488000; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v6 02/10] Revert "drm/qxl: do not run release if qxl failed to init"
Hi Tong Am 04.02.21 um 19:52 schrieb Tong Zhang: Hi Thomas, The original problem was qxl_device_init() can fail, when it fails there is no need to call qxl_modeset_fini(qdev); qxl_device_fini(qdev); But those two functions are otherwise called in the qxl_drm_release() - OK, makes sense. Thanks for the explanation. I have posted an updated patch. The new patch use the following logic + if (!qdev->ddev.mode_config.funcs) + return; This is again just papering over the issue. Better don't call qxl_drm_release() in the error path if qxl_device_init() fails. I see two solutions: either roll-back manually, or use our new managed DRM interfaces. This is what the other drivers do. Best regards Thomas qxl_modeset_fini(qdev); qxl_device_fini(qdev); Thanks, - Tong On Feb 4, 2021, at 1:34 PM, Thomas Zimmermann wrote: Hi Am 04.02.21 um 15:57 schrieb Gerd Hoffmann: This reverts commit b91907a6241193465ca92e357adf16822242296d. This should be in the correct format, as given by 'dim cite'. dim cite b91907a6241193465ca92e357adf16822242296d b91907a62411 ("drm/qxl: do not run release if qxl failed to init") Patch is broken, it effectively makes qxl_drm_release() a nop because on normal driver shutdown qxl_drm_release() is called *after* drm_dev_unregister(). Cc: Tong Zhang Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 34c8b25b5780..fb5f6a5e81d7 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -144,8 +144,6 @@ static void qxl_drm_release(struct drm_device *dev) * reodering qxl_modeset_fini() + qxl_device_fini() calls is * non-trivial though. */ - if (!dev->registered) - return; I'm not sure what the original problem was, but I'm sure that this isn't the fix for it. If there's a problem with shutdown, the operations rather have to be reordered correctly. With the citation style address: Acked-by: Thomas Zimmermann qxl_modeset_fini(qdev); qxl_device_fini(qdev); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v6 02/10] Revert "drm/qxl: do not run release if qxl failed to init"
Hi Am 04.02.21 um 15:57 schrieb Gerd Hoffmann: This reverts commit b91907a6241193465ca92e357adf16822242296d. This should be in the correct format, as given by 'dim cite'. dim cite b91907a6241193465ca92e357adf16822242296d b91907a62411 ("drm/qxl: do not run release if qxl failed to init") Patch is broken, it effectively makes qxl_drm_release() a nop because on normal driver shutdown qxl_drm_release() is called *after* drm_dev_unregister(). Cc: Tong Zhang Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 34c8b25b5780..fb5f6a5e81d7 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -144,8 +144,6 @@ static void qxl_drm_release(struct drm_device *dev) * reodering qxl_modeset_fini() + qxl_device_fini() calls is * non-trivial though. */ - if (!dev->registered) - return; I'm not sure what the original problem was, but I'm sure that this isn't the fix for it. If there's a problem with shutdown, the operations rather have to be reordered correctly. With the citation style address: Acked-by: Thomas Zimmermann qxl_modeset_fini(qdev); qxl_device_fini(qdev); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/mgag200: make a const array static, makes object smaller
Hi Am 04.02.21 um 19:17 schrieb Colin King: From: Colin Ian King Don't populate the const array m_div_val on the stack but instead make it static. Makes the object code smaller by 29 bytes: Before: text data bss dechex filename 34736 4552 0 39288 9978 drivers/gpu/drm/mgag200/mgag200_mode.o After: text data bss dechex filename 34625 4616 0 39241 9949 drivers/gpu/drm/mgag200/mgag200_mode.o (gcc version 10.2.0) Signed-off-by: Colin Ian King Very nice. I'm actually surprised that the compiler doesn't figure this out automatically. When I once tested this (in userspace) it did so. Maybe the kernel is different? For style reasons, I would have moved the static definition to the top of the function; before the variable declarations. In any case: Reviewed-by: Thomas Zimmermann If I don't here from you, I'll merge the patch soonish. Best regards Thomas --- drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 1dfc42170059..27f33af09798 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -712,7 +712,7 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) unsigned int p, m, n; unsigned int computed, vco; int tmp; - const unsigned int m_div_val[] = { 1, 2, 4, 8 }; + static const unsigned int m_div_val[] = { 1, 2, 4, 8 }; m = n = p = 0; vcomax = 1488000; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v6 10/10] drm/qxl: allocate dumb buffers in ram
Am 04.02.21 um 15:57 schrieb Gerd Hoffmann: dumb buffers are shadowed anyway, so there is no need to store them in device memory. Use QXL_GEM_DOMAIN_CPU (TTM_PL_SYSTEM) instead. Makes sense. I had similar issues in other drivers about the placement of buffers. For them, all new buffers now go into system ram by default, and only move into device memory when they have to. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_dumb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index c04cd5a2553c..48a58ba1db96 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -59,7 +59,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, surf.stride = pitch; surf.format = format; r = qxl_gem_object_create_with_handle(qdev, file_priv, - QXL_GEM_DOMAIN_SURFACE, + QXL_GEM_DOMAIN_CPU, args->size, , , ); if (r) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v6 06/10] drm/qxl: properly pin/unpin shadow
Am 04.02.21 um 15:57 schrieb Gerd Hoffmann: Suggested-by: Thomas Zimmermann Signed-off-by: Gerd Hoffmann Thanks for this. Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_display.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 60331e31861a..d25fd3acc891 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -802,12 +802,14 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, } if (user_bo->shadow != qdev->dumb_shadow_bo) { if (user_bo->shadow) { + qxl_bo_unpin(user_bo->shadow); drm_gem_object_put (_bo->shadow->tbo.base); user_bo->shadow = NULL; } drm_gem_object_get(>dumb_shadow_bo->tbo.base); user_bo->shadow = qdev->dumb_shadow_bo; + qxl_bo_pin(user_bo->shadow); } } @@ -833,6 +835,7 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, qxl_bo_unpin(user_bo); if (old_state->fb != plane->state->fb && user_bo->shadow) { + qxl_bo_unpin(user_bo->shadow); drm_gem_object_put(_bo->shadow->tbo.base); user_bo->shadow = NULL; } @@ -1230,6 +1233,7 @@ int qxl_modeset_init(struct qxl_device *qdev) void qxl_modeset_fini(struct qxl_device *qdev) { if (qdev->dumb_shadow_bo) { + qxl_bo_unpin(qdev->dumb_shadow_bo); drm_gem_object_put(>dumb_shadow_bo->tbo.base); qdev->dumb_shadow_bo = NULL; } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v6 05/10] drm/qxl: release shadow on shutdown
Am 04.02.21 um 15:57 schrieb Gerd Hoffmann: In case we have a shadow surface on shutdown release it so it doesn't leak. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_display.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 38d6b596094d..60331e31861a 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1229,5 +1229,9 @@ int qxl_modeset_init(struct qxl_device *qdev) void qxl_modeset_fini(struct qxl_device *qdev) { + if (qdev->dumb_shadow_bo) { + drm_gem_object_put(>dumb_shadow_bo->tbo.base); + qdev->dumb_shadow_bo = NULL; + } qxl_destroy_monitors_object(qdev); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v5 6/6] drm/qxl: simplify qxl_fence_wait
Am 03.02.21 um 14:16 schrieb Gerd Hoffmann: Now that we have the new release_event wait queue we can just use that in qxl_fence_wait() and simplify the code alot. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_release.c | 42 +++ 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 43a5436853b7..b6f4b8dcf228 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -59,53 +59,19 @@ static long qxl_fence_wait(struct dma_fence *fence, bool intr, { struct qxl_device *qdev; struct qxl_release *release; - int count = 0, sc = 0; - bool have_drawable_releases; unsigned long cur, end = jiffies + timeout; qdev = container_of(fence->lock, struct qxl_device, release_lock); release = container_of(fence, struct qxl_release, base); - have_drawable_releases = release->type == QXL_RELEASE_DRAWABLE; - -retry: - sc++; if (dma_fence_is_signaled(fence)) goto signaled; qxl_io_notify_oom(qdev); - - for (count = 0; count < 11; count++) { - if (!qxl_queue_garbage_collect(qdev, true)) - break; - - if (dma_fence_is_signaled(fence)) - goto signaled; - } - - if (dma_fence_is_signaled(fence)) - goto signaled; - - if (have_drawable_releases || sc < 4) { - if (sc > 2) - /* back off */ - usleep_range(500, 1000); - - if (time_after(jiffies, end)) - return 0; - - if (have_drawable_releases && sc > 300) { - DMA_FENCE_WARN(fence, "failed to wait on release %llu " - "after spincount %d\n", - fence->context & ~0xf000, sc); - goto signaled; - } - goto retry; - } - /* -* yeah, original sync_obj_wait gave up after 3 spins when -* have_drawable_releases is not set. -*/ + if (!wait_event_timeout(qdev->release_event, + dma_fence_is_signaled(fence), + timeout)) + return 0; signaled: cur = jiffies; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v5 5/6] drm/qxl: properly free qxl releases
Am 03.02.21 um 14:16 schrieb Gerd Hoffmann: Reorganize qxl_device_fini() a bit. Add missing unpin() calls. Count releases. Add wait queue for releases. That way qxl_device_fini() can easily wait until everything is ready for proper shutdown. Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_drv.h | 2 ++ drivers/gpu/drm/qxl/qxl_cmd.c | 1 + drivers/gpu/drm/qxl/qxl_irq.c | 1 + drivers/gpu/drm/qxl/qxl_kms.c | 22 -- drivers/gpu/drm/qxl/qxl_release.c | 2 ++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 01354b43c413..6dd57cfb2e7c 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -214,6 +214,8 @@ struct qxl_device { spinlock_t release_lock; struct idr release_idr; uint32_trelease_seqno; + atomic_trelease_count; + wait_queue_head_t release_event; spinlock_t release_idr_lock; struct mutexasync_io_mutex; unsigned int last_sent_io_cmd; diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 54e3c3a97440..7e22a81bfb36 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -254,6 +254,7 @@ int qxl_garbage_collect(struct qxl_device *qdev) } } + wake_up_all(>release_event); DRM_DEBUG_DRIVER("%d\n", i); return i; diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c index ddf6588a2a38..d312322cacd1 100644 --- a/drivers/gpu/drm/qxl/qxl_irq.c +++ b/drivers/gpu/drm/qxl/qxl_irq.c @@ -87,6 +87,7 @@ int qxl_irq_init(struct qxl_device *qdev) init_waitqueue_head(>display_event); init_waitqueue_head(>cursor_event); init_waitqueue_head(>io_cmd_event); + init_waitqueue_head(>release_event); INIT_WORK(>client_monitors_config_work, qxl_client_monitors_config_work_func); atomic_set(>irq_received, 0); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 4a60a52ab62e..616aea948863 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -286,8 +286,26 @@ int qxl_device_init(struct qxl_device *qdev, void qxl_device_fini(struct qxl_device *qdev) { - qxl_bo_unref(>current_release_bo[0]); - qxl_bo_unref(>current_release_bo[1]); + int cur_idx; + + for (cur_idx = 0; cur_idx < 3; cur_idx++) { + if (!qdev->current_release_bo[cur_idx]) + continue; + qxl_bo_unpin(qdev->current_release_bo[cur_idx]); + qxl_bo_unref(>current_release_bo[cur_idx]); + qdev->current_release_bo_offset[cur_idx] = 0; + qdev->current_release_bo[cur_idx] = NULL; + } + + /* +* Ask host to release resources (+fill release ring), +* then wait for the release actually happening. +*/ + qxl_io_notify_oom(qdev); + wait_event_timeout(qdev->release_event, + atomic_read(>release_count) == 0, + HZ); + qxl_gem_fini(qdev); qxl_bo_fini(qdev); flush_work(>gc_work); diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 28013fd1f8ea..43a5436853b7 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -196,6 +196,7 @@ qxl_release_free(struct qxl_device *qdev, qxl_release_free_list(release); kfree(release); } + atomic_dec(>release_count); } static int qxl_release_bo_alloc(struct qxl_device *qdev, @@ -344,6 +345,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, *rbo = NULL; return idr_ret; } + atomic_inc(>release_count); mutex_lock(>release_mutex); if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v5 4/6] drm/qxl: handle shadow in primary destroy
Am 03.02.21 um 14:16 schrieb Gerd Hoffmann: qxl_primary_atomic_disable must check whenever the framebuffer bo has a shadow surface and in case it has check the shadow primary status. I believe you :) Acked-by: Thomas Zimmermann Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 60331e31861a..f5ee8cd72b5b 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -562,6 +562,8 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane, if (old_state->fb) { struct qxl_bo *bo = gem_to_qxl_bo(old_state->fb->obj[0]); + if (bo->shadow) + bo = bo->shadow; if (bo->is_primary) { qxl_io_destroy_primary(qdev); bo->is_primary = false; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v5 3/6] drm/qxl: release shadow on shutdown
Hi Am 03.02.21 um 14:16 schrieb Gerd Hoffmann: In case we have a shadow surface on shutdown release it so it doesn't leak. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 38d6b596094d..60331e31861a 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1229,5 +1229,9 @@ int qxl_modeset_init(struct qxl_device *qdev) void qxl_modeset_fini(struct qxl_device *qdev) { + if (qdev->dumb_shadow_bo) { + drm_gem_object_put(>dumb_shadow_bo->tbo.base); + qdev->dumb_shadow_bo = NULL; + } In qxl_plane_prepare_fb(), qdev->dumb_shadow_bo is being created as pinned object. Wouldn't it have to be unpinned here and during the release in qxl_plane_prepare_fb()? Best regards Thomas qxl_destroy_monitors_object(qdev); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v5 2/6] drm/qxl: unpin release objects
Am 03.02.21 um 14:16 schrieb Gerd Hoffmann: Balances the qxl_create_bo(..., pinned=true, ...); call in qxl_release_bo_alloc(). Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_release.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index c52412724c26..28013fd1f8ea 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -347,6 +347,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, mutex_lock(>release_mutex); if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { + qxl_bo_unpin(qdev->current_release_bo[cur_idx]); qxl_bo_unref(>current_release_bo[cur_idx]); qdev->current_release_bo_offset[cur_idx] = 0; qdev->current_release_bo[cur_idx] = NULL; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/nouveau: remove set but not used variable ‘pdev’ in nouveau_bios_init
Applied to drm-misc-next. Thanks for the patch! Am 23.01.21 um 02:30 schrieb Ye Bin: Fix follow warning: drivers/gpu/drm/nouveau/nouveau_bios.c:2086:18: warning: variable ‘pdev’ set but not used [-Wunused-but-set-variable] struct pci_dev *pdev; ^~~~ Reported-by: Hulk Robot Signed-off-by: Ye Bin --- drivers/gpu/drm/nouveau/nouveau_bios.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 7cc683b8dc7a..e8c445eb1100 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2083,13 +2083,11 @@ nouveau_bios_init(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); struct nvbios *bios = >vbios; - struct pci_dev *pdev; int ret; /* only relevant for PCI devices */ if (!dev_is_pci(dev->dev)) return 0; - pdev = to_pci_dev(dev->dev); if (!NVInitVBIOS(dev)) return -ENODEV; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: fbcon: remove soft scrollback code (missing Doc. patch)
Hi Am 15.01.21 um 09:06 schrieb Geert Uytterhoeven: Hi Daniel, On Thu, Jan 14, 2021 at 5:11 PM Daniel Vetter wrote: On Thu, Jan 14, 2021 at 4:56 PM Geert Uytterhoeven wrote: On Tue, Jan 12, 2021 at 5:00 PM Daniel Vetter wrote: On Sat, Jan 9, 2021 at 12:11 AM Linus Torvalds wrote: On Fri, Jan 8, 2021 at 11:13 AM Phillip Susi wrote: Could we pause this madness? Scrollback is still useful. I needed it today... it was too small, so command results I was looking for already scrolled away, but... life will be really painful with 0 scrollback. You'll need it, too... as soon as you get oops and will want to see errors just prior to that oops. If it means I get to maintain it... I'm not happy about it but that's better than no scrollback. Amen! What self respecting admin installs a gui on servers? What do we have to do to get this back in? What was so buggy with this code that it needed to be removed? Why was it such a burden to just leave it be? It really was buggy, with security implications. And we have no maintainers. So the scroll-back code can't come back until we have a maintainer and a cleaner and simpler implementation. And no, maintaining it really doesn't mean "just get it back to the old broken state". So far I haven't actually seen any patches, which means that it's not coming back. The good news? If you have an actual text VGA console, that should still work just fine. IIRC, all of this was written for systems lacking VGA text consoles in the first place... Also on anything that is remotely modern (i.e. runs a drm kernel modesetting driver undearneath the fbdev/fbcon stack) there's a pile more issues on top of just the scrollback/fbcon code being a mess. Would it help to remove DRM_FBDEV_EMULATION (instead)? Of the fbdev code, DRM's fbdev emulation is the cleanest. We now even have test cases for the userspace I/O. It's a problem with the hardware. "Write some registers and done" isn't how display blocks work nowadays. So your proposal amounts to "no fbdev/fbcon for anything modern-ish". With "modern-ish" actually meaning: "desktop/gaming/mobile-style 3D-accelerated wide-color display hardware". There's plenty of display hardware that doesn't fall into that class, and is served by fbdev (also out-of-tree due to the moratorium) because of that. Userspace has been moving away from fbdev. Writing an fbdev driver locks you into a legacy userspace. I also found that DRM drivers are smaller, because of all the DRM helper libraries. Using DRM + fbdev emulation is a win in almost any case. We did have some complaints about performance of the emulation. So that might be worth looking into. Best regards Thomas Also I said "a pile more", most of the issues in fbcon/fbdev code apply for all drivers. Specifically the locking is somewhere between yolo and outright deadlocks. This holds even more so if the use case here is "I want scrollback for an oops". There's rough sketches for how it could be solved, but it's all very tricky work. When an oops happens, all bets are off. At that point, all information you can extract from the system is valuable, and additional locking issues are moot. Except the first oops then scrolls aways because it's getting buried under further fail. Your locking needs to be minimally good enough to not make the situation worse. When an oops happens, all bets are off... Gr{oetje,eeting}s, Geert -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 3/4] drm/qxl: release shadow on shutdown
Hi Am 20.01.21 um 12:12 schrieb Gerd Hoffmann: In case we have a shadow surface on shutdown release it so it doesn't leak. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 38d6b596094d..60331e31861a 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1229,5 +1229,9 @@ int qxl_modeset_init(struct qxl_device *qdev) void qxl_modeset_fini(struct qxl_device *qdev) { + if (qdev->dumb_shadow_bo) { Wrt to my comment on patch 2, this might be the place to unpin the BO. + drm_gem_object_put(>dumb_shadow_bo->tbo.base); + qdev->dumb_shadow_bo = NULL; + } qxl_destroy_monitors_object(qdev); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 2/4] drm/qxl: unpin release objects
Hi Am 20.01.21 um 12:12 schrieb Gerd Hoffmann: Balances the qxl_create_bo(..., pinned=true, ...); call in qxl_release_bo_alloc(). Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_release.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 0fcfc952d5e9..add979cba11b 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -166,6 +166,7 @@ qxl_release_free_list(struct qxl_release *release) entry = container_of(release->bos.next, struct qxl_bo_list, tv.head); bo = to_qxl_bo(entry->tv.bo); + bo->tbo.pin_count = 0; /* ttm_bo_unpin(>tbo); */ This code looks like a workaround or a bug. AFAICT the only place with pre-pinned BO is qdev->dumb_shadow_bo. Can you remove the pinned flag entirely and handle pinning as part of dumb_shadow_bo's code. Otherwise maybe use if (pin_count) ttm_bo_unpin(); WARN_ON(pin_count); /* should always be 0 now */ with a comment similar to the commit's description. Best regards Thomas qxl_bo_unref(); list_del(>tv.head); kfree(entry); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3 1/4] drm/qxl: use drmm_mode_config_init
Am 20.01.21 um 12:12 schrieb Gerd Hoffmann: Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Acked-by: Thomas Zimmermann --- drivers/gpu/drm/qxl/qxl_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 012bce0cdb65..38d6b596094d 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1195,7 +1195,9 @@ int qxl_modeset_init(struct qxl_device *qdev) int i; int ret; - drm_mode_config_init(>ddev); + ret = drmm_mode_config_init(>ddev); + if (ret) + return ret; ret = qxl_create_monitors_object(qdev); if (ret) @@ -1228,5 +1230,4 @@ int qxl_modeset_init(struct qxl_device *qdev) void qxl_modeset_fini(struct qxl_device *qdev) { qxl_destroy_monitors_object(qdev); - drm_mode_config_cleanup(>ddev); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/ast: Update the sequence of Clearing Fast-reset
Hi Am 18.01.21 um 09:57 schrieb KuoHsiang Chou: [Bug][AST2500] If SCU00 is not unlocked, just enter its password again. It is unnecessary to clear AHB lock condition and restore WDT default setting again, before Fast-reset clearing. Signed-off-by: KuoHsiang Chou Is this a separate issue? This patch looks like a fix for the previous patch. [1] Can you add this change to v3 of the other patch? Best regards Thomas [1] https://lore.kernel.org/dri-devel/20210112075811.9354-1-kuohsiang_c...@aspeedtech.com/ --- drivers/gpu/drm/ast/ast_post.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 1f0007daa005..4f194c5fd2c2 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -2030,7 +2030,6 @@ void ast_patch_ahb_2500(struct ast_private *ast) { u32 data; -patch_ahb_lock: /* Clear bus lock condition */ ast_moutdwm(ast, 0x1e60, 0xAEED1A03); ast_moutdwm(ast, 0x1e600084, 0x0001); @@ -2044,11 +2043,9 @@ void ast_patch_ahb_2500(struct ast_private *ast) ast_moutdwm(ast, 0x1E78500c, 0x0033); udelay(1000); } - ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8); do { + ast_moutdwm(ast, 0x1e6e2000, 0x1688A8A8); data = ast_mindwm(ast, 0x1e6e2000); - if (data == 0x) - goto patch_ahb_lock; } while (data != 1); ast_moutdwm(ast, 0x1e6e207c, 0x0800); /* clear fast reset */ } -- 2.18.4 ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: Change eats memory on my server
Hi Am 18.01.21 um 14:23 schrieb Christian König: Am 18.01.21 um 14:22 schrieb Eli Cohen: On Mon, Jan 18, 2021 at 02:20:49PM +0100, Thomas Zimmermann wrote: Hi Am 18.01.21 um 14:16 schrieb Eli Cohen: On Mon, Jan 18, 2021 at 10:30:56AM +0100, Thomas Zimmermann wrote: Here's the patch against the latest DRM tree. v5.11-rc3 should work as well. I was able to reproduce the memory leak locally and found that the patch fixes it. Please give it a try. As far as I am concerned, this issue is fixed by the patch you sent. Thanks for looking into it. OK, great. I'll prepare the real patch soon. Can I add your Reported-by and Tested-by tags? Yes, sure. Feel free to add an Acked-by from my side as well. Done, thanks. I sent out the patch. If no one complains, I'll merge it on Wednesday or so. Best regards Thomas Christian. Best regards Thomas Eli -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: Change eats memory on my server
Hi Am 18.01.21 um 14:16 schrieb Eli Cohen: On Mon, Jan 18, 2021 at 10:30:56AM +0100, Thomas Zimmermann wrote: Here's the patch against the latest DRM tree. v5.11-rc3 should work as well. I was able to reproduce the memory leak locally and found that the patch fixes it. Please give it a try. As far as I am concerned, this issue is fixed by the patch you sent. Thanks for looking into it. OK, great. I'll prepare the real patch soon. Can I add your Reported-by and Tested-by tags? Best regards Thomas Eli -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: Change eats memory on my server
Hi Am 18.01.21 um 10:13 schrieb Eli Cohen: On Mon, Jan 18, 2021 at 08:54:07AM +0100, Thomas Zimmermann wrote: Hi Am 18.01.21 um 08:43 schrieb Christian König: Hi Eli, have you already tried using kmemleak? This sounds like a leak of memory allocated using kmalloc(), so kmemleak should be able to catch it. I have an idea what happens here. When the refcount is 0 in kmap, a new page mapping for the BO is being established. But VRAM helpers unmap the previous pages only on BO moves or frees; not in kunmap. So the old mapping might still be around. I'll send out a test patch later today. Great! Looking forward to test it. Here's the patch against the latest DRM tree. v5.11-rc3 should work as well. I was able to reproduce the memory leak locally and found that the patch fixes it. Please give it a try. Best regards Thomas Best regards Thomas Regards, Christian. Am 17.01.21 um 06:08 schrieb Eli Cohen: On Fri, Jan 15, 2021 at 10:03:50AM +0100, Thomas Zimmermann wrote: Could you please double-check that 3fb91f56aea4 ("drm/udl: Retrieve USB device from struct drm_device.dev") works correctly Checked again, it does not seem to leak. and that 823efa922102 ("drm/cma-helper: Remove empty drm_gem_cma_prime_vunmap()") is broken? Yes, this one leaks, as does the one preceding it: 1086db71a1db ("drm/vram-helper: Remove invariant parameters from internal kmap function") For one of the broken commits, could you please send us the output of dmesg | grep -i drm after most of the memory got leaked? I ran the following script in the shell: while true; do cat /proc/meminfo | grep MemFree:; sleep 5; done and this is what I saw before I got disconnected from the shell: MemFree: 148208 kB MemFree: 148304 kB MemFree: 146660 kB Connection to nps-server-24 closed by remote host. Connection to nps-server-24 closed. I also mointored the output of dmesg | grep -i drm The last output I was able to save on disk is this: [ 46.140720] ast :03:00.0: [drm] Using P2A bridge for configuration [ 46.140737] ast :03:00.0: [drm] AST 2500 detected [ 46.140754] ast :03:00.0: [drm] Analog VGA only [ 46.140772] ast :03:00.0: [drm] dram MCLK=800 Mhz type=7 bus_width=16 [ 46.153553] [drm] Initialized ast 0.1.0 20120228 for :03:00.0 on minor 0 [ 46.165097] fbcon: astdrmfb (fb0) is primary device [ 46.391381] ast :03:00.0: [drm] fb0: astdrmfb frame buffer device [ 56.097697] systemd[1]: Starting Load Kernel Module drm... [ 56.343556] systemd[1]: modprobe@drm.service: Succeeded. [ 56.350382] systemd[1]: Finished Load Kernel Module drm. [13319.469462] [ 2683] 70889 2683 55586 0 73728 138 0 tdrm [13320.658386] [ 2683] 70889 2683 55586 0 73728 138 0 tdrm [13321.800970] [ 2683] 70889 2683 55586 0 73728 138 0 tdrm ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer From e8462600662621db47bccf8174bf683513aa7102 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 18 Jan 2021 09:58:07 +0100 Subject: [PATCH] drm/vram-helper: Reuse existing page mappings in vmap For performance, BO page mappings can stay in place even if the map counter has returned to 0. In these cases, the existing page mapping has to be reused by the next vmap operation. Otherwise a new mapping would be installed and the old mapping's pages leak. Fix the issue by reusing existing page mappings for vmap operations. Signed-off-by: Thomas Zimmermann Reported-by: Eli Cohen --- drivers/gpu/drm/drm_gem_vram_helper.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 02ca22e90290..a57790b0d985 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -387,9 +387,16 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo, if (gbo->vmap_use_count > 0) goto out; - ret = ttm_bo_vmap(>bo, >map); - if (ret) - return ret; + /* + * VRAM helpers unmap the BO only on demand. So the previous + * page mapping might still be arround. Only vmap if the there's + * no mapping present. + */ + if (dma_buf_map_is_null(>map)) { + ret = ttm_bo_vmap(>bo, >map); + if (ret) + return ret; + } out: ++gbo->vmap_use_count; @@ -577,6 +584,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm
Re: [PATCH v2] drm/ast: Disable fast reset after DRAM initial
ast_moutdwm(ast, 0x1E78502C, 0x); + ast_moutdwm(ast, 0x1E78504C, 0x); + /* Reset USB port */ + ast_moutdwm(ast, 0x1E6E2090, 0x2000); + ast_moutdwm(ast, 0x1E6E2094, 0x4000); + if (ast_mindwm(ast, 0x1E6E2070) & 0x0080) { + ast_moutdwm(ast, 0x1E6E207C, 0x0080); + mdelay(100); + ast_moutdwm(ast, 0x1E6E2070, 0x0080); + } + /* Modify eSPI reset pin */ + temp = ast_mindwm(ast, 0x1E6E2070); + if (temp & 0x0200) + ast_moutdwm(ast, 0x1E6E207C, 0x4000); Instead of answering my question, you simply deleted the comments. It doesn't work like that. Best regards Thomas /* Slow down CPU/AHB CLK in VGA only mode */ temp = ast_read32(ast, 0x12008); temp |= 0x73; ast_write32(ast, 0x12008, temp); - /* Reset USB port to patch USB unknown device issue */ - ast_moutdwm(ast, 0x1e6e2090, 0x2000); - temp = ast_mindwm(ast, 0x1e6e2094); - temp |= 0x4000; - ast_moutdwm(ast, 0x1e6e2094, temp); - temp = ast_mindwm(ast, 0x1e6e2070); - if (temp & 0x0080) { - ast_moutdwm(ast, 0x1e6e207c, 0x0080); - mdelay(100); - ast_moutdwm(ast, 0x1e6e2070, 0x0080); - } - if (!ast_dram_init_2500(ast)) drm_err(dev, "DRAM init failed !\n"); -- 2.18.4 ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: Change eats memory on my server
Hi Am 18.01.21 um 08:43 schrieb Christian König: Hi Eli, have you already tried using kmemleak? This sounds like a leak of memory allocated using kmalloc(), so kmemleak should be able to catch it. I have an idea what happens here. When the refcount is 0 in kmap, a new page mapping for the BO is being established. But VRAM helpers unmap the previous pages only on BO moves or frees; not in kunmap. So the old mapping might still be around. I'll send out a test patch later today. Best regards Thomas Regards, Christian. Am 17.01.21 um 06:08 schrieb Eli Cohen: On Fri, Jan 15, 2021 at 10:03:50AM +0100, Thomas Zimmermann wrote: Could you please double-check that 3fb91f56aea4 ("drm/udl: Retrieve USB device from struct drm_device.dev") works correctly Checked again, it does not seem to leak. and that 823efa922102 ("drm/cma-helper: Remove empty drm_gem_cma_prime_vunmap()") is broken? Yes, this one leaks, as does the one preceding it: 1086db71a1db ("drm/vram-helper: Remove invariant parameters from internal kmap function") For one of the broken commits, could you please send us the output of dmesg | grep -i drm after most of the memory got leaked? I ran the following script in the shell: while true; do cat /proc/meminfo | grep MemFree:; sleep 5; done and this is what I saw before I got disconnected from the shell: MemFree: 148208 kB MemFree: 148304 kB MemFree: 146660 kB Connection to nps-server-24 closed by remote host. Connection to nps-server-24 closed. I also mointored the output of dmesg | grep -i drm The last output I was able to save on disk is this: [ 46.140720] ast :03:00.0: [drm] Using P2A bridge for configuration [ 46.140737] ast :03:00.0: [drm] AST 2500 detected [ 46.140754] ast :03:00.0: [drm] Analog VGA only [ 46.140772] ast :03:00.0: [drm] dram MCLK=800 Mhz type=7 bus_width=16 [ 46.153553] [drm] Initialized ast 0.1.0 20120228 for :03:00.0 on minor 0 [ 46.165097] fbcon: astdrmfb (fb0) is primary device [ 46.391381] ast :03:00.0: [drm] fb0: astdrmfb frame buffer device [ 56.097697] systemd[1]: Starting Load Kernel Module drm... [ 56.343556] systemd[1]: modprobe@drm.service: Succeeded. [ 56.350382] systemd[1]: Finished Load Kernel Module drm. [13319.469462] [ 2683] 70889 2683 55586 0 73728 138 0 tdrm [13320.658386] [ 2683] 70889 2683 55586 0 73728 138 0 tdrm [13321.800970] [ 2683] 70889 2683 55586 0 73728 138 0 tdrm ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3] drm: Improve the output_poll_changed description
Hi Am 18.01.21 um 02:22 schrieb ZhiJie.Zhang: From: zhangzhijie this callback was used by drm_kms_helper_hotplug_event() V2: (Thanks for Daniel's suggestions) - remove the FIXME below.since with the drm_client - infrastructure and the generic fbdev emulation we've - resolved this all very neatly now. V3: Add comments that This hook is deprecated - new implementation methods instead of this hook Signed-off-by: zhangzhijie Signed-off-by: ZhiJie.Zhang --- include/drm/drm_mode_config.h | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index ab424ddd7665..a084482d579a 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -103,14 +103,14 @@ struct drm_mode_config_funcs { * Callback used by helpers to inform the driver of output configuration * changes. * -* Drivers implementing fbdev emulation with the helpers can call -* drm_fb_helper_hotplug_changed from this hook to inform the fbdev +* Drivers implementing fbdev emulation with the helpers. Drivers use +* drm_kms_helper_hotplug_event() to call this hook to inform the fbdev I don't understand this. Maybe it's "Drivers implementing fbdev emulation use drm_kms_helper_hotplug_event() to call ..." ? Best regards Thomas * helper of output changes. * -* FIXME: -* -* Except that there's no vtable for device-level helper callbacks -* there's no reason this is a core function. +* This hook is deprecated, drivers should instead use +* drm_fbdev_generic_setup() which takes care of any necessary +* hotplug event forwarding already without further involvement by +* the driver. */ void (*output_poll_changed)(struct drm_device *dev); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 02/10] drm: Rename plane atomic_check state names
Hi Am 15.01.21 um 13:56 schrieb Maxime Ripard: diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 8a4235d9d9f1..2cb09e9d9306 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -344,12 +344,12 @@ static const struct drm_plane_funcs ipu_plane_funcs = { }; static int ipu_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_plane_state *new_state) It's not 'new_plane_state' ? Best regards Thomas { struct drm_plane_state *old_state = plane->state; struct drm_crtc_state *crtc_state; struct device *dev = plane->dev->dev; - struct drm_framebuffer *fb = state->fb; + struct drm_framebuffer *fb = new_state->fb; struct drm_framebuffer *old_fb = old_state->fb; unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba; bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY); @@ -359,15 +359,16 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, if (!fb) return 0; - if (WARN_ON(!state->crtc)) + if (WARN_ON(!new_state->crtc)) return -EINVAL; crtc_state = - drm_atomic_get_existing_crtc_state(state->state, state->crtc); + drm_atomic_get_existing_crtc_state(new_state->state, + new_state->crtc); if (WARN_ON(!crtc_state)) return -EINVAL; - ret = drm_atomic_helper_check_plane_state(state, crtc_state, + ret = drm_atomic_helper_check_plane_state(new_state, crtc_state, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, can_position, true); @@ -381,7 +382,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, switch (plane->type) { case DRM_PLANE_TYPE_PRIMARY: /* full plane minimum width is 13 pixels */ - if (drm_rect_width(>dst) < 13) + if (drm_rect_width(_state->dst) < 13) return -EINVAL; break; case DRM_PLANE_TYPE_OVERLAY: @@ -391,7 +392,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - if (drm_rect_height(>dst) < 2) + if (drm_rect_height(_state->dst) < 2) return -EINVAL; /* @@ -402,12 +403,12 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, * callback. */ if (old_fb && - (drm_rect_width(>dst) != drm_rect_width(_state->dst) || -drm_rect_height(>dst) != drm_rect_height(_state->dst) || + (drm_rect_width(_state->dst) != drm_rect_width(_state->dst) || +drm_rect_height(_state->dst) != drm_rect_height(_state->dst) || fb->format != old_fb->format)) crtc_state->mode_changed = true; - eba = drm_plane_state_to_eba(state, 0); + eba = drm_plane_state_to_eba(new_state, 0); if (eba & 0x7) return -EINVAL; @@ -433,7 +434,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, * - Only EBA may be changed while scanout is active * - The strides of U and V planes must be identical. */ - vbo = drm_plane_state_to_vbo(state); + vbo = drm_plane_state_to_vbo(new_state); if (vbo & 0x7 || vbo > 0xf8) return -EINVAL; @@ -450,7 +451,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, fallthrough; case DRM_FORMAT_NV12: case DRM_FORMAT_NV16: - ubo = drm_plane_state_to_ubo(state); + ubo = drm_plane_state_to_ubo(new_state); if (ubo & 0x7 || ubo > 0xf8) return -EINVAL; @@ -471,8 +472,8 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, * The x/y offsets must be even in case of horizontal/vertical * chroma subsampling. */ - if (((state->src.x1 >> 16) & (fb->format->hsub - 1)) || - ((state->src.y1 >> 16) & (fb->format->vsub - 1))) + if (((new_state->src.x1 >> 16) & (fb->format->hsub - 1)) || + ((new_state->src.y1 >> 16) & (fb->format->vsub - 1))) return -EINVAL; break; case DRM_FORMAT_RGB565_A8: @@ -481,7 +482,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, case DRM_FORMAT_BGR888_A8: case DRM_FORMAT_RGBX_A8: case DRM_FORMAT_BGRX_A8: - alpha_eba = drm_plane_state_to_eba(state, 1); + alpha_eba = drm_plane_state_to_eba(new_state, 1); if
Re: [PATCH 01/10] drm/atomic: Pass the full state to planes async atomic check and update
ible; - new_vc4_state = to_vc4_plane_state(state); + new_vc4_state = to_vc4_plane_state(new_plane_state); vc4_state = to_vc4_plane_state(plane->state); vc4_state->crtc_x = new_vc4_state->crtc_x; @@ -1187,23 +1189,25 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, } static int vc4_plane_atomic_async_check(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_atomic_state *state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); struct vc4_plane_state *old_vc4_state, *new_vc4_state; int ret; u32 i; - ret = vc4_plane_mode_set(plane, state); + ret = vc4_plane_mode_set(plane, new_plane_state); if (ret) return ret; old_vc4_state = to_vc4_plane_state(plane->state); - new_vc4_state = to_vc4_plane_state(state); + new_vc4_state = to_vc4_plane_state(new_plane_state); if (old_vc4_state->dlist_count != new_vc4_state->dlist_count || old_vc4_state->pos0_offset != new_vc4_state->pos0_offset || old_vc4_state->pos2_offset != new_vc4_state->pos2_offset || old_vc4_state->ptr0_offset != new_vc4_state->ptr0_offset || - vc4_lbm_size(plane->state) != vc4_lbm_size(state)) + vc4_lbm_size(plane->state) != vc4_lbm_size(new_plane_state)) return -EINVAL; /* Only pos0, pos2 and ptr0 DWORDS can be updated in an async update diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index cbe613858a93..a7141e6e05c5 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -1286,7 +1286,7 @@ struct drm_plane_helper_funcs { /** * @atomic_async_check: * -* Drivers should set this function pointer to check if the plane state +* Drivers should set this function pointer to check if the atomic state Using 'atomic state' sounds like all of it. I'd keep 'plane state' or use 'plane's atomic state' to be more precise. In any case: Acked-by: Thomas Zimmermann * can be updated in a async fashion. Here async means "not vblank * synchronized". * @@ -1300,7 +1300,7 @@ struct drm_plane_helper_funcs { * can not be applied in asynchronous manner. */ int (*atomic_async_check)(struct drm_plane *plane, - struct drm_plane_state *state); + struct drm_atomic_state *state); /** * @atomic_async_update: @@ -1316,11 +1316,9 @@ struct drm_plane_helper_funcs { * update won't happen if there is an outstanding commit modifying * the same plane. * -* Note that unlike _plane_helper_funcs.atomic_update this hook -* takes the new _plane_state as parameter. When doing async_update - * drivers shouldn't replace the _plane_state but update the -* current one with the new plane configurations in the new -* plane_state. +* When doing async_update drivers shouldn't replace the +* _plane_state but update the current one with the new plane +* configurations in the new plane_state. * * Drivers should also swap the framebuffers between current plane * state (_plane.state) and new_state. @@ -1339,7 +1337,7 @@ struct drm_plane_helper_funcs { *for deferring if needed, until a common solution is created. */ void (*atomic_async_update)(struct drm_plane *plane, - struct drm_plane_state *new_state); + struct drm_atomic_state *state); }; /** -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: Change eats memory on my server
(cc'ing dri-devel) Hi Am 14.01.21 um 16:15 schrieb Eli Cohen: Hi Thomas, After long bisecting I found that this patch, commit 1086db71a1dbbfb32ffb42cf0d540b69956f951e Author: Thomas Zimmermann Date: Tue Nov 3 10:30:06 2020 +0100 drm/vram-helper: Remove invariant parameters from internal kmap function is the offending patch causing the kernel to eat my server memory. It will eat all 24 GB of ram after around 7 hours. Thanks for reporting. It's a bit strange that this commit shows up, because there's nothing that should produce a memory leak. Could you please double-check that 3fb91f56aea4 ("drm/udl: Retrieve USB device from struct drm_device.dev") works correctly and that 823efa922102 ("drm/cma-helper: Remove empty drm_gem_cma_prime_vunmap()") is broken? For one of the broken commits, could you please send us the output of dmesg | grep -i drm after most of the memory got leaked? Best regards Thomas It's a a super micro server. The output of dmidecode is below: # dmidecode 3.2 Getting SMBIOS data from sysfs. SMBIOS 3.1.1 present. Table at 0x6F01B000. Handle 0x, DMI type 0, 26 bytes BIOS Information Vendor: American Megatrends Inc. Version: 2.0 Release Date: 11/30/2017 Address: 0xF Runtime Size: 64 kB ROM Size: 32 MB Characteristics: PCI is supported BIOS is upgradeable BIOS shadowing is allowed Boot from CD is supported Selectable boot is supported BIOS ROM is socketed EDD is supported 5.25"/1.2 MB floppy services are supported (int 13h) 3.5"/720 kB floppy services are supported (int 13h) 3.5"/2.88 MB floppy services are supported (int 13h) Print screen service is supported (int 5h) Serial services are supported (int 14h) Printer services are supported (int 17h) ACPI is supported USB legacy is supported BIOS boot specification is supported Targeted content distribution is supported UEFI is supported BIOS Revision: 5.12 Handle 0x0001, DMI type 1, 27 bytes System Information Manufacturer: Supermicro Product Name: Super Server Version: 0123456789 Serial Number: 0123456789 UUID: ----0cc47af973ca Wake-up Type: Power Switch SKU Number: To be filled by O.E.M. Family: To be filled by O.E.M. Handle 0x0002, DMI type 2, 15 bytes Base Board Information Manufacturer: Supermicro Product Name: X11DPT-B Version: 1.02 Serial Number: HM179S003332 Asset Tag: To be filled by O.E.M. Features: Board is a hosting board Board is replaceable Location In Chassis: To be filled by O.E.M. Chassis Handle: 0x0003 Type: Motherboard Contained Object Handles: 0 Handle 0x0003, DMI type 3, 22 bytes Chassis Information Manufacturer: Supermicro Type: Main Server Chassis Lock: Not Present Version: 0123456789 Serial Number: 0123456789 Asset Tag: To be filled by O.E.M. Boot-up State: Safe Power Supply State: Safe Thermal State: Safe Security Status: None OEM Information: 0x Height: Unspecified Number Of Power Cords: 1 Contained Elements: 0 SKU Number: To be filled by O.E.M. Handle 0x0004, DMI type 8, 9 bytes Port Connector Information Internal Reference Designator: JVGA1 Internal Connector Type: None External Reference Designator: VGA External Connector Type: DB-15 female Port Type: Video Port Handle 0x0005, DMI type 8, 9 bytes Port Connector Information Internal Reference Designator: JLAN1 Internal Connector Type: None External Reference Designator: IPMI_LAN External Connector Type: RJ-45 Port Type: Network Port Handle 0x0006, DMI type 8, 9 bytes Port Connector Information Internal Reference Designator: JUSB1 Internal Connector Type: None External Reference Designator: USB0/1(3.0) External Connector Type: Access Bus (USB) Port Type: USB Handle 0x0007, DMI type 8, 9 bytes Port Connector Information Internal Reference Designator: TPM/PORT80 Internal Connector Type: Other External Reference Designator: Not Specified External Connector Type: None Port Type: Other Handle 0x0008, DMI type 8, 9 bytes Port Connector Information Internal Reference Designator: FAN3 Internal Connector Type: Other External Reference Designator: Not Specified External Connector Type: None Port Type: Other Handle 0x0009,
Re: linux-next: build failure after merge of the drm-misc tree
Hi Am 14.01.21 um 01:31 schrieb Stephen Rothwell: Hi all, After merging the drm-misc tree, today's linux-next build (arm multi_v7_defconfig) failed like this: drivers/gpu/drm/drm_cache.c: In function 'drm_need_swiotlb': drivers/gpu/drm/drm_cache.c:202:6: error: implicit declaration of function 'mem_encrypt_active' [-Werror=implicit-function-declaration] 202 | if (mem_encrypt_active()) | ^~ Caused by commit 3abc66706385 ("drm: Implement drm_need_swiotlb() in drm_cache.c") I have used the drm-misc tree from next-20210107 again for today. Sorry for the breakage. Fixed in drm-misc-next. Best regards Thomas -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/hisilicon: Use drm_crtc_mask()
Hi Am 11.01.21 um 04:30 schrieb Tian Tao: Use drm_crtc_mask() where appropriate. Signed-off-by: Tian Tao Looks like the right thing to do. Acked-by: Thomas Zimmermann Best regards Thomas --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index c76f996..1c5f2fa 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -96,6 +96,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) struct drm_device *dev = >dev; struct hibmc_connector *hibmc_connector = >connector; struct drm_encoder *encoder = >encoder; + struct drm_crtc *crtc = >crtc; struct drm_connector *connector = _connector->base; int ret; @@ -105,7 +106,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) return ret; } - encoder->possible_crtcs = 0x1; + encoder->possible_crtcs = drm_crtc_mask(crtc); ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); if (ret) { drm_err(dev, "failed to init encoder: %d\n", ret); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/ast: Disable fast reset after DRAM initial
0x1E78504C, 0x); + /* Reset USB port */ + ast_moutdwm(ast, 0x1E6E2090, 0x2000); /* add at V1.2 */ + ast_moutdwm(ast, 0x1E6E2094, 0x4000); /* add at V1.2 */ + if (ast_mindwm(ast, 0x1E6E2070) & 0x0080) { /* add at V1.2 */ + ast_moutdwm(ast, 0x1E6E207C, 0x0080); /* add at V1.2 */ + mdelay(100);/* add at V1.2 */ + ast_moutdwm(ast, 0x1E6E2070, 0x0080); /* add at V1.2 */ + } /* add at V1.2 */ + /* Modify eSPI reset pin */ + temp = ast_mindwm(ast, 0x1E6E2070); /* add at V1.3 */ + if (temp & 0x0200) {/* add at V1.3 */ + ast_moutdwm(ast, 0x1E6E207C, 0x4000); /* add at V1.3 */ + } Do these v1.2 and v1.3 code paths not need a version check in the code? Best regards Thomas /* Slow down CPU/AHB CLK in VGA only mode */ temp = ast_read32(ast, 0x12008); temp |= 0x73; ast_write32(ast, 0x12008, temp); - /* Reset USB port to patch USB unknown device issue */ - ast_moutdwm(ast, 0x1e6e2090, 0x2000); - temp = ast_mindwm(ast, 0x1e6e2094); - temp |= 0x4000; - ast_moutdwm(ast, 0x1e6e2094, temp); - temp = ast_mindwm(ast, 0x1e6e2070); - if (temp & 0x0080) { - ast_moutdwm(ast, 0x1e6e207c, 0x0080); - mdelay(100); - ast_moutdwm(ast, 0x1e6e2070, 0x0080); - } - if (!ast_dram_init_2500(ast)) drm_err(dev, "DRAM init failed !\n"); -- 2.18.4 ___ dri-devel mailing list dri-de...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/hisilicon: Use simple encoder
Hi Am 28.12.20 um 08:35 schrieb Tian Tao: The hibmc driver uses empty implementations for its encoders. Replace the code with the generic simple encoder. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Thanks for the patch. --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index d35548d..c76f996 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "hibmc_drm_drv.h" #include "hibmc_drm_regs.h" @@ -90,10 +91,6 @@ static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = { .mode_set = hibmc_encoder_mode_set, }; -static const struct drm_encoder_funcs hibmc_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - int hibmc_vdac_init(struct hibmc_drm_private *priv) { struct drm_device *dev = >dev; @@ -109,8 +106,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) } encoder->possible_crtcs = 0x1; - ret = drm_encoder_init(dev, encoder, _encoder_funcs, - DRM_MODE_ENCODER_DAC, NULL); + ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); if (ret) { drm_err(dev, "failed to init encoder: %d\n", ret); return ret; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v2] drm/hisilicon: Add load and unload callback functions
Hi, and a happy new year. Am 24.12.20 um 09:45 schrieb Tian Tao: Add the callback functions of drm_driver structure member functions load and unload, no need to call load in the hibmc_pci_probe function and unload in the hibmc_pci_remove function. The load and unload callbacks are left over from long ago. They are now deprecated.* Don't use them. v2: remove the hibmc_unload called from hibmc_pic_remove. If anything, you'd want to inline hibmc's load/unload into their callers. Best regards Thomas *) White lie: They are used by the old non-KMS drivers. Anything with KMS should not use them. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 18 +++--- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 0d4e902..10042cf 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -27,6 +27,9 @@ DEFINE_DRM_GEM_FOPS(hibmc_fops); +static int hibmc_load(struct drm_device *dev, unsigned long flags); +static void hibmc_unload(struct drm_device *dev); + static irqreturn_t hibmc_drm_interrupt(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg; @@ -63,6 +66,8 @@ static const struct drm_driver hibmc_driver = { .dumb_map_offset= drm_gem_vram_driver_dumb_mmap_offset, .gem_prime_mmap = drm_gem_prime_mmap, .irq_handler= hibmc_drm_interrupt, + .load = hibmc_load, + .unload = hibmc_unload, }; static int __maybe_unused hibmc_pm_suspend(struct device *dev) @@ -248,7 +253,7 @@ static int hibmc_hw_init(struct hibmc_drm_private *priv) return 0; } -static int hibmc_unload(struct drm_device *dev) +static void hibmc_unload(struct drm_device *dev) { drm_atomic_helper_shutdown(dev); @@ -256,11 +261,9 @@ static int hibmc_unload(struct drm_device *dev) drm_irq_uninstall(dev); pci_disable_msi(dev->pdev); - - return 0; } -static int hibmc_load(struct drm_device *dev) +static int hibmc_load(struct drm_device *dev, unsigned long flags) { struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int ret; @@ -335,12 +338,6 @@ static int hibmc_pci_probe(struct pci_dev *pdev, goto err_return; } - ret = hibmc_load(dev); - if (ret) { - drm_err(dev, "failed to load hibmc: %d\n", ret); - goto err_return; - } - ret = drm_dev_register(dev, 0); if (ret) { drm_err(dev, "failed to register drv for userspace access: %d\n", @@ -363,7 +360,6 @@ static void hibmc_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); drm_dev_unregister(dev); - hibmc_unload(dev); } static const struct pci_device_id hibmc_pci_table[] = { -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/hisilicon: Fix rmmod hibmc_drm failed
Hi Tian Am 15.12.20 um 04:01 schrieb Tian Tao: drm_irq_uninstall should be called before pci_disable_msi, if use devm_drm_irq_install to register the interrupt, the system will call pci_disable_msi first and then call drm_irq_uninstall, which will result in the following callstack. kernel BUG at drivers/pci/msi.c:376! Internal error: Oops - BUG: 0 [#1] SMP CPU: 93 PID: 173814 Comm: rmmod Tainted: pstate: a049 (NzCv daif +PAN -UAO -TCO BTYPE=--) pc : free_msi_irqs+0x17c/0x1a0 lr : free_msi_irqs+0x16c/0x1a0 sp : 2028157f7bd0 x29: 2028157f7bd0 x28: 202849edab00 x27: x26: x25: x24: x23: 0020851da000 x22: 0020851da2d8 x21: 0020cc829000 x20: x19: 0020d6714800 x18: 0010 x17: x16: x15: x14: 2028957f77df x13: 2028157f77ed x12: x11: 0040 x10: 800011b2f8e0 x9 : 800011b2f8d8 x8 : 2020203fc458 x7 : x6 : x5 : 2020203fc430 x4 : 2020203fc4a0 x3 : x2 : x1 : 02c9 x0 : 0020d6719500 Call trace: free_msi_irqs+0x17c/0x1a0 pci_disable_msi+0xe4/0x118 hibmc_unload+0x44/0x80 [hibmc_drm] hibmc_pci_remove+0x2c/0x38 [hibmc_drm] pci_device_remove+0x48/0x108 device_release_driver_internal+0x118/0x1f0 driver_detach+0x6c/0xe0 bus_remove_driver+0x74/0x100 driver_unregister+0x34/0x60 pci_unregister_driver+0x24/0xd8 hibmc_pci_driver_exit+0x14/0xe768 [hibmc_drm] __arm64_sys_delete_module+0x1fc/0x2d0 el0_svc_common.constprop.3+0xa8/0x188 do_el0_svc+0x80/0xa0 el0_sync_handler+0x8c/0xb0 el0_sync+0x15c/0x180 Code: f940b400 b400 a903e7b8 f90013b5 (d421) ---[ end trace 310d94ee8abef44f ]--- Kernel panic - not syncing: Oops - BUG: Fatal exception Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index e3ab765b..02f3bd1 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -251,6 +251,10 @@ static int hibmc_hw_init(struct hibmc_drm_private *priv) static int hibmc_unload(struct drm_device *dev) { drm_atomic_helper_shutdown(dev); + + if (dev->irq_enabled) + drm_irq_uninstall(dev); + pci_disable_msi(dev->pdev); We're trying to move towards managed driver releases; and this feels like a step backwards. I looked through the PCI-device release code in pcim_release() and it already disables MSI automatically. [1] You can enable the PCI device with pcim_enable_device() instead of pci_enable_device() to use the automatic release. No more need to disable MSI manually. If this does not work, could you provide a managed version of pci_disable_msi() that solves the problem? Best regards Thomas [1] https://elixir.bootlin.com/linux/latest/source/drivers/pci/pci.c#L1976 return 0; @@ -286,7 +290,7 @@ static int hibmc_load(struct drm_device *dev) if (ret) { drm_warn(dev, "enabling MSI failed: %d\n", ret); } else { - ret = devm_drm_irq_install(dev, dev->pdev->irq); + ret = drm_irq_install(dev, dev->pdev->irq); if (ret) drm_warn(dev, "install irq failed: %d\n", ret); } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/drv: switch to using devm_add_action_or_reset()
Am 07.12.20 um 02:04 schrieb Tian Tao: switch to using devm_add_action_or_reset() instead of devm_add_action. Signed-off-by: Tian Tao I'm surprised that devm_drm_dev_init() didn't already use devm_add_action_or_reset(). But it doesn't look special, so Acked-by: Thomas Zimmermann --- drivers/gpu/drm/drm_drv.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 7343038..b92f7fd 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -675,11 +675,8 @@ static int devm_drm_dev_init(struct device *parent, if (ret) return ret; - ret = devm_add_action(parent, devm_drm_dev_init_release, dev); - if (ret) - devm_drm_dev_init_release(dev); - - return ret; + return devm_add_action_or_reset(parent, + devm_drm_dev_init_release, dev); } void *__devm_drm_dev_alloc(struct device *parent, -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Use managed mode-config init
Hi Am 07.12.20 um 10:29 schrieb tiantao (H): 在 2020/12/7 17:22, Thomas Zimmermann 写道: Hi Am 07.12.20 um 10:05 schrieb Tian Tao: Using drmm_mode_config_init() sets up managed release of modesetting resources. Individual patches usually contain a changelog to highlight the difference to previous versions. Please add one before committing the Just to be sure: I don't need to add a changlog to this individual patch, right? You should. It's supposed to be good style to add a changelog for each patch and also highlight the series' overall changes in the cover letter. Best regards Thomas patch. Your cover letter for the series already does this correctly. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Thanks for all these updates. Thank you for your constant help with the review code and your careful guidance! --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 14 +++--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 - 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 3687753..7f01213 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -96,8 +96,9 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) struct drm_device *dev = >dev; int ret; - drm_mode_config_init(dev); - priv->mode_config_initialized = true; + ret = drmm_mode_config_init(dev); + if (ret) + return ret; dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; @@ -125,14 +126,6 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) return 0; } -static void hibmc_kms_fini(struct hibmc_drm_private *priv) -{ - if (priv->mode_config_initialized) { - drm_mode_config_cleanup(>dev); - priv->mode_config_initialized = false; - } -} - /* * It can operate in one of three modes: 0, 1 or Sleep. */ @@ -262,7 +255,6 @@ static int hibmc_unload(struct drm_device *dev) drm_atomic_helper_shutdown(dev); pci_disable_msi(dev->pdev); - hibmc_kms_fini(priv); dev->dev_private = NULL; return 0; } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index a49c10e..7d263f4 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -42,7 +42,6 @@ struct hibmc_drm_private { struct drm_crtc crtc; struct drm_encoder encoder; struct hibmc_connector connector; - bool mode_config_initialized; }; static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon v2 1/2] drm/hisilicon: Use managed mode-config init
Hi Am 07.12.20 um 10:05 schrieb Tian Tao: Using drmm_mode_config_init() sets up managed release of modesetting resources. Individual patches usually contain a changelog to highlight the difference to previous versions. Please add one before committing the patch. Your cover letter for the series already does this correctly. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann Thanks for all these updates. --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 14 +++--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 - 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 3687753..7f01213 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -96,8 +96,9 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) struct drm_device *dev = >dev; int ret; - drm_mode_config_init(dev); - priv->mode_config_initialized = true; + ret = drmm_mode_config_init(dev); + if (ret) + return ret; dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; @@ -125,14 +126,6 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) return 0; } -static void hibmc_kms_fini(struct hibmc_drm_private *priv) -{ - if (priv->mode_config_initialized) { - drm_mode_config_cleanup(>dev); - priv->mode_config_initialized = false; - } -} - /* * It can operate in one of three modes: 0, 1 or Sleep. */ @@ -262,7 +255,6 @@ static int hibmc_unload(struct drm_device *dev) drm_atomic_helper_shutdown(dev); pci_disable_msi(dev->pdev); - hibmc_kms_fini(priv); dev->dev_private = NULL; return 0; } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index a49c10e..7d263f4 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -42,7 +42,6 @@ struct hibmc_drm_private { struct drm_crtc crtc; struct drm_encoder encoder; struct hibmc_connector connector; - bool mode_config_initialized; }; static inline struct hibmc_connector *to_hibmc_connector(struct drm_connector *connector) -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon 1/2] drm/hisilicon: Use managed mode-config init
Hi Am 07.12.20 um 01:49 schrieb Tian Tao: Using drmm_mode_config_init() sets up managed release of modesetting resources. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 3687753..d631f82 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -96,7 +96,9 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) struct drm_device *dev = >dev; int ret; - drm_mode_config_init(dev); + ret = drmm_mode_config_init(dev); + if (ret) + return ret; priv->mode_config_initialized = true; I think mode_config_initialized is only required by hibmc_kms_finit(), which you remove. You should remove this line and the field from struct hibmc_drm_private. Best regards Thomas dev->mode_config.min_width = 0; @@ -125,14 +127,6 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) return 0; } -static void hibmc_kms_fini(struct hibmc_drm_private *priv) -{ - if (priv->mode_config_initialized) { - drm_mode_config_cleanup(>dev); - priv->mode_config_initialized = false; - } -} - /* * It can operate in one of three modes: 0, 1 or Sleep. */ @@ -262,7 +256,6 @@ static int hibmc_unload(struct drm_device *dev) drm_atomic_helper_shutdown(dev); pci_disable_msi(dev->pdev); - hibmc_kms_fini(priv); dev->dev_private = NULL; return 0; } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon 2/2] drm/hisilicon: Delete unused local parameters
Am 07.12.20 um 01:49 schrieb Tian Tao: delete unused variable ‘priv’ to avoid warning. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d631f82..772f58e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -251,12 +251,9 @@ static int hibmc_hw_init(struct hibmc_drm_private *priv) static int hibmc_unload(struct drm_device *dev) { - struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); - drm_atomic_helper_shutdown(dev); - pci_disable_msi(dev->pdev); - dev->dev_private = NULL; + return 0; } -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/hisilicon: Deletted the entire file hibmc_ttm.c
Hi Am 03.12.20 um 10:05 schrieb Tian Tao: Deletted the entire file hibmc_ttm.c. drmm_vram_helper_init() can be Deletted -> Delete Here and in the subject line. called directly from hibmc_load(). hibmc_dumb_create() and hibmc_mode_funcs can go to hibmc_drm_drv.c Signed-off-by: Tian Tao Code changes look good. Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/hisilicon/hibmc/Makefile| 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 21 ++- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 -- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 50 - 4 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/hisilicon/hibmc/Makefile index 684ef79..d25c75e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_ttm.o hibmc_drm_i2c.o +hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 5aea2e9..3687753 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,12 @@ static irqreturn_t hibmc_drm_interrupt(int irq, void *arg) return IRQ_HANDLED; } +static int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, +struct drm_mode_create_dumb *args) +{ + return drm_gem_vram_fill_create_dumb(file, dev, 0, 128, args); +} + static const struct drm_driver hibmc_driver = { .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = _fops, @@ -77,6 +84,13 @@ static const struct dev_pm_ops hibmc_pm_ops = { hibmc_pm_resume) }; +static const struct drm_mode_config_funcs hibmc_mode_funcs = { + .mode_valid = drm_vram_helper_mode_valid, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, + .fb_create = drm_gem_fb_create, +}; + static int hibmc_kms_init(struct hibmc_drm_private *priv) { struct drm_device *dev = >dev; @@ -262,9 +276,12 @@ static int hibmc_load(struct drm_device *dev) if (ret) goto err; - ret = hibmc_mm_init(priv); - if (ret) + ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), + priv->fb_size); + if (ret) { + drm_err(dev, "Error initializing VRAM MM; %d\n", ret); goto err; + } ret = hibmc_kms_init(priv); if (ret) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 2786de5..a49c10e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -64,10 +64,6 @@ int hibmc_de_init(struct hibmc_drm_private *priv); int hibmc_vdac_init(struct hibmc_drm_private *priv); int hibmc_mm_init(struct hibmc_drm_private *hibmc); -int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args); int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); -extern const struct drm_mode_config_funcs hibmc_mode_funcs; - #endif diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c deleted file mode 100644 index 892d566..000 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* Hisilicon Hibmc SoC drm driver - * - * Based on the bochs drm driver. - * - * Copyright (c) 2016 Huawei Limited. - * - * Author: - * Rongrong Zou - * Rongrong Zou - * Jianhua Li - */ - -#include - -#include -#include -#include -#include -#include - -#include "hibmc_drm_drv.h" - -int hibmc_mm_init(struct hibmc_drm_private *hibmc) -{ - int ret; - struct drm_device *dev = >dev; - - ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), - hibmc->fb_size); - if (ret) { - drm_err(dev, "Error initializing VRAM MM; %d\n", ret); - return ret; - } - - return 0; -} - -int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - return drm_gem_vram_fill_create_dumb(file, dev, 0, 1
Re: [drm/fb] 1d46491d4a: WARNING:at_drivers/gpu/drm/drm_fb_helper.c:#drm_fb_helper_damage_work[drm_kms_helper]
Hi Am 03.12.20 um 09:36 schrieb Oliver Sang: On Thu, Dec 03, 2020 at 08:41:49AM +0100, Thomas Zimmermann wrote: Hi there should be a line in the kernel log that says something like "Damage blitter failed" with an error code. Is there any chance of recovering it? Hi Thomas, we attached dmesg in original report, where below comes from. [ 28.258177] [ cut here ] [ 28.259527] bochs-drm :00:02.0: Damage blitter failed: ret=-12 Thanks, that's the line I was looking for. Errno 12 means out-of-memory. It's not something related to the fbdev code, but rather another instance of the test system running out of memory. Presumably, it comes from [1]. Best regards Thomas [1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/ttm/ttm_bo_util.c?id=1d46491d4a08d7ee657e09808f87d169444a2652#n475 [ 28.261007] WARNING: CPU: 0 PID: 122 at drivers/gpu/drm/drm_fb_helper.c:434 drm_fb_helper_damage_work+0x109/0x2d0 [drm_kms_helper] [ 28.263802] Modules linked in: locktorture(E) torture(E) mousedev(E) ppdev(E) psmouse(E) crc32c_intel(E) input_leds(E) bochs_drm(E) drm_vram_helper(E) drm_ttm_helper(E) ttm(E) drm_kms_helper(E) parport_pc(E) rtc_cmos(E) parport(E) drm(E) evbug(E) i6300esb(E) i2c_piix4(E) autofs4(E) [ 28.271897] CPU: 0 PID: 122 Comm: kworker/0:2 Tainted: GE 5.10.0-rc3-01102-g1d46491d4a08 #1 [ 28.273904] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 [ 28.275819] Workqueue: events drm_fb_helper_damage_work [drm_kms_helper] [ 28.279884] EIP: drm_fb_helper_damage_work+0x109/0x2d0 [drm_kms_helper] Best regards Thomas Am 02.12.20 um 03:29 schrieb kernel test robot: Greeting, FYI, we noticed the following commit (built with gcc-9): commit: 1d46491d4a08d7ee657e09808f87d169444a2652 ("drm/fb-helper: Move damage blit code and its setup into separate routine") https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git master in testcase: locktorture version: with following parameters: runtime: 300s test: cpuhotplug test-description: This torture test consists of creating a number of kernel threads which acquire the lock and hold it for specific amount of time, thus simulating different critical region behaviors. test-url: https://www.kernel.org/doc/Documentation/locking/locktorture.txt on test machine: qemu-system-i386 -enable-kvm -cpu SandyBridge -smp 2 -m 8G caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace): +---+++ | | fd2d856538 | 1d46491d4a | +---+++ | WARNING:at_drivers/gpu/drm/drm_fb_helper.c:#drm_fb_helper_damage_work[drm_kms_helper] | 0 | 26 | | EIP:drm_fb_helper_damage_work | 0 | 26 | +---+++ If you fix the issue, kindly add following tag Reported-by: kernel test robot [ 28.261007] WARNING: CPU: 0 PID: 122 at drivers/gpu/drm/drm_fb_helper.c:434 drm_fb_helper_damage_work+0x109/0x2d0 [drm_kms_helper] [ 28.263802] Modules linked in: locktorture(E) torture(E) mousedev(E) ppdev(E) psmouse(E) crc32c_intel(E) input_leds(E) bochs_drm(E) drm_vram_helper(E) drm_ttm_helper(E) ttm(E) drm_kms_helper(E) parport_pc(E) rtc_cmos(E) parport(E) drm(E) evbug(E) i6300esb(E) i2c_piix4(E) autofs4(E) [ 28.271897] CPU: 0 PID: 122 Comm: kworker/0:2 Tainted: GE 5.10.0-rc3-01102-g1d46491d4a08 #1 [ 28.273904] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 [ 28.275819] Workqueue: events drm_fb_helper_damage_work [drm_kms_helper] [ 28.279884] EIP: drm_fb_helper_damage_work+0x109/0x2d0 [drm_kms_helper] [ 28.281467] Code: 47 10 8b 58 2c 85 db 0f 84 bc 01 00 00 e8 1f f0 da f4 89 74 24 0c 89 5c 24 08 89 44 24 04 c7 04 24 98 c1 40 df e8 f7 50 1d f5 <0f> 0b 31 c9 c7 04 24 01 00 00 00 ba 01 00 00 00 b8 3c e8 40 df e8 [ 28.285055] EAX: 0036 EBX: c1c91420 ECX: EDX: [ 28.289443] ESI: fff4 EDI: d2014000 EBP: d2c0dee4 ESP: d2c0de9c [ 28.291058] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010292 [ 28.292717] CR0: 80050033 CR2: b727a028 CR3: 12141000 CR4: 00040690 [ 28.294316] DR0: DR1: DR2: DR3: [ 28.295915] DR6: fffe0ff0 DR7: 0400 [ 28.300768] Call Trace: [ 28.302117] process_one_work+0x31b/0x7b0 [ 28.303532] ? process_one_work+0x272/0x7b0 [ 28.304976] worker_thread+0x29a/0x5d0 [ 28.308712] ? process_one_work+0x7b0/0x7b0 [ 28.31
Re: [drm/fb] 1d46491d4a: WARNING:at_drivers/gpu/drm/drm_fb_helper.c:#drm_fb_helper_damage_work[drm_kms_helper]
: 00e0 SS: 0068 EFLAGS: 00010292 [ 28.345883] ? cpu_latency_qos_write+0xeb/0xf0 [ 28.347203] ? run_init_process+0x5b/0x158 [ 28.348483] ? run_init_process+0x5b/0x158 [ 28.349714] ? exc_overflow+0x60/0x60 [ 28.350895] ? drm_fb_helper_damage_work+0x109/0x2d0 [drm_kms_helper] [ 28.352244] process_one_work+0x31b/0x7b0 [ 28.353432] ? process_one_work+0x272/0x7b0 [ 28.354599] worker_thread+0x29a/0x5d0 [ 28.355730] ? process_one_work+0x7b0/0x7b0 [ 28.356894] kthread+0x181/0x1a0 [ 28.357942] ? process_one_work+0x7b0/0x7b0 [ 28.359019] ? kthread_create_worker_on_cpu+0x30/0x30 [ 28.360134] ret_from_fork+0x1c/0x28 [ 28.376652] irq event stamp: 9469 [ 28.377678] hardirqs last enabled at (9477): [] console_unlock+0x515/0x650 [ 28.378986] hardirqs last disabled at (9484): [] console_unlock+0x425/0x650 [ 28.380284] softirqs last enabled at (9464): [] __do_softirq+0x3fd/0x57c [ 28.381595] softirqs last disabled at (9381): [] call_on_stack+0x4c/0x60 [ 28.382878] ---[ end trace b5fac24d1c204ab3 ]--- To reproduce: # build kernel cd linux cp config-5.10.0-rc3-01102-g1d46491d4a08 .config make HOSTCC=gcc-9 CC=gcc-9 ARCH=i386 olddefconfig prepare modules_prepare bzImage modules make HOSTCC=gcc-9 CC=gcc-9 ARCH=i386 INSTALL_MOD_PATH= modules_install cd find lib/ | cpio -o -H newc --quiet | gzip > modules.cgz git clone https://github.com/intel/lkp-tests.git cd lkp-tests bin/lkp qemu -k -m modules.cgz job-script # job-script is attached in this email Thanks, Oliver Sang -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/hisilicon: Use managed VRAM-helper initialization
Hi Am 03.12.20 um 04:09 schrieb Tian Tao: updated to use drmm_vram_helper_init() Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann As a good follow-up patch, I would suggest to get rig of the entire file hibmc_ttm.c. drmm_vram_helper_init() can be called directly from hibmc_load(). hibmc_dumb_create() and hibmc_mode_funcs can go to hibmc_drm_drv.c. Best regards Thomas --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 1 - drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 - drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 19 +++ 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 8020604..5aea2e9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -249,7 +249,6 @@ static int hibmc_unload(struct drm_device *dev) pci_disable_msi(dev->pdev); hibmc_kms_fini(priv); - hibmc_mm_fini(priv); dev->dev_private = NULL; return 0; } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index 7e0c756..2786de5 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -64,7 +64,6 @@ int hibmc_de_init(struct hibmc_drm_private *priv); int hibmc_vdac_init(struct hibmc_drm_private *priv); int hibmc_mm_init(struct hibmc_drm_private *hibmc); -void hibmc_mm_fini(struct hibmc_drm_private *hibmc); int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *connector); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c index e84fb81..892d566 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c @@ -23,15 +23,12 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) { - struct drm_vram_mm *vmm; int ret; struct drm_device *dev = >dev; - vmm = drm_vram_helper_alloc_mm(dev, - pci_resource_start(dev->pdev, 0), - hibmc->fb_size); - if (IS_ERR(vmm)) { - ret = PTR_ERR(vmm); + ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0), + hibmc->fb_size); + if (ret) { drm_err(dev, "Error initializing VRAM MM; %d\n", ret); return ret; } @@ -39,16 +36,6 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) return 0; } -void hibmc_mm_fini(struct hibmc_drm_private *hibmc) -{ - struct drm_device *dev = >dev; - - if (!dev->vram_mm) - return; - - drm_vram_helper_release_mm(dev); -} - int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) { -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon v2 2/3] drm/irq: Add the new api to install irq
Am 02.12.20 um 10:26 schrieb Tian Tao: Add new api devm_drm_irq_install() to register interrupts, no need to call drm_irq_uninstall() when the drm module is removed. Signed-off-by: Tian Tao Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/drm_irq.c | 32 include/drm/drm_irq.h | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 09d6e9e..803af4b 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -214,6 +214,38 @@ int drm_irq_uninstall(struct drm_device *dev) } EXPORT_SYMBOL(drm_irq_uninstall); +static void devm_drm_irq_uninstall(void *data) +{ + drm_irq_uninstall(data); +} + +/** + * devm_drm_irq_install - install IRQ handler + * @dev: DRM device + * @irq: IRQ number to install the handler for + * + * devm_drm_irq_install is a help function of drm_irq_install. + * + * if the driver uses devm_drm_irq_install, there is no need + * to call drm_irq_uninstall when the drm module get unloaded, + * as this will done automagically. + * + * Returns: + * Zero on success or a negative error code on failure. + */ +int devm_drm_irq_install(struct drm_device *dev, int irq) +{ + int ret; + + ret = drm_irq_install(dev, irq); + if (ret) + return ret; + + return devm_add_action_or_reset(dev->dev, + devm_drm_irq_uninstall, dev); +} +EXPORT_SYMBOL(devm_drm_irq_install); + #if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_irq_control(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index d77f6e6..631b22f 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -28,5 +28,5 @@ struct drm_device; int drm_irq_install(struct drm_device *dev, int irq); int drm_irq_uninstall(struct drm_device *dev); - +int devm_drm_irq_install(struct drm_device *dev, int irq); #endif -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon 1/3] drm/hisilicon: Code refactoring for hibmc_drm_drv
Am 02.12.20 um 09:47 schrieb Tian Tao: Use the devm_drm_dev_alloc provided by the drm framework to alloc a structure hibmc_drm_private. Signed-off-by: Tian Tao This looks good now. Thanks for sticking to it. Acked-by: Thomas Zimmermann --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 46 +++- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 4 +-- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 8 +++-- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index ea962ac..096eea9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -499,7 +499,7 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { int hibmc_de_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct drm_crtc *crtc = >crtc; struct drm_plane *plane = >primary_plane; int ret; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d845657..13e8a28 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -79,31 +79,32 @@ static const struct dev_pm_ops hibmc_pm_ops = { static int hibmc_kms_init(struct hibmc_drm_private *priv) { + struct drm_device *dev = >dev; int ret; - drm_mode_config_init(priv->dev); + drm_mode_config_init(dev); priv->mode_config_initialized = true; - priv->dev->mode_config.min_width = 0; - priv->dev->mode_config.min_height = 0; - priv->dev->mode_config.max_width = 1920; - priv->dev->mode_config.max_height = 1200; + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 1920; + dev->mode_config.max_height = 1200; - priv->dev->mode_config.fb_base = priv->fb_base; - priv->dev->mode_config.preferred_depth = 32; - priv->dev->mode_config.prefer_shadow = 1; + dev->mode_config.fb_base = priv->fb_base; + dev->mode_config.preferred_depth = 32; + dev->mode_config.prefer_shadow = 1; - priv->dev->mode_config.funcs = (void *)_mode_funcs; + dev->mode_config.funcs = (void *)_mode_funcs; ret = hibmc_de_init(priv); if (ret) { - drm_err(priv->dev, "failed to init de: %d\n", ret); + drm_err(dev, "failed to init de: %d\n", ret); return ret; } ret = hibmc_vdac_init(priv); if (ret) { - drm_err(priv->dev, "failed to init vdac: %d\n", ret); + drm_err(dev, "failed to init vdac: %d\n", ret); return ret; } @@ -113,7 +114,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) static void hibmc_kms_fini(struct hibmc_drm_private *priv) { if (priv->mode_config_initialized) { - drm_mode_config_cleanup(priv->dev); + drm_mode_config_cleanup(>dev); priv->mode_config_initialized = false; } } @@ -202,7 +203,7 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) static int hibmc_hw_map(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct pci_dev *pdev = dev->pdev; resource_size_t addr, size, ioaddr, iosize; @@ -258,17 +259,9 @@ static int hibmc_unload(struct drm_device *dev) static int hibmc_load(struct drm_device *dev) { - struct hibmc_drm_private *priv; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int ret; - priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - drm_err(dev, "no memory to allocate for hibmc_drm_private\n"); - return -ENOMEM; - } - dev->dev_private = priv; - priv->dev = dev; - ret = hibmc_hw_init(priv); if (ret) goto err; @@ -310,6 +303,7 @@ static int hibmc_load(struct drm_device *dev) static int hibmc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct hibmc_drm_private *priv; struct drm_device *dev; int ret; @@ -318,12 +312,14 @@ static int hibmc_pci_probe(struct pci_dev *pdev, if (ret) return ret; - dev = drm_dev_alloc(_driver, >dev); - if (IS_ERR(dev)) { + priv = devm_drm_dev_alloc(>dev, _driver, + s
Re: [PATCH drm/hisilicon 2/3] drm/irq: Add the new api to install irq
Hi Am 02.12.20 um 09:47 schrieb Tian Tao: Add new api devm_drm_irq_install() to register interrupts, no need to call drm_irq_uninstall() when the drm module is removed. Signed-off-by: Tian Tao --- drivers/gpu/drm/drm_irq.c | 35 +++ include/drm/drm_irq.h | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 09d6e9e..b363dec 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -214,6 +214,41 @@ int drm_irq_uninstall(struct drm_device *dev) } EXPORT_SYMBOL(drm_irq_uninstall); +static void devm_drm_irq_uninstall(void *data) +{ + drm_irq_uninstall(data); +} + +/** + * devm_drm_irq_install - install IRQ handler + * @dev: DRM device + * @irq: IRQ number to install the handler for + * + * devm_drm_irq_install is a help function of drm_irq_install. + * + * if the driver uses devm_drm_irq_install, there is no need + * to call drm_irq_uninstall when the drm module get unloaded, + * as this will done automagically. + * + * Returns: + * Zero on success or a negative error code on failure. + */ +int devm_drm_irq_install(struct drm_device *dev, int irq) +{ + int ret; + + ret = drm_irq_install(dev, irq); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev->dev, devm_drm_irq_uninstall, dev); + if (ret) + devm_drm_irq_uninstall(dev); If anything went wrong, devm_add_action_or_reset() will have already cleaned up for you. [1] So just return the result of devm_add_action_or_reset(). Best regards Thomas [1] https://elixir.bootlin.com/linux/latest/source/include/linux/device.h#L255 + + return ret; +} +EXPORT_SYMBOL(devm_drm_irq_install); + #if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_irq_control(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index d77f6e6..631b22f 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -28,5 +28,5 @@ struct drm_device; int drm_irq_install(struct drm_device *dev, int irq); int drm_irq_uninstall(struct drm_device *dev); - +int devm_drm_irq_install(struct drm_device *dev, int irq); #endif -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH drm/hisilicon v2 1/4] drm/hisilicon: Assgin local variable to drm_device
Hi Am 02.12.20 um 03:54 schrieb tiantao (H): 在 2020/12/2 10:06, tiantao (H) 写道: 在 2020/12/1 21:44, Thomas Zimmermann 写道: Hi Am 01.12.20 um 14:05 schrieb tiantao (H): 在 2020/12/1 20:36, Thomas Zimmermann 写道: Hi Am 01.12.20 um 13:26 schrieb tiantao (H): 在 2020/12/1 20:17, Thomas Zimmermann 写道: Hi Am 01.12.20 um 12:55 schrieb Tian Tao: Assign local variable to struct drm_device *dev because they are used multiple times within a function. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 30 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 8 --- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index ea962ac..096eea9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -499,7 +499,7 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { int hibmc_de_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct drm_crtc *crtc = >crtc; struct drm_plane *plane = >primary_plane; int ret; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d845657..dd9fadc 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -79,31 +79,32 @@ static const struct dev_pm_ops hibmc_pm_ops = { static int hibmc_kms_init(struct hibmc_drm_private *priv) { + struct drm_device *dev = >dev; int ret; - drm_mode_config_init(priv->dev); + drm_mode_config_init(dev); priv->mode_config_initialized = true; - priv->dev->mode_config.min_width = 0; - priv->dev->mode_config.min_height = 0; - priv->dev->mode_config.max_width = 1920; - priv->dev->mode_config.max_height = 1200; + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 1920; + dev->mode_config.max_height = 1200; - priv->dev->mode_config.fb_base = priv->fb_base; - priv->dev->mode_config.preferred_depth = 32; - priv->dev->mode_config.prefer_shadow = 1; + dev->mode_config.fb_base = priv->fb_base; + dev->mode_config.preferred_depth = 32; + dev->mode_config.prefer_shadow = 1; - priv->dev->mode_config.funcs = (void *)_mode_funcs; + dev->mode_config.funcs = (void *)_mode_funcs; ret = hibmc_de_init(priv); if (ret) { - drm_err(priv->dev, "failed to init de: %d\n", ret); + drm_err(dev, "failed to init de: %d\n", ret); return ret; } ret = hibmc_vdac_init(priv); if (ret) { - drm_err(priv->dev, "failed to init vdac: %d\n", ret); + drm_err(dev, "failed to init vdac: %d\n", ret); return ret; } @@ -113,7 +114,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) static void hibmc_kms_fini(struct hibmc_drm_private *priv) { if (priv->mode_config_initialized) { - drm_mode_config_cleanup(priv->dev); + drm_mode_config_cleanup(>dev); priv->mode_config_initialized = false; } } @@ -202,7 +203,7 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) static int hibmc_hw_map(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct pci_dev *pdev = dev->pdev; resource_size_t addr, size, ioaddr, iosize; @@ -258,7 +259,7 @@ static int hibmc_unload(struct drm_device *dev) static int hibmc_load(struct drm_device *dev) { - struct hibmc_drm_private *priv; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int ret; priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -267,7 +268,6 @@ static int hibmc_load(struct drm_device *dev) return -ENOMEM; } dev->dev_private = priv; - priv->dev = dev; I'm sure this either does not build or does not work. There's a call to drm_dev_alloc(), which initialized the DRM device. You need to assign the returned device here. The embedding of dev only work after you switched to devm_drm_dev_alloc() in the next patch. For the patch at hand, just keep struct hibmc_drm_private.dev as a pointer and you should be fine. Changing drm_device *dev to drm_device dev and using devm_drm_dev_alloc does not easily split into two patches. The patch does not compile well on its own, but it will compile fine with patch #2. Can patch #1 and patch #2 be combined into a singl
Re: [PATCH drm/hisilicon v2 1/4] drm/hisilicon: Assgin local variable to drm_device
Hi Am 01.12.20 um 14:05 schrieb tiantao (H): 在 2020/12/1 20:36, Thomas Zimmermann 写道: Hi Am 01.12.20 um 13:26 schrieb tiantao (H): 在 2020/12/1 20:17, Thomas Zimmermann 写道: Hi Am 01.12.20 um 12:55 schrieb Tian Tao: Assign local variable to struct drm_device *dev because they are used multiple times within a function. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 30 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 8 --- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index ea962ac..096eea9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -499,7 +499,7 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { int hibmc_de_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct drm_crtc *crtc = >crtc; struct drm_plane *plane = >primary_plane; int ret; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d845657..dd9fadc 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -79,31 +79,32 @@ static const struct dev_pm_ops hibmc_pm_ops = { static int hibmc_kms_init(struct hibmc_drm_private *priv) { + struct drm_device *dev = >dev; int ret; - drm_mode_config_init(priv->dev); + drm_mode_config_init(dev); priv->mode_config_initialized = true; - priv->dev->mode_config.min_width = 0; - priv->dev->mode_config.min_height = 0; - priv->dev->mode_config.max_width = 1920; - priv->dev->mode_config.max_height = 1200; + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 1920; + dev->mode_config.max_height = 1200; - priv->dev->mode_config.fb_base = priv->fb_base; - priv->dev->mode_config.preferred_depth = 32; - priv->dev->mode_config.prefer_shadow = 1; + dev->mode_config.fb_base = priv->fb_base; + dev->mode_config.preferred_depth = 32; + dev->mode_config.prefer_shadow = 1; - priv->dev->mode_config.funcs = (void *)_mode_funcs; + dev->mode_config.funcs = (void *)_mode_funcs; ret = hibmc_de_init(priv); if (ret) { - drm_err(priv->dev, "failed to init de: %d\n", ret); + drm_err(dev, "failed to init de: %d\n", ret); return ret; } ret = hibmc_vdac_init(priv); if (ret) { - drm_err(priv->dev, "failed to init vdac: %d\n", ret); + drm_err(dev, "failed to init vdac: %d\n", ret); return ret; } @@ -113,7 +114,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) static void hibmc_kms_fini(struct hibmc_drm_private *priv) { if (priv->mode_config_initialized) { - drm_mode_config_cleanup(priv->dev); + drm_mode_config_cleanup(>dev); priv->mode_config_initialized = false; } } @@ -202,7 +203,7 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) static int hibmc_hw_map(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct pci_dev *pdev = dev->pdev; resource_size_t addr, size, ioaddr, iosize; @@ -258,7 +259,7 @@ static int hibmc_unload(struct drm_device *dev) static int hibmc_load(struct drm_device *dev) { - struct hibmc_drm_private *priv; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int ret; priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -267,7 +268,6 @@ static int hibmc_load(struct drm_device *dev) return -ENOMEM; } dev->dev_private = priv; - priv->dev = dev; I'm sure this either does not build or does not work. There's a call to drm_dev_alloc(), which initialized the DRM device. You need to assign the returned device here. The embedding of dev only work after you switched to devm_drm_dev_alloc() in the next patch. For the patch at hand, just keep struct hibmc_drm_private.dev as a pointer and you should be fine. Changing drm_device *dev to drm_device dev and using devm_drm_dev_alloc does not easily split into two patches. The patch does not compile well on its own, but it will compile fine with patch #2. Can patch #1 and patch #2 be combined into a single patch,just like V1. Most of the code in this patch does struct drm_device *dev = >dev; to get dev as a local va
Re: [PATCH drm/hisilicon v2 1/4] drm/hisilicon: Assgin local variable to drm_device
Hi Am 01.12.20 um 13:26 schrieb tiantao (H): 在 2020/12/1 20:17, Thomas Zimmermann 写道: Hi Am 01.12.20 um 12:55 schrieb Tian Tao: Assign local variable to struct drm_device *dev because they are used multiple times within a function. Signed-off-by: Tian Tao --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 30 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 8 --- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index ea962ac..096eea9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -499,7 +499,7 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { int hibmc_de_init(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct drm_crtc *crtc = >crtc; struct drm_plane *plane = >primary_plane; int ret; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index d845657..dd9fadc 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -79,31 +79,32 @@ static const struct dev_pm_ops hibmc_pm_ops = { static int hibmc_kms_init(struct hibmc_drm_private *priv) { + struct drm_device *dev = >dev; int ret; - drm_mode_config_init(priv->dev); + drm_mode_config_init(dev); priv->mode_config_initialized = true; - priv->dev->mode_config.min_width = 0; - priv->dev->mode_config.min_height = 0; - priv->dev->mode_config.max_width = 1920; - priv->dev->mode_config.max_height = 1200; + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + dev->mode_config.max_width = 1920; + dev->mode_config.max_height = 1200; - priv->dev->mode_config.fb_base = priv->fb_base; - priv->dev->mode_config.preferred_depth = 32; - priv->dev->mode_config.prefer_shadow = 1; + dev->mode_config.fb_base = priv->fb_base; + dev->mode_config.preferred_depth = 32; + dev->mode_config.prefer_shadow = 1; - priv->dev->mode_config.funcs = (void *)_mode_funcs; + dev->mode_config.funcs = (void *)_mode_funcs; ret = hibmc_de_init(priv); if (ret) { - drm_err(priv->dev, "failed to init de: %d\n", ret); + drm_err(dev, "failed to init de: %d\n", ret); return ret; } ret = hibmc_vdac_init(priv); if (ret) { - drm_err(priv->dev, "failed to init vdac: %d\n", ret); + drm_err(dev, "failed to init vdac: %d\n", ret); return ret; } @@ -113,7 +114,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) static void hibmc_kms_fini(struct hibmc_drm_private *priv) { if (priv->mode_config_initialized) { - drm_mode_config_cleanup(priv->dev); + drm_mode_config_cleanup(>dev); priv->mode_config_initialized = false; } } @@ -202,7 +203,7 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) static int hibmc_hw_map(struct hibmc_drm_private *priv) { - struct drm_device *dev = priv->dev; + struct drm_device *dev = >dev; struct pci_dev *pdev = dev->pdev; resource_size_t addr, size, ioaddr, iosize; @@ -258,7 +259,7 @@ static int hibmc_unload(struct drm_device *dev) static int hibmc_load(struct drm_device *dev) { - struct hibmc_drm_private *priv; + struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); int ret; priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -267,7 +268,6 @@ static int hibmc_load(struct drm_device *dev) return -ENOMEM; } dev->dev_private = priv; - priv->dev = dev; I'm sure this either does not build or does not work. There's a call to drm_dev_alloc(), which initialized the DRM device. You need to assign the returned device here. The embedding of dev only work after you switched to devm_drm_dev_alloc() in the next patch. For the patch at hand, just keep struct hibmc_drm_private.dev as a pointer and you should be fine. Changing drm_device *dev to drm_device dev and using devm_drm_dev_alloc does not easily split into two patches. The patch does not compile well on its own, but it will compile fine with patch #2. Can patch #1 and patch #2 be combined into a single patch,just like V1. Most of the code in this patch does struct drm_device *dev = >dev; to get dev as a local variable. Why don't you do struct drm_device *dev = priv->dev; ? That's all that's really ne