From c4b3c1332f55c48785e6661cebeb7269a92a45fd Mon Sep 17 00:00:00 2001 From: Liao Chen <liaochen4@huawei.com> Date: Tue, 20 Aug 2024 02:20:29 +0000 Subject: [PATCH 001/970] zonefs: add support for FS_IOC_GETFSSYSFSPATH FS_IOC_GETFSSYSFSPATH ioctl expects sysfs sub-path of a filesystem, the format can be "$FSTYP/$SYSFS_IDENTIFIER" under /sys/fs, it can helps to standardizes exporting sysfs datas across filesystems. This patch wires up FS_IOC_GETFSSYSFSPATH for zonefs, it will output "zonefs/<dev>". Signed-off-by: Liao Chen <liaochen4@huawei.com> Signed-off-by: Damien Le Moal <dlemoal@kernel.org> --- fs/zonefs/sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/zonefs/sysfs.c b/fs/zonefs/sysfs.c index 8ccb65c2b419..ff9a688f1f9c 100644 --- a/fs/zonefs/sysfs.c +++ b/fs/zonefs/sysfs.c @@ -92,6 +92,7 @@ int zonefs_sysfs_register(struct super_block *sb) struct zonefs_sb_info *sbi = ZONEFS_SB(sb); int ret; + super_set_sysfs_name_id(sb); init_completion(&sbi->s_kobj_unregister); ret = kobject_init_and_add(&sbi->s_kobj, &zonefs_sb_ktype, zonefs_sysfs_root, "%s", sb->s_id); -- GitLab From 3cb6e7c2957bcacedfe7aedad7fb22f3e0c1f343 Mon Sep 17 00:00:00 2001 From: Thierry Reding <treding@nvidia.com> Date: Thu, 29 Aug 2024 11:09:16 +0200 Subject: [PATCH 002/970] Revert "drm/tegra: gr3d: Convert into dev_pm_domain_attach|detach_list()" This reverts commit f790b5c09665cab0d51dfcc84832d79d2b1e6c0e. An updated version of patch was applied to the PM tree. Sorry for the mixup. Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240829090916.1288854-1-thierry.reding@gmail.com --- drivers/gpu/drm/tegra/gr3d.c | 46 ++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 4de1ea0fc7c0..00c8564520e7 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -46,7 +46,6 @@ struct gr3d { unsigned int nclocks; struct reset_control_bulk_data resets[RST_GR3D_MAX]; unsigned int nresets; - struct dev_pm_domain_list *pd_list; DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); }; @@ -370,12 +369,18 @@ static int gr3d_power_up_legacy_domain(struct device *dev, const char *name, return 0; } +static void gr3d_del_link(void *link) +{ + device_link_del(link); +} + static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) { - struct dev_pm_domain_attach_data pd_data = { - .pd_names = (const char *[]) { "3d0", "3d1" }, - .num_pd_names = 2, - }; + static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL }; + const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; + struct device **opp_virt_devs, *pd_dev; + struct device_link *link; + unsigned int i; int err; err = of_count_phandle_with_args(dev->of_node, "power-domains", @@ -409,10 +414,29 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d) if (dev->pm_domain) return 0; - err = dev_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list); - if (err < 0) + err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs); + if (err) return err; + for (i = 0; opp_genpd_names[i]; i++) { + pd_dev = opp_virt_devs[i]; + if (!pd_dev) { + dev_err(dev, "failed to get %s power domain\n", + opp_genpd_names[i]); + return -EINVAL; + } + + link = device_link_add(dev, pd_dev, link_flags); + if (!link) { + dev_err(dev, "failed to link to %s\n", dev_name(pd_dev)); + return -EINVAL; + } + + err = devm_add_action_or_reset(dev, gr3d_del_link, link); + if (err) + return err; + } + return 0; } @@ -503,13 +527,13 @@ static int gr3d_probe(struct platform_device *pdev) err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); if (err) - goto err; + return err; err = host1x_client_register(&gr3d->client.base); if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); - goto err; + return err; } /* initialize address register map */ @@ -517,9 +541,6 @@ static int gr3d_probe(struct platform_device *pdev) set_bit(gr3d_addr_regs[i], gr3d->addr_regs); return 0; -err: - dev_pm_domain_detach_list(gr3d->pd_list); - return err; } static void gr3d_remove(struct platform_device *pdev) @@ -528,7 +549,6 @@ static void gr3d_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); host1x_client_unregister(&gr3d->client.base); - dev_pm_domain_detach_list(gr3d->pd_list); } static int __maybe_unused gr3d_runtime_suspend(struct device *dev) -- GitLab From 4ed09565e0873a8ffdf6d71923f485bc778f2988 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen <mperttunen@nvidia.com> Date: Wed, 24 Apr 2024 08:13:34 +0300 Subject: [PATCH 003/970] drm/tegra: gem: Open code drm_prime_gem_destroy Since we aren't using drm_gem_prime_import(_dev), for clarity don't use the corresponding destroy function either. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240424051335.2872574-1-cyndis@kapsi.fi --- drivers/gpu/drm/tegra/gem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index b4eb030ea961..189861c6c630 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -520,9 +520,12 @@ void tegra_bo_free_object(struct drm_gem_object *gem) tegra_bo_iommu_unmap(tegra, bo); if (gem->import_attach) { + struct dma_buf *dmabuf = gem->import_attach->dmabuf; + dma_buf_unmap_attachment_unlocked(gem->import_attach, bo->sgt, DMA_TO_DEVICE); - drm_prime_gem_destroy(gem, NULL); + dma_buf_detach(dmabuf, gem->import_attach); + dma_buf_put(dmabuf); } else { tegra_bo_free(gem->dev, bo); } -- GitLab From f5b8794e17e40219f22cf9b1216db21e38aa8dbb Mon Sep 17 00:00:00 2001 From: Mikko Perttunen <mperttunen@nvidia.com> Date: Wed, 24 Apr 2024 08:13:35 +0300 Subject: [PATCH 004/970] drm/tegra: gem: Don't attach dma-bufs when not needed The dma-buf import code currently attaches and maps all imported dma-bufs to the drm device to get their sgt for mapping to the directly managed IOMMU domain. In many cases, like for newer chips (Tegra186+), the directly managed IOMMU domain is, however, not used. Mapping to the drm device can also cause issues e.g. with swiotlb since it is not a real device. To improve the situation, only attach and map imported dma-bufs when required. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240424051335.2872574-2-cyndis@kapsi.fi --- drivers/gpu/drm/tegra/gem.c | 66 ++++++++++++++++++++----------------- drivers/gpu/drm/tegra/gem.h | 21 ++++++++++++ 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 189861c6c630..d275404ad0e9 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -76,8 +76,8 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ /* * Imported buffers need special treatment to satisfy the semantics of DMA-BUF. */ - if (gem->import_attach) { - struct dma_buf *buf = gem->import_attach->dmabuf; + if (obj->dma_buf) { + struct dma_buf *buf = obj->dma_buf; map->attach = dma_buf_attach(buf, dev); if (IS_ERR(map->attach)) { @@ -184,8 +184,8 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) if (obj->vaddr) return obj->vaddr; - if (obj->gem.import_attach) { - ret = dma_buf_vmap_unlocked(obj->gem.import_attach->dmabuf, &map); + if (obj->dma_buf) { + ret = dma_buf_vmap_unlocked(obj->dma_buf, &map); if (ret < 0) return ERR_PTR(ret); @@ -208,8 +208,8 @@ static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) if (obj->vaddr) return; - if (obj->gem.import_attach) - return dma_buf_vunmap_unlocked(obj->gem.import_attach->dmabuf, &map); + if (obj->dma_buf) + return dma_buf_vunmap_unlocked(obj->dma_buf, &map); vunmap(addr); } @@ -465,27 +465,32 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, if (IS_ERR(bo)) return bo; - attach = dma_buf_attach(buf, drm->dev); - if (IS_ERR(attach)) { - err = PTR_ERR(attach); - goto free; - } - - get_dma_buf(buf); + /* + * If we need to use IOMMU API to map the dma-buf into the internally managed + * domain, map it first to the DRM device to get an sgt. + */ + if (tegra->domain) { + attach = dma_buf_attach(buf, drm->dev); + if (IS_ERR(attach)) { + err = PTR_ERR(attach); + goto free; + } - bo->sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE); - if (IS_ERR(bo->sgt)) { - err = PTR_ERR(bo->sgt); - goto detach; - } + bo->sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE); + if (IS_ERR(bo->sgt)) { + err = PTR_ERR(bo->sgt); + goto detach; + } - if (tegra->domain) { err = tegra_bo_iommu_map(tegra, bo); if (err < 0) goto detach; + + bo->gem.import_attach = attach; } - bo->gem.import_attach = attach; + get_dma_buf(buf); + bo->dma_buf = buf; return bo; @@ -516,20 +521,21 @@ void tegra_bo_free_object(struct drm_gem_object *gem) dev_name(mapping->dev)); } - if (tegra->domain) + if (tegra->domain) { tegra_bo_iommu_unmap(tegra, bo); - if (gem->import_attach) { - struct dma_buf *dmabuf = gem->import_attach->dmabuf; - - dma_buf_unmap_attachment_unlocked(gem->import_attach, bo->sgt, - DMA_TO_DEVICE); - dma_buf_detach(dmabuf, gem->import_attach); - dma_buf_put(dmabuf); - } else { - tegra_bo_free(gem->dev, bo); + if (gem->import_attach) { + dma_buf_unmap_attachment_unlocked(gem->import_attach, bo->sgt, + DMA_TO_DEVICE); + dma_buf_detach(gem->import_attach->dmabuf, gem->import_attach); + } } + tegra_bo_free(gem->dev, bo); + + if (bo->dma_buf) + dma_buf_put(bo->dma_buf); + drm_gem_object_release(gem); kfree(bo); } diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h index cb5146a67668..bf2cbd48eb3f 100644 --- a/drivers/gpu/drm/tegra/gem.h +++ b/drivers/gpu/drm/tegra/gem.h @@ -32,6 +32,26 @@ struct tegra_bo_tiling { enum tegra_bo_sector_layout sector_layout; }; +/* + * How memory is referenced within a tegra_bo: + * + * Buffer source | Mapping API(*) | Fields + * ---------------+-----------------+--------------- + * Allocated here | DMA API | iova (IOVA mapped to drm->dev), vaddr (CPU VA) + * + * Allocated here | IOMMU API | pages/num_pages (Phys. memory), sgt (Mapped to drm->dev), + * | iova/size (Mapped to domain) + * + * Imported | DMA API | dma_buf (Imported dma_buf) + * + * Imported | IOMMU API | dma_buf (Imported dma_buf), + * | gem->import_attach (Attachment on drm->dev), + * | sgt (Mapped to drm->dev) + * | iova/size (Mapped to domain) + * + * (*) If tegra->domain is set, i.e. TegraDRM IOMMU domain is directly managed through IOMMU API, + * this is IOMMU API. Otherwise DMA API. + */ struct tegra_bo { struct drm_gem_object gem; struct host1x_bo base; @@ -39,6 +59,7 @@ struct tegra_bo { struct sg_table *sgt; dma_addr_t iova; void *vaddr; + struct dma_buf *dma_buf; struct drm_mm_node *mm; unsigned long num_pages; -- GitLab From 955df44b5d861039354ac8aebb5b25bd39eb440f Mon Sep 17 00:00:00 2001 From: Mikko Perttunen <mperttunen@nvidia.com> Date: Thu, 25 Apr 2024 08:02:33 +0300 Subject: [PATCH 005/970] gpu: host1x: Fix _writel function declarations Some of the _writel functions in dev.h had the r and v parameters swapped. Fix this to avoid confusion. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240425050238.2943404-1-cyndis@kapsi.fi --- drivers/gpu/host1x/dev.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h index 92031b240a17..d3855a1c6b47 100644 --- a/drivers/gpu/host1x/dev.h +++ b/drivers/gpu/host1x/dev.h @@ -175,11 +175,11 @@ struct host1x { }; void host1x_common_writel(struct host1x *host1x, u32 v, u32 r); -void host1x_hypervisor_writel(struct host1x *host1x, u32 r, u32 v); +void host1x_hypervisor_writel(struct host1x *host1x, u32 v, u32 r); u32 host1x_hypervisor_readl(struct host1x *host1x, u32 r); -void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v); +void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r); u32 host1x_sync_readl(struct host1x *host1x, u32 r); -void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v); +void host1x_ch_writel(struct host1x_channel *ch, u32 v, u32 r); u32 host1x_ch_readl(struct host1x_channel *ch, u32 r); static inline void host1x_hw_syncpt_restore(struct host1x *host, -- GitLab From e436a40830f0fda1a1e5e51d3102644f3e0645fa Mon Sep 17 00:00:00 2001 From: Mikko Perttunen <mperttunen@nvidia.com> Date: Thu, 25 Apr 2024 08:02:34 +0300 Subject: [PATCH 006/970] gpu: host1x: Handle CDMA wraparound when debug printing During channel debug information dump, when printing CDMA opcodes, the circular nature of the CDMA pushbuffer wasn't being taken into account, sometimes accessing past the end. Change the printing to take this into account. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240425050238.2943404-2-cyndis@kapsi.fi --- drivers/gpu/host1x/hw/debug_hw.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c index 54e31d81517b..4c32aa1b95e8 100644 --- a/drivers/gpu/host1x/hw/debug_hw.c +++ b/drivers/gpu/host1x/hw/debug_hw.c @@ -177,7 +177,16 @@ static void show_gather(struct output *o, dma_addr_t phys_addr, for (i = 0; i < words; i++) { dma_addr_t addr = phys_addr + i * 4; - u32 val = *(map_addr + offset / 4 + i); + u32 voffset = offset + i * 4; + u32 val; + + /* If we reach the RESTART opcode, continue at the beginning of pushbuffer */ + if (cdma && voffset >= cdma->push_buffer.size) { + addr -= cdma->push_buffer.size; + voffset -= cdma->push_buffer.size; + } + + val = *(map_addr + voffset / 4); if (!data_count) { host1x_debug_output(o, " %pad: %08x: ", &addr, val); @@ -203,7 +212,7 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) job->num_slots, job->num_unpins); show_gather(o, pb->dma + job->first_get, job->num_slots * 2, cdma, - pb->dma + job->first_get, pb->mapped + job->first_get); + pb->dma, pb->mapped); for (i = 0; i < job->num_cmds; i++) { struct host1x_job_gather *g; @@ -227,7 +236,7 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) host1x_debug_output(o, " GATHER at %pad+%#x, %d words\n", &g->base, g->offset, g->words); - show_gather(o, g->base + g->offset, g->words, cdma, + show_gather(o, g->base + g->offset, g->words, NULL, g->base, mapped); if (!job->gather_copy_mapped) -- GitLab From 4e90b03a4b0771df6a2062f755524573c58843eb Mon Sep 17 00:00:00 2001 From: Mikko Perttunen <mperttunen@nvidia.com> Date: Thu, 25 Apr 2024 08:02:35 +0300 Subject: [PATCH 007/970] gpu: host1x: Complete stream ID entry tables These tables contain fixed values to program the host1x hardware with, so fill in the missing entries. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240425050238.2943404-3-cyndis@kapsi.fi --- drivers/gpu/host1x/dev.c | 150 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index b62e4f0e8130..bc3cda4625d0 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -142,18 +142,29 @@ static const struct host1x_info host1x05_info = { }; static const struct host1x_sid_entry tegra186_sid_table[] = { - { - /* VIC */ - .base = 0x1af0, - .offset = 0x30, - .limit = 0x34 - }, - { - /* NVDEC */ - .base = 0x1b00, - .offset = 0x30, - .limit = 0x34 - }, + { /* SE1 */ .base = 0x1ac8, .offset = 0x90, .limit = 0x90 }, + { /* SE2 */ .base = 0x1ad0, .offset = 0x90, .limit = 0x90 }, + { /* SE3 */ .base = 0x1ad8, .offset = 0x90, .limit = 0x90 }, + { /* SE4 */ .base = 0x1ae0, .offset = 0x90, .limit = 0x90 }, + { /* ISP */ .base = 0x1ae8, .offset = 0x50, .limit = 0x50 }, + { /* VIC */ .base = 0x1af0, .offset = 0x30, .limit = 0x34 }, + { /* NVENC */ .base = 0x1af8, .offset = 0x30, .limit = 0x34 }, + { /* NVDEC */ .base = 0x1b00, .offset = 0x30, .limit = 0x34 }, + { /* NVJPG */ .base = 0x1b08, .offset = 0x30, .limit = 0x34 }, + { /* TSEC */ .base = 0x1b10, .offset = 0x30, .limit = 0x34 }, + { /* TSECB */ .base = 0x1b18, .offset = 0x30, .limit = 0x34 }, + { /* VI 0 */ .base = 0x1b80, .offset = 0x10000, .limit = 0x10000 }, + { /* VI 1 */ .base = 0x1b88, .offset = 0x20000, .limit = 0x20000 }, + { /* VI 2 */ .base = 0x1b90, .offset = 0x30000, .limit = 0x30000 }, + { /* VI 3 */ .base = 0x1b98, .offset = 0x40000, .limit = 0x40000 }, + { /* VI 4 */ .base = 0x1ba0, .offset = 0x50000, .limit = 0x50000 }, + { /* VI 5 */ .base = 0x1ba8, .offset = 0x60000, .limit = 0x60000 }, + { /* VI 6 */ .base = 0x1bb0, .offset = 0x70000, .limit = 0x70000 }, + { /* VI 7 */ .base = 0x1bb8, .offset = 0x80000, .limit = 0x80000 }, + { /* VI 8 */ .base = 0x1bc0, .offset = 0x90000, .limit = 0x90000 }, + { /* VI 9 */ .base = 0x1bc8, .offset = 0xa0000, .limit = 0xa0000 }, + { /* VI 10 */ .base = 0x1bd0, .offset = 0xb0000, .limit = 0xb0000 }, + { /* VI 11 */ .base = 0x1bd8, .offset = 0xc0000, .limit = 0xc0000 }, }; static const struct host1x_info host1x06_info = { @@ -173,24 +184,26 @@ static const struct host1x_info host1x06_info = { }; static const struct host1x_sid_entry tegra194_sid_table[] = { - { - /* VIC */ - .base = 0x1af0, - .offset = 0x30, - .limit = 0x34 - }, - { - /* NVDEC */ - .base = 0x1b00, - .offset = 0x30, - .limit = 0x34 - }, - { - /* NVDEC1 */ - .base = 0x1bc0, - .offset = 0x30, - .limit = 0x34 - }, + { /* SE1 */ .base = 0x1ac8, .offset = 0x90, .limit = 0x90 }, + { /* SE2 */ .base = 0x1ad0, .offset = 0x90, .limit = 0x90 }, + { /* SE3 */ .base = 0x1ad8, .offset = 0x90, .limit = 0x90 }, + { /* SE4 */ .base = 0x1ae0, .offset = 0x90, .limit = 0x90 }, + { /* ISP */ .base = 0x1ae8, .offset = 0x800, .limit = 0x800 }, + { /* VIC */ .base = 0x1af0, .offset = 0x30, .limit = 0x34 }, + { /* NVENC */ .base = 0x1af8, .offset = 0x30, .limit = 0x34 }, + { /* NVDEC */ .base = 0x1b00, .offset = 0x30, .limit = 0x34 }, + { /* NVJPG */ .base = 0x1b08, .offset = 0x30, .limit = 0x34 }, + { /* TSEC */ .base = 0x1b10, .offset = 0x30, .limit = 0x34 }, + { /* TSECB */ .base = 0x1b18, .offset = 0x30, .limit = 0x34 }, + { /* VI */ .base = 0x1b80, .offset = 0x800, .limit = 0x800 }, + { /* VI_THI */ .base = 0x1b88, .offset = 0x30, .limit = 0x34 }, + { /* ISP_THI */ .base = 0x1b90, .offset = 0x30, .limit = 0x34 }, + { /* PVA0_CLUSTER */ .base = 0x1b98, .offset = 0x0, .limit = 0x0 }, + { /* PVA0_CLUSTER */ .base = 0x1ba0, .offset = 0x0, .limit = 0x0 }, + { /* NVDLA0 */ .base = 0x1ba8, .offset = 0x30, .limit = 0x34 }, + { /* NVDLA1 */ .base = 0x1bb0, .offset = 0x30, .limit = 0x34 }, + { /* NVENC1 */ .base = 0x1bb8, .offset = 0x30, .limit = 0x34 }, + { /* NVDEC1 */ .base = 0x1bc0, .offset = 0x30, .limit = 0x34 }, }; static const struct host1x_info host1x07_info = { @@ -215,54 +228,35 @@ static const struct host1x_info host1x07_info = { * and firmware stream ID in the MMIO path table. */ static const struct host1x_sid_entry tegra234_sid_table[] = { - { - /* SE2 MMIO */ - .base = 0x1658, - .offset = 0x90, - .limit = 0x90 - }, - { - /* SE4 MMIO */ - .base = 0x1660, - .offset = 0x90, - .limit = 0x90 - }, - { - /* SE2 channel */ - .base = 0x1738, - .offset = 0x90, - .limit = 0x90 - }, - { - /* SE4 channel */ - .base = 0x1740, - .offset = 0x90, - .limit = 0x90 - }, - { - /* VIC channel */ - .base = 0x17b8, - .offset = 0x30, - .limit = 0x30 - }, - { - /* VIC MMIO */ - .base = 0x1688, - .offset = 0x34, - .limit = 0x34 - }, - { - /* NVDEC channel */ - .base = 0x17c8, - .offset = 0x30, - .limit = 0x30, - }, - { - /* NVDEC MMIO */ - .base = 0x1698, - .offset = 0x34, - .limit = 0x34, - }, + { /* SE1 MMIO */ .base = 0x1650, .offset = 0x90, .limit = 0x90 }, + { /* SE1 ch */ .base = 0x1730, .offset = 0x90, .limit = 0x90 }, + { /* SE2 MMIO */ .base = 0x1658, .offset = 0x90, .limit = 0x90 }, + { /* SE2 ch */ .base = 0x1738, .offset = 0x90, .limit = 0x90 }, + { /* SE4 MMIO */ .base = 0x1660, .offset = 0x90, .limit = 0x90 }, + { /* SE4 ch */ .base = 0x1740, .offset = 0x90, .limit = 0x90 }, + { /* ISP MMIO */ .base = 0x1680, .offset = 0x800, .limit = 0x800 }, + { /* VIC MMIO */ .base = 0x1688, .offset = 0x34, .limit = 0x34 }, + { /* VIC ch */ .base = 0x17b8, .offset = 0x30, .limit = 0x30 }, + { /* NVENC MMIO */ .base = 0x1690, .offset = 0x34, .limit = 0x34 }, + { /* NVENC ch */ .base = 0x17c0, .offset = 0x30, .limit = 0x30 }, + { /* NVDEC MMIO */ .base = 0x1698, .offset = 0x34, .limit = 0x34 }, + { /* NVDEC ch */ .base = 0x17c8, .offset = 0x30, .limit = 0x30 }, + { /* NVJPG MMIO */ .base = 0x16a0, .offset = 0x34, .limit = 0x34 }, + { /* NVJPG ch */ .base = 0x17d0, .offset = 0x30, .limit = 0x30 }, + { /* TSEC MMIO */ .base = 0x16a8, .offset = 0x30, .limit = 0x34 }, + { /* NVJPG1 MMIO */ .base = 0x16b0, .offset = 0x34, .limit = 0x34 }, + { /* NVJPG1 ch */ .base = 0x17a8, .offset = 0x30, .limit = 0x30 }, + { /* VI MMIO */ .base = 0x16b8, .offset = 0x800, .limit = 0x800 }, + { /* VI_THI MMIO */ .base = 0x16c0, .offset = 0x30, .limit = 0x34 }, + { /* ISP_THI MMIO */ .base = 0x16c8, .offset = 0x30, .limit = 0x34 }, + { /* NVDLA MMIO */ .base = 0x16d8, .offset = 0x30, .limit = 0x34 }, + { /* NVDLA ch */ .base = 0x17e0, .offset = 0x30, .limit = 0x34 }, + { /* NVDLA1 MMIO */ .base = 0x16e0, .offset = 0x30, .limit = 0x34 }, + { /* NVDLA1 ch */ .base = 0x17e8, .offset = 0x30, .limit = 0x34 }, + { /* OFA MMIO */ .base = 0x16e8, .offset = 0x34, .limit = 0x34 }, + { /* OFA ch */ .base = 0x1768, .offset = 0x30, .limit = 0x30 }, + { /* VI2 MMIO */ .base = 0x16f0, .offset = 0x800, .limit = 0x800 }, + { /* VI2_THI MMIO */ .base = 0x16f8, .offset = 0x30, .limit = 0x34 }, }; static const struct host1x_info host1x08_info = { -- GitLab From 57d298bdb46bc240498675a7f887fc71089da2c0 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen <mperttunen@nvidia.com> Date: Thu, 25 Apr 2024 08:02:36 +0300 Subject: [PATCH 008/970] gpu: host1x: Add MLOCK recovery for rest of engines Add class IDs / MLOCKs for MLOCK recovery for rest of engines present on Tegra234. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240425050238.2943404-4-cyndis@kapsi.fi --- drivers/gpu/host1x/hw/cdma_hw.c | 12 ++++++++++++ include/linux/host1x.h | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c index 1b65a10b9dfc..3f3f0018eee0 100644 --- a/drivers/gpu/host1x/hw/cdma_hw.c +++ b/drivers/gpu/host1x/hw/cdma_hw.c @@ -254,12 +254,24 @@ static void timeout_release_mlock(struct host1x_cdma *cdma) u32 offset; switch (ch->client->class) { + case HOST1X_CLASS_NVJPG1: + offset = HOST1X_COMMON_NVJPG1_MLOCK; + break; + case HOST1X_CLASS_NVENC: + offset = HOST1X_COMMON_NVENC_MLOCK; + break; case HOST1X_CLASS_VIC: offset = HOST1X_COMMON_VIC_MLOCK; break; + case HOST1X_CLASS_NVJPG: + offset = HOST1X_COMMON_NVJPG_MLOCK; + break; case HOST1X_CLASS_NVDEC: offset = HOST1X_COMMON_NVDEC_MLOCK; break; + case HOST1X_CLASS_OFA: + offset = HOST1X_COMMON_OFA_MLOCK; + break; default: WARN(1, "%s was not updated for class %u", __func__, ch->client->class); return; diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 9c8119ed13a4..5a7a81e5f9bd 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -14,12 +14,17 @@ enum host1x_class { HOST1X_CLASS_HOST1X = 0x1, + HOST1X_CLASS_NVJPG1 = 0x7, + HOST1X_CLASS_NVENC = 0x21, + HOST1X_CLASS_NVENC1 = 0x22, HOST1X_CLASS_GR2D = 0x51, HOST1X_CLASS_GR2D_SB = 0x52, HOST1X_CLASS_VIC = 0x5D, HOST1X_CLASS_GR3D = 0x60, + HOST1X_CLASS_NVJPG = 0xC0, HOST1X_CLASS_NVDEC = 0xF0, HOST1X_CLASS_NVDEC1 = 0xF5, + HOST1X_CLASS_OFA = 0xF8, }; struct host1x; -- GitLab From 3d70eb8e60c6d009c988c8e696cb68c77ff59628 Mon Sep 17 00:00:00 2001 From: Kunwu Chan <chentao@kylinos.cn> Date: Fri, 23 Aug 2024 16:07:24 +0800 Subject: [PATCH 009/970] gpu: host1x: Make host1x_context_device_bus_type constant Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type a const *"), the driver core can properly handle constant struct bus_type, move the host1x_context_device_bus_type variable to be a constant structure as well, placing it into read-only memory which can not be modified at runtime. Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Kunwu Chan <chentao@kylinos.cn> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240823080724.148423-1-kunwu.chan@linux.dev --- drivers/gpu/host1x/context_bus.c | 2 +- include/linux/host1x_context_bus.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/host1x/context_bus.c b/drivers/gpu/host1x/context_bus.c index d9421179d7b4..7cd0e1a5edd1 100644 --- a/drivers/gpu/host1x/context_bus.c +++ b/drivers/gpu/host1x/context_bus.c @@ -6,7 +6,7 @@ #include <linux/device.h> #include <linux/of.h> -struct bus_type host1x_context_device_bus_type = { +const struct bus_type host1x_context_device_bus_type = { .name = "host1x-context", }; EXPORT_SYMBOL_GPL(host1x_context_device_bus_type); diff --git a/include/linux/host1x_context_bus.h b/include/linux/host1x_context_bus.h index 72462737a6db..c928cb432680 100644 --- a/include/linux/host1x_context_bus.h +++ b/include/linux/host1x_context_bus.h @@ -9,7 +9,7 @@ #include <linux/device.h> #ifdef CONFIG_TEGRA_HOST1X_CONTEXT_BUS -extern struct bus_type host1x_context_device_bus_type; +extern const struct bus_type host1x_context_device_bus_type; #endif #endif -- GitLab From e75356ef5baef69e9f577023c453d91a902dc082 Mon Sep 17 00:00:00 2001 From: Colin Ian King <colin.i.king@gmail.com> Date: Thu, 22 Aug 2024 21:50:47 +0100 Subject: [PATCH 010/970] drm/tegra: hdmi: Make read-only const array freqs static Don't populate the const read-only array freqs on the stack at run time, instead make it static. Signed-off-by: Colin Ian King <colin.i.king@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240822205047.642845-1-colin.i.king@gmail.com --- drivers/gpu/drm/tegra/hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 09987e372e3e..6bf2dae82ca0 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -434,7 +434,7 @@ tegra_hdmi_get_audio_config(unsigned int audio_freq, unsigned int pix_clock, static void tegra_hdmi_setup_audio_fs_tables(struct tegra_hdmi *hdmi) { - const unsigned int freqs[] = { + static const unsigned int freqs[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 }; unsigned int i; -- GitLab From 7a5115ba1d691bd14db91d2fcc3ce0b056574ce9 Mon Sep 17 00:00:00 2001 From: Chen Yufan <chenyufan@vivo.com> Date: Fri, 23 Aug 2024 17:39:24 +0800 Subject: [PATCH 011/970] drm/imagination: Convert to use time_before macro Use time_*() macros instead of using jiffies directly to handle overflow issues. Fixes: cc1aeedb98ad ("drm/imagination: Implement firmware infrastructure and META FW support") Signed-off-by: Chen Yufan <chenyufan@vivo.com> Reviewed-by: Matt Coster <matt.coster@imgtec.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240823093925.9599-1-chenyufan@vivo.com Signed-off-by: Matt Coster <matt.coster@imgtec.com> --- drivers/gpu/drm/imagination/pvr_ccb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c index 4deeac7ed40a..2bbdc05a3b97 100644 --- a/drivers/gpu/drm/imagination/pvr_ccb.c +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -321,7 +321,7 @@ static int pvr_kccb_reserve_slot_sync(struct pvr_device *pvr_dev) bool reserved = false; u32 retries = 0; - while ((jiffies - start_timestamp) < (u32)RESERVE_SLOT_TIMEOUT || + while (time_before(jiffies, start_timestamp + RESERVE_SLOT_TIMEOUT) || retries < RESERVE_SLOT_MIN_RETRIES) { reserved = pvr_kccb_try_reserve_slot(pvr_dev); if (reserved) -- GitLab From c7d84a45f4266e9ff4c61eddde4acbfddb8f6b57 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Fri, 30 Aug 2024 15:36:54 +0800 Subject: [PATCH 012/970] drm/nouveau: Use for_each_child_of_node_scoped() Avoids the need for manual cleanup of_node_put() in early exits from the loop. Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240830073654.3539640-1-ruanjinjie@huawei.com --- drivers/gpu/drm/nouveau/nouveau_connector.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index b06aa473102b..8d5c9c74cbb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -477,14 +477,14 @@ nouveau_connector_of_detect(struct drm_connector *connector) struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder; struct pci_dev *pdev = to_pci_dev(dev->dev); - struct device_node *cn, *dn = pci_device_to_OF_node(pdev); + struct device_node *dn = pci_device_to_OF_node(pdev); if (!dn || !((nv_encoder = find_encoder(connector, DCB_OUTPUT_TMDS)) || (nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG)))) return NULL; - for_each_child_of_node(dn, cn) { + for_each_child_of_node_scoped(dn, cn) { const char *name = of_get_property(cn, "name", NULL); const void *edid = of_get_property(cn, "EDID", NULL); int idx = name ? name[strlen(name) - 1] - 'A' : 0; @@ -492,7 +492,6 @@ nouveau_connector_of_detect(struct drm_connector *connector) if (nv_encoder->dcb->i2c_index == idx && edid) { nv_connector->edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL); - of_node_put(cn); return nv_encoder; } } -- GitLab From eb4accc5234525e2cb2b720187ccaf6db99b705f Mon Sep 17 00:00:00 2001 From: Matt Coster <Matt.Coster@imgtec.com> Date: Fri, 30 Aug 2024 15:06:01 +0000 Subject: [PATCH 013/970] drm/imagination: Use pvr_vm_context_get() I missed this open-coded kref_get() while trying to debug a refcount bug, so let's use the helper function here to avoid that waste of time again in the future. Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code") Reviewed-by: Frank Binns <frank.binns@imgtec.com> Link: https://patchwork.freedesktop.org/patch/msgid/8616641d-6005-4b25-bc0a-0b53985a0e08@imgtec.com Signed-off-by: Matt Coster <matt.coster@imgtec.com> --- drivers/gpu/drm/imagination/pvr_vm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/imagination/pvr_vm.c b/drivers/gpu/drm/imagination/pvr_vm.c index e59517ba039e..ffd466509d0b 100644 --- a/drivers/gpu/drm/imagination/pvr_vm.c +++ b/drivers/gpu/drm/imagination/pvr_vm.c @@ -636,9 +636,7 @@ pvr_vm_context_lookup(struct pvr_file *pvr_file, u32 handle) xa_lock(&pvr_file->vm_ctx_handles); vm_ctx = xa_load(&pvr_file->vm_ctx_handles, handle); - if (vm_ctx) - kref_get(&vm_ctx->ref_count); - + pvr_vm_context_get(vm_ctx); xa_unlock(&pvr_file->vm_ctx_handles); return vm_ctx; -- GitLab From 3742c20958a5b02ecba08d71036bae3e7b9d21b3 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Sat, 31 Aug 2024 18:29:30 +0800 Subject: [PATCH 014/970] drm/imagination: Use memdup_user() helper to simplify code Switching to memdup_user(), which combines kmalloc() and copy_from_user(), and it can simplfy code. Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Reviewed-by: Frank Binns <frank.binns@imgtec.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240831102930.97502-1-ruanjinjie@huawei.com Signed-off-by: Matt Coster <matt.coster@imgtec.com> --- drivers/gpu/drm/imagination/pvr_job.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/imagination/pvr_job.c b/drivers/gpu/drm/imagination/pvr_job.c index 78c2f3c6dce0..618503a212a7 100644 --- a/drivers/gpu/drm/imagination/pvr_job.c +++ b/drivers/gpu/drm/imagination/pvr_job.c @@ -90,20 +90,13 @@ static int pvr_fw_cmd_init(struct pvr_device *pvr_dev, struct pvr_job *job, void *stream; int err; - stream = kzalloc(stream_len, GFP_KERNEL); - if (!stream) - return -ENOMEM; - - if (copy_from_user(stream, u64_to_user_ptr(stream_userptr), stream_len)) { - err = -EFAULT; - goto err_free_stream; - } + stream = memdup_user(u64_to_user_ptr(stream_userptr), stream_len); + if (IS_ERR(stream)) + return PTR_ERR(stream); err = pvr_job_process_stream(pvr_dev, stream_def, stream, stream_len, job); -err_free_stream: kfree(stream); - return err; } -- GitLab From 2872a57c7ad427d428c6d12e95e55b32bdc8e3b8 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 2 Sep 2024 10:33:00 +0800 Subject: [PATCH 015/970] drm/imagination: Use memdup_user() helper Switching to memdup_user(), which combines kmalloc() and copy_from_user(), and it can simplfy code. Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Suggested-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Reviewed-by: Frank Binns <frank.binns@imgtec.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902023300.1214753-1-ruanjinjie@huawei.com Signed-off-by: Matt Coster <matt.coster@imgtec.com> --- drivers/gpu/drm/imagination/pvr_context.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/imagination/pvr_context.c b/drivers/gpu/drm/imagination/pvr_context.c index eded5e955cc0..98327f9bbd9c 100644 --- a/drivers/gpu/drm/imagination/pvr_context.c +++ b/drivers/gpu/drm/imagination/pvr_context.c @@ -69,24 +69,12 @@ process_static_context_state(struct pvr_device *pvr_dev, const struct pvr_stream void *stream; int err; - stream = kzalloc(stream_size, GFP_KERNEL); - if (!stream) - return -ENOMEM; - - if (copy_from_user(stream, u64_to_user_ptr(stream_user_ptr), stream_size)) { - err = -EFAULT; - goto err_free; - } + stream = memdup_user(u64_to_user_ptr(stream_user_ptr), stream_size); + if (IS_ERR(stream)) + return PTR_ERR(stream); err = pvr_stream_process(pvr_dev, cmd_defs, stream, stream_size, dest); - if (err) - goto err_free; - - kfree(stream); - - return 0; -err_free: kfree(stream); return err; -- GitLab From 9c75b16cabc69adbbfdc9d219df87c9173f0da0a Mon Sep 17 00:00:00 2001 From: Mary Guillemard <mary.guillemard@collabora.com> Date: Mon, 19 Aug 2024 10:02:22 +0200 Subject: [PATCH 016/970] drm/panfrost: Add SYSTEM_TIMESTAMP and SYSTEM_TIMESTAMP_FREQUENCY parameters Expose system timestamp and frequency supported by the GPU. Mali uses an external timer as GPU system time. On ARM, this is wired to the generic arch timer so we wire cntfrq_el0 as device frequency. This new uAPI will be used in Mesa to implement timestamp queries and VK_KHR_calibrated_timestamps. v2: - Rewrote to use GPU timestamp register - Add missing include for arch_timer_get_cntfrq - Rework commit message v3: - Move panfrost_cycle_counter_get and panfrost_cycle_counter_put to panfrost_ioctl_query_timestamp - Handle possible overflow in panfrost_timestamp_read Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Steven Price <steven.price@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240819080224.24914-2-mary.guillemard@collabora.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 37 ++++++++++++++++++++++++ drivers/gpu/drm/panfrost/panfrost_gpu.c | 12 ++++++++ drivers/gpu/drm/panfrost/panfrost_gpu.h | 1 + drivers/gpu/drm/panfrost/panfrost_regs.h | 2 ++ include/uapi/drm/panfrost_drm.h | 2 ++ 5 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 671eed4ad890..790c4ad31143 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -3,6 +3,10 @@ /* Copyright 2019 Linaro, Ltd., Rob Herring <robh@kernel.org> */ /* Copyright 2019 Collabora ltd. */ +#ifdef CONFIG_ARM_ARCH_TIMER +#include <asm/arch_timer.h> +#endif + #include <linux/module.h> #include <linux/of.h> #include <linux/pagemap.h> @@ -24,10 +28,28 @@ static bool unstable_ioctls; module_param_unsafe(unstable_ioctls, bool, 0600); +static int panfrost_ioctl_query_timestamp(struct panfrost_device *pfdev, + u64 *arg) +{ + int ret; + + ret = pm_runtime_resume_and_get(pfdev->dev); + if (ret) + return ret; + + panfrost_cycle_counter_get(pfdev); + *arg = panfrost_timestamp_read(pfdev); + panfrost_cycle_counter_put(pfdev); + + pm_runtime_put(pfdev->dev); + return 0; +} + static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct drm_file *file) { struct drm_panfrost_get_param *param = data; struct panfrost_device *pfdev = ddev->dev_private; + int ret; if (param->pad != 0) return -EINVAL; @@ -69,6 +91,21 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct PANFROST_FEATURE_ARRAY(JS_FEATURES, js_features, 15); PANFROST_FEATURE(NR_CORE_GROUPS, nr_core_groups); PANFROST_FEATURE(THREAD_TLS_ALLOC, thread_tls_alloc); + + case DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP: + ret = panfrost_ioctl_query_timestamp(pfdev, ¶m->value); + if (ret) + return ret; + break; + + case DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP_FREQUENCY: +#ifdef CONFIG_ARM_ARCH_TIMER + param->value = arch_timer_get_cntfrq(); +#else + param->value = 0; +#endif + break; + default: return -EINVAL; } diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c index fd8e44992184..f19f918e2330 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -380,6 +380,18 @@ unsigned long long panfrost_cycle_counter_read(struct panfrost_device *pfdev) return ((u64)hi << 32) | lo; } +unsigned long long panfrost_timestamp_read(struct panfrost_device *pfdev) +{ + u32 hi, lo; + + do { + hi = gpu_read(pfdev, GPU_TIMESTAMP_HI); + lo = gpu_read(pfdev, GPU_TIMESTAMP_LO); + } while (hi != gpu_read(pfdev, GPU_TIMESTAMP_HI)); + + return ((u64)hi << 32) | lo; +} + static u64 panfrost_get_core_mask(struct panfrost_device *pfdev) { u64 core_mask; diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.h b/drivers/gpu/drm/panfrost/panfrost_gpu.h index d841b86504ea..b4fef11211d5 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gpu.h +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.h @@ -20,6 +20,7 @@ void panfrost_gpu_suspend_irq(struct panfrost_device *pfdev); void panfrost_cycle_counter_get(struct panfrost_device *pfdev); void panfrost_cycle_counter_put(struct panfrost_device *pfdev); unsigned long long panfrost_cycle_counter_read(struct panfrost_device *pfdev); +unsigned long long panfrost_timestamp_read(struct panfrost_device *pfdev); void panfrost_gpu_amlogic_quirk(struct panfrost_device *pfdev); diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h b/drivers/gpu/drm/panfrost/panfrost_regs.h index c25743b05c55..c7bba476ab3f 100644 --- a/drivers/gpu/drm/panfrost/panfrost_regs.h +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h @@ -78,6 +78,8 @@ #define GPU_CYCLE_COUNT_LO 0x90 #define GPU_CYCLE_COUNT_HI 0x94 +#define GPU_TIMESTAMP_LO 0x98 +#define GPU_TIMESTAMP_HI 0x9C #define GPU_THREAD_MAX_THREADS 0x0A0 /* (RO) Maximum number of threads per core */ #define GPU_THREAD_MAX_WORKGROUP_SIZE 0x0A4 /* (RO) Maximum workgroup size */ diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index 9f231d40a146..52b050e2b660 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -172,6 +172,8 @@ enum drm_panfrost_param { DRM_PANFROST_PARAM_NR_CORE_GROUPS, DRM_PANFROST_PARAM_THREAD_TLS_ALLOC, DRM_PANFROST_PARAM_AFBC_FEATURES, + DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP, + DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP_FREQUENCY, }; struct drm_panfrost_get_param { -- GitLab From 3a8d97611b564b5b25f68c90b543056fc9ae0bec Mon Sep 17 00:00:00 2001 From: Mary Guillemard <mary.guillemard@collabora.com> Date: Mon, 19 Aug 2024 10:02:23 +0200 Subject: [PATCH 017/970] drm/panfrost: Add cycle counter job requirement Extend the uAPI with a new job requirement flag for cycle counters. This requirement is used by userland to indicate that a job requires cycle counters or system timestamp to be propagated. (for use with write value timestamp jobs) We cannot enable cycle counters unconditionally as this would result in an increase of GPU power consumption. As a result, they should be left off unless required by the application. If a job requires cycle counters or system timestamps propagation, we must enable cycle counting before issuing a job and disable it right after the job completes. Since this extends the uAPI and because userland needs a way to advertise features like VK_KHR_shader_clock conditionally, we bumps the driver minor version. v2: - Rework commit message - Squash uAPI changes and implementation in this commit - Simplify changes based on Steven Price comments v3: - Add Steven Price r-b - Fix a codestyle issue Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Steven Price <steven.price@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240819080224.24914-3-mary.guillemard@collabora.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 8 +++++-- drivers/gpu/drm/panfrost/panfrost_job.c | 28 +++++++++++++++---------- include/uapi/drm/panfrost_drm.h | 1 + 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 790c4ad31143..04d615df5259 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -25,6 +25,8 @@ #include "panfrost_gpu.h" #include "panfrost_perfcnt.h" +#define JOB_REQUIREMENTS (PANFROST_JD_REQ_FS | PANFROST_JD_REQ_CYCLE_COUNT) + static bool unstable_ioctls; module_param_unsafe(unstable_ioctls, bool, 0600); @@ -282,7 +284,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, if (!args->jc) return -EINVAL; - if (args->requirements && args->requirements != PANFROST_JD_REQ_FS) + if (args->requirements & ~JOB_REQUIREMENTS) return -EINVAL; if (args->out_sync > 0) { @@ -621,6 +623,8 @@ static const struct file_operations panfrost_drm_driver_fops = { * - 1.0 - initial interface * - 1.1 - adds HEAP and NOEXEC flags for CREATE_BO * - 1.2 - adds AFBC_FEATURES query + * - 1.3 - adds JD_REQ_CYCLE_COUNT job requirement for SUBMIT + * - adds SYSTEM_TIMESTAMP and SYSTEM_TIMESTAMP_FREQUENCY queries */ static const struct drm_driver panfrost_drm_driver = { .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ, @@ -634,7 +638,7 @@ static const struct drm_driver panfrost_drm_driver = { .desc = "panfrost DRM", .date = "20180908", .major = 1, - .minor = 2, + .minor = 3, .gem_create_object = panfrost_gem_create_object, .gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table, diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index df49d37d0e7e..3ad131eb6657 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -159,16 +159,17 @@ panfrost_dequeue_job(struct panfrost_device *pfdev, int slot) struct panfrost_job *job = pfdev->jobs[slot][0]; WARN_ON(!job); - if (job->is_profiled) { - if (job->engine_usage) { - job->engine_usage->elapsed_ns[slot] += - ktime_to_ns(ktime_sub(ktime_get(), job->start_time)); - job->engine_usage->cycles[slot] += - panfrost_cycle_counter_read(pfdev) - job->start_cycles; - } - panfrost_cycle_counter_put(job->pfdev); + + if (job->is_profiled && job->engine_usage) { + job->engine_usage->elapsed_ns[slot] += + ktime_to_ns(ktime_sub(ktime_get(), job->start_time)); + job->engine_usage->cycles[slot] += + panfrost_cycle_counter_read(pfdev) - job->start_cycles; } + if (job->requirements & PANFROST_JD_REQ_CYCLE_COUNT || job->is_profiled) + panfrost_cycle_counter_put(pfdev); + pfdev->jobs[slot][0] = pfdev->jobs[slot][1]; pfdev->jobs[slot][1] = NULL; @@ -243,9 +244,13 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) subslot = panfrost_enqueue_job(pfdev, js, job); /* Don't queue the job if a reset is in progress */ if (!atomic_read(&pfdev->reset.pending)) { - if (pfdev->profile_mode) { + job->is_profiled = pfdev->profile_mode; + + if (job->requirements & PANFROST_JD_REQ_CYCLE_COUNT || + job->is_profiled) panfrost_cycle_counter_get(pfdev); - job->is_profiled = true; + + if (job->is_profiled) { job->start_time = ktime_get(); job->start_cycles = panfrost_cycle_counter_read(pfdev); } @@ -693,7 +698,8 @@ panfrost_reset(struct panfrost_device *pfdev, spin_lock(&pfdev->js->job_lock); for (i = 0; i < NUM_JOB_SLOTS; i++) { for (j = 0; j < ARRAY_SIZE(pfdev->jobs[0]) && pfdev->jobs[i][j]; j++) { - if (pfdev->jobs[i][j]->is_profiled) + if (pfdev->jobs[i][j]->requirements & PANFROST_JD_REQ_CYCLE_COUNT || + pfdev->jobs[i][j]->is_profiled) panfrost_cycle_counter_put(pfdev->jobs[i][j]->pfdev); pm_runtime_put_noidle(pfdev->dev); panfrost_devfreq_record_idle(&pfdev->pfdevfreq); diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index 52b050e2b660..568724be6628 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -40,6 +40,7 @@ extern "C" { #define DRM_IOCTL_PANFROST_PERFCNT_DUMP DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_DUMP, struct drm_panfrost_perfcnt_dump) #define PANFROST_JD_REQ_FS (1 << 0) +#define PANFROST_JD_REQ_CYCLE_COUNT (1 << 1) /** * struct drm_panfrost_submit - ioctl argument for submitting commands to the 3D * engine. -- GitLab From 9b79594aa470fd5fe2173d281fd604d11ec8e902 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 2 Sep 2024 17:44:04 +0800 Subject: [PATCH 018/970] drm/panthor: Use the BITS_PER_LONG macro sizeof(unsigned long) * 8 is the number of bits in an unsigned long variable, replace it with BITS_PER_LONG macro to make them simpler. And fix the warning: WARNING: Comparisons should place the constant on the right side of the test #23: FILE: drivers/gpu/drm/panthor/panthor_mmu.c:2696: + if (BITS_PER_LONG < va_bits) { Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Steven Price <steven.price@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902094404.1943710-1-ruanjinjie@huawei.com --- drivers/gpu/drm/panthor/panthor_mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index d47972806d50..cd2bac54e761 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -2693,9 +2693,9 @@ int panthor_mmu_init(struct panthor_device *ptdev) * which passes iova as an unsigned long. Patch the mmu_features to reflect this * limitation. */ - if (sizeof(unsigned long) * 8 < va_bits) { + if (va_bits > BITS_PER_LONG) { ptdev->gpu_info.mmu_features &= ~GENMASK(7, 0); - ptdev->gpu_info.mmu_features |= sizeof(unsigned long) * 8; + ptdev->gpu_info.mmu_features |= BITS_PER_LONG; } return drmm_add_action_or_reset(&ptdev->base, panthor_mmu_release_wq, mmu->vm.wq); -- GitLab From e8653e63e834e4c7de60b81b8b24deb7bdd3bf56 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: Tue, 13 Aug 2024 12:12:58 +0300 Subject: [PATCH 019/970] drm/panel: ili9341: Remove duplicate code Remove duplicate code that is handled by tinyDRM, i.e. drivers/gpu/drm/tiny/ili9341.c. Suggested-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240813091258.1625646-1-andriy.shevchenko@linux.intel.com Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 210 +------------------ 1 file changed, 3 insertions(+), 207 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index 1fbc5d433d75..ff39f5dd4097 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -13,9 +13,6 @@ * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c * the reuse of DBI abstraction part referred from Linus's patch * "drm/panel: s6e63m0: Switch to DBI abstraction for SPI" - * - * For only-dbi part, copy from David's code (drm/tiny/ili9341.c) - * Copyright 2018 David Lechner <david@lechnology.com> */ #include <linux/backlight.h> @@ -486,176 +483,6 @@ static const struct drm_panel_funcs ili9341_dpi_funcs = { .get_modes = ili9341_dpi_get_modes, }; -static void ili9341_dbi_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state, - struct drm_plane_state *plane_state) -{ - struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); - struct mipi_dbi *dbi = &dbidev->dbi; - u8 addr_mode; - int ret, idx; - - if (!drm_dev_enter(pipe->crtc.dev, &idx)) - return; - - ret = mipi_dbi_poweron_conditional_reset(dbidev); - if (ret < 0) - goto out_exit; - if (ret == 1) - goto out_enable; - - mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF); - - mipi_dbi_command(dbi, ILI9341_POWERB, 0x00, 0xc1, 0x30); - mipi_dbi_command(dbi, ILI9341_POWER_SEQ, 0x64, 0x03, 0x12, 0x81); - mipi_dbi_command(dbi, ILI9341_DTCA, 0x85, 0x00, 0x78); - mipi_dbi_command(dbi, ILI9341_POWERA, 0x39, 0x2c, 0x00, 0x34, 0x02); - mipi_dbi_command(dbi, ILI9341_PRC, ILI9341_DBI_PRC_NORMAL); - mipi_dbi_command(dbi, ILI9341_DTCB, 0x00, 0x00); - - /* Power Control */ - mipi_dbi_command(dbi, ILI9341_POWER1, ILI9341_DBI_VCOMH_4P6V); - mipi_dbi_command(dbi, ILI9341_POWER2, ILI9341_DBI_PWR_2_DEFAULT); - /* VCOM */ - mipi_dbi_command(dbi, ILI9341_VCOM1, ILI9341_DBI_VCOM_1_VMH_4P25V, - ILI9341_DBI_VCOM_1_VML_1P5V); - mipi_dbi_command(dbi, ILI9341_VCOM2, ILI9341_DBI_VCOM_2_DEC_58); - - /* Memory Access Control */ - mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, - MIPI_DCS_PIXEL_FMT_16BIT); - - /* Frame Rate */ - mipi_dbi_command(dbi, ILI9341_FRC, ILI9341_DBI_FRC_DIVA & 0x03, - ILI9341_DBI_FRC_RTNA & 0x1f); - - /* Gamma */ - mipi_dbi_command(dbi, ILI9341_3GAMMA_EN, 0x00); - mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, ILI9341_GAMMA_CURVE_1); - mipi_dbi_command(dbi, ILI9341_PGAMMA, - 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, - 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00); - mipi_dbi_command(dbi, ILI9341_NGAMMA, - 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1, - 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f); - - /* DDRAM */ - mipi_dbi_command(dbi, ILI9341_ETMOD, ILI9341_DBI_EMS_GAS | - ILI9341_DBI_EMS_DTS | - ILI9341_DBI_EMS_GON); - - /* Display */ - mipi_dbi_command(dbi, ILI9341_DFC, 0x08, 0x82, 0x27, 0x00); - mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); - msleep(100); - - mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); - msleep(100); - -out_enable: - switch (dbidev->rotation) { - default: - addr_mode = ILI9341_MADCTL_MX; - break; - case 90: - addr_mode = ILI9341_MADCTL_MV; - break; - case 180: - addr_mode = ILI9341_MADCTL_MY; - break; - case 270: - addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY | - ILI9341_MADCTL_MX; - break; - } - - addr_mode |= ILI9341_MADCTL_BGR; - mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); - mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); - drm_info(&dbidev->drm, "Initialized display serial interface\n"); -out_exit: - drm_dev_exit(idx); -} - -static const struct drm_simple_display_pipe_funcs ili9341_dbi_funcs = { - DRM_MIPI_DBI_SIMPLE_DISPLAY_PIPE_FUNCS(ili9341_dbi_enable), -}; - -static const struct drm_display_mode ili9341_dbi_mode = { - DRM_SIMPLE_MODE(240, 320, 37, 49), -}; - -DEFINE_DRM_GEM_DMA_FOPS(ili9341_dbi_fops); - -static struct drm_driver ili9341_dbi_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - .fops = &ili9341_dbi_fops, - DRM_GEM_DMA_DRIVER_OPS_VMAP, - .debugfs_init = mipi_dbi_debugfs_init, - .name = "ili9341", - .desc = "Ilitek ILI9341", - .date = "20210716", - .major = 1, - .minor = 0, -}; - -static int ili9341_dbi_probe(struct spi_device *spi, struct gpio_desc *dc, - struct gpio_desc *reset) -{ - struct device *dev = &spi->dev; - struct mipi_dbi_dev *dbidev; - struct mipi_dbi *dbi; - struct drm_device *drm; - struct regulator *vcc; - u32 rotation = 0; - int ret; - - vcc = devm_regulator_get_optional(dev, "vcc"); - if (IS_ERR(vcc)) { - dev_err(dev, "get optional vcc failed\n"); - vcc = NULL; - } - - dbidev = devm_drm_dev_alloc(dev, &ili9341_dbi_driver, - struct mipi_dbi_dev, drm); - if (IS_ERR(dbidev)) - return PTR_ERR(dbidev); - - dbi = &dbidev->dbi; - drm = &dbidev->drm; - dbi->reset = reset; - dbidev->regulator = vcc; - - drm_mode_config_init(drm); - - dbidev->backlight = devm_of_find_backlight(dev); - if (IS_ERR(dbidev->backlight)) - return PTR_ERR(dbidev->backlight); - - device_property_read_u32(dev, "rotation", &rotation); - - ret = mipi_dbi_spi_init(spi, dbi, dc); - if (ret) - return ret; - - ret = mipi_dbi_dev_init(dbidev, &ili9341_dbi_funcs, - &ili9341_dbi_mode, rotation); - if (ret) - return ret; - - drm_mode_config_reset(drm); - - ret = drm_dev_register(drm, 0); - if (ret) - return ret; - - spi_set_drvdata(spi, drm); - - drm_fbdev_dma_setup(drm, 0); - - return 0; -} - static int ili9341_dpi_probe(struct spi_device *spi, struct gpio_desc *dc, struct gpio_desc *reset) { @@ -711,7 +538,6 @@ static int ili9341_probe(struct spi_device *spi) struct device *dev = &spi->dev; struct gpio_desc *dc; struct gpio_desc *reset; - const struct spi_device_id *id = spi_get_device_id(spi); reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset)) @@ -721,36 +547,15 @@ static int ili9341_probe(struct spi_device *spi) if (IS_ERR(dc)) return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n"); - if (!strcmp(id->name, "sf-tc240t-9370-t")) - return ili9341_dpi_probe(spi, dc, reset); - - if (!strcmp(id->name, "yx240qv29")) - return ili9341_dbi_probe(spi, dc, reset); - - return -ENODEV; + return ili9341_dpi_probe(spi, dc, reset); } static void ili9341_remove(struct spi_device *spi) { - const struct spi_device_id *id = spi_get_device_id(spi); struct ili9341 *ili = spi_get_drvdata(spi); - struct drm_device *drm = spi_get_drvdata(spi); - - if (!strcmp(id->name, "sf-tc240t-9370-t")) { - ili9341_dpi_power_off(ili); - drm_panel_remove(&ili->panel); - } else if (!strcmp(id->name, "yx240qv29")) { - drm_dev_unplug(drm); - drm_atomic_helper_shutdown(drm); - } -} -static void ili9341_shutdown(struct spi_device *spi) -{ - const struct spi_device_id *id = spi_get_device_id(spi); - - if (!strcmp(id->name, "yx240qv29")) - drm_atomic_helper_shutdown(spi_get_drvdata(spi)); + ili9341_dpi_power_off(ili); + drm_panel_remove(&ili->panel); } static const struct of_device_id ili9341_of_match[] = { @@ -758,19 +563,11 @@ static const struct of_device_id ili9341_of_match[] = { .compatible = "st,sf-tc240t-9370-t", .data = &ili9341_stm32f429_disco_data, }, - { - /* porting from tiny/ili9341.c - * for original mipi dbi compitable - */ - .compatible = "adafruit,yx240qv29", - .data = NULL, - }, { } }; MODULE_DEVICE_TABLE(of, ili9341_of_match); static const struct spi_device_id ili9341_id[] = { - { "yx240qv29", 0 }, { "sf-tc240t-9370-t", 0 }, { } }; @@ -779,7 +576,6 @@ MODULE_DEVICE_TABLE(spi, ili9341_id); static struct spi_driver ili9341_driver = { .probe = ili9341_probe, .remove = ili9341_remove, - .shutdown = ili9341_shutdown, .id_table = ili9341_id, .driver = { .name = "panel-ilitek-ili9341", -- GitLab From ca097d4d94d808409386fde414370900cc41adad Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Thu, 4 Jul 2024 22:17:08 +0300 Subject: [PATCH 020/970] drm/display: split DSC helpers from DP helpers Currently the DRM DSC functions are selected by the DRM_DISPLAY_DP_HELPER Kconfig symbol. This is not optimal, since the DSI code (both panel and host drivers) end up selecting the seemingly irrelevant DP helpers. Split the DSC code to be guarded by the separate DRM_DISPLAY_DSC_HELPER Kconfig symbol. Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com> Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #i915 Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240704-panel-sw43408-fix-v6-1-3ea1c94bbb9b@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/amd/amdgpu/Kconfig | 1 + drivers/gpu/drm/display/Kconfig | 6 ++++++ drivers/gpu/drm/display/Makefile | 5 +++-- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/panel/Kconfig | 6 +++--- 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 0051fb1b437f..fc3237da8090 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -6,6 +6,7 @@ config DRM_AMDGPU depends on !UML select FW_LOADER select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 479e62690d75..a2e42014ffe0 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -59,6 +59,12 @@ config DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG If in doubt, say "N". +config DRM_DISPLAY_DSC_HELPER + bool + depends on DRM_DISPLAY_HELPER + help + DRM display helpers for VESA DSC (used by DSI and DisplayPort). + config DRM_DISPLAY_HDCP_HELPER bool depends on DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile index 629df2f4d322..a023f72fa139 100644 --- a/drivers/gpu/drm/display/Makefile +++ b/drivers/gpu/drm/display/Makefile @@ -6,10 +6,11 @@ drm_display_helper-y := drm_display_helper_mod.o drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \ drm_dp_dual_mode_helper.o \ drm_dp_helper.o \ - drm_dp_mst_topology.o \ - drm_dsc_helper.o + drm_dp_mst_topology.o drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \ drm_dp_tunnel.o +drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \ + drm_dsc_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \ drm_hdmi_helper.o \ diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index faa253b27664..db400aad88fa 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -11,6 +11,7 @@ config DRM_I915 select SHMEM select TMPFS select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 26a4c71da63a..420385c47193 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -112,6 +112,7 @@ config DRM_MSM_DSI depends on DRM_MSM select DRM_PANEL select DRM_MIPI_DSI + select DRM_DISPLAY_DSC_HELPER default y help Choose this option if you have a need for MIPI DSI connector diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index d3a9a9fafe4e..1077fd2307d4 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -378,7 +378,7 @@ config DRM_PANEL_LG_SW43408 depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE - select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HELPER help Say Y here if you want to enable support for LG sw43408 panel. @@ -587,7 +587,7 @@ config DRM_PANEL_RAYDIUM_RM692E5 depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE - select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HELPER help Say Y here if you want to enable support for Raydium RM692E5-based @@ -946,7 +946,7 @@ config DRM_PANEL_VISIONOX_R66451 depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE - select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HELPER help Say Y here if you want to enable support for Visionox -- GitLab From 2d736aa4f2e791f2b6e33cd7336058493bdbb239 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:41 +0300 Subject: [PATCH 021/970] dt-bindings: display: fsl-imx-drm: drop edid property support None of the in-kernel DT files ever used edid override with the fsl-imx-drm driver. In case the EDID needs to be specified manually, DRM core allows one to either override it via the debugfs or to load it via request_firmware by using DRM_LOAD_EDID_FIRMWARE. In all other cases EDID and/or modes are to be provided as a part of the panel driver. Drop the edid property from the fsl-imx-drm bindings. Acked-by: Rob Herring <robh@kernel.org> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-1-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt index 3c35338a2867..269b1ae2fca9 100644 --- a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt +++ b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt @@ -119,7 +119,6 @@ Optional properties: - interface-pix-fmt: How this display is connected to the display interface. Currently supported types: "rgb24", "rgb565", "bgr666" and "lvds666". -- edid: verbatim EDID data block describing attached display. - ddc: phandle describing the i2c bus handling the display data channel - port@[0-1]: Port nodes with endpoint definitions as defined in @@ -131,7 +130,6 @@ example: disp0 { compatible = "fsl,imx-parallel-display"; - edid = [edid-data]; interface-pix-fmt = "rgb24"; port@0 { -- GitLab From af8c9ad7144d8f7e45b217303339bbdb199a048c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:42 +0300 Subject: [PATCH 022/970] dt-bindings: display: imx/ldb: drop ddc-i2c-bus property The in-kernel DT files do not use ddc-i2c-bus property with the iMX LVDS Display Bridge. If in future a need arises to support such usecase, the panel-simple should be used, which is able to handle the DDC bus. Acked-by: Rob Herring <robh@kernel.org> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-2-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- Documentation/devicetree/bindings/display/imx/ldb.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/imx/ldb.txt b/Documentation/devicetree/bindings/display/imx/ldb.txt index 8e6e7d797943..03653a291b54 100644 --- a/Documentation/devicetree/bindings/display/imx/ldb.txt +++ b/Documentation/devicetree/bindings/display/imx/ldb.txt @@ -62,7 +62,6 @@ Required properties: display-timings are used instead. Optional properties (required if display-timings are used): - - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing - display-timings : A node that describes the display timings as defined in Documentation/devicetree/bindings/display/panel/display-timing.txt. - fsl,data-mapping : should be "spwg" or "jeida" -- GitLab From cc3fcd88808a43ae9fd59b48cd2e01989c4996f8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:43 +0300 Subject: [PATCH 023/970] drm/imx: cleanup the imx-drm header Drop unused defines and obsolete prototypes from the imx-drm.h header. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Rob Herring <robh@kernel.org> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-3-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/imx-drm.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm.h b/drivers/gpu/drm/imx/ipuv3/imx-drm.h index e721bebda2bd..e01f026047de 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm.h +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm.h @@ -3,14 +3,9 @@ #define _IMX_DRM_H_ struct device_node; -struct drm_crtc; struct drm_connector; struct drm_device; -struct drm_display_mode; struct drm_encoder; -struct drm_framebuffer; -struct drm_plane; -struct platform_device; struct imx_crtc_state { struct drm_crtc_state base; @@ -24,16 +19,9 @@ static inline struct imx_crtc_state *to_imx_crtc_state(struct drm_crtc_state *s) { return container_of(s, struct imx_crtc_state, base); } -int imx_drm_init_drm(struct platform_device *pdev, - int preferred_bpp); -int imx_drm_exit_drm(void); extern struct platform_driver ipu_drm_driver; -void imx_drm_mode_config_init(struct drm_device *drm); - -struct drm_gem_dma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); - int imx_drm_encoder_parse_of(struct drm_device *drm, struct drm_encoder *encoder, struct device_node *np); -- GitLab From fe30fabf229f7542a10dd249079fdb83844a7dba Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:44 +0300 Subject: [PATCH 024/970] drm/imx: parallel-display: drop edid override support None of the in-kernel DT files ever used edid override with the fsl-imx-drm driver. In case the EDID needs to be specified manually, DRM core allows one to either override it via the debugfs or to load it via request_firmware by using DRM_LOAD_EDID_FIRMWARE. In all other cases EDID and/or modes are to be provided as a part of the panel driver. Drop support for the edid property. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Rob Herring <robh@kernel.org> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-4-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/parallel-display.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 91d7808a2d8d..4d17fb96e77c 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -16,7 +16,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> -#include <drm/drm_edid.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> @@ -34,7 +33,6 @@ struct imx_parallel_display_encoder { struct imx_parallel_display { struct device *dev; - const struct drm_edid *drm_edid; u32 bus_format; u32 bus_flags; struct drm_display_mode mode; @@ -62,11 +60,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) if (num_modes > 0) return num_modes; - if (imxpd->drm_edid) { - drm_edid_connector_update(connector, imxpd->drm_edid); - num_modes = drm_edid_connector_add_modes(connector); - } - if (np) { struct drm_display_mode *mode = drm_mode_create(connector->dev); int ret; @@ -312,9 +305,7 @@ static int imx_pd_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - const u8 *edidp; struct imx_parallel_display *imxpd; - int edid_len; int ret; u32 bus_format = 0; const char *fmt; @@ -329,10 +320,6 @@ static int imx_pd_probe(struct platform_device *pdev) if (ret && ret != -ENODEV) return ret; - edidp = of_get_property(np, "edid", &edid_len); - if (edidp) - imxpd->drm_edid = drm_edid_alloc(edidp, edid_len); - ret = of_property_read_string(np, "interface-pix-fmt", &fmt); if (!ret) { if (!strcmp(fmt, "rgb24")) @@ -355,11 +342,7 @@ static int imx_pd_probe(struct platform_device *pdev) static void imx_pd_remove(struct platform_device *pdev) { - struct imx_parallel_display *imxpd = platform_get_drvdata(pdev); - component_del(&pdev->dev, &imx_pd_ops); - - drm_edid_free(imxpd->drm_edid); } static const struct of_device_id imx_pd_dt_ids[] = { -- GitLab From aed7b500315004a917463d571fa9cd12e0e94370 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:45 +0300 Subject: [PATCH 025/970] drm/imx: ldb: drop custom EDID support Bindings for the imx-ldb never allowed specifying the EDID in DT. None of the existing DT files use it. Drop it now in favour of using debugfs overrides or the drm.edid_firmware support. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-5-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/imx-ldb.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c index 793dfb1a3ed0..1924d8921c62 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c @@ -72,7 +72,6 @@ struct imx_ldb_channel { struct device_node *child; struct i2c_adapter *ddc; int chno; - const struct drm_edid *drm_edid; struct drm_display_mode mode; int mode_valid; u32 bus_format; @@ -142,14 +141,17 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) if (num_modes > 0) return num_modes; - if (!imx_ldb_ch->drm_edid && imx_ldb_ch->ddc) { - imx_ldb_ch->drm_edid = drm_edid_read_ddc(connector, - imx_ldb_ch->ddc); - drm_edid_connector_update(connector, imx_ldb_ch->drm_edid); - } + if (imx_ldb_ch->ddc) { + const struct drm_edid *edid = drm_edid_read_ddc(connector, + imx_ldb_ch->ddc); - if (imx_ldb_ch->drm_edid) - num_modes = drm_edid_connector_add_modes(connector); + if (edid) { + drm_edid_connector_update(connector, edid); + drm_edid_free(edid); + + return drm_edid_connector_add_modes(connector); + } + } if (imx_ldb_ch->mode_valid) { struct drm_display_mode *mode; @@ -566,18 +568,10 @@ static int imx_ldb_panel_ddc(struct device *dev, } if (!channel->ddc) { - const void *edidp; - int edid_len; - /* if no DDC available, fallback to hardcoded EDID */ dev_dbg(dev, "no ddc available\n"); - edidp = of_get_property(child, "edid", &edid_len); - if (edidp) { - channel->drm_edid = drm_edid_alloc(edidp, edid_len); - if (!channel->drm_edid) - return -ENOMEM; - } else if (!channel->panel) { + if (!channel->panel) { /* fallback to display-timings node */ ret = of_get_drm_display_mode(child, &channel->mode, @@ -744,7 +738,6 @@ static void imx_ldb_remove(struct platform_device *pdev) for (i = 0; i < 2; i++) { struct imx_ldb_channel *channel = &imx_ldb->channel[i]; - drm_edid_free(channel->drm_edid); i2c_put_adapter(channel->ddc); } -- GitLab From b2f3418b516e3485a14f10bfc09f20211dedc156 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:46 +0300 Subject: [PATCH 026/970] drm/imx: ldb: drop custom DDC bus support None of the boards ever supported by the upstream kernel used the custom DDC bus support with the LDB connector. If a need arises to do so, one should use panel-simple and its DDC bus code. Drop ddc-i2c-bus support from the imx-ldb driver. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-6-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/imx-ldb.c | 73 ++++------------------------- 1 file changed, 10 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c index 1924d8921c62..3f669604377e 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c @@ -25,7 +25,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> -#include <drm/drm_edid.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> @@ -70,7 +69,6 @@ struct imx_ldb_channel { struct drm_bridge *bridge; struct device_node *child; - struct i2c_adapter *ddc; int chno; struct drm_display_mode mode; int mode_valid; @@ -141,18 +139,6 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) if (num_modes > 0) return num_modes; - if (imx_ldb_ch->ddc) { - const struct drm_edid *edid = drm_edid_read_ddc(connector, - imx_ldb_ch->ddc); - - if (edid) { - drm_edid_connector_update(connector, edid); - drm_edid_free(edid); - - return drm_edid_connector_add_modes(connector); - } - } - if (imx_ldb_ch->mode_valid) { struct drm_display_mode *mode; @@ -481,10 +467,9 @@ static int imx_ldb_register(struct drm_device *drm, */ drm_connector_helper_add(connector, &imx_ldb_connector_helper_funcs); - drm_connector_init_with_ddc(drm, connector, - &imx_ldb_connector_funcs, - DRM_MODE_CONNECTOR_LVDS, - imx_ldb_ch->ddc); + drm_connector_init(drm, connector, + &imx_ldb_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); drm_connector_attach_encoder(connector, encoder); } @@ -551,39 +536,6 @@ static const struct of_device_id imx_ldb_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); -static int imx_ldb_panel_ddc(struct device *dev, - struct imx_ldb_channel *channel, struct device_node *child) -{ - struct device_node *ddc_node; - int ret; - - ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); - if (ddc_node) { - channel->ddc = of_find_i2c_adapter_by_node(ddc_node); - of_node_put(ddc_node); - if (!channel->ddc) { - dev_warn(dev, "failed to get ddc i2c adapter\n"); - return -EPROBE_DEFER; - } - } - - if (!channel->ddc) { - /* if no DDC available, fallback to hardcoded EDID */ - dev_dbg(dev, "no ddc available\n"); - - if (!channel->panel) { - /* fallback to display-timings node */ - ret = of_get_drm_display_mode(child, - &channel->mode, - &channel->bus_flags, - OF_USE_NATIVE_MODE); - if (!ret) - channel->mode_valid = 1; - } - } - return 0; -} - static int imx_ldb_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; @@ -694,11 +646,15 @@ static int imx_ldb_probe(struct platform_device *pdev) if (ret && ret != -ENODEV) goto free_child; - /* panel ddc only if there is no bridge */ - if (!channel->bridge) { - ret = imx_ldb_panel_ddc(dev, channel, child); + if (!channel->bridge && !channel->panel) { + ret = of_get_drm_display_mode(child, + &channel->mode, + &channel->bus_flags, + OF_USE_NATIVE_MODE); if (ret) goto free_child; + + channel->mode_valid = 1; } bus_format = of_get_bus_format(dev, child); @@ -732,15 +688,6 @@ static int imx_ldb_probe(struct platform_device *pdev) static void imx_ldb_remove(struct platform_device *pdev) { - struct imx_ldb *imx_ldb = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < 2; i++) { - struct imx_ldb_channel *channel = &imx_ldb->channel[i]; - - i2c_put_adapter(channel->ddc); - } - component_del(&pdev->dev, &imx_ldb_ops); } -- GitLab From 5c5843b20bbb1e4b4de2359573c20e416b41cb48 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:47 +0300 Subject: [PATCH 027/970] drm/imx: ldb: switch to drm_panel_bridge Defer panel handling to drm_panel_bridge, unifying codepaths for the panel and bridge cases. The MFD_SYSCON symbol is moved to select to prevent Kconfig symbol loops. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-7-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/Kconfig | 6 ++-- drivers/gpu/drm/imx/ipuv3/imx-ldb.c | 44 +++++++++-------------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig index bacf0655ebaf..6abcf9c833d4 100644 --- a/drivers/gpu/drm/imx/ipuv3/Kconfig +++ b/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -26,9 +26,11 @@ config DRM_IMX_TVE config DRM_IMX_LDB tristate "Support for LVDS displays" - depends on DRM_IMX && MFD_SYSCON + depends on DRM_IMX depends on COMMON_CLK - select DRM_PANEL + select MFD_SYSCON + select DRM_BRIDGE + select DRM_PANEL_BRIDGE help Choose this to enable the internal LVDS Display Bridge (LDB) found on i.MX53 and i.MX6 processors. diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c index 3f669604377e..bc7ad9697130 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c @@ -27,7 +27,6 @@ #include <drm/drm_bridge.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> @@ -64,8 +63,6 @@ struct imx_ldb; struct imx_ldb_channel { struct imx_ldb *ldb; - /* Defines what is connected to the ldb, only one at a time */ - struct drm_panel *panel; struct drm_bridge *bridge; struct device_node *child; @@ -135,10 +132,6 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); int num_modes; - num_modes = drm_panel_get_modes(imx_ldb_ch->panel, connector); - if (num_modes > 0) - return num_modes; - if (imx_ldb_ch->mode_valid) { struct drm_display_mode *mode; @@ -193,8 +186,6 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder) return; } - drm_panel_prepare(imx_ldb_ch->panel); - if (dual) { clk_set_parent(ldb->clk_sel[mux], ldb->clk[0]); clk_set_parent(ldb->clk_sel[mux], ldb->clk[1]); @@ -233,8 +224,6 @@ static void imx_ldb_encoder_enable(struct drm_encoder *encoder) } regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); - - drm_panel_enable(imx_ldb_ch->panel); } static void @@ -311,8 +300,6 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; int mux, ret; - drm_panel_disable(imx_ldb_ch->panel); - if (imx_ldb_ch == &ldb->channel[0] || dual) ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; if (imx_ldb_ch == &ldb->channel[1] || dual) @@ -346,8 +333,6 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) dev_err(ldb->dev, "unable to set di%d parent clock to original parent\n", mux); - - drm_panel_unprepare(imx_ldb_ch->panel); } static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder, @@ -640,13 +625,15 @@ static int imx_ldb_probe(struct platform_device *pdev) * The output port is port@4 with an external 4-port mux or * port@2 with the internal 2-port mux. */ - ret = drm_of_find_panel_or_bridge(child, - imx_ldb->lvds_mux ? 4 : 2, 0, - &channel->panel, &channel->bridge); - if (ret && ret != -ENODEV) - goto free_child; + channel->bridge = devm_drm_of_get_bridge(dev, child, + imx_ldb->lvds_mux ? 4 : 2, 0); + if (IS_ERR(channel->bridge)) { + ret = PTR_ERR(channel->bridge); + if (ret != -ENODEV) + goto free_child; + + channel->bridge = NULL; - if (!channel->bridge && !channel->panel) { ret = of_get_drm_display_mode(child, &channel->mode, &channel->bus_flags, @@ -658,15 +645,12 @@ static int imx_ldb_probe(struct platform_device *pdev) } bus_format = of_get_bus_format(dev, child); - if (bus_format == -EINVAL) { - /* - * If no bus format was specified in the device tree, - * we can still get it from the connected panel later. - */ - if (channel->panel && channel->panel->funcs && - channel->panel->funcs->get_modes) - bus_format = 0; - } + /* + * If no bus format was specified in the device tree, + * we can still get it from the connected panel later. + */ + if (bus_format == -EINVAL && channel->bridge) + bus_format = 0; if (bus_format < 0) { dev_err(dev, "could not determine data mapping: %d\n", bus_format); -- GitLab From 5f6e56d3319d2fd20d4c81b4f0212f4d09d7c1f1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:48 +0300 Subject: [PATCH 028/970] drm/imx: parallel-display: switch to drm_panel_bridge Defer panel handling to drm_panel_bridge, unifying codepaths for the panel and bridge cases. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-8-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/Kconfig | 3 +- drivers/gpu/drm/imx/ipuv3/parallel-display.c | 36 +++++--------------- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig index 6abcf9c833d4..f083d313d1d3 100644 --- a/drivers/gpu/drm/imx/ipuv3/Kconfig +++ b/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -11,8 +11,9 @@ config DRM_IMX config DRM_IMX_PARALLEL_DISPLAY tristate "Support for parallel displays" - select DRM_PANEL depends on DRM_IMX + select DRM_BRIDGE + select DRM_PANEL_BRIDGE select VIDEOMODE_HELPERS config DRM_IMX_TVE diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 4d17fb96e77c..9ac2a94fa62b 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -18,7 +18,6 @@ #include <drm/drm_bridge.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> @@ -36,7 +35,6 @@ struct imx_parallel_display { u32 bus_format; u32 bus_flags; struct drm_display_mode mode; - struct drm_panel *panel; struct drm_bridge *next_bridge; }; @@ -56,10 +54,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) struct device_node *np = imxpd->dev->of_node; int num_modes; - num_modes = drm_panel_get_modes(imxpd->panel, connector); - if (num_modes > 0) - return num_modes; - if (np) { struct drm_display_mode *mode = drm_mode_create(connector->dev); int ret; @@ -84,22 +78,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) return num_modes; } -static void imx_pd_bridge_enable(struct drm_bridge *bridge) -{ - struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge); - - drm_panel_prepare(imxpd->panel); - drm_panel_enable(imxpd->panel); -} - -static void imx_pd_bridge_disable(struct drm_bridge *bridge) -{ - struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge); - - drm_panel_disable(imxpd->panel); - drm_panel_unprepare(imxpd->panel); -} - static const u32 imx_pd_bus_fmts[] = { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_BGR888_1X24, @@ -237,8 +215,6 @@ static const struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = { }; static const struct drm_bridge_funcs imx_pd_bridge_funcs = { - .enable = imx_pd_bridge_enable, - .disable = imx_pd_bridge_disable, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, @@ -315,10 +291,14 @@ static int imx_pd_probe(struct platform_device *pdev) return -ENOMEM; /* port@1 is the output port */ - ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel, - &imxpd->next_bridge); - if (ret && ret != -ENODEV) - return ret; + imxpd->next_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); + if (IS_ERR(imxpd->next_bridge)) { + ret = PTR_ERR(imxpd->next_bridge); + if (ret != -ENODEV) + return ret; + + imxpd->next_bridge = NULL; + } ret = of_property_read_string(np, "interface-pix-fmt", &fmt); if (!ret) { -- GitLab From cc3e8a216d6b817c509e1e1a3700055d178e04f8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:49 +0300 Subject: [PATCH 029/970] drm/imx: add internal bridge handling display-timings DT node i.MX DRM DT bindings allow using either a proper panel / bridge graph to provide information about connected panels, or just a display-timings DT node, describing just the timings and the flags. Add helper bridge driver supporting the latter usecase. It will be used by both LDB and parallel-display drivers. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-9-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/imx/Kconfig | 10 +++ drivers/gpu/drm/bridge/imx/Makefile | 1 + .../gpu/drm/bridge/imx/imx-legacy-bridge.c | 87 +++++++++++++++++++ include/drm/bridge/imx.h | 13 +++ 4 files changed, 111 insertions(+) create mode 100644 drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c create mode 100644 include/drm/bridge/imx.h diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig index 8dd89efa8ea7..9a480c6abb85 100644 --- a/drivers/gpu/drm/bridge/imx/Kconfig +++ b/drivers/gpu/drm/bridge/imx/Kconfig @@ -3,6 +3,16 @@ if ARCH_MXC || COMPILE_TEST config DRM_IMX_LDB_HELPER tristate +config DRM_IMX_LEGACY_BRIDGE + tristate + depends on DRM_IMX + help + This is a DRM bridge implementation for the DRM i.MX IPUv3 driver, + that uses of_get_drm_display_mode to acquire display mode. + + Newer designs should not use this bridge and should use proper panel + driver instead. + config DRM_IMX8MP_DW_HDMI_BRIDGE tristate "Freescale i.MX8MP HDMI-TX bridge support" depends on OF diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile index edb0a7b71b30..dd5d48584806 100644 --- a/drivers/gpu/drm/bridge/imx/Makefile +++ b/drivers/gpu/drm/bridge/imx/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_DRM_IMX_LDB_HELPER) += imx-ldb-helper.o +obj-$(CONFIG_DRM_IMX_LEGACY_BRIDGE) += imx-legacy-bridge.o obj-$(CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE) += imx8mp-hdmi-tx.o obj-$(CONFIG_DRM_IMX8MP_HDMI_PVI) += imx8mp-hdmi-pvi.o obj-$(CONFIG_DRM_IMX8QM_LDB) += imx8qm-ldb.o diff --git a/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c b/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c new file mode 100644 index 000000000000..07a78a02a884 --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Freescale i.MX drm driver + * + * bridge driver for legacy DT bindings, utilizing display-timings node + */ + +#include <drm/drm_bridge.h> +#include <drm/drm_modes.h> +#include <drm/drm_probe_helper.h> +#include <drm/bridge/imx.h> + +#include <video/of_display_timing.h> +#include <video/of_videomode.h> + +struct imx_legacy_bridge { + struct drm_bridge base; + + struct drm_display_mode mode; + u32 bus_flags; +}; + +#define to_imx_legacy_bridge(bridge) container_of(bridge, struct imx_legacy_bridge, base) + +static int imx_legacy_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) + return -EINVAL; + + return 0; +} + +static int imx_legacy_bridge_get_modes(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct imx_legacy_bridge *imx_bridge = to_imx_legacy_bridge(bridge); + int ret; + + ret = drm_connector_helper_get_modes_fixed(connector, &imx_bridge->mode); + if (ret) + return ret; + + connector->display_info.bus_flags = imx_bridge->bus_flags; + + return 0; +} + +struct drm_bridge_funcs imx_legacy_bridge_funcs = { + .attach = imx_legacy_bridge_attach, + .get_modes = imx_legacy_bridge_get_modes, +}; + +struct drm_bridge *devm_imx_drm_legacy_bridge(struct device *dev, + struct device_node *np, + int type) +{ + struct imx_legacy_bridge *imx_bridge; + int ret; + + imx_bridge = devm_kzalloc(dev, sizeof(*imx_bridge), GFP_KERNEL); + if (!imx_bridge) + return ERR_PTR(-ENOMEM); + + ret = of_get_drm_display_mode(np, + &imx_bridge->mode, + &imx_bridge->bus_flags, + OF_USE_NATIVE_MODE); + if (ret) + return ERR_PTR(ret); + + imx_bridge->mode.type |= DRM_MODE_TYPE_DRIVER; + + imx_bridge->base.funcs = &imx_legacy_bridge_funcs; + imx_bridge->base.of_node = np; + imx_bridge->base.ops = DRM_BRIDGE_OP_MODES; + imx_bridge->base.type = type; + + ret = devm_drm_bridge_add(dev, &imx_bridge->base); + if (ret) + return ERR_PTR(ret); + + return &imx_bridge->base; +} +EXPORT_SYMBOL_GPL(devm_imx_drm_legacy_bridge); + +MODULE_LICENSE("GPL"); diff --git a/include/drm/bridge/imx.h b/include/drm/bridge/imx.h new file mode 100644 index 000000000000..e14f429a9ca2 --- /dev/null +++ b/include/drm/bridge/imx.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2012 Sascha Hauer, Pengutronix + */ + +#ifndef DRM_IMX_BRIDGE_H +#define DRM_IMX_BRIDGE_H + +struct drm_bridge *devm_imx_drm_legacy_bridge(struct device *dev, + struct device_node *np, + int type); + +#endif -- GitLab From 4c3d525f65733e760f3700c0f3c83e8e46d2dcd8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:50 +0300 Subject: [PATCH 030/970] drm/imx: ldb: switch to imx_legacy_bridge / drm_bridge_connector Use the imx_legacy bridge driver instead of handlign display modes via the connector node. All existing usecases already support attaching using the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, while the imx_legacy bridge doesn't support creating connector at all. Switch to drm_bridge_connector at the same time. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-10-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/Kconfig | 1 + drivers/gpu/drm/imx/ipuv3/imx-ldb.c | 103 ++++++++-------------------- 2 files changed, 30 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig index f083d313d1d3..5a40c878ebb0 100644 --- a/drivers/gpu/drm/imx/ipuv3/Kconfig +++ b/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -32,6 +32,7 @@ config DRM_IMX_LDB select MFD_SYSCON select DRM_BRIDGE select DRM_PANEL_BRIDGE + select DRM_IMX_LEGACY_BRIDGE help Choose this to enable the internal LVDS Display Bridge (LDB) found on i.MX53 and i.MX6 processors. diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c index bc7ad9697130..ff74018ac5cd 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c @@ -19,17 +19,16 @@ #include <linux/regmap.h> #include <linux/videodev2.h> -#include <video/of_display_timing.h> -#include <video/of_videomode.h> - #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> +#include <drm/bridge/imx.h> #include "imx-drm.h" @@ -53,7 +52,6 @@ struct imx_ldb_channel; struct imx_ldb_encoder { - struct drm_connector connector; struct drm_encoder encoder; struct imx_ldb_channel *channel; }; @@ -67,17 +65,9 @@ struct imx_ldb_channel { struct device_node *child; int chno; - struct drm_display_mode mode; - int mode_valid; u32 bus_format; - u32 bus_flags; }; -static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector *c) -{ - return container_of(c, struct imx_ldb_encoder, connector)->channel; -} - static inline struct imx_ldb_channel *enc_to_imx_ldb_ch(struct drm_encoder *e) { return container_of(e, struct imx_ldb_encoder, encoder)->channel; @@ -127,25 +117,6 @@ static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch, } } -static int imx_ldb_connector_get_modes(struct drm_connector *connector) -{ - struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); - int num_modes; - - if (imx_ldb_ch->mode_valid) { - struct drm_display_mode *mode; - - mode = drm_mode_duplicate(connector->dev, &imx_ldb_ch->mode); - if (!mode) - return -EINVAL; - mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, mode); - num_modes++; - } - - return num_modes; -} - static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, unsigned long serial_clk, unsigned long di_clk) { @@ -347,11 +318,12 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder, /* Bus format description in DT overrides connector display info. */ if (!bus_format && di->num_bus_formats) { bus_format = di->bus_formats[0]; - imx_crtc_state->bus_flags = di->bus_flags; } else { bus_format = imx_ldb_ch->bus_format; - imx_crtc_state->bus_flags = imx_ldb_ch->bus_flags; } + + imx_crtc_state->bus_flags = di->bus_flags; + switch (bus_format) { case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18; @@ -371,18 +343,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder, } -static const struct drm_connector_funcs imx_ldb_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = imx_drm_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static const struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { - .get_modes = imx_ldb_connector_get_modes, -}; - static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { .atomic_mode_set = imx_ldb_encoder_atomic_mode_set, .enable = imx_ldb_encoder_enable, @@ -420,7 +380,6 @@ static int imx_ldb_register(struct drm_device *drm, return PTR_ERR(ldb_encoder); ldb_encoder->channel = imx_ldb_ch; - connector = &ldb_encoder->connector; encoder = &ldb_encoder->encoder; ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child); @@ -439,24 +398,16 @@ static int imx_ldb_register(struct drm_device *drm, drm_encoder_helper_add(encoder, &imx_ldb_encoder_helper_funcs); - if (imx_ldb_ch->bridge) { - ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, 0); - if (ret) - return ret; - } else { - /* - * We want to add the connector whenever there is no bridge - * that brings its own, not only when there is a panel. For - * historical reasons, the ldb driver can also work without - * a panel. - */ - drm_connector_helper_add(connector, - &imx_ldb_connector_helper_funcs); - drm_connector_init(drm, connector, - &imx_ldb_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - drm_connector_attach_encoder(connector, encoder); - } + ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ret; + + connector = drm_bridge_connector_init(drm, encoder); + if (IS_ERR(connector)) + return PTR_ERR(connector); + + drm_connector_attach_encoder(connector, encoder); return 0; } @@ -631,17 +582,7 @@ static int imx_ldb_probe(struct platform_device *pdev) ret = PTR_ERR(channel->bridge); if (ret != -ENODEV) goto free_child; - channel->bridge = NULL; - - ret = of_get_drm_display_mode(child, - &channel->mode, - &channel->bus_flags, - OF_USE_NATIVE_MODE); - if (ret) - goto free_child; - - channel->mode_valid = 1; } bus_format = of_get_bus_format(dev, child); @@ -658,6 +599,20 @@ static int imx_ldb_probe(struct platform_device *pdev) goto free_child; } channel->bus_format = bus_format; + + /* + * legacy bridge doesn't handle bus_format, so create it after + * checking the bus_format property. + */ + if (!channel->bridge) { + channel->bridge = devm_imx_drm_legacy_bridge(dev, child, + DRM_MODE_CONNECTOR_LVDS); + if (IS_ERR(channel->bridge)) { + ret = PTR_ERR(channel->bridge); + goto free_child; + } + } + channel->child = child; } -- GitLab From f94b9707a1c91292c32f82847aa00d66472c0c62 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:51 +0300 Subject: [PATCH 031/970] drm/imx: parallel-display: switch to imx_legacy_bridge / drm_bridge_connector Use the imx_legacy bridge driver instead of handlign display modes via the connector node. All existing usecases already support attaching using the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, while the imx_legacy bridge doesn't support creating connector at all. Switch to drm_bridge_connector at the same time. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-11-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/parallel-display.c | 100 ++++--------------- 1 file changed, 20 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 9ac2a94fa62b..70f62e89622e 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -12,19 +12,18 @@ #include <linux/platform_device.h> #include <linux/videodev2.h> -#include <video/of_display_timing.h> - #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> #include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> +#include <drm/bridge/imx.h> #include "imx-drm.h" struct imx_parallel_display_encoder { - struct drm_connector connector; struct drm_encoder encoder; struct drm_bridge bridge; struct imx_parallel_display *pd; @@ -33,51 +32,14 @@ struct imx_parallel_display_encoder { struct imx_parallel_display { struct device *dev; u32 bus_format; - u32 bus_flags; - struct drm_display_mode mode; struct drm_bridge *next_bridge; }; -static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c) -{ - return container_of(c, struct imx_parallel_display_encoder, connector)->pd; -} - static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b) { return container_of(b, struct imx_parallel_display_encoder, bridge)->pd; } -static int imx_pd_connector_get_modes(struct drm_connector *connector) -{ - struct imx_parallel_display *imxpd = con_to_imxpd(connector); - struct device_node *np = imxpd->dev->of_node; - int num_modes; - - if (np) { - struct drm_display_mode *mode = drm_mode_create(connector->dev); - int ret; - - if (!mode) - return 0; - - ret = of_get_drm_display_mode(np, &imxpd->mode, - &imxpd->bus_flags, - OF_USE_NATIVE_MODE); - if (ret) { - drm_mode_destroy(connector->dev, mode); - return 0; - } - - drm_mode_copy(mode, &imxpd->mode); - mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, mode); - num_modes++; - } - - return num_modes; -} - static const u32 imx_pd_bus_fmts[] = { MEDIA_BUS_FMT_RGB888_1X24, MEDIA_BUS_FMT_BGR888_1X24, @@ -171,7 +133,6 @@ static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge, { struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); struct drm_display_info *di = &conn_state->connector->display_info; - struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge); struct drm_bridge_state *next_bridge_state = NULL; struct drm_bridge *next_bridge; u32 bus_flags, bus_fmt; @@ -183,10 +144,8 @@ static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge, if (next_bridge_state) bus_flags = next_bridge_state->input_bus_cfg.flags; - else if (di->num_bus_formats) - bus_flags = di->bus_flags; else - bus_flags = imxpd->bus_flags; + bus_flags = di->bus_flags; bus_fmt = bridge_state->input_bus_cfg.format; if (!imx_pd_format_supported(bus_fmt)) @@ -202,19 +161,16 @@ static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge, return 0; } -static const struct drm_connector_funcs imx_pd_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = imx_drm_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; +static int imx_pd_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge); -static const struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = { - .get_modes = imx_pd_connector_get_modes, -}; + return drm_bridge_attach(bridge->encoder, imxpd->next_bridge, bridge, flags); +} static const struct drm_bridge_funcs imx_pd_bridge_funcs = { + .attach = imx_pd_bridge_attach, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, @@ -239,7 +195,6 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(imxpd_encoder); imxpd_encoder->pd = imxpd; - connector = &imxpd_encoder->connector; encoder = &imxpd_encoder->encoder; bridge = &imxpd_encoder->bridge; @@ -247,28 +202,14 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - /* set the connector's dpms to OFF so that - * drm_helper_connector_dpms() won't return - * immediately since the current state is ON - * at this point. - */ - connector->dpms = DRM_MODE_DPMS_OFF; - bridge->funcs = &imx_pd_bridge_funcs; - drm_bridge_attach(encoder, bridge, NULL, 0); - - if (imxpd->next_bridge) { - ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0); - if (ret < 0) - return ret; - } else { - drm_connector_helper_add(connector, - &imx_pd_connector_helper_funcs); - drm_connector_init(drm, connector, &imx_pd_connector_funcs, - DRM_MODE_CONNECTOR_DPI); - - drm_connector_attach_encoder(connector, encoder); - } + drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); + + connector = drm_bridge_connector_init(drm, encoder); + if (IS_ERR(connector)) + return PTR_ERR(connector); + + drm_connector_attach_encoder(connector, encoder); return 0; } @@ -292,12 +233,11 @@ static int imx_pd_probe(struct platform_device *pdev) /* port@1 is the output port */ imxpd->next_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); + if (imxpd->next_bridge == ERR_PTR(-ENODEV)) + imxpd->next_bridge = devm_imx_drm_legacy_bridge(dev, np, DRM_MODE_CONNECTOR_DPI); if (IS_ERR(imxpd->next_bridge)) { ret = PTR_ERR(imxpd->next_bridge); - if (ret != -ENODEV) - return ret; - - imxpd->next_bridge = NULL; + return ret; } ret = of_property_read_string(np, "interface-pix-fmt", &fmt); -- GitLab From 9345e3aab7fef06b8908308634974ea32a29e276 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sun, 2 Jun 2024 15:04:52 +0300 Subject: [PATCH 032/970] drm/imx: move imx_drm_connector_destroy to imx-tve The imx-tve driver is the only remaining user of imx_drm_connector_destroy(). Move the function to imx-tve.c Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Rob Herring <robh@kernel.org> Tested-by: Chris Healy <cphealy@gmail.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # on imx6q-nitrogen6x Link: https://patchwork.freedesktop.org/patch/msgid/20240602-drm-imx-cleanup-v3-12-e549e2a43100@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 7 ------- drivers/gpu/drm/imx/ipuv3/imx-drm.h | 2 -- drivers/gpu/drm/imx/ipuv3/imx-tve.c | 8 +++++++- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c index 4cfabcf7375a..189d395349b8 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c @@ -34,13 +34,6 @@ module_param(legacyfb_depth, int, 0444); DEFINE_DRM_GEM_DMA_FOPS(imx_drm_driver_fops); -void imx_drm_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -} -EXPORT_SYMBOL_GPL(imx_drm_connector_destroy); - static int imx_drm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm.h b/drivers/gpu/drm/imx/ipuv3/imx-drm.h index e01f026047de..0c85bf83ffbf 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm.h +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm.h @@ -25,8 +25,6 @@ extern struct platform_driver ipu_drm_driver; int imx_drm_encoder_parse_of(struct drm_device *drm, struct drm_encoder *encoder, struct device_node *np); -void imx_drm_connector_destroy(struct drm_connector *connector); - int ipu_planes_assign_pre(struct drm_device *dev, struct drm_atomic_state *state); diff --git a/drivers/gpu/drm/imx/ipuv3/imx-tve.c b/drivers/gpu/drm/imx/ipuv3/imx-tve.c index 29f494bfff67..d46d07d25f51 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-tve.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-tve.c @@ -305,9 +305,15 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder, return 0; } +static void imx_tve_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + static const struct drm_connector_funcs imx_tve_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = imx_drm_connector_destroy, + .destroy = imx_tve_connector_destroy, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -- GitLab From 887665792b99430f98e6fbb15991a622ad9524c6 Mon Sep 17 00:00:00 2001 From: Marc Gonzalez <mgonzalez@freebox.fr> Date: Mon, 12 Aug 2024 16:51:01 +0200 Subject: [PATCH 033/970] dt-bindings: display: bridge: add TI TDP158 TDP158 is an AC-coupled DVI / HDMI to TMDS level shifting Redriver. It supports DVI 1.0, HDMI 1.4b and 2.0b. It supports 4 TMDS channels, HPD, and a DDC interface. It supports dual power supply rails (1.1V on VDD, 3.3V on VCC) for power reduction. Several methods of power management are implemented to reduce overall power consumption. It supports fixed receiver EQ gain using I2C or pin strap to compensate for different lengths input cable or board traces. Features - AC-coupled TMDS or DisplayPort dual-mode physical layer input to HDMI 2.0b TMDS physical layer output supporting up to 6Gbps data rate, compatible with HDMI 2.0b electrical parameters - DisplayPort dual-mode standard version 1.1 - Programmable fixed receiver equalizer up to 15.5dB - Global or independent high speed lane control, pre-emphasis and transmit swing, and slew rate control - I2C or pin strap programmable - Configurable as a DisplayPort redriver through I2C - Full lane swap on main lanes - Low power consumption (200 mW at 6Gbps, 8 mW in shutdown) https://www.ti.com/lit/ds/symlink/tdp158.pdf Like the TFP410, the TDP158 can be set up in 2 different ways: 1) hard-coding its configuration settings using pin-strapping resistors 2) placing it on an I2C bus, and defer set-up until run-time The mode is selected via pin 8 = I2C_EN I2C_EN high = I2C Control Mode I2C_EN low = Pin Strap Mode On our board, I2C_EN is pulled high. Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Signed-off-by: Marc Gonzalez <mgonzalez@freebox.fr> Signed-off-by: Robert Foss <rfoss@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240812-tdp158-v5-1-78684a84ec23@freebox.fr --- .../bindings/display/bridge/ti,tdp158.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml new file mode 100644 index 000000000000..1c522f72c4ba --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/ti,tdp158.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI TDP158 HDMI to TMDS Redriver + +maintainers: + - Arnaud Vrac <avrac@freebox.fr> + - Pierre-Hugues Husson <phhusson@freebox.fr> + +properties: + compatible: + const: ti,tdp158 + +# The reg property is required if and only if the device is connected +# to an I2C bus. In pin strap mode, reg must not be specified. + reg: + description: I2C address of the device + +# Pin 36 = Operation Enable / Reset Pin +# OE = L: Power Down Mode +# OE = H: Normal Operation +# Internal weak pullup - device resets on H to L transitions + enable-gpios: + description: GPIO controlling bridge enable + + vcc-supply: + description: Power supply 3.3V + + vdd-supply: + description: Power supply 1.1V + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Bridge input + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Bridge output + + required: + - port@0 + - port@1 + +required: + - compatible + - vcc-supply + - vdd-supply + - ports + +additionalProperties: false -- GitLab From a15710027afb40c7c1e352902fa5b8c949f021de Mon Sep 17 00:00:00 2001 From: Marc Gonzalez <mgonzalez@freebox.fr> Date: Mon, 12 Aug 2024 16:51:02 +0200 Subject: [PATCH 034/970] drm/bridge: add support for TI TDP158 TDP158 is an AC-coupled DVI / HDMI to TMDS level shifting Redriver. It supports DVI 1.0, HDMI 1.4b and 2.0b. It supports 4 TMDS channels, HPD, and a DDC interface. It supports dual power supply rails (1.1V on VDD, 3.3V on VCC) for power reduction. Several methods of power management are implemented to reduce overall power consumption. It supports fixed receiver EQ gain using I2C or pin strap to compensate for different lengths input cable or board traces. Features - AC-coupled TMDS or DisplayPort dual-mode physical layer input to HDMI 2.0b TMDS physical layer output supporting up to 6Gbps data rate, compatible with HDMI 2.0b electrical parameters - DisplayPort dual-mode standard version 1.1 - Programmable fixed receiver equalizer up to 15.5dB - Global or independent high speed lane control, pre-emphasis and transmit swing, and slew rate control - I2C or pin strap programmable - Configurable as a DisplayPort redriver through I2C - Full lane swap on main lanes - Low power consumption (200 mW at 6Gbps, 8 mW in shutdown) https://www.ti.com/lit/ds/symlink/tdp158.pdf On our board, I2C_EN is pulled high. Thus, this code defines a module_i2c_driver. The default settings work fine for our use-case. So this basic driver doesn't need to tweak any I2C registers. Signed-off-by: Marc Gonzalez <mgonzalez@freebox.fr> Reviewed-by: Robert Foss <rfoss@kernel.org> Signed-off-by: Robert Foss <rfoss@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240812-tdp158-v5-2-78684a84ec23@freebox.fr --- drivers/gpu/drm/bridge/Kconfig | 7 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/ti-tdp158.c | 108 +++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 drivers/gpu/drm/bridge/ti-tdp158.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index c621be1a99a8..c0ab5b620b57 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -368,6 +368,13 @@ config DRM_TI_DLPC3433 It supports up to 720p resolution with 60 and 120 Hz refresh rates. +config DRM_TI_TDP158 + tristate "TI TDP158 HDMI/TMDS bridge" + depends on OF + select DRM_PANEL_BRIDGE + help + Texas Instruments TDP158 HDMI/TMDS Bridge driver + config DRM_TI_TFP410 tristate "TI TFP410 DVI/HDMI bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 7df87b582dca..3daf803ce80b 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ obj-$(CONFIG_DRM_TI_DLPC3433) += ti-dlpc3433.o obj-$(CONFIG_DRM_TI_SN65DSI83) += ti-sn65dsi83.o obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o +obj-$(CONFIG_DRM_TI_TDP158) += ti-tdp158.o obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o diff --git a/drivers/gpu/drm/bridge/ti-tdp158.c b/drivers/gpu/drm/bridge/ti-tdp158.c new file mode 100644 index 000000000000..4ee0ad29874d --- /dev/null +++ b/drivers/gpu/drm/bridge/ti-tdp158.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2024 Freebox SAS + */ +#include <drm/drm_bridge.h> +#include <drm/drm_atomic_helper.h> +#include <linux/i2c.h> + +struct tdp158 { + struct drm_bridge bridge; + struct drm_bridge *next; + struct gpio_desc *enable; // Operation Enable - pin 36 + struct regulator *vcc; // 3.3V + struct regulator *vdd; // 1.1V + struct device *dev; +}; + +static void tdp158_enable(struct drm_bridge *bridge, struct drm_bridge_state *prev) +{ + int err; + struct tdp158 *tdp158 = bridge->driver_private; + + err = regulator_enable(tdp158->vcc); + if (err) + dev_err(tdp158->dev, "failed to enable vcc: %d", err); + + err = regulator_enable(tdp158->vdd); + if (err) + dev_err(tdp158->dev, "failed to enable vdd: %d", err); + + gpiod_set_value_cansleep(tdp158->enable, 1); +} + +static void tdp158_disable(struct drm_bridge *bridge, struct drm_bridge_state *prev) +{ + struct tdp158 *tdp158 = bridge->driver_private; + + gpiod_set_value_cansleep(tdp158->enable, 0); + regulator_disable(tdp158->vdd); + regulator_disable(tdp158->vcc); +} + +static int tdp158_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) +{ + struct tdp158 *tdp158 = bridge->driver_private; + + return drm_bridge_attach(bridge->encoder, tdp158->next, bridge, flags); +} + +static const struct drm_bridge_funcs tdp158_bridge_funcs = { + .attach = tdp158_attach, + .atomic_enable = tdp158_enable, + .atomic_disable = tdp158_disable, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, +}; + +static int tdp158_probe(struct i2c_client *client) +{ + struct tdp158 *tdp158; + struct device *dev = &client->dev; + + tdp158 = devm_kzalloc(dev, sizeof(*tdp158), GFP_KERNEL); + if (!tdp158) + return -ENOMEM; + + tdp158->next = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); + if (IS_ERR(tdp158->next)) + return dev_err_probe(dev, PTR_ERR(tdp158->next), "missing bridge"); + + tdp158->vcc = devm_regulator_get(dev, "vcc"); + if (IS_ERR(tdp158->vcc)) + return dev_err_probe(dev, PTR_ERR(tdp158->vcc), "vcc"); + + tdp158->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(tdp158->vdd)) + return dev_err_probe(dev, PTR_ERR(tdp158->vdd), "vdd"); + + tdp158->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(tdp158->enable)) + return dev_err_probe(dev, PTR_ERR(tdp158->enable), "enable"); + + tdp158->bridge.of_node = dev->of_node; + tdp158->bridge.funcs = &tdp158_bridge_funcs; + tdp158->bridge.driver_private = tdp158; + tdp158->dev = dev; + + return devm_drm_bridge_add(dev, &tdp158->bridge); +} + +static const struct of_device_id tdp158_match_table[] = { + { .compatible = "ti,tdp158" }, + { } +}; +MODULE_DEVICE_TABLE(of, tdp158_match_table); + +static struct i2c_driver tdp158_driver = { + .probe = tdp158_probe, + .driver = { + .name = "tdp158", + .of_match_table = tdp158_match_table, + }, +}; +module_i2c_driver(tdp158_driver); + +MODULE_DESCRIPTION("TI TDP158 driver"); +MODULE_LICENSE("GPL"); -- GitLab From f909e61f24744fb010b5ce830e916ff936451a14 Mon Sep 17 00:00:00 2001 From: Aryabhatta Dey <aryabhattadey35@gmail.com> Date: Tue, 27 Aug 2024 18:48:52 +0530 Subject: [PATCH 035/970] Documentation/gpu: Fix typo in Documentation/gpu/komeda-kms.rst Change 'indenpendently' to 'independently'. Signed-off-by: Aryabhatta Dey <aryabhattadey35@gmail.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/l5wzytcamcc43eadaquqbrfqilq6ajfnnseh37c77eceamtw35@hhtdipi4h22c --- Documentation/gpu/komeda-kms.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/gpu/komeda-kms.rst b/Documentation/gpu/komeda-kms.rst index 633a016563ae..eaea40eb725b 100644 --- a/Documentation/gpu/komeda-kms.rst +++ b/Documentation/gpu/komeda-kms.rst @@ -86,7 +86,7 @@ types of working mode: - Single display mode Two pipelines work together to drive only one display output. - On this mode, pipeline_B doesn't work indenpendently, but outputs its + On this mode, pipeline_B doesn't work independently, but outputs its composition result into pipeline_A, and its pixel timing also derived from pipeline_A.timing_ctrlr. The pipeline_B works just like a "slave" of pipeline_A(master) -- GitLab From 8e514bad271723473d31fcc496f7143ba49c43c5 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Mon, 2 Sep 2024 19:13:17 +0300 Subject: [PATCH 036/970] drm/tegra: fix potential uninitialized variable use It's likely either output->drm_edid or output->ddc is non-NULL, but avoid the uninitialized variable usage anyway. Reported-by: kernel test robot <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/r/ZtXLyXxew7z6H2bD@stanley.mountain Fixes: 98365ca74cbf ("drm/tegra: convert to struct drm_edid") Cc: Thierry Reding <treding@nvidia.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: linux-tegra@vger.kernel.org Acked-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902161317.2437148-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/tegra/output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index e6b5863fec71..49e4f63a5550 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -21,7 +21,7 @@ int tegra_output_connector_get_modes(struct drm_connector *connector) { struct tegra_output *output = connector_to_output(connector); - const struct drm_edid *drm_edid; + const struct drm_edid *drm_edid = NULL; int err = 0; /* -- GitLab From 053d157840870fc56aad8c4d3122690a65b2d462 Mon Sep 17 00:00:00 2001 From: Detlev Casanova <detlev.casanova@collabora.com> Date: Tue, 3 Sep 2024 11:22:35 -0400 Subject: [PATCH 037/970] dt-bindings: gpu: Add rockchip,rk3576-mali compatible The rk3576 SoC has an ARM Mali G52 MC3 GPU, that is compatible with arm,mali-bifrost. Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240903152308.13565-6-detlev.casanova@collabora.com --- Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml index 278399adc550..735c7f06c24e 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml @@ -26,6 +26,7 @@ properties: - renesas,r9a07g054-mali - rockchip,px30-mali - rockchip,rk3568-mali + - rockchip,rk3576-mali - const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully discoverable - items: - enum: -- GitLab From 0bf469888efda8dc81c1dafa14f23048d6b4d663 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Thu, 22 Aug 2024 20:42:48 +0300 Subject: [PATCH 038/970] drm/exynos: hdmi: use display_info for printing display dimensions Look up display dimensions from display_info instead of the EDID directly. This will be helpful for the follow-up work. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Inki Dae <inki.dae@samsung.com> Link: https://patchwork.freedesktop.org/patch/msgid/8a6fd6de1853dbc337c5c26c65268604d3e91fe2.1724348429.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/exynos/exynos_hdmi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 1e26cd4f8347..25d508b25921 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -883,6 +883,7 @@ static const struct drm_connector_funcs hdmi_connector_funcs = { static int hdmi_get_modes(struct drm_connector *connector) { struct hdmi_context *hdata = connector_to_hdmi(connector); + const struct drm_display_info *info = &connector->display_info; struct edid *edid; int ret; @@ -893,10 +894,10 @@ static int hdmi_get_modes(struct drm_connector *connector) if (!edid) goto no_edid; - hdata->dvi_mode = !connector->display_info.is_hdmi; + hdata->dvi_mode = !info->is_hdmi; DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n", (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), - edid->width_cm, edid->height_cm); + info->width_mm / 10, info->height_mm / 10); drm_connector_update_edid_property(connector, edid); cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid); -- GitLab From f6e4f57fd90dc497e0d1cac902935c9ea2686676 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Thu, 22 Aug 2024 20:42:49 +0300 Subject: [PATCH 039/970] drm/exynos: hdmi: convert to struct drm_edid Prefer the struct drm_edid based functions for reading the EDID and updating the connector. The functional change is that the CEC physical address gets invalidated when the EDID could not be read. v2: - display info usage was split to a separate patch - check drm_edid_connector_update() return value Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Inki Dae <inki.dae@samsung.com> Link: https://patchwork.freedesktop.org/patch/msgid/be15dce66a5373a7aed797a4ef63b0ba90b231e9.1724348429.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/exynos/exynos_hdmi.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 25d508b25921..c9d4b9146df9 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -884,14 +884,21 @@ static int hdmi_get_modes(struct drm_connector *connector) { struct hdmi_context *hdata = connector_to_hdmi(connector); const struct drm_display_info *info = &connector->display_info; - struct edid *edid; + const struct drm_edid *drm_edid; int ret; if (!hdata->ddc_adpt) goto no_edid; - edid = drm_get_edid(connector, hdata->ddc_adpt); - if (!edid) + drm_edid = drm_edid_read_ddc(connector, hdata->ddc_adpt); + + ret = drm_edid_connector_update(connector, drm_edid); + if (ret) + return 0; + + cec_notifier_set_phys_addr(hdata->notifier, info->source_physical_address); + + if (!drm_edid) goto no_edid; hdata->dvi_mode = !info->is_hdmi; @@ -899,12 +906,9 @@ static int hdmi_get_modes(struct drm_connector *connector) (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), info->width_mm / 10, info->height_mm / 10); - drm_connector_update_edid_property(connector, edid); - cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid); - - ret = drm_add_edid_modes(connector, edid); + ret = drm_edid_connector_add_modes(connector); - kfree(edid); + drm_edid_free(drm_edid); return ret; -- GitLab From 53bd7c1c0077db533472ae32799157758302ef48 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: Thu, 29 Aug 2024 18:46:40 +0300 Subject: [PATCH 040/970] drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused The INTERVAL_TREE_DEFINE() uncoditionally provides a bunch of helper functions which in some cases may be not used. This, in particular, prevents kernel builds with clang, `make W=1` and CONFIG_WERROR=y: .../drm/drm_mm.c:152:1: error: unused function 'drm_mm_interval_tree_insert' [-Werror,-Wunused-function] 152 | INTERVAL_TREE_DEFINE(struct drm_mm_node, rb, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 153 | u64, __subtree_last, | ~~~~~~~~~~~~~~~~~~~~ 154 | START, LAST, static inline, drm_mm_interval_tree) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix this by marking drm_mm_interval_tree*() functions with __maybe_unused. See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static inline functions for W=1 build"). Fixes: 202b52b7fbf7 ("drm: Track drm_mm nodes with an interval tree") Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240829154640.1120050-1-andriy.shevchenko@linux.intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/drm_mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 5ace481c1901..1ed68d3cd80b 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -151,7 +151,7 @@ static void show_leaks(struct drm_mm *mm) { } INTERVAL_TREE_DEFINE(struct drm_mm_node, rb, u64, __subtree_last, - START, LAST, static inline, drm_mm_interval_tree) + START, LAST, static inline __maybe_unused, drm_mm_interval_tree) struct drm_mm_node * __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last) -- GitLab From 461ed4aad0189eee670c980656de93bf6fa3a3dc Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Tue, 3 Sep 2024 20:34:37 +0300 Subject: [PATCH 041/970] drm/mm: annotate drm_mm_node_scanned_block() with __maybe_unused Clang build with CONFIG_DRM_DEBUG_MM=n, CONFIG_WERROR=y, and W=1 leads to: CC [M] drivers/gpu/drm/drm_mm.o ../drivers/gpu/drm/drm_mm.c:614:20: error: function 'drm_mm_node_scanned_block' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] static inline bool drm_mm_node_scanned_block(const struct drm_mm_node *node) ^ Fix this by annotating drm_mm_node_scanned_block() with __maybe_unused. Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240903173437.3212437-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/drm_mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 1ed68d3cd80b..ca254611b382 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -611,7 +611,7 @@ int drm_mm_insert_node_in_range(struct drm_mm * const mm, } EXPORT_SYMBOL(drm_mm_insert_node_in_range); -static inline bool drm_mm_node_scanned_block(const struct drm_mm_node *node) +static inline __maybe_unused bool drm_mm_node_scanned_block(const struct drm_mm_node *node) { return test_bit(DRM_MM_NODE_SCANNED_BIT, &node->flags); } -- GitLab From 532f0d109658232b44dc36b1656c92ec4d1cb28b Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 4 Sep 2024 11:52:06 +0300 Subject: [PATCH 042/970] drm/bridge/tdp158: fix build failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ARCH=arm build fails with: CC [M] drivers/gpu/drm/bridge/ti-tdp158.o ../drivers/gpu/drm/bridge/ti-tdp158.c: In function ‘tdp158_enable’: ../drivers/gpu/drm/bridge/ti-tdp158.c:31:9: error: implicit declaration of function ‘gpiod_set_value_cansleep’ [-Werror=implicit-function-declaration] 31 | gpiod_set_value_cansleep(tdp158->enable, 1); | ^~~~~~~~~~~~~~~~~~~~~~~~ ../drivers/gpu/drm/bridge/ti-tdp158.c: In function ‘tdp158_probe’: ../drivers/gpu/drm/bridge/ti-tdp158.c:80:26: error: implicit declaration of function ‘devm_gpiod_get_optional’; did you mean ‘devm_regulator_get_optional’? [-Werror=implicit-function-declaration] 80 | tdp158->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); | ^~~~~~~~~~~~~~~~~~~~~~~ | devm_regulator_get_optional ../drivers/gpu/drm/bridge/ti-tdp158.c:80:65: error: ‘GPIOD_OUT_LOW’ undeclared (first use in this function) 80 | tdp158->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); | ^~~~~~~~~~~~~ ../drivers/gpu/drm/bridge/ti-tdp158.c:80:65: note: each undeclared identifier is reported only once for each function it appears in Add the proper gpio consumer #include to fix this, and juggle the include order to be a bit more pleasant on the eye while at it. Fixes: a15710027afb ("drm/bridge: add support for TI TDP158") Cc: Marc Gonzalez <mgonzalez@freebox.fr> Cc: Robert Foss <rfoss@kernel.org> Cc: Andrzej Hajda <andrzej.hajda@intel.com> Cc: Neil Armstrong <neil.armstrong@linaro.org> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com> Cc: Jonas Karlman <jonas@kwiboo.se> Cc: Jernej Skrabec <jernej.skrabec@gmail.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240904085206.3331553-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/bridge/ti-tdp158.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-tdp158.c b/drivers/gpu/drm/bridge/ti-tdp158.c index 4ee0ad29874d..3472ed5924e8 100644 --- a/drivers/gpu/drm/bridge/ti-tdp158.c +++ b/drivers/gpu/drm/bridge/ti-tdp158.c @@ -2,10 +2,13 @@ /* * Copyright 2024 Freebox SAS */ -#include <drm/drm_bridge.h> -#include <drm/drm_atomic_helper.h> + +#include <linux/gpio/consumer.h> #include <linux/i2c.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> + struct tdp158 { struct drm_bridge bridge; struct drm_bridge *next; -- GitLab From bf7835facc09569eb038db7cfe42590d50b73567 Mon Sep 17 00:00:00 2001 From: Lu Baolu <baolu.lu@linux.intel.com> Date: Mon, 2 Sep 2024 09:46:58 +0800 Subject: [PATCH 043/970] drm/nouveau/tegra: Use iommu_paging_domain_alloc() In nvkm_device_tegra_probe_iommu(), a paging domain is allocated for @dev and attached to it on success. Use iommu_paging_domain_alloc() to make it explicit. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902014700.66095-2-baolu.lu@linux.intel.com --- drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index d1c294f00665..78a83f904bbd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -120,8 +120,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) mutex_init(&tdev->iommu.mutex); if (device_iommu_mapped(dev)) { - tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); - if (!tdev->iommu.domain) + tdev->iommu.domain = iommu_paging_domain_alloc(dev); + if (IS_ERR(tdev->iommu.domain)) goto error; /* -- GitLab From c6430a8eb08d73f79a0f6cd8dbbc7e71037faac0 Mon Sep 17 00:00:00 2001 From: Li Zetao <lizetao1@huawei.com> Date: Sat, 31 Aug 2024 09:28:03 +0800 Subject: [PATCH 044/970] drm/nouveau/volt: use clamp() in nvkm_volt_map() When it needs to get a value within a certain interval, using clamp() makes the code easier to understand than min(max()). Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Li Zetao <lizetao1@huawei.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240831012803.3950100-4-lizetao1@huawei.com --- drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c index a17a6dd8d3de..803b98df4858 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c @@ -142,7 +142,7 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id, u8 temp) return -ENODEV; } - result = min(max(result, (s64)info.min), (s64)info.max); + result = clamp(result, (s64)info.min, (s64)info.max); if (info.link != 0xff) { int ret = nvkm_volt_map(volt, info.link, temp); -- GitLab From a778028cc575deeb5224cc798de6e03d37331bca Mon Sep 17 00:00:00 2001 From: Mary Guillemard <mary.guillemard@collabora.com> Date: Fri, 30 Aug 2024 10:03:50 +0200 Subject: [PATCH 045/970] drm/panthor: Add DEV_QUERY_TIMESTAMP_INFO dev query Expose timestamp information supported by the GPU with a new device query. Mali uses an external timer as GPU system time. On ARM, this is wired to the generic arch timer so we wire cntfrq_el0 as device frequency. This new uAPI will be used in Mesa to implement timestamp queries and VK_KHR_calibrated_timestamps. Since this extends the uAPI and because userland needs a way to advertise those features conditionally, this also bumps the driver minor version. v2: - Rewrote to use GPU timestamp register - Added timestamp_offset to drm_panthor_timestamp_info - Add missing include for arch_timer_get_cntfrq - Rework commit message v3: - Add panthor_gpu_read_64bit_counter - Change panthor_gpu_read_timestamp to use panthor_gpu_read_64bit_counter v4: - Fix multiple typos in uAPI documentation - Mention behavior when the timestamp frequency is unknown - Use u64 instead of unsigned long long for panthor_gpu_read_timestamp - Apply r-b from Mihail Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Mihail Atanassov <mihail.atanassov@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240830080349.24736-2-mary.guillemard@collabora.com --- drivers/gpu/drm/panthor/panthor_drv.c | 43 +++++++++++++++++++++++- drivers/gpu/drm/panthor/panthor_gpu.c | 47 +++++++++++++++++++++++++++ drivers/gpu/drm/panthor/panthor_gpu.h | 4 +++ include/uapi/drm/panthor_drm.h | 22 +++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index b5e7b919f241..444e3bb1cfb5 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -3,6 +3,10 @@ /* Copyright 2019 Linaro, Ltd., Rob Herring <robh@kernel.org> */ /* Copyright 2019 Collabora ltd. */ +#ifdef CONFIG_ARM_ARCH_TIMER +#include <asm/arch_timer.h> +#endif + #include <linux/list.h> #include <linux/module.h> #include <linux/of_platform.h> @@ -164,6 +168,7 @@ panthor_get_uobj_array(const struct drm_panthor_obj_array *in, u32 min_stride, _Generic(_obj_name, \ PANTHOR_UOBJ_DECL(struct drm_panthor_gpu_info, tiler_present), \ PANTHOR_UOBJ_DECL(struct drm_panthor_csif_info, pad), \ + PANTHOR_UOBJ_DECL(struct drm_panthor_timestamp_info, current_timestamp), \ PANTHOR_UOBJ_DECL(struct drm_panthor_sync_op, timeline_value), \ PANTHOR_UOBJ_DECL(struct drm_panthor_queue_submit, syncs), \ PANTHOR_UOBJ_DECL(struct drm_panthor_queue_create, ringbuf_size), \ @@ -750,10 +755,33 @@ static void panthor_submit_ctx_cleanup(struct panthor_submit_ctx *ctx, kvfree(ctx->jobs); } +static int panthor_query_timestamp_info(struct panthor_device *ptdev, + struct drm_panthor_timestamp_info *arg) +{ + int ret; + + ret = pm_runtime_resume_and_get(ptdev->base.dev); + if (ret) + return ret; + +#ifdef CONFIG_ARM_ARCH_TIMER + arg->timestamp_frequency = arch_timer_get_cntfrq(); +#else + arg->timestamp_frequency = 0; +#endif + arg->current_timestamp = panthor_gpu_read_timestamp(ptdev); + arg->timestamp_offset = panthor_gpu_read_timestamp_offset(ptdev); + + pm_runtime_put(ptdev->base.dev); + return 0; +} + static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct drm_file *file) { struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base); struct drm_panthor_dev_query *args = data; + struct drm_panthor_timestamp_info timestamp_info; + int ret; if (!args->pointer) { switch (args->type) { @@ -765,6 +793,10 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d args->size = sizeof(ptdev->csif_info); return 0; + case DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO: + args->size = sizeof(timestamp_info); + return 0; + default: return -EINVAL; } @@ -777,6 +809,14 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d case DRM_PANTHOR_DEV_QUERY_CSIF_INFO: return PANTHOR_UOBJ_SET(args->pointer, args->size, ptdev->csif_info); + case DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO: + ret = panthor_query_timestamp_info(ptdev, ×tamp_info); + + if (ret) + return ret; + + return PANTHOR_UOBJ_SET(args->pointer, args->size, timestamp_info); + default: return -EINVAL; } @@ -1372,6 +1412,7 @@ static void panthor_debugfs_init(struct drm_minor *minor) /* * PanCSF driver version: * - 1.0 - initial interface + * - 1.1 - adds DEV_QUERY_TIMESTAMP_INFO query */ static const struct drm_driver panthor_drm_driver = { .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ | @@ -1385,7 +1426,7 @@ static const struct drm_driver panthor_drm_driver = { .desc = "Panthor DRM driver", .date = "20230801", .major = 1, - .minor = 0, + .minor = 1, .gem_create_object = panthor_gem_create_object, .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c index 5251d8764e7d..2d3529a0b156 100644 --- a/drivers/gpu/drm/panthor/panthor_gpu.c +++ b/drivers/gpu/drm/panthor/panthor_gpu.c @@ -480,3 +480,50 @@ void panthor_gpu_resume(struct panthor_device *ptdev) panthor_gpu_irq_resume(&ptdev->gpu->irq, GPU_INTERRUPTS_MASK); panthor_gpu_l2_power_on(ptdev); } + +/** + * panthor_gpu_read_64bit_counter() - Read a 64-bit counter at a given offset. + * @ptdev: Device. + * @reg: The offset of the register to read. + * + * Return: The counter value. + */ +static u64 +panthor_gpu_read_64bit_counter(struct panthor_device *ptdev, u32 reg) +{ + u32 hi, lo; + + do { + hi = gpu_read(ptdev, reg + 0x4); + lo = gpu_read(ptdev, reg); + } while (hi != gpu_read(ptdev, reg + 0x4)); + + return ((u64)hi << 32) | lo; +} + +/** + * panthor_gpu_read_timestamp() - Read the timestamp register. + * @ptdev: Device. + * + * Return: The GPU timestamp value. + */ +u64 panthor_gpu_read_timestamp(struct panthor_device *ptdev) +{ + return panthor_gpu_read_64bit_counter(ptdev, GPU_TIMESTAMP_LO); +} + +/** + * panthor_gpu_read_timestamp_offset() - Read the timestamp offset register. + * @ptdev: Device. + * + * Return: The GPU timestamp offset value. + */ +u64 panthor_gpu_read_timestamp_offset(struct panthor_device *ptdev) +{ + u32 hi, lo; + + hi = gpu_read(ptdev, GPU_TIMESTAMP_OFFSET_HI); + lo = gpu_read(ptdev, GPU_TIMESTAMP_OFFSET_LO); + + return ((u64)hi << 32) | lo; +} diff --git a/drivers/gpu/drm/panthor/panthor_gpu.h b/drivers/gpu/drm/panthor/panthor_gpu.h index bba7555dd3c6..7f6133a66127 100644 --- a/drivers/gpu/drm/panthor/panthor_gpu.h +++ b/drivers/gpu/drm/panthor/panthor_gpu.h @@ -5,6 +5,8 @@ #ifndef __PANTHOR_GPU_H__ #define __PANTHOR_GPU_H__ +#include <linux/types.h> + struct panthor_device; int panthor_gpu_init(struct panthor_device *ptdev); @@ -48,5 +50,7 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev); int panthor_gpu_flush_caches(struct panthor_device *ptdev, u32 l2, u32 lsc, u32 other); int panthor_gpu_soft_reset(struct panthor_device *ptdev); +u64 panthor_gpu_read_timestamp(struct panthor_device *ptdev); +u64 panthor_gpu_read_timestamp_offset(struct panthor_device *ptdev); #endif diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index 926b1deb1116..95e3a984c69a 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -260,6 +260,9 @@ enum drm_panthor_dev_query_type { /** @DRM_PANTHOR_DEV_QUERY_CSIF_INFO: Query command-stream interface information. */ DRM_PANTHOR_DEV_QUERY_CSIF_INFO, + + /** @DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO: Query timestamp information. */ + DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO, }; /** @@ -377,6 +380,25 @@ struct drm_panthor_csif_info { __u32 pad; }; +/** + * struct drm_panthor_timestamp_info - Timestamp information + * + * Structure grouping all queryable information relating to the GPU timestamp. + */ +struct drm_panthor_timestamp_info { + /** + * @timestamp_frequency: The frequency of the timestamp timer or 0 if + * unknown. + */ + __u64 timestamp_frequency; + + /** @current_timestamp: The current timestamp. */ + __u64 current_timestamp; + + /** @timestamp_offset: The offset of the timestamp timer. */ + __u64 timestamp_offset; +}; + /** * struct drm_panthor_dev_query - Arguments passed to DRM_PANTHOR_IOCTL_DEV_QUERY */ -- GitLab From f6882661cf5afe6eac89bcd05c832e6bb6eba22c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Thu, 5 Sep 2024 06:08:21 +0300 Subject: [PATCH 046/970] drm/xe: select DRM_DISPLAY_DSC_HELPER The Xe driver shares display code with the i915 driver, pulling in the dependency on the DSC helpers this way. However when working on separating DRM_DISPLAY_DSC_HELPER this was left unnoticed. Add missing dependency. Fixes: ca097d4d94d8 ("drm/display: split DSC helpers from DP helpers") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409032226.x6f4SWQl-lkp@intel.com/ Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240905-fix-dsc-helpers-v1-1-3ae4b5900f89@linaro.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/xe/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index 7bbe46a98ff1..ebd0879e04d4 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -14,6 +14,7 @@ config DRM_XE select DRM_PANEL select DRM_SUBALLOC_HELPER select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HELPER -- GitLab From 8a8a31205e62b57f1fb844d790d682286121f729 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Thu, 5 Sep 2024 06:08:22 +0300 Subject: [PATCH 047/970] drm/msm: add another DRM_DISPLAY_DSC_HELPER selection In the drm/msm driver both DSI and DPU subdrivers use drm_dsc_* functions, but only DSI selects DRM_DISPLAY_DSC_HELPER symbol. Add missing select to the DPU subdriver too. Fixes: ca097d4d94d8 ("drm/display: split DSC helpers from DP helpers") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409040129.rqhtRTeC-lkp@intel.com/ Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240905-fix-dsc-helpers-v1-2-3ae4b5900f89@linaro.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/msm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 420385c47193..8bfebd579a74 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -91,6 +91,7 @@ config DRM_MSM_DPU bool "Enable DPU support in MSM DRM driver" depends on DRM_MSM select DRM_MSM_MDSS + select DRM_DISPLAY_DSC_HELPER default y help Compile in support for the Display Processing Unit in -- GitLab From 13a48a0fa52352f9fe58e2e1927670dcfea64c3a Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Mon, 2 Sep 2024 21:29:53 +0200 Subject: [PATCH 048/970] drm/xe/pf: Sanitize VF scratch registers on FLR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some VF accessible registers (like GuC scratch registers) must be explicitly reset during the FLR. While this is today done by the GuC firmware, according to the design, this should be responsibility of the PF driver, as future platforms may require more registers to be reset. Likewise GuC, the PF can access VFs registers by adding some platform specific offset to the original register address. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902192953.1792-1-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 52 +++++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_sriov_pf.h | 1 + drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c | 3 +- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c index 905f409db74b..919d960165d5 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c @@ -5,8 +5,10 @@ #include <drm/drm_managed.h> +#include "regs/xe_guc_regs.h" #include "regs/xe_regs.h" +#include "xe_gt.h" #include "xe_gt_sriov_pf.h" #include "xe_gt_sriov_pf_config.h" #include "xe_gt_sriov_pf_control.h" @@ -89,6 +91,56 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt) xe_gt_sriov_pf_service_update(gt); } +static u32 pf_get_vf_regs_stride(struct xe_device *xe) +{ + return GRAPHICS_VERx100(xe) > 1200 ? 0x400 : 0x1000; +} + +static struct xe_reg xe_reg_vf_to_pf(struct xe_reg vf_reg, unsigned int vfid, u32 stride) +{ + struct xe_reg pf_reg = vf_reg; + + pf_reg.vf = 0; + pf_reg.addr += stride * vfid; + + return pf_reg; +} + +static void pf_clear_vf_scratch_regs(struct xe_gt *gt, unsigned int vfid) +{ + u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt)); + struct xe_reg scratch; + int n, count; + + if (xe_gt_is_media_type(gt)) { + count = MED_VF_SW_FLAG_COUNT; + for (n = 0; n < count; n++) { + scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride); + xe_mmio_write32(gt, scratch, 0); + } + } else { + count = VF_SW_FLAG_COUNT; + for (n = 0; n < count; n++) { + scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride); + xe_mmio_write32(gt, scratch, 0); + } + } +} + +/** + * xe_gt_sriov_pf_sanitize_hw() - Reset hardware state related to a VF. + * @gt: the &xe_gt + * @vfid: the VF identifier + * + * This function can only be called on PF. + */ +void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + + pf_clear_vf_scratch_regs(gt, vfid); +} + /** * xe_gt_sriov_pf_restart - Restart SR-IOV support after a GT reset. * @gt: the &xe_gt diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h index f0cb726a6919..96fab779a906 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h @@ -11,6 +11,7 @@ struct xe_gt; #ifdef CONFIG_PCI_IOV int xe_gt_sriov_pf_init_early(struct xe_gt *gt); void xe_gt_sriov_pf_init_hw(struct xe_gt *gt); +void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid); void xe_gt_sriov_pf_restart(struct xe_gt *gt); #else static inline int xe_gt_sriov_pf_init_early(struct xe_gt *gt) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c index 02f7328bd6ce..b4fd5a81aff1 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c @@ -9,6 +9,7 @@ #include "xe_device.h" #include "xe_gt.h" +#include "xe_gt_sriov_pf.h" #include "xe_gt_sriov_pf_config.h" #include "xe_gt_sriov_pf_control.h" #include "xe_gt_sriov_pf_helpers.h" @@ -1008,7 +1009,7 @@ static bool pf_exit_vf_flr_reset_mmio(struct xe_gt *gt, unsigned int vfid) if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_FLR_RESET_MMIO)) return false; - /* XXX: placeholder */ + xe_gt_sriov_pf_sanitize_hw(gt, vfid); pf_enter_vf_flr_send_finish(gt, vfid); return true; -- GitLab From cd89de14bbacce1fc060fdfab75bacf95b1c5d40 Mon Sep 17 00:00:00 2001 From: Nitin Gote <nitin.r.gote@intel.com> Date: Fri, 23 Aug 2024 13:36:43 +0530 Subject: [PATCH 049/970] drm/xe: Replace double space with single space after comma Avoid using double space, ", " in function or macro parameters where it's not required by any alignment purpose. Replace it with a single space, ", ". Signed-off-by: Nitin Gote <nitin.r.gote@intel.com> Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240823080643.2461992-1-nitin.r.gote@intel.com Signed-off-by: Nirmoy Das <nirmoy.das@intel.com> --- drivers/gpu/drm/xe/regs/xe_reg_defs.h | 2 +- drivers/gpu/drm/xe/xe_guc.c | 2 +- drivers/gpu/drm/xe/xe_guc_ct.c | 4 ++-- drivers/gpu/drm/xe/xe_irq.c | 4 ++-- drivers/gpu/drm/xe/xe_trace_bo.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/xe/regs/xe_reg_defs.h b/drivers/gpu/drm/xe/regs/xe_reg_defs.h index 23f7dc5bbe99..51fd40ffafcb 100644 --- a/drivers/gpu/drm/xe/regs/xe_reg_defs.h +++ b/drivers/gpu/drm/xe/regs/xe_reg_defs.h @@ -128,7 +128,7 @@ struct xe_reg_mcr { * options. */ #define XE_REG_MCR(r_, ...) ((const struct xe_reg_mcr){ \ - .__reg = XE_REG_INITIALIZER(r_, ##__VA_ARGS__, .mcr = 1) \ + .__reg = XE_REG_INITIALIZER(r_, ##__VA_ARGS__, .mcr = 1) \ }) static inline bool xe_reg_is_valid(struct xe_reg r) diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index 52df28032a6f..c67d4807f37d 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -985,7 +985,7 @@ int xe_guc_mmio_send_recv(struct xe_guc *guc, const u32 *request, BUILD_BUG_ON(FIELD_MAX(GUC_HXG_MSG_0_TYPE) != GUC_HXG_TYPE_RESPONSE_SUCCESS); BUILD_BUG_ON((GUC_HXG_TYPE_RESPONSE_SUCCESS ^ GUC_HXG_TYPE_RESPONSE_FAILURE) != 1); - ret = xe_mmio_wait32(gt, reply_reg, resp_mask, resp_mask, + ret = xe_mmio_wait32(gt, reply_reg, resp_mask, resp_mask, 1000000, &header, false); if (unlikely(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, header) != diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index f24dd5223926..4b95f75b1546 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -182,7 +182,7 @@ int xe_guc_ct_init(struct xe_guc_ct *ct) spin_lock_init(&ct->fast_lock); xa_init(&ct->fence_lookup); INIT_WORK(&ct->g2h_worker, g2h_worker_func); - INIT_DELAYED_WORK(&ct->safe_mode_worker, safe_mode_worker_func); + INIT_DELAYED_WORK(&ct->safe_mode_worker, safe_mode_worker_func); init_waitqueue_head(&ct->wq); init_waitqueue_head(&ct->g2h_fence_wq); @@ -852,7 +852,7 @@ static bool retry_failure(struct xe_guc_ct *ct, int ret) #define ct_alive(ct) \ (xe_guc_ct_enabled(ct) && !ct->ctbs.h2g.info.broken && \ !ct->ctbs.g2h.info.broken) - if (!wait_event_interruptible_timeout(ct->wq, ct_alive(ct), HZ * 5)) + if (!wait_event_interruptible_timeout(ct->wq, ct_alive(ct), HZ * 5)) return false; #undef ct_alive diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 5f2c368c35ad..14c3a476597a 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -173,7 +173,7 @@ void xe_irq_enable_hwe(struct xe_gt *gt) if (ccs_mask & (BIT(0)|BIT(1))) xe_mmio_write32(gt, CCS0_CCS1_INTR_MASK, ~dmask); if (ccs_mask & (BIT(2)|BIT(3))) - xe_mmio_write32(gt, CCS2_CCS3_INTR_MASK, ~dmask); + xe_mmio_write32(gt, CCS2_CCS3_INTR_MASK, ~dmask); } if (xe_gt_is_media_type(gt) || MEDIA_VER(xe) < 13) { @@ -504,7 +504,7 @@ static void gt_irq_reset(struct xe_tile *tile) if (ccs_mask & (BIT(0)|BIT(1))) xe_mmio_write32(mmio, CCS0_CCS1_INTR_MASK, ~0); if (ccs_mask & (BIT(2)|BIT(3))) - xe_mmio_write32(mmio, CCS2_CCS3_INTR_MASK, ~0); + xe_mmio_write32(mmio, CCS2_CCS3_INTR_MASK, ~0); if ((tile->media_gt && xe_hw_engine_mask_per_class(tile->media_gt, XE_ENGINE_CLASS_OTHER)) || diff --git a/drivers/gpu/drm/xe/xe_trace_bo.h b/drivers/gpu/drm/xe/xe_trace_bo.h index 9b1a1d4304ae..30a3cfbaaa09 100644 --- a/drivers/gpu/drm/xe/xe_trace_bo.h +++ b/drivers/gpu/drm/xe/xe_trace_bo.h @@ -189,7 +189,7 @@ DECLARE_EVENT_CLASS(xe_vm, ), TP_printk("dev=%s, vm=%p, asid=0x%05x", __get_str(dev), - __entry->vm, __entry->asid) + __entry->vm, __entry->asid) ); DEFINE_EVENT(xe_vm, xe_vm_kill, -- GitLab From 89076b5a8b4e0a01040585e156a0b014cd472fd3 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 28 Aug 2024 11:43:42 +0100 Subject: [PATCH 050/970] drm/xe: prevent potential UAF in pf_provision_vf_ggtt() The node ptr can point to an already freed ptr, if we hit the path with an already allocated node. We later dereference that pointer with: xe_gt_assert(gt, !xe_ggtt_node_allocated(node)); which is a potential UAF. Fix this by not stashing the ptr for node. Also since it is likely a bad idea to leave config->ggtt_region pointing to a stale ptr, also set that to NULL by calling pf_release_vf_config_ggtt() instead of pf_release_ggtt(). Fixes: 34e804220f69 ("drm/xe: Make xe_ggtt_node struct independent") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240828104341.180111-2-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c index a95e546b7744..8250ef71e685 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c @@ -399,7 +399,7 @@ static void pf_release_vf_config_ggtt(struct xe_gt *gt, struct xe_gt_sriov_confi static int pf_provision_vf_ggtt(struct xe_gt *gt, unsigned int vfid, u64 size) { struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); - struct xe_ggtt_node *node = config->ggtt_region; + struct xe_ggtt_node *node; struct xe_tile *tile = gt_to_tile(gt); struct xe_ggtt *ggtt = tile->mem.ggtt; u64 alignment = pf_get_ggtt_alignment(gt); @@ -411,14 +411,14 @@ static int pf_provision_vf_ggtt(struct xe_gt *gt, unsigned int vfid, u64 size) size = round_up(size, alignment); - if (xe_ggtt_node_allocated(node)) { + if (xe_ggtt_node_allocated(config->ggtt_region)) { err = pf_distribute_config_ggtt(tile, vfid, 0, 0); if (unlikely(err)) return err; - pf_release_ggtt(tile, node); + pf_release_vf_config_ggtt(gt, config); } - xe_gt_assert(gt, !xe_ggtt_node_allocated(node)); + xe_gt_assert(gt, !xe_ggtt_node_allocated(config->ggtt_region)); if (!size) return 0; -- GitLab From 1ff14648dc58b3de39b9d241607a41c833110d90 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 28 Aug 2024 10:22:58 +0100 Subject: [PATCH 051/970] drm/xe/pat: sanity check compression and coh_mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an implicit assumption in the driver that compression and coh_1way+ are mutually exclusive. If this is ever not true then userptr and imported dma-buf from external device will have uncleared ccs state. Add a build bug for this so we don't forget. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240828092257.169063-2-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_pat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c index f291a1730024..5bf48e99c939 100644 --- a/drivers/gpu/drm/xe/xe_pat.c +++ b/drivers/gpu/drm/xe/xe_pat.c @@ -100,6 +100,10 @@ static const struct xe_pat_table_entry xelpg_pat_table[] = { * Reserved entries should be programmed with the maximum caching, minimum * coherency (which matches an all-0's encoding), so we can just omit them * in the table. + * + * Note: There is an implicit assumption in the driver that compression and + * coh_1way+ are mutually exclusive. If this is ever not true then userptr + * and imported dma-buf from external device will have uncleared ccs state. */ #define XE2_PAT(no_promote, comp_en, l3clos, l3_policy, l4_policy, __coh_mode) \ { \ @@ -109,7 +113,8 @@ static const struct xe_pat_table_entry xelpg_pat_table[] = { REG_FIELD_PREP(XE2_L3_POLICY, l3_policy) | \ REG_FIELD_PREP(XE2_L4_POLICY, l4_policy) | \ REG_FIELD_PREP(XE2_COH_MODE, __coh_mode), \ - .coh_mode = __coh_mode ? XE_COH_AT_LEAST_1WAY : XE_COH_NONE \ + .coh_mode = (BUILD_BUG_ON_ZERO(__coh_mode && comp_en) || __coh_mode) ? \ + XE_COH_AT_LEAST_1WAY : XE_COH_NONE \ } static const struct xe_pat_table_entry xe2_pat_table[] = { -- GitLab From ae304b054520fec0a5ad5dec103a37abb53fef0e Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 4 Sep 2024 12:46:47 +0300 Subject: [PATCH 052/970] drm/xe/pciids: add some missing ADL-N PCI IDs Similar to commit 425b463859ed ("drm/i915: Update ADL-N PCI IDs"). Reviewed-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/47d543393e4026588401a03c4e3ce12ce29780e3.1725443121.git.jani.nikula@intel.com --- include/drm/intel/xe_pciids.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h index 644872a35c35..4aab1bc2327e 100644 --- a/include/drm/intel/xe_pciids.h +++ b/include/drm/intel/xe_pciids.h @@ -97,7 +97,9 @@ #define XE_ADLN_IDS(MACRO__, ...) \ MACRO__(0x46D0, ## __VA_ARGS__), \ MACRO__(0x46D1, ## __VA_ARGS__), \ - MACRO__(0x46D2, ## __VA_ARGS__) + MACRO__(0x46D2, ## __VA_ARGS__), \ + MACRO__(0x46D3, ## __VA_ARGS__), \ + MACRO__(0x46D4, ## __VA_ARGS__) /* RPL-S */ #define XE_RPLS_IDS(MACRO__, ...) \ -- GitLab From d454902a690db47f1880f963514bbf0fc7a129a8 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 4 Sep 2024 12:46:48 +0300 Subject: [PATCH 053/970] drm/xe/pciids: separate RPL-U and RPL-P PCI IDs Avoid including PCI IDs for one platform to the PCI IDs of another. It's more clear to deal with them completely separately at the PCI ID macro level. Reviewed-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/4868d36fbfa8c38ea2d490bca82cf6370b8d65dd.1725443121.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 1 + include/drm/intel/xe_pciids.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 7eb00a87b786..14fe08e40c98 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -383,6 +383,7 @@ static const struct pci_device_id pciidlist[] = { XE_ADLS_IDS(INTEL_VGA_DEVICE, &adl_s_desc), XE_ADLP_IDS(INTEL_VGA_DEVICE, &adl_p_desc), XE_ADLN_IDS(INTEL_VGA_DEVICE, &adl_n_desc), + XE_RPLU_IDS(INTEL_VGA_DEVICE, &adl_p_desc), XE_RPLP_IDS(INTEL_VGA_DEVICE, &adl_p_desc), XE_RPLS_IDS(INTEL_VGA_DEVICE, &adl_s_desc), XE_DG1_IDS(INTEL_VGA_DEVICE, &dg1_desc), diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h index 4aab1bc2327e..7a9a7d0a89ca 100644 --- a/include/drm/intel/xe_pciids.h +++ b/include/drm/intel/xe_pciids.h @@ -122,7 +122,6 @@ /* RPL-P */ #define XE_RPLP_IDS(MACRO__, ...) \ - XE_RPLU_IDS(MACRO__, ## __VA_ARGS__), \ MACRO__(0xA720, ## __VA_ARGS__), \ MACRO__(0xA7A0, ## __VA_ARGS__), \ MACRO__(0xA7A8, ## __VA_ARGS__), \ -- GitLab From cdb56a63f7eef34e89b045fc8bcae8d326bbdb19 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 4 Sep 2024 12:46:49 +0300 Subject: [PATCH 054/970] drm/xe/pciids: separate ARL and MTL PCI IDs Avoid including PCI IDs for one platform to the PCI IDs of another. It's more clear to deal with them completely separately at the PCI ID macro level. Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/a30cb0da7694a8eccceba66d676ac59aa0e96176.1725443121.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 1 + include/drm/intel/xe_pciids.h | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 14fe08e40c98..942817e5a79e 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -388,6 +388,7 @@ static const struct pci_device_id pciidlist[] = { XE_RPLS_IDS(INTEL_VGA_DEVICE, &adl_s_desc), XE_DG1_IDS(INTEL_VGA_DEVICE, &dg1_desc), XE_ATS_M_IDS(INTEL_VGA_DEVICE, &ats_m_desc), + XE_ARL_IDS(INTEL_VGA_DEVICE, &mtl_desc), XE_DG2_IDS(INTEL_VGA_DEVICE, &dg2_desc), XE_MTL_IDS(INTEL_VGA_DEVICE, &mtl_desc), XE_LNL_IDS(INTEL_VGA_DEVICE, &lnl_desc), diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h index 7a9a7d0a89ca..79001afa7d27 100644 --- a/include/drm/intel/xe_pciids.h +++ b/include/drm/intel/xe_pciids.h @@ -176,16 +176,19 @@ XE_ATS_M150_IDS(MACRO__, ## __VA_ARGS__),\ XE_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) -/* MTL / ARL */ +/* ARL */ +#define XE_ARL_IDS(MACRO__, ...) \ + MACRO__(0x7D41, ## __VA_ARGS__), \ + MACRO__(0x7D51, ## __VA_ARGS__), \ + MACRO__(0x7D67, ## __VA_ARGS__), \ + MACRO__(0x7DD1, ## __VA_ARGS__) + +/* MTL */ #define XE_MTL_IDS(MACRO__, ...) \ MACRO__(0x7D40, ## __VA_ARGS__), \ - MACRO__(0x7D41, ## __VA_ARGS__), \ MACRO__(0x7D45, ## __VA_ARGS__), \ - MACRO__(0x7D51, ## __VA_ARGS__), \ MACRO__(0x7D55, ## __VA_ARGS__), \ MACRO__(0x7D60, ## __VA_ARGS__), \ - MACRO__(0x7D67, ## __VA_ARGS__), \ - MACRO__(0x7DD1, ## __VA_ARGS__), \ MACRO__(0x7DD5, ## __VA_ARGS__) #define XE_LNL_IDS(MACRO__, ...) \ -- GitLab From c5c4c8fba06ded032be2bae8f4bff972c3d9812e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:39 +0200 Subject: [PATCH 055/970] drm/bochs: Remove manual format test from fb_create An updated implementation of drm_gem_fb_create() already tests the driver's planes for supported formats. [1] No need to duplicate this test in bochs. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://elixir.bootlin.com/linux/v6.9/source/drivers/gpu/drm/drm_gem_framebuffer_helper.c#L169 # 1 Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-2-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 31fc5d839e10..47a45a14306c 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -511,19 +511,8 @@ static void bochs_connector_init(struct drm_device *dev) } } -static struct drm_framebuffer * -bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - if (mode_cmd->pixel_format != DRM_FORMAT_XRGB8888 && - mode_cmd->pixel_format != DRM_FORMAT_BGRX8888) - return ERR_PTR(-EINVAL); - - return drm_gem_fb_create(dev, file, mode_cmd); -} - static const struct drm_mode_config_funcs bochs_mode_funcs = { - .fb_create = bochs_gem_fb_create, + .fb_create = drm_gem_fb_create, .mode_valid = drm_vram_helper_mode_valid, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, -- GitLab From 759ef92532f3c332541f475f5ca91161dbde72e8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:40 +0200 Subject: [PATCH 056/970] drm/bochs: Use helpers for struct drm_edid Implement a read function for struct drm_edid and read the EDID data with drm_edit_read_custom(). Update the connector data accordingly. The EDID data comes from the emulator itself and the connector stores a copy in its EDID property. The drm_edid field in struct bochs_device is therefore not required. Remove it. If qemu provides no EDID data, install default display modes as before. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-3-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 48 +++++++++++++++++------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 47a45a14306c..197fc00b373f 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -85,7 +85,6 @@ struct bochs_device { u16 yres_virtual; u32 stride; u32 bpp; - const struct drm_edid *drm_edid; /* drm */ struct drm_device *dev; @@ -172,12 +171,14 @@ static void bochs_hw_set_little_endian(struct bochs_device *bochs) #define bochs_hw_set_native_endian(_b) bochs_hw_set_little_endian(_b) #endif -static int bochs_get_edid_block(void *data, u8 *buf, - unsigned int block, size_t len) +static int bochs_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len) { struct bochs_device *bochs = data; size_t i, start = block * EDID_LENGTH; + if (!bochs->mmio) + return -1; + if (start + len > 0x400 /* vga register offset */) return -1; @@ -187,25 +188,20 @@ static int bochs_get_edid_block(void *data, u8 *buf, return 0; } -static int bochs_hw_load_edid(struct bochs_device *bochs) +static const struct drm_edid *bochs_hw_read_edid(struct drm_connector *connector) { + struct drm_device *dev = connector->dev; + struct bochs_device *bochs = dev->dev_private; u8 header[8]; - if (!bochs->mmio) - return -1; - /* check header to detect whenever edid support is enabled in qemu */ bochs_get_edid_block(bochs, header, 0, ARRAY_SIZE(header)); if (drm_edid_header_is_valid(header) != 8) - return -1; + return NULL; - drm_edid_free(bochs->drm_edid); - bochs->drm_edid = drm_edid_read_custom(&bochs->connector, - bochs_get_edid_block, bochs); - if (!bochs->drm_edid) - return -1; + drm_dbg(dev, "Found EDID data blob.\n"); - return 0; + return drm_edid_read_custom(connector, bochs_get_edid_block, bochs); } static int bochs_hw_init(struct drm_device *dev) @@ -303,7 +299,6 @@ static void bochs_hw_fini(struct drm_device *dev) if (bochs->fb_map) iounmap(bochs->fb_map); pci_release_regions(to_pci_dev(dev->dev)); - drm_edid_free(bochs->drm_edid); } static void bochs_hw_blank(struct bochs_device *bochs, bool blank) @@ -469,21 +464,28 @@ static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = { .cleanup_fb = drm_gem_vram_simple_display_pipe_cleanup_fb, }; -static int bochs_connector_get_modes(struct drm_connector *connector) +static int bochs_connector_helper_get_modes(struct drm_connector *connector) { + const struct drm_edid *edid; int count; - count = drm_edid_connector_add_modes(connector); + edid = bochs_hw_read_edid(connector); - if (!count) { + if (edid) { + drm_edid_connector_update(connector, edid); + count = drm_edid_connector_add_modes(connector); + drm_edid_free(edid); + } else { + drm_edid_connector_update(connector, NULL); count = drm_add_modes_noedid(connector, 8192, 8192); drm_set_preferred_mode(connector, defx, defy); } + return count; } static const struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = { - .get_modes = bochs_connector_get_modes, + .get_modes = bochs_connector_helper_get_modes, }; static const struct drm_connector_funcs bochs_connector_connector_funcs = { @@ -501,14 +503,8 @@ static void bochs_connector_init(struct drm_device *dev) drm_connector_init(dev, connector, &bochs_connector_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); + drm_connector_attach_edid_property(connector); drm_connector_helper_add(connector, &bochs_connector_connector_helper_funcs); - - bochs_hw_load_edid(bochs); - if (bochs->drm_edid) { - DRM_INFO("Found EDID data blob.\n"); - drm_connector_attach_edid_property(connector); - drm_edid_connector_update(&bochs->connector, bochs->drm_edid); - } } static const struct drm_mode_config_funcs bochs_mode_funcs = { -- GitLab From 58e980c16815ce4ff8a5e036a126358afceca538 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:41 +0200 Subject: [PATCH 057/970] drm/bochs: Do managed resource cleanup Do managed cleanup of all PCI resources. Remove the now-unused cleanup helper bochs_hw_fini(). Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-4-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 42 +++++++++--------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 197fc00b373f..5d09b4cb28ed 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -212,14 +212,14 @@ static int bochs_hw_init(struct drm_device *dev) u16 id; if (pdev->resource[2].flags & IORESOURCE_MEM) { + ioaddr = pci_resource_start(pdev, 2); + iosize = pci_resource_len(pdev, 2); /* mmio bar with vga and bochs registers present */ - if (pci_request_region(pdev, 2, "bochs-drm") != 0) { + if (!devm_request_mem_region(&pdev->dev, ioaddr, iosize, "bochs-drm")) { DRM_ERROR("Cannot request mmio region\n"); return -EBUSY; } - ioaddr = pci_resource_start(pdev, 2); - iosize = pci_resource_len(pdev, 2); - bochs->mmio = ioremap(ioaddr, iosize); + bochs->mmio = devm_ioremap(&pdev->dev, ioaddr, iosize); if (bochs->mmio == NULL) { DRM_ERROR("Cannot map mmio region\n"); return -ENOMEM; @@ -227,7 +227,7 @@ static int bochs_hw_init(struct drm_device *dev) } else { ioaddr = VBE_DISPI_IOPORT_INDEX; iosize = 2; - if (!request_region(ioaddr, iosize, "bochs-drm")) { + if (!devm_request_region(&pdev->dev, ioaddr, iosize, "bochs-drm")) { DRM_ERROR("Cannot request ioports\n"); return -EBUSY; } @@ -254,10 +254,10 @@ static int bochs_hw_init(struct drm_device *dev) size = min(size, mem); } - if (pci_request_region(pdev, 0, "bochs-drm") != 0) + if (!devm_request_mem_region(&pdev->dev, addr, size, "bochs-drm")) DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); - bochs->fb_map = ioremap(addr, size); + bochs->fb_map = devm_ioremap(&pdev->dev, addr, size); if (bochs->fb_map == NULL) { DRM_ERROR("Cannot map framebuffer\n"); return -ENOMEM; @@ -286,21 +286,6 @@ static int bochs_hw_init(struct drm_device *dev) return 0; } -static void bochs_hw_fini(struct drm_device *dev) -{ - struct bochs_device *bochs = dev->dev_private; - - /* TODO: shot down existing vram mappings */ - - if (bochs->mmio) - iounmap(bochs->mmio); - if (bochs->ioports) - release_region(VBE_DISPI_IOPORT_INDEX, 2); - if (bochs->fb_map) - iounmap(bochs->fb_map); - pci_release_regions(to_pci_dev(dev->dev)); -} - static void bochs_hw_blank(struct bochs_device *bochs, bool blank) { DRM_DEBUG_DRIVER("hw_blank %d\n", blank); @@ -565,17 +550,13 @@ static int bochs_load(struct drm_device *dev) ret = drmm_vram_helper_init(dev, bochs->fb_base, bochs->fb_size); if (ret) - goto err_hw_fini; + return ret; ret = bochs_kms_init(bochs); if (ret) - goto err_hw_fini; + return ret; return 0; - -err_hw_fini: - bochs_hw_fini(dev); - return ret; } DEFINE_DRM_GEM_FOPS(bochs_fops); @@ -650,13 +631,11 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent ret = drm_dev_register(dev, 0); if (ret) - goto err_hw_fini; + goto err_free_dev; drm_fbdev_ttm_setup(dev, 32); return ret; -err_hw_fini: - bochs_hw_fini(dev); err_free_dev: drm_dev_put(dev); return ret; @@ -668,7 +647,6 @@ static void bochs_pci_remove(struct pci_dev *pdev) drm_dev_unplug(dev); drm_atomic_helper_shutdown(dev); - bochs_hw_fini(dev); drm_dev_put(dev); } -- GitLab From 7a195f1c4042110ca37c88ec2829134541f6ecf7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:42 +0200 Subject: [PATCH 058/970] drm/bochs: Pass bochs device to various functions Avoid upcasting from struct drm_device by passing the bochs device directly to functions. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-5-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 5d09b4cb28ed..acb2652577d4 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -204,9 +204,9 @@ static const struct drm_edid *bochs_hw_read_edid(struct drm_connector *connector return drm_edid_read_custom(connector, bochs_get_edid_block, bochs); } -static int bochs_hw_init(struct drm_device *dev) +static int bochs_hw_init(struct bochs_device *bochs) { - struct bochs_device *bochs = dev->dev_private; + struct drm_device *dev = bochs->dev; struct pci_dev *pdev = to_pci_dev(dev->dev); unsigned long addr, size, mem, ioaddr, iosize; u16 id; @@ -481,9 +481,9 @@ static const struct drm_connector_funcs bochs_connector_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static void bochs_connector_init(struct drm_device *dev) +static void bochs_connector_init(struct bochs_device *bochs) { - struct bochs_device *bochs = dev->dev_private; + struct drm_device *dev = bochs->dev; struct drm_connector *connector = &bochs->connector; drm_connector_init(dev, connector, &bochs_connector_connector_funcs, @@ -516,7 +516,7 @@ static int bochs_kms_init(struct bochs_device *bochs) bochs->dev->mode_config.funcs = &bochs_mode_funcs; - bochs_connector_init(bochs->dev); + bochs_connector_init(bochs); drm_simple_display_pipe_init(bochs->dev, &bochs->pipe, &bochs_pipe_funcs, @@ -544,7 +544,7 @@ static int bochs_load(struct drm_device *dev) dev->dev_private = bochs; bochs->dev = dev; - ret = bochs_hw_init(dev); + ret = bochs_hw_init(bochs); if (ret) return ret; -- GitLab From 1d614a46743ce291d87ffae7a3658cb2195d6e8b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:43 +0200 Subject: [PATCH 059/970] drm/bochs: Upcast with to_bochs_device() The dev_private field in struct drm_device is deprecated. Limit its use by moving it into a helper function. A later change will remove it entirely. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-6-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index acb2652577d4..61b2b7aa03cb 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -92,6 +92,11 @@ struct bochs_device { struct drm_connector connector; }; +static struct bochs_device *to_bochs_device(const struct drm_device *dev) +{ + return (struct bochs_device *)dev->dev_private; +} + /* ---------------------------------------------------------------------- */ static void bochs_vga_writeb(struct bochs_device *bochs, u16 ioport, u8 val) @@ -191,7 +196,7 @@ static int bochs_get_edid_block(void *data, u8 *buf, unsigned int block, size_t static const struct drm_edid *bochs_hw_read_edid(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct bochs_device *bochs = dev->dev_private; + struct bochs_device *bochs = to_bochs_device(dev); u8 header[8]; /* check header to detect whenever edid support is enabled in qemu */ @@ -420,7 +425,7 @@ static void bochs_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) { - struct bochs_device *bochs = pipe->crtc.dev->dev_private; + struct bochs_device *bochs = to_bochs_device(pipe->crtc.dev); bochs_hw_setmode(bochs, &crtc_state->mode); bochs_plane_update(bochs, plane_state); @@ -428,7 +433,7 @@ static void bochs_pipe_enable(struct drm_simple_display_pipe *pipe, static void bochs_pipe_disable(struct drm_simple_display_pipe *pipe) { - struct bochs_device *bochs = pipe->crtc.dev->dev_private; + struct bochs_device *bochs = to_bochs_device(pipe->crtc.dev); bochs_hw_blank(bochs, true); } @@ -436,7 +441,7 @@ static void bochs_pipe_disable(struct drm_simple_display_pipe *pipe) static void bochs_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) { - struct bochs_device *bochs = pipe->crtc.dev->dev_private; + struct bochs_device *bochs = to_bochs_device(pipe->crtc.dev); bochs_plane_update(bochs, pipe->plane.state); } -- GitLab From 04826f588682ed565cede451f8000be6c2245f20 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:44 +0200 Subject: [PATCH 060/970] drm/bochs: Allocate DRM device in struct bochs_device Allocate an instance of struct drm_device in struct bochs_device. Also remove all uses of dev_private from bochs and upcast from the embedded instance if necessary. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-7-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 52 +++++++++++++++++------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 61b2b7aa03cb..5679f1b090af 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -71,6 +71,8 @@ enum bochs_types { }; struct bochs_device { + struct drm_device dev; + /* hw */ void __iomem *mmio; int ioports; @@ -87,14 +89,13 @@ struct bochs_device { u32 bpp; /* drm */ - struct drm_device *dev; struct drm_simple_display_pipe pipe; struct drm_connector connector; }; static struct bochs_device *to_bochs_device(const struct drm_device *dev) { - return (struct bochs_device *)dev->dev_private; + return container_of(dev, struct bochs_device, dev); } /* ---------------------------------------------------------------------- */ @@ -211,7 +212,7 @@ static const struct drm_edid *bochs_hw_read_edid(struct drm_connector *connector static int bochs_hw_init(struct bochs_device *bochs) { - struct drm_device *dev = bochs->dev; + struct drm_device *dev = &bochs->dev; struct pci_dev *pdev = to_pci_dev(dev->dev); unsigned long addr, size, mem, ioaddr, iosize; u16 id; @@ -306,7 +307,7 @@ static void bochs_hw_setmode(struct bochs_device *bochs, struct drm_display_mode { int idx; - if (!drm_dev_enter(bochs->dev, &idx)) + if (!drm_dev_enter(&bochs->dev, &idx)) return; bochs->xres = mode->hdisplay; @@ -342,7 +343,7 @@ static void bochs_hw_setformat(struct bochs_device *bochs, const struct drm_form { int idx; - if (!drm_dev_enter(bochs->dev, &idx)) + if (!drm_dev_enter(&bochs->dev, &idx)) return; DRM_DEBUG_DRIVER("format %c%c%c%c\n", @@ -373,7 +374,7 @@ static void bochs_hw_setbase(struct bochs_device *bochs, int x, int y, int strid unsigned long offset; unsigned int vx, vy, vwidth, idx; - if (!drm_dev_enter(bochs->dev, &idx)) + if (!drm_dev_enter(&bochs->dev, &idx)) return; bochs->stride = stride; @@ -488,7 +489,7 @@ static const struct drm_connector_funcs bochs_connector_connector_funcs = { static void bochs_connector_init(struct bochs_device *bochs) { - struct drm_device *dev = bochs->dev; + struct drm_device *dev = &bochs->dev; struct drm_connector *connector = &bochs->connector; drm_connector_init(dev, connector, &bochs_connector_connector_funcs, @@ -506,23 +507,24 @@ static const struct drm_mode_config_funcs bochs_mode_funcs = { static int bochs_kms_init(struct bochs_device *bochs) { + struct drm_device *dev = &bochs->dev; int ret; - ret = drmm_mode_config_init(bochs->dev); + ret = drmm_mode_config_init(dev); if (ret) return ret; - bochs->dev->mode_config.max_width = 8192; - bochs->dev->mode_config.max_height = 8192; + dev->mode_config.max_width = 8192; + dev->mode_config.max_height = 8192; - bochs->dev->mode_config.preferred_depth = 24; - bochs->dev->mode_config.prefer_shadow = 0; - bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true; + dev->mode_config.preferred_depth = 24; + dev->mode_config.prefer_shadow = 0; + dev->mode_config.quirk_addfb_prefer_host_byte_order = true; - bochs->dev->mode_config.funcs = &bochs_mode_funcs; + dev->mode_config.funcs = &bochs_mode_funcs; bochs_connector_init(bochs); - drm_simple_display_pipe_init(bochs->dev, + drm_simple_display_pipe_init(dev, &bochs->pipe, &bochs_pipe_funcs, bochs_formats, @@ -530,7 +532,7 @@ static int bochs_kms_init(struct bochs_device *bochs) NULL, &bochs->connector); - drm_mode_config_reset(bochs->dev); + drm_mode_config_reset(dev); return 0; } @@ -538,17 +540,11 @@ static int bochs_kms_init(struct bochs_device *bochs) /* ---------------------------------------------------------------------- */ /* drm interface */ -static int bochs_load(struct drm_device *dev) +static int bochs_load(struct bochs_device *bochs) { - struct bochs_device *bochs; + struct drm_device *dev = &bochs->dev; int ret; - bochs = drmm_kzalloc(dev, sizeof(*bochs), GFP_KERNEL); - if (bochs == NULL) - return -ENOMEM; - dev->dev_private = bochs; - bochs->dev = dev; - ret = bochs_hw_init(bochs); if (ret) return ret; @@ -606,6 +602,7 @@ static const struct dev_pm_ops bochs_pm_ops = { static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct bochs_device *bochs; struct drm_device *dev; unsigned long fbsize; int ret; @@ -620,9 +617,10 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent if (ret) return ret; - dev = drm_dev_alloc(&bochs_driver, &pdev->dev); - if (IS_ERR(dev)) + bochs = devm_drm_dev_alloc(&pdev->dev, &bochs_driver, struct bochs_device, dev); + if (IS_ERR(bochs)) return PTR_ERR(dev); + dev = &bochs->dev; ret = pcim_enable_device(pdev); if (ret) @@ -630,7 +628,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent pci_set_drvdata(pdev, dev); - ret = bochs_load(dev); + ret = bochs_load(bochs); if (ret) goto err_free_dev; -- GitLab From 2037174993c80c059c2cb58af2184157cb08039e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:45 +0200 Subject: [PATCH 061/970] drm/bochs: Use regular atomic helpers Remove the simple display pipeline in favor of the regular atomic helpers in bochs. The simple-pipe helpers are considered deprecated in DRM. This effectivly inlines the simple-pipe code for plane and CRTC support. Instead of a single update helper, there's now a mode-set helper for the CRTC and an update helper for the plane. The encoder changes type from NONE ot VIRTUAL. Removing simple-pipe helpers from bochs will allow for related cleanups in GEM VRAM helpers. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-8-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 177 ++++++++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 5679f1b090af..76e29950a807 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -4,6 +4,7 @@ #include <linux/pci.h> #include <drm/drm_aperture.h> +#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> @@ -14,8 +15,8 @@ #include <drm/drm_gem_vram_helper.h> #include <drm/drm_managed.h> #include <drm/drm_module.h> +#include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> -#include <drm/drm_simple_kms_helper.h> #include <video/vga.h> @@ -89,7 +90,9 @@ struct bochs_device { u32 bpp; /* drm */ - struct drm_simple_display_pipe pipe; + struct drm_plane primary_plane; + struct drm_crtc crtc; + struct drm_encoder encoder; struct drm_connector connector; }; @@ -396,11 +399,34 @@ static void bochs_hw_setbase(struct bochs_device *bochs, int x, int y, int strid /* ---------------------------------------------------------------------- */ -static const uint32_t bochs_formats[] = { +static const uint32_t bochs_primary_plane_formats[] = { DRM_FORMAT_XRGB8888, DRM_FORMAT_BGRX8888, }; +static int bochs_primary_plane_helper_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_crtc *new_crtc = new_plane_state->crtc; + struct drm_crtc_state *new_crtc_state = NULL; + int ret; + + if (new_crtc) + new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); + + ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); + if (ret) + return ret; + else if (!new_plane_state->visible) + return 0; + + return 0; +} + static void bochs_plane_update(struct bochs_device *bochs, struct drm_plane_state *state) { struct drm_gem_vram_object *gbo; @@ -422,37 +448,80 @@ static void bochs_plane_update(struct bochs_device *bochs, struct drm_plane_stat bochs_hw_setformat(bochs, state->fb->format); } -static void bochs_pipe_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state, - struct drm_plane_state *plane_state) +static void bochs_primary_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) { - struct bochs_device *bochs = to_bochs_device(pipe->crtc.dev); + struct bochs_device *bochs = to_bochs_device(plane->dev); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); - bochs_hw_setmode(bochs, &crtc_state->mode); bochs_plane_update(bochs, plane_state); } -static void bochs_pipe_disable(struct drm_simple_display_pipe *pipe) +static const struct drm_plane_helper_funcs bochs_primary_plane_helper_funcs = { + DRM_GEM_VRAM_PLANE_HELPER_FUNCS, + .atomic_check = bochs_primary_plane_helper_atomic_check, + .atomic_update = bochs_primary_plane_helper_atomic_update, +}; + +static const struct drm_plane_funcs bochs_primary_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +}; + +static void bochs_crtc_helper_mode_set_nofb(struct drm_crtc *crtc) +{ + struct bochs_device *bochs = to_bochs_device(crtc->dev); + struct drm_crtc_state *crtc_state = crtc->state; + + bochs_hw_setmode(bochs, &crtc_state->mode); +} + +static int bochs_crtc_helper_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) { - struct bochs_device *bochs = to_bochs_device(pipe->crtc.dev); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); - bochs_hw_blank(bochs, true); + if (!crtc_state->enable) + return 0; + + return drm_atomic_helper_check_crtc_primary_plane(crtc_state); +} + +static void bochs_crtc_helper_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ } -static void bochs_pipe_update(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *old_state) +static void bochs_crtc_helper_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_state *crtc_state) { - struct bochs_device *bochs = to_bochs_device(pipe->crtc.dev); + struct bochs_device *bochs = to_bochs_device(crtc->dev); - bochs_plane_update(bochs, pipe->plane.state); + bochs_hw_blank(bochs, true); } -static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = { - .enable = bochs_pipe_enable, - .disable = bochs_pipe_disable, - .update = bochs_pipe_update, - .prepare_fb = drm_gem_vram_simple_display_pipe_prepare_fb, - .cleanup_fb = drm_gem_vram_simple_display_pipe_cleanup_fb, +static const struct drm_crtc_helper_funcs bochs_crtc_helper_funcs = { + .mode_set_nofb = bochs_crtc_helper_mode_set_nofb, + .atomic_check = bochs_crtc_helper_atomic_check, + .atomic_enable = bochs_crtc_helper_atomic_enable, + .atomic_disable = bochs_crtc_helper_atomic_disable, +}; + +static const struct drm_crtc_funcs bochs_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +}; + +static const struct drm_encoder_funcs bochs_encoder_funcs = { + .destroy = drm_encoder_cleanup, }; static int bochs_connector_helper_get_modes(struct drm_connector *connector) @@ -475,11 +544,11 @@ static int bochs_connector_helper_get_modes(struct drm_connector *connector) return count; } -static const struct drm_connector_helper_funcs bochs_connector_connector_helper_funcs = { +static const struct drm_connector_helper_funcs bochs_connector_helper_funcs = { .get_modes = bochs_connector_helper_get_modes, }; -static const struct drm_connector_funcs bochs_connector_connector_funcs = { +static const struct drm_connector_funcs bochs_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, @@ -487,18 +556,7 @@ static const struct drm_connector_funcs bochs_connector_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static void bochs_connector_init(struct bochs_device *bochs) -{ - struct drm_device *dev = &bochs->dev; - struct drm_connector *connector = &bochs->connector; - - drm_connector_init(dev, connector, &bochs_connector_connector_funcs, - DRM_MODE_CONNECTOR_VIRTUAL); - drm_connector_attach_edid_property(connector); - drm_connector_helper_add(connector, &bochs_connector_connector_helper_funcs); -} - -static const struct drm_mode_config_funcs bochs_mode_funcs = { +static const struct drm_mode_config_funcs bochs_mode_config_funcs = { .fb_create = drm_gem_fb_create, .mode_valid = drm_vram_helper_mode_valid, .atomic_check = drm_atomic_helper_check, @@ -508,6 +566,10 @@ static const struct drm_mode_config_funcs bochs_mode_funcs = { static int bochs_kms_init(struct bochs_device *bochs) { struct drm_device *dev = &bochs->dev; + struct drm_plane *primary_plane; + struct drm_crtc *crtc; + struct drm_connector *connector; + struct drm_encoder *encoder; int ret; ret = drmm_mode_config_init(dev); @@ -518,19 +580,44 @@ static int bochs_kms_init(struct bochs_device *bochs) dev->mode_config.max_height = 8192; dev->mode_config.preferred_depth = 24; - dev->mode_config.prefer_shadow = 0; dev->mode_config.quirk_addfb_prefer_host_byte_order = true; - dev->mode_config.funcs = &bochs_mode_funcs; + dev->mode_config.funcs = &bochs_mode_config_funcs; - bochs_connector_init(bochs); - drm_simple_display_pipe_init(dev, - &bochs->pipe, - &bochs_pipe_funcs, - bochs_formats, - ARRAY_SIZE(bochs_formats), - NULL, - &bochs->connector); + primary_plane = &bochs->primary_plane; + ret = drm_universal_plane_init(dev, primary_plane, 0, + &bochs_primary_plane_funcs, + bochs_primary_plane_formats, + ARRAY_SIZE(bochs_primary_plane_formats), + NULL, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) + return ret; + drm_plane_helper_add(primary_plane, &bochs_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + crtc = &bochs->crtc; + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &bochs_crtc_funcs, NULL); + if (ret) + return ret; + drm_crtc_helper_add(crtc, &bochs_crtc_helper_funcs); + + encoder = &bochs->encoder; + ret = drm_encoder_init(dev, encoder, &bochs_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) + return ret; + encoder->possible_crtcs = drm_crtc_mask(crtc); + + connector = &bochs->connector; + ret = drm_connector_init(dev, connector, &bochs_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL); + if (ret) + return ret; + drm_connector_helper_add(connector, &bochs_connector_helper_funcs); + drm_connector_attach_edid_property(connector); + drm_connector_attach_encoder(connector, encoder); drm_mode_config_reset(dev); -- GitLab From c3ac343c1448599952829456bc2d65b6a4307c6c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:46 +0200 Subject: [PATCH 062/970] drm/bochs: Use GEM SHMEM helpers for memory management Replace GEM VRAM with GEM SHMEM in bochs. The new memory manager stores buffer objects in system memory. Makes the driver's memory management more reliably. Most of the changes are hidden in external helpers that allocate buffers. Replacing DRM_GEM_VRAM_DRIVER with DRM_GEM_SHMEM_DRIVER_OPS swaps these. With GEM VRAM, the video memory was updated directly by the DRM client. The biggest change within bochs is in atomic_update, which now updates video memory via memcpy() from the BO in system memory. Shadow-plane helpers maintaining the pointers to the buffer's data, so bochs doesn't have to. The update is triggered by each page flip's call to the framebuffer's dirty helper. The driver supports damage clipping to minimize memcpy() overhead. The advantage of GEM SHMEM is that it makes memory management more reliable. Given DRM's double buffering during page flips, the minimum amount of video memory is three times the maximum consumption in some pathological cases. For example, if the maximum size of a GEM buffer is 1920x1080-32 (i.e., 32-bit FullHD), the buffer size is 8 MiB. Display hardware has to provide at lease 24 MiB to reliably page flip such configurations. This cannot always be guaranteed and bochs already contains code to rule out <4 MiB configurations. With GEM SHMEM, only 8 MiB of video memory are required for the given example. Unsupported modes can be sorted out easily. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-9-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 4 +- drivers/gpu/drm/tiny/bochs.c | 78 +++++++++++++++++------------------- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index f6889f649bc1..8f206c6387ec 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -13,10 +13,8 @@ config DRM_ARCPGU config DRM_BOCHS tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" depends on DRM && PCI && MMU + select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER - select DRM_VRAM_HELPER - select DRM_TTM - select DRM_TTM_HELPER help This is a KMS driver for qemu's stdvga output. Choose this option for qemu. diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 76e29950a807..bde70a6075ec 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -6,13 +6,15 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> -#include <drm/drm_fbdev_ttm.h> +#include <drm/drm_fbdev_shmem.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> -#include <drm/drm_gem_vram_helper.h> +#include <drm/drm_gem_shmem_helper.h> #include <drm/drm_managed.h> #include <drm/drm_module.h> #include <drm/drm_plane_helper.h> @@ -427,49 +429,49 @@ static int bochs_primary_plane_helper_atomic_check(struct drm_plane *plane, return 0; } -static void bochs_plane_update(struct bochs_device *bochs, struct drm_plane_state *state) +static void bochs_primary_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) { - struct drm_gem_vram_object *gbo; - s64 gpu_addr; - - if (!state->fb || !bochs->stride) + struct drm_device *dev = plane->dev; + struct bochs_device *bochs = to_bochs_device(dev); + struct drm_plane_state *plane_state = plane->state; + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect damage; + + if (!fb || !bochs->stride) return; - gbo = drm_gem_vram_of_gem(state->fb->obj[0]); - gpu_addr = drm_gem_vram_offset(gbo); - if (WARN_ON_ONCE(gpu_addr < 0)) - return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(bochs->fb_map); - bochs_hw_setbase(bochs, - state->crtc_x, - state->crtc_y, - state->fb->pitches[0], - state->fb->offsets[0] + gpu_addr); - bochs_hw_setformat(bochs, state->fb->format); -} - -static void bochs_primary_plane_helper_atomic_update(struct drm_plane *plane, - struct drm_atomic_state *state) -{ - struct bochs_device *bochs = to_bochs_device(plane->dev); - struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, &damage)); + drm_fb_memcpy(&dst, fb->pitches, shadow_plane_state->data, fb, &damage); + } - bochs_plane_update(bochs, plane_state); + /* Always scanout image at VRAM offset 0 */ + bochs_hw_setbase(bochs, + plane_state->crtc_x, + plane_state->crtc_y, + fb->pitches[0], + 0); + bochs_hw_setformat(bochs, fb->format); } static const struct drm_plane_helper_funcs bochs_primary_plane_helper_funcs = { - DRM_GEM_VRAM_PLANE_HELPER_FUNCS, + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, .atomic_check = bochs_primary_plane_helper_atomic_check, .atomic_update = bochs_primary_plane_helper_atomic_update, }; static const struct drm_plane_funcs bochs_primary_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, - .destroy = drm_plane_cleanup, - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + DRM_GEM_SHADOW_PLANE_FUNCS }; static void bochs_crtc_helper_mode_set_nofb(struct drm_crtc *crtc) @@ -557,8 +559,7 @@ static const struct drm_connector_funcs bochs_connector_funcs = { }; static const struct drm_mode_config_funcs bochs_mode_config_funcs = { - .fb_create = drm_gem_fb_create, - .mode_valid = drm_vram_helper_mode_valid, + .fb_create = drm_gem_fb_create_with_dirty, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; @@ -629,17 +630,12 @@ static int bochs_kms_init(struct bochs_device *bochs) static int bochs_load(struct bochs_device *bochs) { - struct drm_device *dev = &bochs->dev; int ret; ret = bochs_hw_init(bochs); if (ret) return ret; - ret = drmm_vram_helper_init(dev, bochs->fb_base, bochs->fb_size); - if (ret) - return ret; - ret = bochs_kms_init(bochs); if (ret) return ret; @@ -657,7 +653,7 @@ static const struct drm_driver bochs_driver = { .date = "20130925", .major = 1, .minor = 0, - DRM_GEM_VRAM_DRIVER, + DRM_GEM_SHMEM_DRIVER_OPS, }; /* ---------------------------------------------------------------------- */ @@ -723,7 +719,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent if (ret) goto err_free_dev; - drm_fbdev_ttm_setup(dev, 32); + drm_fbdev_shmem_setup(dev, 32); return ret; err_free_dev: -- GitLab From 4dc9bb66ebdd123cc6dc823516b2710e7ff8df7b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:47 +0200 Subject: [PATCH 063/970] drm/bochs: Validate display modes against available video memory For each mode, test the required memory against the available video memory. Filters out modes that do not fit into display memory. Also remove the old test against the 4 MiB limit. It is now obsolete and did not necessarily produce correct results. v2: - fix __udivdi3 linker error (kernel test robot) - fix vdisplay and hdisplay usage Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-10-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index bde70a6075ec..69c5f65e9853 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -558,8 +558,28 @@ static const struct drm_connector_funcs bochs_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; +static enum drm_mode_status bochs_mode_config_mode_valid(struct drm_device *dev, + const struct drm_display_mode *mode) +{ + struct bochs_device *bochs = to_bochs_device(dev); + const struct drm_format_info *format = drm_format_info(DRM_FORMAT_XRGB8888); + u64 pitch; + + if (drm_WARN_ON(dev, !format)) + return MODE_ERROR; + + pitch = drm_format_info_min_pitch(format, 0, mode->hdisplay); + if (!pitch) + return MODE_BAD_WIDTH; + if (mode->vdisplay > DIV_ROUND_DOWN_ULL(bochs->fb_size, pitch)) + return MODE_MEM; + + return MODE_OK; +} + static const struct drm_mode_config_funcs bochs_mode_config_funcs = { .fb_create = drm_gem_fb_create_with_dirty, + .mode_valid = bochs_mode_config_mode_valid, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; @@ -687,15 +707,8 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent { struct bochs_device *bochs; struct drm_device *dev; - unsigned long fbsize; int ret; - fbsize = pci_resource_len(pdev, 0); - if (fbsize < 4 * 1024 * 1024) { - DRM_ERROR("less than 4 MB video memory, ignoring device\n"); - return -ENOMEM; - } - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &bochs_driver); if (ret) return ret; -- GitLab From 498ba74654bec380974d87da04361c5edea07181 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 2 Sep 2024 12:53:48 +0200 Subject: [PATCH 064/970] drm/gem-vram: Remove support for simple display pipelines There are no more drivers that use GEM VRAM helpers with a simple display pipeline. Remove the respective code. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240902105546.792625-11-tzimmermann@suse.de --- drivers/gpu/drm/drm_gem_vram_helper.c | 45 --------------------------- include/drm/drm_gem_vram_helper.h | 13 -------- 2 files changed, 58 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 6027584406af..22b1fe9c03b8 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -16,7 +16,6 @@ #include <drm/drm_mode.h> #include <drm/drm_plane.h> #include <drm/drm_prime.h> -#include <drm/drm_simple_kms_helper.h> #include <drm/ttm/ttm_range_manager.h> #include <drm/ttm/ttm_tt.h> @@ -686,50 +685,6 @@ drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane, } EXPORT_SYMBOL(drm_gem_vram_plane_helper_cleanup_fb); -/* - * Helpers for struct drm_simple_display_pipe_funcs - */ - -/** - * drm_gem_vram_simple_display_pipe_prepare_fb() - Implements &struct - * drm_simple_display_pipe_funcs.prepare_fb - * @pipe: a simple display pipe - * @new_state: the plane's new state - * - * During plane updates, this function pins the GEM VRAM - * objects of the plane's new framebuffer to VRAM. Call - * drm_gem_vram_simple_display_pipe_cleanup_fb() to unpin them. - * - * Returns: - * 0 on success, or - * a negative errno code otherwise. - */ -int drm_gem_vram_simple_display_pipe_prepare_fb( - struct drm_simple_display_pipe *pipe, - struct drm_plane_state *new_state) -{ - return drm_gem_vram_plane_helper_prepare_fb(&pipe->plane, new_state); -} -EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_prepare_fb); - -/** - * drm_gem_vram_simple_display_pipe_cleanup_fb() - Implements &struct - * drm_simple_display_pipe_funcs.cleanup_fb - * @pipe: a simple display pipe - * @old_state: the plane's old state - * - * During plane updates, this function unpins the GEM VRAM - * objects of the plane's old framebuffer from VRAM. Complements - * drm_gem_vram_simple_display_pipe_prepare_fb(). - */ -void drm_gem_vram_simple_display_pipe_cleanup_fb( - struct drm_simple_display_pipe *pipe, - struct drm_plane_state *old_state) -{ - drm_gem_vram_plane_helper_cleanup_fb(&pipe->plane, old_state); -} -EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb); - /* * PRIME helpers */ diff --git a/include/drm/drm_gem_vram_helper.h b/include/drm/drm_gem_vram_helper.h index 9a73f786f4ad..00830b49a3ff 100644 --- a/include/drm/drm_gem_vram_helper.h +++ b/include/drm/drm_gem_vram_helper.h @@ -17,7 +17,6 @@ struct drm_mode_create_dumb; struct drm_plane; struct drm_plane_state; -struct drm_simple_display_pipe; struct filp; struct vm_area_struct; @@ -137,18 +136,6 @@ drm_gem_vram_plane_helper_cleanup_fb(struct drm_plane *plane, .prepare_fb = drm_gem_vram_plane_helper_prepare_fb, \ .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb -/* - * Helpers for struct drm_simple_display_pipe_funcs - */ - -int drm_gem_vram_simple_display_pipe_prepare_fb( - struct drm_simple_display_pipe *pipe, - struct drm_plane_state *new_state); - -void drm_gem_vram_simple_display_pipe_cleanup_fb( - struct drm_simple_display_pipe *pipe, - struct drm_plane_state *old_state); - /** * define DRM_GEM_VRAM_DRIVER - default callback functions for * &struct drm_driver -- GitLab From 5ea28f921a1cd8e722ddfd9cc0cb92b8e37b5adb Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 4 Sep 2024 17:52:31 +0300 Subject: [PATCH 065/970] drm/xe: use IS_ENABLED() instead of defined() on config options Prefer IS_ENABLED() instead of defined() for checking whether a kconfig option is enabled. Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240904145231.3902289-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/xe/xe_bo.c | 2 +- drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.c | 2 +- drivers/gpu/drm/xe/xe_guc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 0c64d3b3155e..3a9653e33481 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -468,7 +468,7 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev, mem->bus.offset += vram->io_start; mem->bus.is_iomem = true; -#if !defined(CONFIG_X86) +#if !IS_ENABLED(CONFIG_X86) mem->bus.caching = ttm_write_combined; #endif return 0; diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.c index f3ddcbefc6bc..2ed5b6780d30 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf_debugfs.c @@ -33,7 +33,7 @@ static const struct drm_info_list vf_info[] = { .show = xe_gt_debugfs_simple_show, .data = xe_gt_sriov_vf_print_version, }, -#if defined(CONFIG_DRM_XE_DEBUG) || defined(CONFIG_DRM_XE_DEBUG_SRIOV) +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) || IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) { "runtime_regs", .show = xe_gt_debugfs_simple_show, diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index c67d4807f37d..5599464013bd 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -583,7 +583,7 @@ static s32 guc_pc_get_cur_freq(struct xe_guc_pc *guc_pc) * extreme thermal throttling. And a system that is that hot during boot is probably * dead anyway! */ -#if defined(CONFIG_DRM_XE_DEBUG) +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) #define GUC_LOAD_RETRY_LIMIT 20 #else #define GUC_LOAD_RETRY_LIMIT 3 -- GitLab From b2ef808786d93df36585cee42cfb973fc41636eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <ckoenig.leichtzumerken@gmail.com> Date: Mon, 26 Aug 2024 14:25:38 +0200 Subject: [PATCH 066/970] drm/sched: add optional errno to drm_sched_start() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation of drm_sched_start uses a hardcoded -ECANCELED to dispose of a job when the parent/hw fence is NULL. This results in drm_sched_job_done being called with -ECANCELED for each job with a NULL parent in the pending list, making it difficult to distinguish between recovery methods, whether a queue reset or a full GPU reset was used. To improve this, we first try a soft recovery for timeout jobs and use the error code -ENODATA. If soft recovery fails, we proceed with a queue reset, where the error code remains -ENODATA for the job. Finally, for a full GPU reset, we use error codes -ECANCELED or -ETIME. This patch adds an error code parameter to drm_sched_start, allowing us to differentiate between queue reset and GPU reset failures. This enables user mode and test applications to validate the expected correctness of the requested operation. After a successful queue reset, the only way to continue normal operation is to call drm_sched_job_done with the specific error code -ENODATA. v1: Initial implementation by Jesse utilized amdgpu_device_lock_reset_domain and amdgpu_device_unlock_reset_domain to allow user mode to track the queue reset status and distinguish between queue reset and GPU reset. v2: Christian suggested using the error codes -ENODATA for queue reset and -ECANCELED or -ETIME for GPU reset, returned to amdgpu_cs_wait_ioctl. v3: To meet the requirements, we introduce a new function drm_sched_start_ex with an additional parameter to set dma_fence_set_error, allowing us to handle the specific error codes appropriately and dispose of bad jobs with the selected error code depending on whether it was a queue reset or GPU reset. v4: Alex suggested using a new name, drm_sched_start_with_recovery_error, which more accurately describes the function's purpose. Additionally, it was recommended to add documentation details about the new method. v5: Fixed declaration of new function drm_sched_start_with_recovery_error.(Alex) v6 (chk): rebase on upstream changes, cleanup the commit message, drop the new function again and update all callers, apply the errno also to scheduler fences with hw fences v7 (chk): rebased Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com> Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240826122541.85663-1-christian.koenig@amd.com --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 2 +- drivers/gpu/drm/imagination/pvr_queue.c | 4 ++-- drivers/gpu/drm/lima/lima_sched.c | 2 +- drivers/gpu/drm/nouveau/nouveau_sched.c | 2 +- drivers/gpu/drm/panfrost/panfrost_job.c | 2 +- drivers/gpu/drm/panthor/panthor_mmu.c | 2 +- drivers/gpu/drm/panthor/panthor_sched.c | 2 +- drivers/gpu/drm/scheduler/sched_main.c | 7 ++++--- drivers/gpu/drm/v3d/v3d_sched.c | 2 +- include/drm/gpu_scheduler.h | 2 +- 13 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 73b2b401b450..30c5172d208e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -300,7 +300,7 @@ static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool sus if (r) goto out; } else { - drm_sched_start(&ring->sched); + drm_sched_start(&ring->sched, 0); } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 49ef22dcf7fb..0aad05b4f32e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5907,7 +5907,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, if (!amdgpu_ring_sched_ready(ring)) continue; - drm_sched_start(&ring->sched); + drm_sched_start(&ring->sched, 0); } if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) @@ -6414,7 +6414,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev) if (!amdgpu_ring_sched_ready(ring)) continue; - drm_sched_start(&ring->sched); + drm_sched_start(&ring->sched, 0); } amdgpu_device_unset_mp1_state(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 597489dea114..3bb9d1ca74b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -87,7 +87,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) atomic_inc(&ring->adev->gpu_reset_counter); amdgpu_fence_driver_force_completion(ring); if (amdgpu_ring_sched_ready(ring)) - drm_sched_start(&ring->sched); + drm_sched_start(&ring->sched, 0); goto exit; } } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c index ab9ca4824b62..23ced5896c7c 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c @@ -72,7 +72,7 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job drm_sched_resubmit_jobs(&gpu->sched); - drm_sched_start(&gpu->sched); + drm_sched_start(&gpu->sched, 0); return DRM_GPU_SCHED_STAT_NOMINAL; out_no_timeout: diff --git a/drivers/gpu/drm/imagination/pvr_queue.c b/drivers/gpu/drm/imagination/pvr_queue.c index 20cb46012082..c4f08432882b 100644 --- a/drivers/gpu/drm/imagination/pvr_queue.c +++ b/drivers/gpu/drm/imagination/pvr_queue.c @@ -782,7 +782,7 @@ static void pvr_queue_start(struct pvr_queue *queue) } } - drm_sched_start(&queue->scheduler); + drm_sched_start(&queue->scheduler, 0); } /** @@ -842,7 +842,7 @@ pvr_queue_timedout_job(struct drm_sched_job *s_job) } mutex_unlock(&pvr_dev->queues.lock); - drm_sched_start(sched); + drm_sched_start(sched, 0); return DRM_GPU_SCHED_STAT_NOMINAL; } diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c index 1a944edb6ddc..b40c90e97d7e 100644 --- a/drivers/gpu/drm/lima/lima_sched.c +++ b/drivers/gpu/drm/lima/lima_sched.c @@ -463,7 +463,7 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job lima_pm_idle(ldev); drm_sched_resubmit_jobs(&pipe->base); - drm_sched_start(&pipe->base); + drm_sched_start(&pipe->base, 0); return DRM_GPU_SCHED_STAT_NOMINAL; } diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c index eb6c3f9a01f5..4412f2711fb5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sched.c +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c @@ -379,7 +379,7 @@ nouveau_sched_timedout_job(struct drm_sched_job *sched_job) else NV_PRINTK(warn, job->cli, "Generic job timeout.\n"); - drm_sched_start(sched); + drm_sched_start(sched, 0); return stat; } diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index 3ad131eb6657..9b8e82fb8bc4 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -733,7 +733,7 @@ panfrost_reset(struct panfrost_device *pfdev, /* Restart the schedulers */ for (i = 0; i < NUM_JOB_SLOTS; i++) - drm_sched_start(&pfdev->js->queue[i].sched); + drm_sched_start(&pfdev->js->queue[i].sched, 0); /* Re-enable job interrupts now that everything has been restarted. */ job_write(pfdev, JOB_INT_MASK, diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index cd2bac54e761..7d0a90559182 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -827,7 +827,7 @@ static void panthor_vm_stop(struct panthor_vm *vm) static void panthor_vm_start(struct panthor_vm *vm) { - drm_sched_start(&vm->sched); + drm_sched_start(&vm->sched, 0); } /** diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index c426a392b081..d3246f7d9591 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -2538,7 +2538,7 @@ static void queue_start(struct panthor_queue *queue) list_for_each_entry(job, &queue->scheduler.pending_list, base.list) job->base.s_fence->parent = dma_fence_get(job->done_fence); - drm_sched_start(&queue->scheduler); + drm_sched_start(&queue->scheduler, 0); } static void panthor_group_stop(struct panthor_group *group) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index ab53ab486fe6..f093616fe53c 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -674,9 +674,10 @@ EXPORT_SYMBOL(drm_sched_stop); * drm_sched_start - recover jobs after a reset * * @sched: scheduler instance + * @errno: error to set on the pending fences * */ -void drm_sched_start(struct drm_gpu_scheduler *sched) +void drm_sched_start(struct drm_gpu_scheduler *sched, int errno) { struct drm_sched_job *s_job, *tmp; @@ -691,13 +692,13 @@ void drm_sched_start(struct drm_gpu_scheduler *sched) atomic_add(s_job->credits, &sched->credit_count); if (!fence) { - drm_sched_job_done(s_job, -ECANCELED); + drm_sched_job_done(s_job, errno ?: -ECANCELED); continue; } if (dma_fence_add_callback(fence, &s_job->cb, drm_sched_job_done_cb)) - drm_sched_job_done(s_job, fence->error); + drm_sched_job_done(s_job, fence->error ?: errno); } drm_sched_start_timeout_unlocked(sched); diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index fa6859dd8368..090bbaebb496 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -661,7 +661,7 @@ v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) /* Unblock schedulers and restart their jobs. */ for (q = 0; q < V3D_MAX_QUEUES; q++) { - drm_sched_start(&v3d->queue[q].sched); + drm_sched_start(&v3d->queue[q].sched, 0); } mutex_unlock(&v3d->reset_lock); diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index fe8edb917360..a8d19b10f9b8 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -579,7 +579,7 @@ bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched); void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched); void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched); void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad); -void drm_sched_start(struct drm_gpu_scheduler *sched); +void drm_sched_start(struct drm_gpu_scheduler *sched, int errno); void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched); void drm_sched_increase_karma(struct drm_sched_job *bad); void drm_sched_reset_karma(struct drm_sched_job *bad); -- GitLab From a401bd1264b400f96a4cf61ed3fc144008e97a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <ckoenig.leichtzumerken@gmail.com> Date: Mon, 26 Aug 2024 14:25:39 +0200 Subject: [PATCH 067/970] dma-buf: give examples of error codes to use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dma_fence_set_error() function allows to set an error code on a dma_fence object before it is signaled. Document some of the potential error codes drivers should use and especially what they mean. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240826122541.85663-2-christian.koenig@amd.com --- include/linux/dma-fence.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index e06bad467f55..e7ad819962e3 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -574,6 +574,12 @@ int dma_fence_get_status(struct dma_fence *fence); * rather than success. This must be set before signaling (so that the value * is visible before any waiters on the signal callback are woken). This * helper exists to help catching erroneous setting of #dma_fence.error. + * + * Examples of error codes which drivers should use: + * + * * %-ENODATA This operation produced no data, no other operation affected. + * * %-ECANCELED All operations from the same context have been canceled. + * * %-ETIME Operation caused a timeout and potentially device reset. */ static inline void dma_fence_set_error(struct dma_fence *fence, int error) -- GitLab From f07a0d1bf7de562b2806bce0ba8601c325627c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <ckoenig.leichtzumerken@gmail.com> Date: Mon, 26 Aug 2024 14:25:40 +0200 Subject: [PATCH 068/970] drm/doc: Document submission error signaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Different approaches have been tried to signal resets and other errors in vendor specific ways which not only resulted in a wide variety of implementations but also repeating the same bugs and problems over different drivers. Document that drivers should use dma_fence based error signaling which is vendor agnostic and allows userspace to query submission errors in generic non-vendor specific code. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240826122541.85663-3-christian.koenig@amd.com --- Documentation/gpu/drm-uapi.rst | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 370d820be248..b75cc9a70d1f 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -305,13 +305,26 @@ Kernel Mode Driver ------------------ The KMD is responsible for checking if the device needs a reset, and to perform -it as needed. Usually a hang is detected when a job gets stuck executing. KMD -should keep track of resets, because userspace can query any time about the -reset status for a specific context. This is needed to propagate to the rest of -the stack that a reset has happened. Currently, this is implemented by each -driver separately, with no common DRM interface. Ideally this should be properly -integrated at DRM scheduler to provide a common ground for all drivers. After a -reset, KMD should reject new command submissions for affected contexts. +it as needed. Usually a hang is detected when a job gets stuck executing. + +Propagation of errors to userspace has proven to be tricky since it goes in +the opposite direction of the usual flow of commands. Because of this vendor +independent error handling was added to the &dma_fence object, this way drivers +can add an error code to their fences before signaling them. See function +dma_fence_set_error() on how to do this and for examples of error codes to use. + +The DRM scheduler also allows setting error codes on all pending fences when +hardware submissions are restarted after an reset. Error codes are also +forwarded from the hardware fence to the scheduler fence to bubble up errors +to the higher levels of the stack and eventually userspace. + +Fence errors can be queried by userspace through the generic SYNC_IOC_FILE_INFO +IOCTL as well as through driver specific interfaces. + +Additional to setting fence errors drivers should also keep track of resets per +context, the DRM scheduler provides the drm_sched_entity_error() function as +helper for this use case. After a reset, KMD should reject new command +submissions for affected contexts. User Mode Driver ---------------- -- GitLab From a6bb1f77a94335de67dba12e7f52651c115b82d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <ckoenig.leichtzumerken@gmail.com> Date: Mon, 26 Aug 2024 14:25:41 +0200 Subject: [PATCH 069/970] drm/todos: add entry for drm_syncobj error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That would be rather nice to have and the kernel side is really trivial, only the userspace side might be a bit more complex. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240826122541.85663-4-christian.koenig@amd.com --- Documentation/gpu/todo.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 96c453980ab6..c771f0c9610f 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -834,6 +834,22 @@ Contact: Javier Martinez Canillas <javierm@redhat.com> Level: Advanced +Querying errors from drm_syncobj +================================ + +The drm_syncobj container can be used by driver independent code to signal +complection of submission. + +One minor feature still missing is a generic DRM IOCTL to query the error +status of binary and timeline drm_syncobj. + +This should probably be improved by implementing the necessary kernel interface +and adding support for that in the userspace stack. + +Contact: Christian König + +Level: Starter + Outside DRM =========== -- GitLab From c2bf07dd0bbce1f318b73b525e21fbc6d67a3a94 Mon Sep 17 00:00:00 2001 From: Riana Tauro <riana.tauro@intel.com> Date: Fri, 6 Sep 2024 12:41:25 +0530 Subject: [PATCH 070/970] drm/xe/xe_gt_idle: modify powergate enable condition Modify powergate enable condition based on the type of GT or presence of media engines. Also have a copy of the value written to powergate enable register. v2: add condition to enable render or media powergating (Badal) v3: fix commit message (Shekhar) fix kernel-doc Signed-off-by: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906071126.28078-2-riana.tauro@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_gt_idle.c | 26 ++++++++++++++++++-------- drivers/gpu/drm/xe/xe_gt_idle_types.h | 2 ++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c index 67aba4140510..3924f9f3d0a5 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.c +++ b/drivers/gpu/drm/xe/xe_gt_idle.c @@ -98,7 +98,8 @@ static u64 get_residency_ms(struct xe_gt_idle *gtidle, u64 cur_residency) void xe_gt_idle_enable_pg(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); - u32 pg_enable; + struct xe_gt_idle *gtidle = >->gtidle; + u32 vcs_mask, vecs_mask; int i, j; if (IS_SRIOV_VF(xe)) @@ -110,12 +111,19 @@ void xe_gt_idle_enable_pg(struct xe_gt *gt) xe_device_assert_mem_access(gt_to_xe(gt)); - pg_enable = RENDER_POWERGATE_ENABLE | MEDIA_POWERGATE_ENABLE; + vcs_mask = xe_hw_engine_mask_per_class(gt, XE_ENGINE_CLASS_VIDEO_DECODE); + vecs_mask = xe_hw_engine_mask_per_class(gt, XE_ENGINE_CLASS_VIDEO_ENHANCE); + + if (vcs_mask || vecs_mask) + gtidle->powergate_enable = MEDIA_POWERGATE_ENABLE; + + if (!xe_gt_is_media_type(gt)) + gtidle->powergate_enable |= RENDER_POWERGATE_ENABLE; for (i = XE_HW_ENGINE_VCS0, j = 0; i <= XE_HW_ENGINE_VCS7; ++i, ++j) { if ((gt->info.engine_mask & BIT(i))) - pg_enable |= (VDN_HCP_POWERGATE_ENABLE(j) | - VDN_MFXVDENC_POWERGATE_ENABLE(j)); + gtidle->powergate_enable |= (VDN_HCP_POWERGATE_ENABLE(j) | + VDN_MFXVDENC_POWERGATE_ENABLE(j)); } XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); @@ -128,20 +136,22 @@ void xe_gt_idle_enable_pg(struct xe_gt *gt) xe_mmio_write32(gt, RENDER_POWERGATE_IDLE_HYSTERESIS, 25); } - xe_mmio_write32(gt, POWERGATE_ENABLE, pg_enable); + xe_mmio_write32(gt, POWERGATE_ENABLE, gtidle->powergate_enable); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); } void xe_gt_idle_disable_pg(struct xe_gt *gt) { + struct xe_gt_idle *gtidle = >->gtidle; + if (IS_SRIOV_VF(gt_to_xe(gt))) return; xe_device_assert_mem_access(gt_to_xe(gt)); - XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); - - xe_mmio_write32(gt, POWERGATE_ENABLE, 0); + gtidle->powergate_enable = 0; + XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); + xe_mmio_write32(gt, POWERGATE_ENABLE, gtidle->powergate_enable); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); } diff --git a/drivers/gpu/drm/xe/xe_gt_idle_types.h b/drivers/gpu/drm/xe/xe_gt_idle_types.h index f99b447534f3..b8b297a3f884 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle_types.h +++ b/drivers/gpu/drm/xe/xe_gt_idle_types.h @@ -23,6 +23,8 @@ enum xe_gt_idle_state { struct xe_gt_idle { /** @name: name */ char name[16]; + /** @powergate_enable: copy of powergate enable bits */ + u32 powergate_enable; /** @residency_multiplier: residency multiplier in ns */ u32 residency_multiplier; /** @cur_residency: raw driver copy of idle residency */ -- GitLab From 0914c1e45d3a1a747faeebae27ba197d7ba41f94 Mon Sep 17 00:00:00 2001 From: Riana Tauro <riana.tauro@intel.com> Date: Fri, 6 Sep 2024 12:41:26 +0530 Subject: [PATCH 071/970] drm/xe/xe_gt_idle: add debugfs entry for powergating info Coarse Powergating is a power saving technique where Render and Media can be power-gated independently irrespective of the rest of the GT. For debug purposes, it is useful to expose the powergating information. v2: move to debugfs add details to commit message add per-slice status for media define reg bits in descending order (Matt Roper) v3: fix return statement fix kernel-doc use loop for media slices use helper function for status (Michal) v4: add pg prefix do not wake GT if in C6 (Badal) Signed-off-by: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906071126.28078-3-riana.tauro@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 8 +++ drivers/gpu/drm/xe/xe_gt_debugfs.c | 13 ++++ drivers/gpu/drm/xe/xe_gt_idle.c | 91 ++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_idle.h | 2 + 4 files changed, 114 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 0d1a4a9f4e11..cbead3f75fad 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -341,6 +341,14 @@ #define CTC_SOURCE_DIVIDE_LOGIC REG_BIT(0) #define FORCEWAKE_RENDER XE_REG(0xa278) + +#define POWERGATE_DOMAIN_STATUS XE_REG(0xa2a0) +#define MEDIA_SLICE3_AWAKE_STATUS REG_BIT(4) +#define MEDIA_SLICE2_AWAKE_STATUS REG_BIT(3) +#define MEDIA_SLICE1_AWAKE_STATUS REG_BIT(2) +#define RENDER_AWAKE_STATUS REG_BIT(1) +#define MEDIA_SLICE0_AWAKE_STATUS REG_BIT(0) + #define FORCEWAKE_MEDIA_VDBOX(n) XE_REG(0xa540 + (n) * 4) #define FORCEWAKE_MEDIA_VEBOX(n) XE_REG(0xa560 + (n) * 4) #define FORCEWAKE_GSC XE_REG(0xa618) diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c index 8f95d3a5949b..cbc43973ff7e 100644 --- a/drivers/gpu/drm/xe/xe_gt_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c @@ -15,6 +15,7 @@ #include "xe_ggtt.h" #include "xe_gt.h" #include "xe_gt_mcr.h" +#include "xe_gt_idle.h" #include "xe_gt_sriov_pf_debugfs.h" #include "xe_gt_sriov_vf_debugfs.h" #include "xe_gt_stats.h" @@ -109,6 +110,17 @@ static int hw_engines(struct xe_gt *gt, struct drm_printer *p) return 0; } +static int powergate_info(struct xe_gt *gt, struct drm_printer *p) +{ + int ret; + + xe_pm_runtime_get(gt_to_xe(gt)); + ret = xe_gt_idle_pg_print(gt, p); + xe_pm_runtime_put(gt_to_xe(gt)); + + return ret; +} + static int force_reset(struct xe_gt *gt, struct drm_printer *p) { xe_pm_runtime_get(gt_to_xe(gt)); @@ -288,6 +300,7 @@ static const struct drm_info_list debugfs_list[] = { {"topology", .show = xe_gt_debugfs_simple_show, .data = topology}, {"steering", .show = xe_gt_debugfs_simple_show, .data = steering}, {"ggtt", .show = xe_gt_debugfs_simple_show, .data = ggtt}, + {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info}, {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore}, {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds}, {"pat", .show = xe_gt_debugfs_simple_show, .data = pat}, diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c index 3924f9f3d0a5..85a35ed153a3 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.c +++ b/drivers/gpu/drm/xe/xe_gt_idle.c @@ -53,6 +53,11 @@ pc_to_xe(struct xe_guc_pc *pc) return gt_to_xe(gt); } +static inline const char *str_up_down(bool v) +{ + return v ? "up" : "down"; +} + static const char *gt_idle_state_to_string(enum xe_gt_idle_state state) { switch (state) { @@ -155,6 +160,92 @@ void xe_gt_idle_disable_pg(struct xe_gt *gt) XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); } +/** + * xe_gt_idle_pg_print - Xe powergating info + * @gt: GT object + * @p: drm_printer. + * + * This function prints the powergating information + * + * Return: 0 on success, negative error code otherwise + */ +int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p) +{ + struct xe_gt_idle *gtidle = >->gtidle; + struct xe_device *xe = gt_to_xe(gt); + enum xe_gt_idle_state state; + u32 pg_enabled, pg_status = 0; + u32 vcs_mask, vecs_mask; + int err, n; + /* + * Media Slices + * + * Slice 0: VCS0, VCS1, VECS0 + * Slice 1: VCS2, VCS3, VECS1 + * Slice 2: VCS4, VCS5, VECS2 + * Slice 3: VCS6, VCS7, VECS3 + */ + static const struct { + u64 engines; + u32 status_bit; + } media_slices[] = { + {(BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VCS1) | + BIT(XE_HW_ENGINE_VECS0)), MEDIA_SLICE0_AWAKE_STATUS}, + + {(BIT(XE_HW_ENGINE_VCS2) | BIT(XE_HW_ENGINE_VCS3) | + BIT(XE_HW_ENGINE_VECS1)), MEDIA_SLICE1_AWAKE_STATUS}, + + {(BIT(XE_HW_ENGINE_VCS4) | BIT(XE_HW_ENGINE_VCS5) | + BIT(XE_HW_ENGINE_VECS2)), MEDIA_SLICE2_AWAKE_STATUS}, + + {(BIT(XE_HW_ENGINE_VCS6) | BIT(XE_HW_ENGINE_VCS7) | + BIT(XE_HW_ENGINE_VECS3)), MEDIA_SLICE3_AWAKE_STATUS}, + }; + + if (xe->info.platform == XE_PVC) { + drm_printf(p, "Power Gating not supported\n"); + return 0; + } + + state = gtidle->idle_status(gtidle_to_pc(gtidle)); + pg_enabled = gtidle->powergate_enable; + + /* Do not wake the GT to read powergating status */ + if (state != GT_IDLE_C6) { + err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT); + if (err) + return err; + + pg_enabled = xe_mmio_read32(gt, POWERGATE_ENABLE); + pg_status = xe_mmio_read32(gt, POWERGATE_DOMAIN_STATUS); + + XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); + } + + if (gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK) { + drm_printf(p, "Render Power Gating Enabled: %s\n", + str_yes_no(pg_enabled & RENDER_POWERGATE_ENABLE)); + + drm_printf(p, "Render Power Gate Status: %s\n", + str_up_down(pg_status & RENDER_AWAKE_STATUS)); + } + + vcs_mask = xe_hw_engine_mask_per_class(gt, XE_ENGINE_CLASS_VIDEO_DECODE); + vecs_mask = xe_hw_engine_mask_per_class(gt, XE_ENGINE_CLASS_VIDEO_ENHANCE); + + /* Print media CPG status only if media is present */ + if (vcs_mask || vecs_mask) { + drm_printf(p, "Media Power Gating Enabled: %s\n", + str_yes_no(pg_enabled & MEDIA_POWERGATE_ENABLE)); + + for (n = 0; n < ARRAY_SIZE(media_slices); n++) + if (gt->info.engine_mask & media_slices[n].engines) + drm_printf(p, "Media Slice%d Power Gate Status: %s\n", n, + str_up_down(pg_status & media_slices[n].status_bit)); + } + return 0; +} + static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buff) { diff --git a/drivers/gpu/drm/xe/xe_gt_idle.h b/drivers/gpu/drm/xe/xe_gt_idle.h index 554447b5d46d..4455a6501cb0 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.h +++ b/drivers/gpu/drm/xe/xe_gt_idle.h @@ -8,6 +8,7 @@ #include "xe_gt_idle_types.h" +struct drm_printer; struct xe_gt; int xe_gt_idle_init(struct xe_gt_idle *gtidle); @@ -15,5 +16,6 @@ void xe_gt_idle_enable_c6(struct xe_gt *gt); void xe_gt_idle_disable_c6(struct xe_gt *gt); void xe_gt_idle_enable_pg(struct xe_gt *gt); void xe_gt_idle_disable_pg(struct xe_gt *gt); +int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p); #endif /* _XE_GT_IDLE_H_ */ -- GitLab From cb85e39dc5d1717fab82810984cce0e54712a3c2 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi <rodrigo.vivi@intel.com> Date: Thu, 5 Sep 2024 10:02:15 -0400 Subject: [PATCH 072/970] drm/xe: Suppress missing outer rpm protection warning Do not raise a WARN if we are likely within suspending or resuming path. This is likely this false positive: rpm_status: 0000:03:00.0 status=RPM_SUSPENDING console: xe_bo_evict_all (called from suspend) xe_sched_job_create: dev=0000:03:00.0, ... xe_sched_job_exec: dev=0000:03:00.0, ... xe_pm_runtime_put: dev=0000:03:00.0, ... xe_sched_job_run: dev=0000:03:00.0, ... rpm_usage: 0000:03:00.0 flags-0 cnt-2 ... rpm_usage: 0000:03:00.0 flags-0 cnt-2 ... rpm_usage: 0000:03:00.0 flags-0 cnt-2 ... console: xe 0000:03:00.0: [drm] Missing outer runtime PM protection console: xe_guc_ct_send+0x15/0x50 [xe] console: guc_exec_queue_run_job+0x1509/0x3950 [xe] [snip] console: drm_sched_run_job_work+0x649/0xc20 At this point, BOs are getting evicted from VRAM with rpm usage-counter = 2, but rpm status = SUSPENDING. The xe->pm_callback_task won't be equal 'current' because this call is coming from a work queue. So, pm_runtime_get_if_active() will be called and return 0 because rpm status != ACTIVE (but equal SUSPENDING or RESUMING). v2: Still get the reference even on non suspending/resuming path (Jonathan, Brost). Cc: Matthew Brost <matthew.brost@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905140215.56404-1-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_pm.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index e518557e0eec..9c59a30d7646 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -595,6 +595,18 @@ bool xe_pm_runtime_get_if_in_use(struct xe_device *xe) return pm_runtime_get_if_in_use(xe->drm.dev) > 0; } +/* + * Very unreliable! Should only be used to suppress the false positive case + * in the missing outer rpm protection warning. + */ +static bool xe_pm_suspending_or_resuming(struct xe_device *xe) +{ + struct device *dev = xe->drm.dev; + + return dev->power.runtime_status == RPM_SUSPENDING || + dev->power.runtime_status == RPM_RESUMING; +} + /** * xe_pm_runtime_get_noresume - Bump runtime PM usage counter without resuming * @xe: xe device instance @@ -611,8 +623,11 @@ void xe_pm_runtime_get_noresume(struct xe_device *xe) ref = xe_pm_runtime_get_if_in_use(xe); - if (drm_WARN(&xe->drm, !ref, "Missing outer runtime PM protection\n")) + if (!ref) { pm_runtime_get_noresume(xe->drm.dev); + drm_WARN(&xe->drm, !xe_pm_suspending_or_resuming(xe), + "Missing outer runtime PM protection\n"); + } } /** -- GitLab From 249df8cbecf0ab4877eab66cae857748631831a9 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld <dhirschfeld@habana.ai> Date: Sun, 1 Sep 2024 07:42:27 +0300 Subject: [PATCH 073/970] drm/xe: fix missing 'xe_vm_put' Fix memleak caused by missing xe_vm_put Fixes: 852856e3b6f6 ("drm/xe: Use reserved copy engine for user binds on faulting devices") Signed-off-by: Dafna Hirschfeld <dhirschfeld@habana.ai> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240901044227.1177211-1-dhirschfeld@habana.ai Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_exec_queue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 5a9cbc97f0be..7f28b7fc68d5 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -223,8 +223,10 @@ struct xe_exec_queue *xe_exec_queue_create_bind(struct xe_device *xe, gt->usm.reserved_bcs_instance, false); - if (!hwe) + if (!hwe) { + xe_vm_put(migrate_vm); return ERR_PTR(-EINVAL); + } q = xe_exec_queue_create(xe, migrate_vm, BIT(hwe->logical_instance), 1, hwe, -- GitLab From b43723f864618be715646d6164469f5e4d77aa7e Mon Sep 17 00:00:00 2001 From: Lucas De Marchi <lucas.demarchi@intel.com> Date: Wed, 4 Sep 2024 09:22:37 -0700 Subject: [PATCH 074/970] drm/xe: Cleanup has_flat_ccs handling The flag is set in XE_HP_FEATURES, but then overridden in all but one xe_graphics_desc. Make it set only where needed. Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240904162238.2831202-1-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_pci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 942817e5a79e..add735369f8f 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -103,7 +103,6 @@ static const struct xe_graphics_desc graphics_xelpp = { #define XE_HP_FEATURES \ .has_range_tlb_invalidation = true, \ - .has_flat_ccs = true, \ .dma_mask_size = 46, \ .va_bits = 48, \ .vm_max_level = 3 @@ -120,6 +119,8 @@ static const struct xe_graphics_desc graphics_xehpg = { XE_HP_FEATURES, .vram_flags = XE_VRAM_FLAGS_NEED64K, + + .has_flat_ccs = 1, }; static const struct xe_graphics_desc graphics_xehpc = { @@ -145,7 +146,6 @@ static const struct xe_graphics_desc graphics_xehpc = { .has_asid = 1, .has_atomic_enable_pte_bit = 1, - .has_flat_ccs = 0, .has_usm = 1, }; @@ -156,7 +156,6 @@ static const struct xe_graphics_desc graphics_xelpg = { BIT(XE_HW_ENGINE_CCS0), XE_HP_FEATURES, - .has_flat_ccs = 0, }; #define XE2_GFX_FEATURES \ -- GitLab From 0c841e47d8d94bd0f5444a25052d86c0b1f2c2e8 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi <lucas.demarchi@intel.com> Date: Wed, 4 Sep 2024 09:22:38 -0700 Subject: [PATCH 075/970] drm/xe: Update runtime detection of has_flat_ccs It's confusing to have a *set* function that actually probes the hardware rather than receiving a parameter. Rename it to *probe* along with prefix removal and comment in the relevant places that the has_flat_ccs flag may be overridden in runtime. While at it, fix the mixed declaration of struct xe_gt. Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240904162238.2831202-2-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_device.c | 8 +++++--- drivers/gpu/drm/xe/xe_pci.c | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 1a0d7fdd094b..449b85035d3a 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -588,15 +588,17 @@ int xe_device_probe_early(struct xe_device *xe) return 0; } -static int xe_device_set_has_flat_ccs(struct xe_device *xe) +static int probe_has_flat_ccs(struct xe_device *xe) { + struct xe_gt *gt; u32 reg; int err; + /* Always enabled/disabled, no runtime check to do */ if (GRAPHICS_VER(xe) < 20 || !xe->info.has_flat_ccs) return 0; - struct xe_gt *gt = xe_root_mmio_gt(xe); + gt = xe_root_mmio_gt(xe); err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT); if (err) @@ -688,7 +690,7 @@ int xe_device_probe(struct xe_device *xe) if (err) goto err; - err = xe_device_set_has_flat_ccs(xe); + err = probe_has_flat_ccs(xe); if (err) goto err; diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index add735369f8f..8f8e28894546 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -679,7 +679,10 @@ static int xe_info_init(struct xe_device *xe, xe->info.has_atomic_enable_pte_bit = graphics_desc->has_atomic_enable_pte_bit; if (xe->info.platform != XE_PVC) xe->info.has_device_atomics_on_smem = 1; + + /* Runtime detection may change this later */ xe->info.has_flat_ccs = graphics_desc->has_flat_ccs; + xe->info.has_range_tlb_invalidation = graphics_desc->has_range_tlb_invalidation; xe->info.has_usm = graphics_desc->has_usm; -- GitLab From 7a4fe6525450eb950de040336de996775e40176e Mon Sep 17 00:00:00 2001 From: "T.J. Mercier" <tjmercier@google.com> Date: Fri, 6 Sep 2024 00:03:12 +0000 Subject: [PATCH 076/970] dma-buf: heaps: Add __init to CMA and system heap module_init functions Shrink the kernel .text a bit after successful initialization of the heaps. Signed-off-by: T.J. Mercier <tjmercier@google.com> Acked-by: John Stultz <jstultz@google.com> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240906000314.2368749-1-tjmercier@google.com --- drivers/dma-buf/heaps/cma_heap.c | 4 ++-- drivers/dma-buf/heaps/system_heap.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index c384004b918e..39c1e533a2f2 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -366,7 +366,7 @@ static const struct dma_heap_ops cma_heap_ops = { .allocate = cma_heap_allocate, }; -static int __add_cma_heap(struct cma *cma, void *data) +static int __init __add_cma_heap(struct cma *cma, void *data) { struct cma_heap *cma_heap; struct dma_heap_export_info exp_info; @@ -391,7 +391,7 @@ static int __add_cma_heap(struct cma *cma, void *data) return 0; } -static int add_default_cma_heap(void) +static int __init add_default_cma_heap(void) { struct cma *default_cma = dev_get_cma_area(NULL); int ret = 0; diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index d78cdb9d01e5..26d5dc89ea16 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -421,7 +421,7 @@ static const struct dma_heap_ops system_heap_ops = { .allocate = system_heap_allocate, }; -static int system_heap_create(void) +static int __init system_heap_create(void) { struct dma_heap_export_info exp_info; -- GitLab From 6639d7d9af301994bfc48b69be5a9de67d065756 Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:25 +0100 Subject: [PATCH 077/970] drm/vc4: plane: Keep fractional source coords inside state Fractional source co-ordinates can be used to setup the scaling filters, so retain the information. Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-2-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_drv.h | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 68 ++++++++++++++++----------------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 08e29fa82563..697e9b7c9d0e 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -404,7 +404,7 @@ struct vc4_plane_state { /* Clipped coordinates of the plane on the display. */ int crtc_x, crtc_y, crtc_w, crtc_h; - /* Clipped area being scanned from in the FB. */ + /* Clipped area being scanned from in the FB in u16.16 format */ u32 src_x, src_y; u32 src_w[2], src_h[2]; diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 07caf2a47c6c..e0df210bedcb 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -251,9 +251,9 @@ static const struct hvs_format *vc4_get_hvs_format(u32 drm_format) static enum vc4_scaling_mode vc4_get_scaling_mode(u32 src, u32 dst) { - if (dst == src) + if (dst == src >> 16) return VC4_SCALING_NONE; - if (3 * dst >= 2 * src) + if (3 * dst >= 2 * (src >> 16)) return VC4_SCALING_PPF; else return VC4_SCALING_TPZ; @@ -462,15 +462,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i]; } - /* - * We don't support subpixel source positioning for scaling, - * but fractional coordinates can be generated by clipping - * so just round for now - */ - vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16); - vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16); - vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x; - vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y; + vc4_state->src_x = state->src.x1; + vc4_state->src_y = state->src.y1; + vc4_state->src_w[0] = state->src.x2 - vc4_state->src_x; + vc4_state->src_h[0] = state->src.y2 - vc4_state->src_y; vc4_state->crtc_x = state->dst.x1; vc4_state->crtc_y = state->dst.y1; @@ -523,7 +518,7 @@ static void vc4_write_tpz(struct vc4_plane_state *vc4_state, u32 src, u32 dst) { u32 scale, recip; - scale = (1 << 16) * src / dst; + scale = src / dst; /* The specs note that while the reciprocal would be defined * as (1<<32)/scale, ~0 is close enough. @@ -569,7 +564,7 @@ static u32 vc4_lbm_size(struct drm_plane_state *state) if (vc4_state->x_scaling[0] == VC4_SCALING_TPZ) pix_per_line = vc4_state->crtc_w; else - pix_per_line = vc4_state->src_w[0]; + pix_per_line = vc4_state->src_w[0] >> 16; if (!vc4_state->is_yuv) { if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ) @@ -660,7 +655,8 @@ static void vc4_plane_calc_load(struct drm_plane_state *state) for (i = 0; i < fb->format->num_planes; i++) { /* Even if the bandwidth/plane required for a single frame is * - * vc4_state->src_w[i] * vc4_state->src_h[i] * cpp * vrefresh + * (vc4_state->src_w[i] >> 16) * (vc4_state->src_h[i] >> 16) * + * cpp * vrefresh * * when downscaling, we have to read more pixels per line in * the time frame reserved for a single line, so the bandwidth @@ -669,11 +665,11 @@ static void vc4_plane_calc_load(struct drm_plane_state *state) * load by this number. We're likely over-estimating the read * demand, but that's better than under-estimating it. */ - vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i], + vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i] >> 16, vc4_state->crtc_h); - vc4_state->membus_load += vc4_state->src_w[i] * - vc4_state->src_h[i] * vscale_factor * - fb->format->cpp[i]; + vc4_state->membus_load += (vc4_state->src_w[i] >> 16) * + (vc4_state->src_h[i] >> 16) * + vscale_factor * fb->format->cpp[i]; vc4_state->hvs_load += vc4_state->crtc_h * vc4_state->crtc_w; } @@ -826,7 +822,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, bool mix_plane_alpha; bool covers_screen; u32 scl0, scl1, pitch0; - u32 tiling, src_y; + u32 tiling, src_x, src_y; + u32 width, height; u32 hvs_format = format->hvs; unsigned int rotation; int ret, i; @@ -838,6 +835,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane, if (ret) return ret; + width = vc4_state->src_w[0] >> 16; + height = vc4_state->src_h[0] >> 16; + /* SCL1 is used for Cb/Cr scaling of planar formats. For RGB * and 4:4:4, scl1 should be set to scl0 so both channels of * the scaler do the same thing. For YUV, the Y plane needs @@ -858,9 +858,11 @@ static int vc4_plane_mode_set(struct drm_plane *plane, DRM_MODE_REFLECT_Y); /* We must point to the last line when Y reflection is enabled. */ - src_y = vc4_state->src_y; + src_y = vc4_state->src_y >> 16; if (rotation & DRM_MODE_REFLECT_Y) - src_y += vc4_state->src_h[0] - 1; + src_y += height - 1; + + src_x = vc4_state->src_x >> 16; switch (base_format_mod) { case DRM_FORMAT_MOD_LINEAR: @@ -875,7 +877,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, (i ? v_subsample : 1) * fb->pitches[i]; - vc4_state->offsets[i] += vc4_state->src_x / + vc4_state->offsets[i] += src_x / (i ? h_subsample : 1) * fb->format->cpp[i]; } @@ -898,7 +900,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * pitch * tile_h == tile_size * tiles_per_row */ u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift); - u32 tiles_l = vc4_state->src_x >> tile_w_shift; + u32 tiles_l = src_x >> tile_w_shift; u32 tiles_r = tiles_w - tiles_l; u32 tiles_t = src_y >> tile_h_shift; /* Intra-tile offsets, which modify the base address (the @@ -908,7 +910,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, u32 tile_y = (src_y >> 4) & 1; u32 subtile_y = (src_y >> 2) & 3; u32 utile_y = src_y & 3; - u32 x_off = vc4_state->src_x & tile_w_mask; + u32 x_off = src_x & tile_w_mask; u32 y_off = src_y & tile_h_mask; /* When Y reflection is requested we must set the @@ -1004,7 +1006,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * of the 12-pixels in that 128-bit word is the * first pixel to be used */ - u32 remaining_pixels = vc4_state->src_x % 96; + u32 remaining_pixels = src_x % 96; u32 aligned = remaining_pixels / 12; u32 last_bits = remaining_pixels % 12; @@ -1026,12 +1028,12 @@ static int vc4_plane_mode_set(struct drm_plane *plane, return -EINVAL; } pix_per_tile = tile_w / fb->format->cpp[0]; - x_off = (vc4_state->src_x % pix_per_tile) / + x_off = (src_x % pix_per_tile) / (i ? h_subsample : 1) * fb->format->cpp[i]; } - tile = vc4_state->src_x / pix_per_tile; + tile = src_x / pix_per_tile; vc4_state->offsets[i] += param * tile_w * tile; vc4_state->offsets[i] += src_y / @@ -1092,10 +1094,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, vc4_dlist_write(vc4_state, (mix_plane_alpha ? SCALER_POS2_ALPHA_MIX : 0) | vc4_hvs4_get_alpha_blend_mode(state) | - VC4_SET_FIELD(vc4_state->src_w[0], - SCALER_POS2_WIDTH) | - VC4_SET_FIELD(vc4_state->src_h[0], - SCALER_POS2_HEIGHT)); + VC4_SET_FIELD(width, SCALER_POS2_WIDTH) | + VC4_SET_FIELD(height, SCALER_POS2_HEIGHT)); /* Position Word 3: Context. Written by the HVS. */ vc4_dlist_write(vc4_state, 0xc0c0c0c0); @@ -1148,10 +1148,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, /* Position Word 2: Source Image Size */ vc4_state->pos2_offset = vc4_state->dlist_count; vc4_dlist_write(vc4_state, - VC4_SET_FIELD(vc4_state->src_w[0], - SCALER5_POS2_WIDTH) | - VC4_SET_FIELD(vc4_state->src_h[0], - SCALER5_POS2_HEIGHT)); + VC4_SET_FIELD(width, SCALER5_POS2_WIDTH) | + VC4_SET_FIELD(height, SCALER5_POS2_HEIGHT)); /* Position Word 3: Context. Written by the HVS. */ vc4_dlist_write(vc4_state, 0xc0c0c0c0); -- GitLab From ac69c01fa82504d12431a0909f3132b43639dda4 Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:26 +0100 Subject: [PATCH 078/970] drm/vc4: plane: Handle fractional coordinates using the phase field Apply fractional source co-ordinates into the scaling filters. Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-3-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_plane.c | 87 ++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index e0df210bedcb..b8c68d4688c8 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -532,14 +532,61 @@ static void vc4_write_tpz(struct vc4_plane_state *vc4_state, u32 src, u32 dst) VC4_SET_FIELD(recip, SCALER_TPZ1_RECIP)); } -static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst) +/* phase magnitude bits */ +#define PHASE_BITS 6 + +static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, + u32 xy, int channel) { - u32 scale = (1 << 16) * src / dst; + u32 scale = src / dst; + s32 offset, offset2; + s32 phase; + + /* + * Start the phase at 1/2 pixel from the 1st pixel at src_x. + * 1/4 pixel for YUV. + */ + if (channel) { + /* + * The phase is relative to scale_src->x, so shift it for + * display list's x value + */ + offset = (xy & 0x1ffff) >> (16 - PHASE_BITS) >> 1; + offset += -(1 << PHASE_BITS >> 2); + } else { + /* + * The phase is relative to scale_src->x, so shift it for + * display list's x value + */ + offset = (xy & 0xffff) >> (16 - PHASE_BITS); + offset += -(1 << PHASE_BITS >> 1); + + /* + * This is a kludge to make sure the scaling factors are + * consistent with YUV's luma scaling. We lose 1-bit precision + * because of this. + */ + scale &= ~1; + } + + /* + * There may be a also small error introduced by precision of scale. + * Add half of that as a compromise + */ + offset2 = src - dst * scale; + offset2 >>= 16 - PHASE_BITS; + phase = offset + (offset2 >> 1); + + /* Ensure +ve values don't touch the sign bit, then truncate negative values */ + if (phase >= 1 << PHASE_BITS) + phase = (1 << PHASE_BITS) - 1; + + phase &= SCALER_PPF_IPHASE_MASK; vc4_dlist_write(vc4_state, SCALER_PPF_AGC | VC4_SET_FIELD(scale, SCALER_PPF_SCALE) | - VC4_SET_FIELD(0, SCALER_PPF_IPHASE)); + VC4_SET_FIELD(phase, SCALER_PPF_IPHASE)); } static u32 vc4_lbm_size(struct drm_plane_state *state) @@ -597,27 +644,27 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state, /* Ch0 H-PPF Word 0: Scaling Parameters */ if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) { - vc4_write_ppf(vc4_state, - vc4_state->src_w[channel], vc4_state->crtc_w); + vc4_write_ppf(vc4_state, vc4_state->src_w[channel], + vc4_state->crtc_w, vc4_state->src_x, channel); } /* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */ if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) { - vc4_write_ppf(vc4_state, - vc4_state->src_h[channel], vc4_state->crtc_h); + vc4_write_ppf(vc4_state, vc4_state->src_h[channel], + vc4_state->crtc_h, vc4_state->src_y, channel); vc4_dlist_write(vc4_state, 0xc0c0c0c0); } /* Ch0 H-TPZ Words 0-1: Scaling Parameters, Recip */ if (vc4_state->x_scaling[channel] == VC4_SCALING_TPZ) { - vc4_write_tpz(vc4_state, - vc4_state->src_w[channel], vc4_state->crtc_w); + vc4_write_tpz(vc4_state, vc4_state->src_w[channel], + vc4_state->crtc_w); } /* Ch0 V-TPZ Words 0-2: Scaling Parameters, Recip, Context */ if (vc4_state->y_scaling[channel] == VC4_SCALING_TPZ) { - vc4_write_tpz(vc4_state, - vc4_state->src_h[channel], vc4_state->crtc_h); + vc4_write_tpz(vc4_state, vc4_state->src_h[channel], + vc4_state->crtc_h); vc4_dlist_write(vc4_state, 0xc0c0c0c0); } } @@ -1052,6 +1099,24 @@ static int vc4_plane_mode_set(struct drm_plane *plane, return -EINVAL; } + /* fetch an extra pixel if we don't actually line up with the left edge. */ + if ((vc4_state->src_x & 0xffff) && vc4_state->src_x < (state->fb->width << 16)) + width++; + + /* same for the right side */ + if (((vc4_state->src_x + vc4_state->src_w[0]) & 0xffff) && + vc4_state->src_x + vc4_state->src_w[0] < (state->fb->width << 16)) + width++; + + /* now for the top */ + if ((vc4_state->src_y & 0xffff) && vc4_state->src_y < (state->fb->height << 16)) + height++; + + /* and the bottom */ + if (((vc4_state->src_y + vc4_state->src_h[0]) & 0xffff) && + vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16)) + height++; + /* Don't waste cycles mixing with plane alpha if the set alpha * is opaque or there is no per-pixel alpha information. * In any case we use the alpha property value as the fixed alpha. -- GitLab From 9337d27d230c6f9b5dc965390962509de90b0841 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:27 +0100 Subject: [PATCH 079/970] drm/vc4: crtc: Force trigger of dlist update on margins change When the margins are changed, the dlist needs to be regenerated with the changed updated dest regions for each of the planes. Setting the zpos_changed flag is sufficient to trigger that without doing a full modeset, therefore set it should the margins be changed. Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-4-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_crtc.c | 15 +++++++++++---- drivers/gpu/drm/vc4/vc4_drv.h | 7 +------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 8b5a7e5eb146..1d54176cf811 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -735,10 +735,17 @@ int vc4_crtc_atomic_check(struct drm_crtc *crtc, if (conn_state->crtc != crtc) continue; - vc4_state->margins.left = conn_state->tv.margins.left; - vc4_state->margins.right = conn_state->tv.margins.right; - vc4_state->margins.top = conn_state->tv.margins.top; - vc4_state->margins.bottom = conn_state->tv.margins.bottom; + if (memcmp(&vc4_state->margins, &conn_state->tv.margins, + sizeof(vc4_state->margins))) { + memcpy(&vc4_state->margins, &conn_state->tv.margins, + sizeof(vc4_state->margins)); + + /* + * Need to force the dlist entries for all planes to be + * updated so that the dest rectangles are changed. + */ + crtc_state->zpos_changed = true; + } break; } diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 697e9b7c9d0e..717fd1140561 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -598,12 +598,7 @@ struct vc4_crtc_state { bool txp_armed; unsigned int assigned_channel; - struct { - unsigned int left; - unsigned int right; - unsigned int top; - unsigned int bottom; - } margins; + struct drm_connector_tv_margins margins; unsigned long hvs_load; -- GitLab From b4e5646178e86665f5caef2894578600f597098a Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:28 +0100 Subject: [PATCH 080/970] drm/vc4: hdmi: Avoid log spam for audio start failure We regularly get dmesg error reports of: [ 18.184066] hdmi-audio-codec hdmi-audio-codec.3.auto: ASoC: error at snd_soc_dai_startup on i2s-hifi: -19 [ 18.184098] MAI: soc_pcm_open() failed (-19) These are generated for any disconnected hdmi interface when pulseaudio attempts to open the associated ALSA device (numerous times). Each open generates a kernel error message, generating general log spam. The error messages all come from _soc_pcm_ret in sound/soc/soc-pcm.c#L39 which suggests returning ENOTSUPP, rather that ENODEV will be quiet. And indeed it is. Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-5-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 6611ab7c26a6..43f4e150d726 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1920,7 +1920,7 @@ static int vc4_hdmi_audio_startup(struct device *dev, void *data) } if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) { - ret = -ENODEV; + ret = -ENOTSUPP; goto out_dev_exit; } -- GitLab From 31c8a80b93bdf933e784fe0e890e193e01cef796 Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:29 +0100 Subject: [PATCH 081/970] drm/vc4: plane: Add support for YUV444 formats Support displaying DRM_FORMAT_YUV444 and DRM_FORMAT_YVU444 formats. Tested with kmstest and kodi. e.g. kmstest -r 1920x1080@60 -f 400x300-YU24 Note: without the shift of width, only half the chroma is fetched, resulting in correct left half of image and corrupt colours on right half. The increase in width shouldn't affect fetching of Y data, as the hardware will clamp at dest width. Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-6-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_plane.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index b8c68d4688c8..978433554f3d 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -109,6 +109,18 @@ static const struct hvs_format { .pixel_order = HVS_PIXEL_ORDER_XYCRCB, .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB, }, + { + .drm = DRM_FORMAT_YUV444, + .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE, + .pixel_order = HVS_PIXEL_ORDER_XYCBCR, + .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR, + }, + { + .drm = DRM_FORMAT_YVU444, + .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE, + .pixel_order = HVS_PIXEL_ORDER_XYCRCB, + .pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB, + }, { .drm = DRM_FORMAT_YUV420, .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE, @@ -1117,6 +1129,12 @@ static int vc4_plane_mode_set(struct drm_plane *plane, vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16)) height++; + /* For YUV444 the hardware wants double the width, otherwise it doesn't + * fetch full width of chroma + */ + if (format->drm == DRM_FORMAT_YUV444 || format->drm == DRM_FORMAT_YVU444) + width <<= 1; + /* Don't waste cycles mixing with plane alpha if the set alpha * is opaque or there is no per-pixel alpha information. * In any case we use the alpha property value as the fixed alpha. -- GitLab From 014eccc9da7bfc76a3107fceea37dd60f1d63630 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:30 +0100 Subject: [PATCH 082/970] drm/vc4: hvs: Set AXI panic modes for the HVS The HVS can change AXI request mode based on how full the COB FIFOs are. Until now the vc4 driver has been relying on the firmware to have set these to sensible values. With HVS channel 2 now being used for live video, change the panic mode for all channels to be explicitly set by the driver, and the same for all channels. Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-7-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 2a835a5cff9d..32ecc26a749a 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -951,6 +951,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) SCALER_DISPCTRL_SCLEIRQ); + /* Set AXI panic mode. + * VC4 panics when < 2 lines in FIFO. + * VC5 panics when less than 1 line in the FIFO. + */ + dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK | + SCALER_DISPCTRL_PANIC1_MASK | + SCALER_DISPCTRL_PANIC2_MASK); + dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0); + dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1); + dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2); + /* Set AXI panic mode. * VC4 panics when < 2 lines in FIFO. * VC5 panics when less than 1 line in the FIFO. -- GitLab From 59f8b2b7fb8e460881d21c7d5b32604993973879 Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:31 +0100 Subject: [PATCH 083/970] drm/vc4: hdmi: Increase audio MAI fifo dreq threshold Now we wait for write responses and have a burst size of 4, we can set the fifo threshold much higher. Set it to 28 (of the 32 entry size) to keep fifo fuller and reduce chance of underflow. Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-8-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hdmi.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 43f4e150d726..60cbf1d4c7dd 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2047,6 +2047,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); struct drm_device *drm = vc4_hdmi->connector.dev; struct drm_connector *connector = &vc4_hdmi->connector; + struct vc4_dev *vc4 = to_vc4_dev(drm); unsigned int sample_rate = params->sample_rate; unsigned int channels = params->channels; unsigned long flags; @@ -2104,11 +2105,18 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, VC4_HDMI_AUDIO_PACKET_CEA_MASK); /* Set the MAI threshold */ - HDMI_WRITE(HDMI_MAI_THR, - VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICHIGH) | - VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICLOW) | - VC4_SET_FIELD(0x06, VC4_HD_MAI_THR_DREQHIGH) | - VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_DREQLOW)); + if (vc4->is_vc5) + HDMI_WRITE(HDMI_MAI_THR, + VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) | + VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) | + VC4_SET_FIELD(0x1c, VC4_HD_MAI_THR_DREQHIGH) | + VC4_SET_FIELD(0x1c, VC4_HD_MAI_THR_DREQLOW)); + else + HDMI_WRITE(HDMI_MAI_THR, + VC4_SET_FIELD(0x8, VC4_HD_MAI_THR_PANICHIGH) | + VC4_SET_FIELD(0x8, VC4_HD_MAI_THR_PANICLOW) | + VC4_SET_FIELD(0x6, VC4_HD_MAI_THR_DREQHIGH) | + VC4_SET_FIELD(0x8, VC4_HD_MAI_THR_DREQLOW)); HDMI_WRITE(HDMI_MAI_CONFIG, VC4_HDMI_MAI_CONFIG_BIT_REVERSE | -- GitLab From 6ecfe7c2f925b805efbd1c1e2a93890ea7ec37fd Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:32 +0100 Subject: [PATCH 084/970] drm/vc4: hdmi: Warn if writing to an unknown HDMI register The VC4 HDMI driver has a bunch of accessors to read from a register. The read accessor was warning when accessing an unknown register, but the write one was just returning silently. Let's make sure we warn also when writing to an unknown register. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-9-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h index b04b2fc8d831..68455ce513e7 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h @@ -498,8 +498,11 @@ static inline void vc4_hdmi_write(struct vc4_hdmi *hdmi, field = &variant->registers[reg]; base = __vc4_hdmi_get_field_base(hdmi, field->reg); - if (!base) + if (!base) { + dev_warn(&hdmi->pdev->dev, + "Unknown register ID %u\n", reg); return; + } writel(value, base + field->offset); } -- GitLab From b6d7a953969eef2d30d1213c5f8c565eb8b27f2e Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:33 +0100 Subject: [PATCH 085/970] drm/vc4: hvs: More logging for dlist generation DLIST generation can get pretty tricky and there's not a lot of debug in the driver to help. Let's add a few more to track the generated DLIST size. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-10-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 32ecc26a749a..e37851e13474 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -456,11 +456,21 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) if (hweight32(crtc_state->connector_mask) > 1) return -EINVAL; - drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) - dlist_count += vc4_plane_dlist_size(plane_state); + drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) { + u32 plane_dlist_count = vc4_plane_dlist_size(plane_state); + + drm_dbg_driver(dev, "[CRTC:%d:%s] Found [PLANE:%d:%s] with DLIST size: %u\n", + crtc->base.id, crtc->name, + plane->base.id, plane->name, + plane_dlist_count); + + dlist_count += plane_dlist_count; + } dlist_count++; /* Account for SCALER_CTL0_END. */ + drm_dbg_driver(dev, "[CRTC:%d:%s] Allocating DLIST block with size: %u\n", + crtc->base.id, crtc->name, dlist_count); spin_lock_irqsave(&vc4->hvs->mm_lock, flags); ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm, dlist_count); -- GitLab From 6184b9446d43d36615b75683967a3bbfb06c2d20 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:34 +0100 Subject: [PATCH 086/970] drm/vc4: hvs: Print error if we fail an allocation We need to allocate a few additional structures when checking our atomic_state, especially related to hardware SRAM that will hold the plane descriptors (DLIST) and the current line context (LBM) during composition. Since those allocation can fail, let's add some error message in that case to help debug what goes wrong. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-11-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 4 +++- drivers/gpu/drm/vc4/vc4_plane.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index e37851e13474..3a5d9ba3a67a 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -475,8 +475,10 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm, dlist_count); spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags); - if (ret) + if (ret) { + drm_err(dev, "Failed to allocate DLIST entry: %d\n", ret); return ret; + } return 0; } diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 978433554f3d..e4fcef11cf6f 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -739,7 +739,8 @@ static void vc4_plane_calc_load(struct drm_plane_state *state) static int vc4_plane_allocate_lbm(struct drm_plane_state *state) { - struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev); + struct drm_device *drm = state->plane->dev; + struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); unsigned long irqflags; u32 lbm_size; @@ -765,8 +766,10 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) 0, 0); spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); - if (ret) + if (ret) { + drm_err(drm, "Failed to allocate LBM entry: %d\n", ret); return ret; + } } else { WARN_ON_ONCE(lbm_size != vc4_state->lbm.size); } -- GitLab From f18029bdf2e85d281b6e1a79c33daf84b5730e59 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:35 +0100 Subject: [PATCH 087/970] drm/vc4: plane: Add more debugging for LBM allocation LBM allocations need a different size depending on the line length, format, etc. This can get tricky, and fail. Let's add some more prints to ease the debugging when it does. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-12-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_plane.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index e4fcef11cf6f..16197c4b4b33 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -741,6 +741,7 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) { struct drm_device *drm = state->plane->dev; struct vc4_dev *vc4 = to_vc4_dev(drm); + struct drm_plane *plane = state->plane; struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); unsigned long irqflags; u32 lbm_size; @@ -749,6 +750,9 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) if (!lbm_size) return 0; + drm_dbg_driver(drm, "[PLANE:%d:%s] LBM Allocation Size: %u\n", + plane->base.id, plane->name, lbm_size); + if (WARN_ON(!vc4_state->lbm_offset)) return -EINVAL; -- GitLab From 5171d86a62658dbcb9876fae87e1132320e9a83a Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:36 +0100 Subject: [PATCH 088/970] drm/vc4: plane: Use return variable in atomic_check The vc4_plane_atomic_check() directly returns the result of the final function it calls. Using the already defined ret variable to check its content on error, and a separate return 0 on success, makes it easier to extend. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-13-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_plane.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 16197c4b4b33..d078a2d21eea 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -1386,7 +1386,11 @@ static int vc4_plane_atomic_check(struct drm_plane *plane, if (ret) return ret; - return vc4_plane_allocate_lbm(new_plane_state); + ret = vc4_plane_allocate_lbm(new_plane_state); + if (ret) + return ret; + + return 0; } static void vc4_plane_atomic_update(struct drm_plane *plane, -- GitLab From dbe101b10641e458e37e714f9f1fc50413463c10 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:37 +0100 Subject: [PATCH 089/970] drm/vc4: crtc: Move assigned_channel to a variable We access multiple times the vc4_crtc_state->assigned_channel variable in the vc4_crtc_get_scanout_position() function, so let's store it in a local variable. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-14-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_crtc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 1d54176cf811..ef5ad0ca4c2d 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -105,6 +105,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc, struct vc4_hvs *hvs = vc4->hvs; struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); + unsigned int channel = vc4_crtc_state->assigned_channel; unsigned int cob_size; u32 val; int fifo_lines; @@ -121,7 +122,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc, * Read vertical scanline which is currently composed for our * pixelvalve by the HVS, and also the scaler status. */ - val = HVS_READ(SCALER_DISPSTATX(vc4_crtc_state->assigned_channel)); + val = HVS_READ(SCALER_DISPSTATX(channel)); /* Get optional system timestamp after query. */ if (etime) @@ -137,11 +138,11 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc, *vpos /= 2; /* Use hpos to correct for field offset in interlaced mode. */ - if (vc4_hvs_get_fifo_frame_count(hvs, vc4_crtc_state->assigned_channel) % 2) + if (vc4_hvs_get_fifo_frame_count(hvs, channel) % 2) *hpos += mode->crtc_htotal / 2; } - cob_size = vc4_crtc_get_cob_allocation(vc4, vc4_crtc_state->assigned_channel); + cob_size = vc4_crtc_get_cob_allocation(vc4, channel); /* This is the offset we need for translating hvs -> pv scanout pos. */ fifo_lines = cob_size / mode->crtc_hdisplay; -- GitLab From 52efe364d1968ee3e3ed45eb44eb924b63635315 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:38 +0100 Subject: [PATCH 090/970] drm/vc4: hvs: Don't write gamma luts on 2711 The gamma block has changed in 2711, therefore writing the lut in vc4_hvs_lut_load is incorrect. Whilst the gamma property isn't created for 2711, it is called from vc4_hvs_init_channel, so abort if attempted. Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5") Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-15-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 3a5d9ba3a67a..8dab59341a82 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -222,6 +222,9 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs, if (!drm_dev_enter(drm, &idx)) return; + if (hvs->vc4->is_vc5) + return; + /* The LUT memory is laid out with each HVS channel in order, * each of which takes 256 writes for R, 256 for G, then 256 * for B. -- GitLab From 542962190e55be21fc600ffed47a50390b6101cc Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:39 +0100 Subject: [PATCH 091/970] drm/vc4: plane: YUV planes require vertical scaling to always be enabled It has been observed that a YUV422 unity scaled plane isn't displayed. Enabling vertical scaling on the UV planes solves this. There is already a similar clause to always enable horizontal scaling on the UV planes. Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-16-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_plane.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index d078a2d21eea..4cd1721d2389 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -517,6 +517,12 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) */ if (vc4_state->x_scaling[1] == VC4_SCALING_NONE) vc4_state->x_scaling[1] = VC4_SCALING_PPF; + + /* Similarly UV needs vertical scaling to be enabled. + * Without this a 1:1 scaled YUV422 plane isn't rendered. + */ + if (vc4_state->y_scaling[1] == VC4_SCALING_NONE) + vc4_state->y_scaling[1] = VC4_SCALING_PPF; } else { vc4_state->is_yuv = false; vc4_state->x_scaling[1] = VC4_SCALING_NONE; -- GitLab From 223ee2567a55e4f80315c768d2969e6a3b9fb23d Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:40 +0100 Subject: [PATCH 092/970] drm/vc4: hdmi: Avoid hang with debug registers when suspended Trying to read /sys/kernel/debug/dri/1/hdmi1_regs when the hdmi is disconnected results in a fatal system hang. This is due to the pm suspend code disabling the dvp clock. That is just a gate of the 108MHz clock in DVP_HT_RPI_MISC_CONFIG, which results in accesses hanging AXI bus. Protect against this. Fixes: 25eb441d55d4 ("drm/vc4: hdmi: Add all the vc5 HDMI registers into the debugfs dumps") Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-17-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 60cbf1d4c7dd..28792dfa8c55 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -147,6 +147,8 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused) if (!drm_dev_enter(drm, &idx)) return -ENODEV; + WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev)); + drm_print_regset32(&p, &vc4_hdmi->hdmi_regset); drm_print_regset32(&p, &vc4_hdmi->hd_regset); drm_print_regset32(&p, &vc4_hdmi->cec_regset); @@ -156,6 +158,8 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused) drm_print_regset32(&p, &vc4_hdmi->ram_regset); drm_print_regset32(&p, &vc4_hdmi->rm_regset); + pm_runtime_put(&vc4_hdmi->pdev->dev); + drm_dev_exit(idx); return 0; -- GitLab From 6d5f76e0544b04ec5bdd2a09c19d90aeeb2cd479 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:41 +0100 Subject: [PATCH 093/970] drm/vc4: hvs: Fix dlist debug not resetting the next entry pointer The debug function to display the dlists didn't reset next_entry_start when starting each display, so resulting in not stopping the list at the correct place. Fixes: c6dac00340fc ("drm/vc4: hvs: Add debugfs node that dumps the current display lists") Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-18-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 8dab59341a82..bdc70b629054 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -110,7 +110,7 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_hvs *hvs = vc4->hvs; struct drm_printer p = drm_seq_file_printer(m); - unsigned int next_entry_start = 0; + unsigned int next_entry_start; unsigned int i, j; u32 dlist_word, dispstat; @@ -124,6 +124,7 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data) } drm_printf(&p, "HVS chan %u:\n", i); + next_entry_start = 0; for (j = HVS_READ(SCALER_DISPLISTX(i)); j < 256; j++) { dlist_word = readl((u32 __iomem *)vc4->hvs->dlist + j); -- GitLab From d285bb622ebdfaa84f51df3a1abccb87036157ea Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:42 +0100 Subject: [PATCH 094/970] drm/vc4: hvs: Remove incorrect limit from hvs_dlist debugfs function The debugfs function to dump dlists aborted at 256 bytes, when actually the dlist memory is generally significantly larger but varies based on SoC. We already have the correct limit in __vc4_hvs_alloc, so store it for use in the debugfs dlist function. Fixes: c6dac00340fc ("drm/vc4: hvs: Add debugfs node that dumps the current display lists") Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-19-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_hvs.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 717fd1140561..6908b36d5953 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -315,6 +315,7 @@ struct vc4_hvs { struct platform_device *pdev; void __iomem *regs; u32 __iomem *dlist; + unsigned int dlist_mem_size; struct clk *core_clk; diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index bdc70b629054..66163046986c 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -110,6 +110,7 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_hvs *hvs = vc4->hvs; struct drm_printer p = drm_seq_file_printer(m); + unsigned int dlist_mem_size = hvs->dlist_mem_size; unsigned int next_entry_start; unsigned int i, j; u32 dlist_word, dispstat; @@ -126,7 +127,7 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data) drm_printf(&p, "HVS chan %u:\n", i); next_entry_start = 0; - for (j = HVS_READ(SCALER_DISPLISTX(i)); j < 256; j++) { + for (j = HVS_READ(SCALER_DISPLISTX(i)); j < dlist_mem_size; j++) { dlist_word = readl((u32 __iomem *)vc4->hvs->dlist + j); drm_printf(&p, "dlist: %02d: 0x%08x\n", j, dlist_word); @@ -816,9 +817,10 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde * our 16K), since we don't want to scramble the screen when * transitioning from the firmware's boot setup to runtime. */ + hvs->dlist_mem_size = (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END; drm_mm_init(&hvs->dlist_mm, HVS_BOOTLOADER_DLIST_END, - (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END); + hvs->dlist_mem_size); /* Set up the HVS LBM memory manager. We could have some more * complicated data structure that allowed reuse of LBM areas -- GitLab From 1330d28d7529bf0ab84550053589afaa1ad0ecbb Mon Sep 17 00:00:00 2001 From: Dom Cobley <popcornmix@gmail.com> Date: Fri, 21 Jun 2024 16:20:43 +0100 Subject: [PATCH 095/970] drm/vc4: hvs: Remove ABORT_ON_EMPTY flag ABORT_ON_EMPTY chooses whether the HVS abandons the current frame when it experiences an underflow, or attempts to continue. In theory the frame should be black from the point of underflow, compared to a shift of sebsequent pixels to the left. Unfortunately it seems to put the HVS is a bad state where it is not possible to recover simply. This typically requires a reboot following the 'flip done timed out message'. Discussion with Broadcom has suggested we don't use this flag. All their testing is done with it disabled. Additionally setting BLANK_INSERT_EN causes the HDMI to output blank pixels on an underflow which avoids it losing sync. After this change a 'flip done timed out' due to sdram bandwidth starvation or too low a clock is recoverable once the situation improves. Signed-off-by: Dom Cobley <popcornmix@gmail.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-20-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hdmi.c | 1 + drivers/gpu/drm/vc4/vc4_regs.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 28792dfa8c55..c15372142ba0 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1598,6 +1598,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, VC4_HD_VID_CTL_CLRRGB | VC4_HD_VID_CTL_UNDERFLOW_ENABLE | VC4_HD_VID_CTL_FRAME_COUNTER_RESET | + VC4_HD_VID_CTL_BLANK_INSERT_EN | (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) | (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW)); diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 8ac9515554f8..c55dec383929 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -777,6 +777,7 @@ enum { # define VC4_HD_VID_CTL_CLRSYNC BIT(24) # define VC4_HD_VID_CTL_CLRRGB BIT(23) # define VC4_HD_VID_CTL_BLANKPIX BIT(18) +# define VC4_HD_VID_CTL_BLANK_INSERT_EN BIT(16) # define VC4_HD_CSC_CTL_ORDER_MASK VC4_MASK(7, 5) # define VC4_HD_CSC_CTL_ORDER_SHIFT 5 -- GitLab From 24c5ed3ddf27313b248900455b0312bd7a9d3554 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:44 +0100 Subject: [PATCH 096/970] drm/vc4: Introduce generation number enum With the introduction of the BCM2712 support, we will get yet another generation of display engine to support. The binary check of whether it's VC5 or not thus doesn't work anymore, especially since some parts of the driver will have changed with BCM2711, and some others with BCM2712. Let's introduce an enum to store the generation the driver is running on, which should provide more flexibility. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-21-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/tests/vc4_mock.c | 12 +++---- drivers/gpu/drm/vc4/vc4_bo.c | 28 +++++++-------- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++++--- drivers/gpu/drm/vc4/vc4_drv.c | 22 +++++++----- drivers/gpu/drm/vc4/vc4_drv.h | 7 +++- drivers/gpu/drm/vc4/vc4_gem.c | 24 ++++++------- drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- drivers/gpu/drm/vc4/vc4_hvs.c | 42 ++++++++++++---------- drivers/gpu/drm/vc4/vc4_irq.c | 10 +++--- drivers/gpu/drm/vc4/vc4_kms.c | 14 ++++---- drivers/gpu/drm/vc4/vc4_perfmon.c | 20 +++++------ drivers/gpu/drm/vc4/vc4_plane.c | 12 +++---- drivers/gpu/drm/vc4/vc4_render_cl.c | 2 +- drivers/gpu/drm/vc4/vc4_v3d.c | 10 +++--- drivers/gpu/drm/vc4/vc4_validate.c | 8 ++--- drivers/gpu/drm/vc4/vc4_validate_shaders.c | 2 +- 16 files changed, 121 insertions(+), 107 deletions(-) diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c index 0731a7d85d7a..922849dd4b47 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock.c +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c @@ -155,11 +155,11 @@ KUNIT_DEFINE_ACTION_WRAPPER(kunit_action_drm_dev_unregister, drm_dev_unregister, struct drm_device *); -static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5) +static struct vc4_dev *__mock_device(struct kunit *test, enum vc4_gen gen) { struct drm_device *drm; - const struct drm_driver *drv = is_vc5 ? &vc5_drm_driver : &vc4_drm_driver; - const struct vc4_mock_desc *desc = is_vc5 ? &vc5_mock : &vc4_mock; + const struct drm_driver *drv = (gen == VC4_GEN_5) ? &vc5_drm_driver : &vc4_drm_driver; + const struct vc4_mock_desc *desc = (gen == VC4_GEN_5) ? &vc5_mock : &vc4_mock; struct vc4_dev *vc4; struct device *dev; int ret; @@ -173,7 +173,7 @@ static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4); vc4->dev = dev; - vc4->is_vc5 = is_vc5; + vc4->gen = gen; vc4->hvs = __vc4_hvs_alloc(vc4, NULL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs); @@ -198,10 +198,10 @@ static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5) struct vc4_dev *vc4_mock_device(struct kunit *test) { - return __mock_device(test, false); + return __mock_device(test, VC4_GEN_4); } struct vc4_dev *vc5_mock_device(struct kunit *test) { - return __mock_device(test, true); + return __mock_device(test, VC4_GEN_5); } diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 3f72be7490d5..2a85d08b1985 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -251,7 +251,7 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo) { struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; mutex_lock(&vc4->purgeable.lock); @@ -265,7 +265,7 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct vc4_bo *bo) { struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; /* list_del_init() is used here because the caller might release @@ -396,7 +396,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return ERR_PTR(-ENODEV); bo = kzalloc(sizeof(*bo), GFP_KERNEL); @@ -427,7 +427,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, struct drm_gem_dma_object *dma_obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return ERR_PTR(-ENODEV); if (size == 0) @@ -496,7 +496,7 @@ int vc4_bo_dumb_create(struct drm_file *file_priv, struct vc4_bo *bo = NULL; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; ret = vc4_dumb_fixup_args(args); @@ -622,7 +622,7 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo) struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; /* Fast path: if the BO is already retained by someone, no need to @@ -661,7 +661,7 @@ void vc4_bo_dec_usecnt(struct vc4_bo *bo) { struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; /* Fast path: if the BO is still retained by someone, no need to test @@ -783,7 +783,7 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo = NULL; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; ret = vc4_grab_bin_bo(vc4, vc4file); @@ -813,7 +813,7 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, struct drm_vc4_mmap_bo *args = data; struct drm_gem_object *gem_obj; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; gem_obj = drm_gem_object_lookup(file_priv, args->handle); @@ -839,7 +839,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo = NULL; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (args->size == 0) @@ -918,7 +918,7 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo; bool t_format; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (args->flags != 0) @@ -964,7 +964,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gem_obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (args->flags != 0 || args->modifier != 0) @@ -1007,7 +1007,7 @@ int vc4_bo_cache_init(struct drm_device *dev) int ret; int i; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; /* Create the initial set of BO labels that the kernel will @@ -1071,7 +1071,7 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gem_obj; int ret = 0, label; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!args->len) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index ef5ad0ca4c2d..7220c4a62e12 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -264,7 +264,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format) * Removing 1 from the FIFO full level however * seems to completely remove that issue. */ - if (!vc4->is_vc5) + if (vc4->gen == VC4_GEN_4) return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1; return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX; @@ -429,7 +429,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode if (is_dsi) CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); - if (vc4->is_vc5) + if (vc4->gen == VC4_GEN_5) CRTC_WRITE(PV_MUX_CFG, VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP, PV_MUX_CFG_RGB_PIXEL_MUX_MODE)); @@ -921,7 +921,7 @@ static int vc4_async_set_fence_cb(struct drm_device *dev, struct dma_fence *fence; int ret; - if (!vc4->is_vc5) { + if (vc4->gen == VC4_GEN_4) { struct vc4_bo *bo = to_vc4_bo(&dma_bo->base); return vc4_queue_seqno_cb(dev, &flip_state->cb.seqno, bo->seqno, @@ -1008,7 +1008,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, struct vc4_bo *bo = to_vc4_bo(&dma_bo->base); int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; /* @@ -1051,7 +1051,7 @@ int vc4_page_flip(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); - if (vc4->is_vc5) + if (vc4->gen == VC4_GEN_5) return vc5_async_page_flip(crtc, fb, event, flags); else return vc4_async_page_flip(crtc, fb, event, flags); @@ -1346,9 +1346,8 @@ int __vc4_crtc_init(struct drm_device *drm, drm_crtc_helper_add(crtc, crtc_helper_funcs); - if (!vc4->is_vc5) { + if (vc4->gen == VC4_GEN_4) { drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); - drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size); /* We support CTM, but only for one CRTC at a time. It's therefore diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index c133e96b8aca..550324819f37 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -98,7 +98,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, if (args->pad != 0) return -EINVAL; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!vc4->v3d) @@ -147,7 +147,7 @@ static int vc4_open(struct drm_device *dev, struct drm_file *file) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_file *vc4file; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL); @@ -165,7 +165,7 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_file *vc4file = file->driver_priv; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; if (vc4file->bin_bo_used) @@ -291,13 +291,17 @@ static int vc4_drm_bind(struct device *dev) struct vc4_dev *vc4; struct device_node *node; struct drm_crtc *crtc; - bool is_vc5; + enum vc4_gen gen; int ret = 0; dev->coherent_dma_mask = DMA_BIT_MASK(32); - is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5"); - if (is_vc5) + if (of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5")) + gen = VC4_GEN_5; + else + gen = VC4_GEN_4; + + if (gen == VC4_GEN_5) driver = &vc5_drm_driver; else driver = &vc4_drm_driver; @@ -315,13 +319,13 @@ static int vc4_drm_bind(struct device *dev) vc4 = devm_drm_dev_alloc(dev, driver, struct vc4_dev, base); if (IS_ERR(vc4)) return PTR_ERR(vc4); - vc4->is_vc5 = is_vc5; + vc4->gen = gen; vc4->dev = dev; drm = &vc4->base; platform_set_drvdata(pdev, drm); - if (!is_vc5) { + if (gen == VC4_GEN_4) { ret = drmm_mutex_init(drm, &vc4->bin_bo_lock); if (ret) goto err; @@ -335,7 +339,7 @@ static int vc4_drm_bind(struct device *dev) if (ret) goto err; - if (!is_vc5) { + if (gen == VC4_GEN_4) { ret = vc4_gem_init(drm); if (ret) goto err; diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 6908b36d5953..294858d59e27 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -80,11 +80,16 @@ struct vc4_perfmon { u64 counters[] __counted_by(ncounters); }; +enum vc4_gen { + VC4_GEN_4, + VC4_GEN_5, +}; + struct vc4_dev { struct drm_device base; struct device *dev; - bool is_vc5; + enum vc4_gen gen; unsigned int irq; diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 24fb1b57e1dd..be9c0b72ebe8 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -76,7 +76,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, u32 i; int ret = 0; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!vc4->v3d) { @@ -389,7 +389,7 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, unsigned long timeout_expire; DEFINE_WAIT(wait); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (vc4->finished_seqno >= seqno) @@ -474,7 +474,7 @@ vc4_submit_next_bin_job(struct drm_device *dev) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_exec_info *exec; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; again: @@ -522,7 +522,7 @@ vc4_submit_next_render_job(struct drm_device *dev) if (!exec) return; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; /* A previous RCL may have written to one of our textures, and @@ -543,7 +543,7 @@ vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec) struct vc4_dev *vc4 = to_vc4_dev(dev); bool was_empty = list_empty(&vc4->render_job_list); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; list_move_tail(&exec->head, &vc4->render_job_list); @@ -970,7 +970,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) unsigned long irqflags; struct vc4_seqno_cb *cb, *cb_temp; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; spin_lock_irqsave(&vc4->job_lock, irqflags); @@ -1009,7 +1009,7 @@ int vc4_queue_seqno_cb(struct drm_device *dev, struct vc4_dev *vc4 = to_vc4_dev(dev); unsigned long irqflags; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; cb->func = func; @@ -1065,7 +1065,7 @@ vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_vc4_wait_seqno *args = data; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, @@ -1082,7 +1082,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gem_obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (args->pad != 0) @@ -1131,7 +1131,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, args->shader_rec_size, args->bo_handle_count); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!vc4->v3d) { @@ -1267,7 +1267,7 @@ int vc4_gem_init(struct drm_device *dev) struct vc4_dev *vc4 = to_vc4_dev(dev); int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; vc4->dma_fence_context = dma_fence_context_alloc(1); @@ -1326,7 +1326,7 @@ int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; switch (args->madv) { diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index c15372142ba0..62b82b1eeb36 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2110,7 +2110,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, VC4_HDMI_AUDIO_PACKET_CEA_MASK); /* Set the MAI threshold */ - if (vc4->is_vc5) + if (vc4->gen >= VC4_GEN_5) HDMI_WRITE(HDMI_MAI_THR, VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) | VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) | diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 66163046986c..4ca6587d5a55 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -224,7 +224,7 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs, if (!drm_dev_enter(drm, &idx)) return; - if (hvs->vc4->is_vc5) + if (hvs->vc4->gen == VC4_GEN_4) return; /* The LUT memory is laid out with each HVS channel in order, @@ -296,7 +296,7 @@ int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output) u32 reg; int ret; - if (!vc4->is_vc5) + if (vc4->gen == VC4_GEN_4) return output; /* @@ -377,7 +377,7 @@ static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, dispctrl = SCALER_DISPCTRLX_ENABLE; dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(chan)); - if (!vc4->is_vc5) { + if (vc4->gen == VC4_GEN_4) { dispctrl |= VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) | VC4_SET_FIELD(mode->vdisplay, @@ -399,7 +399,7 @@ static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE; HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx | - ((!vc4->is_vc5) ? SCALER_DISPBKGND_GAMMA : 0) | + ((vc4->gen == VC4_GEN_4) ? SCALER_DISPBKGND_GAMMA : 0) | (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); /* Reload the LUT, since the SRAMs would have been disabled if @@ -685,7 +685,8 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel) { - struct drm_device *drm = &hvs->vc4->base; + struct vc4_dev *vc4 = hvs->vc4; + struct drm_device *drm = &vc4->base; u32 dispctrl; int idx; @@ -693,8 +694,9 @@ void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel) return; dispctrl = HVS_READ(SCALER_DISPCTRL); - dispctrl &= ~(hvs->vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) : - SCALER_DISPCTRL_DSPEISLUR(channel)); + dispctrl &= ~((vc4->gen == VC4_GEN_5) ? + SCALER5_DISPCTRL_DSPEISLUR(channel) : + SCALER_DISPCTRL_DSPEISLUR(channel)); HVS_WRITE(SCALER_DISPCTRL, dispctrl); @@ -703,7 +705,8 @@ void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel) void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel) { - struct drm_device *drm = &hvs->vc4->base; + struct vc4_dev *vc4 = hvs->vc4; + struct drm_device *drm = &vc4->base; u32 dispctrl; int idx; @@ -711,8 +714,9 @@ void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel) return; dispctrl = HVS_READ(SCALER_DISPCTRL); - dispctrl |= (hvs->vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) : - SCALER_DISPCTRL_DSPEISLUR(channel)); + dispctrl |= ((vc4->gen == VC4_GEN_5) ? + SCALER5_DISPCTRL_DSPEISLUR(channel) : + SCALER_DISPCTRL_DSPEISLUR(channel)); HVS_WRITE(SCALER_DISPSTAT, SCALER_DISPSTAT_EUFLOW(channel)); @@ -755,8 +759,10 @@ static irqreturn_t vc4_hvs_irq_handler(int irq, void *data) control = HVS_READ(SCALER_DISPCTRL); for (channel = 0; channel < SCALER_CHANNELS_COUNT; channel++) { - dspeislur = vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) : - SCALER_DISPCTRL_DSPEISLUR(channel); + dspeislur = (vc4->gen == VC4_GEN_5) ? + SCALER5_DISPCTRL_DSPEISLUR(channel) : + SCALER_DISPCTRL_DSPEISLUR(channel); + /* Interrupt masking is not always honored, so check it here. */ if (status & SCALER_DISPSTAT_EUFLOW(channel) && control & dspeislur) { @@ -784,7 +790,7 @@ int vc4_hvs_debugfs_init(struct drm_minor *minor) if (!vc4->hvs) return -ENODEV; - if (!vc4->is_vc5) + if (vc4->gen == VC4_GEN_4) debugfs_create_bool("hvs_load_tracker", S_IRUGO | S_IWUSR, minor->debugfs_root, &vc4->load_tracker_enabled); @@ -827,7 +833,7 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde * between planes when they don't overlap on the screen, but * for now we just allocate globally. */ - if (!vc4->is_vc5) + if (vc4->gen == VC4_GEN_4) /* 48k words of 2x12-bit pixels */ drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024); else @@ -861,7 +867,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) hvs->regset.regs = hvs_regs; hvs->regset.nregs = ARRAY_SIZE(hvs_regs); - if (vc4->is_vc5) { + if (vc4->gen == VC4_GEN_5) { struct rpi_firmware *firmware; struct device_node *node; unsigned int max_rate; @@ -899,7 +905,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) } } - if (!vc4->is_vc5) + if (vc4->gen == VC4_GEN_4) hvs->dlist = hvs->regs + SCALER_DLIST_START; else hvs->dlist = hvs->regs + SCALER5_DLIST_START; @@ -940,7 +946,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) SCALER_DISPCTRL_DISPEIRQ(1) | SCALER_DISPCTRL_DISPEIRQ(2); - if (!vc4->is_vc5) + if (vc4->gen == VC4_GEN_4) dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ | SCALER_DISPCTRL_SLVWREIRQ | SCALER_DISPCTRL_SLVRDEIRQ | @@ -995,7 +1001,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) /* Recompute Composite Output Buffer (COB) allocations for the displays */ - if (!vc4->is_vc5) { + if (vc4->gen == VC4_GEN_4) { /* The COB is 20736 pixels, or just over 10 lines at 2048 wide. * The bottom 2048 pixels are full 32bpp RGBA (intended for the * TXP composing RGBA to memory), whilst the remainder are only diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index ef93d8e22a35..968356d1b91d 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c @@ -263,7 +263,7 @@ vc4_irq_enable(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; if (!vc4->v3d) @@ -280,7 +280,7 @@ vc4_irq_disable(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; if (!vc4->v3d) @@ -303,7 +303,7 @@ int vc4_irq_install(struct drm_device *dev, int irq) struct vc4_dev *vc4 = to_vc4_dev(dev); int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (irq == IRQ_NOTCONNECTED) @@ -324,7 +324,7 @@ void vc4_irq_uninstall(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; vc4_irq_disable(dev); @@ -337,7 +337,7 @@ void vc4_irq_reset(struct drm_device *dev) struct vc4_dev *vc4 = to_vc4_dev(dev); unsigned long irqflags; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; /* Acknowledge any stale IRQs. */ diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 5495f2a94fa9..bddfcad10950 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -369,7 +369,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) old_hvs_state->fifo_state[channel].pending_commit = NULL; } - if (vc4->is_vc5) { + if (vc4->gen == VC4_GEN_5) { unsigned long state_rate = max(old_hvs_state->core_clock_rate, new_hvs_state->core_clock_rate); unsigned long core_rate = clamp_t(unsigned long, state_rate, @@ -388,7 +388,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) vc4_ctm_commit(vc4, state); - if (vc4->is_vc5) + if (vc4->gen == VC4_GEN_5) vc5_hvs_pv_muxing_commit(vc4, state); else vc4_hvs_pv_muxing_commit(vc4, state); @@ -406,7 +406,7 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_helper_cleanup_planes(dev, state); - if (vc4->is_vc5) { + if (vc4->gen == VC4_GEN_5) { unsigned long core_rate = min_t(unsigned long, hvs->max_core_rate, new_hvs_state->core_clock_rate); @@ -461,7 +461,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_mode_fb_cmd2 mode_cmd_local; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return ERR_PTR(-ENODEV); /* If the user didn't specify a modifier, use the @@ -1040,7 +1040,7 @@ int vc4_kms_load(struct drm_device *dev) * the BCM2711, but the load tracker computations are used for * the core clock rate calculation. */ - if (!vc4->is_vc5) { + if (vc4->gen == VC4_GEN_4) { /* Start with the load tracker enabled. Can be * disabled through the debugfs load_tracker file. */ @@ -1056,7 +1056,7 @@ int vc4_kms_load(struct drm_device *dev) return ret; } - if (vc4->is_vc5) { + if (vc4->gen == VC4_GEN_5) { dev->mode_config.max_width = 7680; dev->mode_config.max_height = 7680; } else { @@ -1064,7 +1064,7 @@ int vc4_kms_load(struct drm_device *dev) dev->mode_config.max_height = 2048; } - dev->mode_config.funcs = vc4->is_vc5 ? &vc5_mode_funcs : &vc4_mode_funcs; + dev->mode_config.funcs = (vc4->gen > VC4_GEN_4) ? &vc5_mode_funcs : &vc4_mode_funcs; dev->mode_config.helper_private = &vc4_mode_config_helpers; dev->mode_config.preferred_depth = 24; dev->mode_config.async_page_flip = true; diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c index c4ac2c946238..31ee7ef80274 100644 --- a/drivers/gpu/drm/vc4/vc4_perfmon.c +++ b/drivers/gpu/drm/vc4/vc4_perfmon.c @@ -23,7 +23,7 @@ void vc4_perfmon_get(struct vc4_perfmon *perfmon) return; vc4 = perfmon->dev; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; refcount_inc(&perfmon->refcnt); @@ -37,7 +37,7 @@ void vc4_perfmon_put(struct vc4_perfmon *perfmon) return; vc4 = perfmon->dev; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; if (refcount_dec_and_test(&perfmon->refcnt)) @@ -49,7 +49,7 @@ void vc4_perfmon_start(struct vc4_dev *vc4, struct vc4_perfmon *perfmon) unsigned int i; u32 mask; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon)) @@ -69,7 +69,7 @@ void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon, { unsigned int i; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; if (WARN_ON_ONCE(!vc4->active_perfmon || @@ -90,7 +90,7 @@ struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) struct vc4_dev *vc4 = vc4file->dev; struct vc4_perfmon *perfmon; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return NULL; mutex_lock(&vc4file->perfmon.lock); @@ -105,7 +105,7 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) { struct vc4_dev *vc4 = vc4file->dev; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; mutex_init(&vc4file->perfmon.lock); @@ -126,7 +126,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file) { struct vc4_dev *vc4 = vc4file->dev; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; mutex_lock(&vc4file->perfmon.lock); @@ -146,7 +146,7 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, unsigned int i; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!vc4->v3d) { @@ -200,7 +200,7 @@ int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data, struct drm_vc4_perfmon_destroy *req = data; struct vc4_perfmon *perfmon; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!vc4->v3d) { @@ -228,7 +228,7 @@ int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, struct vc4_perfmon *perfmon; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (!vc4->v3d) { diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 4cd1721d2389..a61a29f02be0 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -647,10 +647,10 @@ static u32 vc4_lbm_size(struct drm_plane_state *state) } /* Align it to 64 or 128 (hvs5) bytes */ - lbm = roundup(lbm, vc4->is_vc5 ? 128 : 64); + lbm = roundup(lbm, vc4->gen == VC4_GEN_5 ? 128 : 64); /* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */ - lbm /= vc4->is_vc5 ? 4 : 2; + lbm /= vc4->gen == VC4_GEN_5 ? 4 : 2; return lbm; } @@ -772,7 +772,7 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, &vc4_state->lbm, lbm_size, - vc4->is_vc5 ? 64 : 32, + vc4->gen == VC4_GEN_5 ? 64 : 32, 0, 0); spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); @@ -1155,7 +1155,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE && fb->format->has_alpha; - if (!vc4->is_vc5) { + if (vc4->gen == VC4_GEN_4) { /* Control word */ vc4_dlist_write(vc4_state, SCALER_CTL0_VALID | @@ -1730,7 +1730,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, }; for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { - if (!hvs_formats[i].hvs5_only || vc4->is_vc5) { + if (!hvs_formats[i].hvs5_only || vc4->gen == VC4_GEN_5) { formats[num_formats] = hvs_formats[i].drm; num_formats++; } @@ -1745,7 +1745,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, return ERR_CAST(vc4_plane); plane = &vc4_plane->base; - if (vc4->is_vc5) + if (vc4->gen == VC4_GEN_5) drm_plane_helper_add(plane, &vc5_plane_helper_funcs); else drm_plane_helper_add(plane, &vc4_plane_helper_funcs); diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c index 1bda5010f15a..ae4ad956f04f 100644 --- a/drivers/gpu/drm/vc4/vc4_render_cl.c +++ b/drivers/gpu/drm/vc4/vc4_render_cl.c @@ -599,7 +599,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) bool has_bin = args->bin_cl_size != 0; int ret; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; if (args->min_x_tile > args->max_x_tile || diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index bf5c4e36c94e..43f69d74e876 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -127,7 +127,7 @@ static int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) int vc4_v3d_pm_get(struct vc4_dev *vc4) { - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; mutex_lock(&vc4->power_lock); @@ -148,7 +148,7 @@ vc4_v3d_pm_get(struct vc4_dev *vc4) void vc4_v3d_pm_put(struct vc4_dev *vc4) { - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; mutex_lock(&vc4->power_lock); @@ -178,7 +178,7 @@ int vc4_v3d_get_bin_slot(struct vc4_dev *vc4) uint64_t seqno = 0; struct vc4_exec_info *exec; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; try_again: @@ -325,7 +325,7 @@ int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used) { int ret = 0; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; mutex_lock(&vc4->bin_bo_lock); @@ -360,7 +360,7 @@ static void bin_bo_release(struct kref *ref) void vc4_v3d_bin_bo_put(struct vc4_dev *vc4) { - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return; mutex_lock(&vc4->bin_bo_lock); diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c index 0c17284bf6f5..f3d7fdbe9083 100644 --- a/drivers/gpu/drm/vc4/vc4_validate.c +++ b/drivers/gpu/drm/vc4/vc4_validate.c @@ -109,7 +109,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) struct drm_gem_dma_object *obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return NULL; if (hindex >= exec->bo_count) { @@ -169,7 +169,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_dma_object *fbo, uint32_t utile_w = utile_width(cpp); uint32_t utile_h = utile_height(cpp); - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return false; /* The shaded vertex format stores signed 12.4 fixed point @@ -495,7 +495,7 @@ vc4_validate_bin_cl(struct drm_device *dev, uint32_t dst_offset = 0; uint32_t src_offset = 0; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; while (src_offset < len) { @@ -942,7 +942,7 @@ vc4_validate_shader_recs(struct drm_device *dev, uint32_t i; int ret = 0; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return -ENODEV; for (i = 0; i < exec->shader_state_count; i++) { diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index 9745f8810eca..afb1a4d82684 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -786,7 +786,7 @@ vc4_validate_shader(struct drm_gem_dma_object *shader_obj) struct vc4_validated_shader_info *validated_shader = NULL; struct vc4_shader_validation_state validation_state; - if (WARN_ON_ONCE(vc4->is_vc5)) + if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) return NULL; memset(&validation_state, 0, sizeof(validation_state)); -- GitLab From dbe8ef676f2764f132d2467882e01e313eef495a Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:45 +0100 Subject: [PATCH 097/970] drm/vc4: Make v3d paths unavailable on any generation newer than vc4 The V3D IP has been separate since BCM2711, so let's make sure we issue a WARN if we're running not only on BCM2711, but also anything newer. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-22-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_bo.c | 28 +++++++++++----------- drivers/gpu/drm/vc4/vc4_crtc.c | 4 ++-- drivers/gpu/drm/vc4/vc4_drv.c | 8 +++---- drivers/gpu/drm/vc4/vc4_gem.c | 24 +++++++++---------- drivers/gpu/drm/vc4/vc4_irq.c | 10 ++++---- drivers/gpu/drm/vc4/vc4_kms.c | 2 +- drivers/gpu/drm/vc4/vc4_perfmon.c | 20 ++++++++-------- drivers/gpu/drm/vc4/vc4_render_cl.c | 2 +- drivers/gpu/drm/vc4/vc4_v3d.c | 10 ++++---- drivers/gpu/drm/vc4/vc4_validate.c | 8 +++---- drivers/gpu/drm/vc4/vc4_validate_shaders.c | 2 +- 11 files changed, 59 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 2a85d08b1985..fb450b6a4d44 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -251,7 +251,7 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo) { struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; mutex_lock(&vc4->purgeable.lock); @@ -265,7 +265,7 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct vc4_bo *bo) { struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; /* list_del_init() is used here because the caller might release @@ -396,7 +396,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return ERR_PTR(-ENODEV); bo = kzalloc(sizeof(*bo), GFP_KERNEL); @@ -427,7 +427,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, struct drm_gem_dma_object *dma_obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return ERR_PTR(-ENODEV); if (size == 0) @@ -496,7 +496,7 @@ int vc4_bo_dumb_create(struct drm_file *file_priv, struct vc4_bo *bo = NULL; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; ret = vc4_dumb_fixup_args(args); @@ -622,7 +622,7 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo) struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; /* Fast path: if the BO is already retained by someone, no need to @@ -661,7 +661,7 @@ void vc4_bo_dec_usecnt(struct vc4_bo *bo) { struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; /* Fast path: if the BO is still retained by someone, no need to test @@ -783,7 +783,7 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo = NULL; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; ret = vc4_grab_bin_bo(vc4, vc4file); @@ -813,7 +813,7 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, struct drm_vc4_mmap_bo *args = data; struct drm_gem_object *gem_obj; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; gem_obj = drm_gem_object_lookup(file_priv, args->handle); @@ -839,7 +839,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo = NULL; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (args->size == 0) @@ -918,7 +918,7 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo; bool t_format; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (args->flags != 0) @@ -964,7 +964,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gem_obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (args->flags != 0 || args->modifier != 0) @@ -1007,7 +1007,7 @@ int vc4_bo_cache_init(struct drm_device *dev) int ret; int i; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; /* Create the initial set of BO labels that the kernel will @@ -1071,7 +1071,7 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gem_obj; int ret = 0, label; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!args->len) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 7220c4a62e12..575900ee67a5 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1008,7 +1008,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, struct vc4_bo *bo = to_vc4_bo(&dma_bo->base); int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; /* @@ -1051,7 +1051,7 @@ int vc4_page_flip(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); - if (vc4->gen == VC4_GEN_5) + if (vc4->gen > VC4_GEN_4) return vc5_async_page_flip(crtc, fb, event, flags); else return vc4_async_page_flip(crtc, fb, event, flags); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 550324819f37..8c104ace3dc6 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -98,7 +98,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, if (args->pad != 0) return -EINVAL; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!vc4->v3d) @@ -147,7 +147,7 @@ static int vc4_open(struct drm_device *dev, struct drm_file *file) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_file *vc4file; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL); @@ -165,7 +165,7 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_file *vc4file = file->driver_priv; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; if (vc4file->bin_bo_used) @@ -301,7 +301,7 @@ static int vc4_drm_bind(struct device *dev) else gen = VC4_GEN_4; - if (gen == VC4_GEN_5) + if (gen > VC4_GEN_4) driver = &vc5_drm_driver; else driver = &vc4_drm_driver; diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index be9c0b72ebe8..22bccd69eb62 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -76,7 +76,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, u32 i; int ret = 0; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!vc4->v3d) { @@ -389,7 +389,7 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns, unsigned long timeout_expire; DEFINE_WAIT(wait); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (vc4->finished_seqno >= seqno) @@ -474,7 +474,7 @@ vc4_submit_next_bin_job(struct drm_device *dev) struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_exec_info *exec; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; again: @@ -522,7 +522,7 @@ vc4_submit_next_render_job(struct drm_device *dev) if (!exec) return; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; /* A previous RCL may have written to one of our textures, and @@ -543,7 +543,7 @@ vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec) struct vc4_dev *vc4 = to_vc4_dev(dev); bool was_empty = list_empty(&vc4->render_job_list); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; list_move_tail(&exec->head, &vc4->render_job_list); @@ -970,7 +970,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) unsigned long irqflags; struct vc4_seqno_cb *cb, *cb_temp; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; spin_lock_irqsave(&vc4->job_lock, irqflags); @@ -1009,7 +1009,7 @@ int vc4_queue_seqno_cb(struct drm_device *dev, struct vc4_dev *vc4 = to_vc4_dev(dev); unsigned long irqflags; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; cb->func = func; @@ -1065,7 +1065,7 @@ vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_vc4_wait_seqno *args = data; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno, @@ -1082,7 +1082,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gem_obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (args->pad != 0) @@ -1131,7 +1131,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, args->shader_rec_size, args->bo_handle_count); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!vc4->v3d) { @@ -1267,7 +1267,7 @@ int vc4_gem_init(struct drm_device *dev) struct vc4_dev *vc4 = to_vc4_dev(dev); int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; vc4->dma_fence_context = dma_fence_context_alloc(1); @@ -1326,7 +1326,7 @@ int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data, struct vc4_bo *bo; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; switch (args->madv) { diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c index 968356d1b91d..69b399f3b802 100644 --- a/drivers/gpu/drm/vc4/vc4_irq.c +++ b/drivers/gpu/drm/vc4/vc4_irq.c @@ -263,7 +263,7 @@ vc4_irq_enable(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; if (!vc4->v3d) @@ -280,7 +280,7 @@ vc4_irq_disable(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; if (!vc4->v3d) @@ -303,7 +303,7 @@ int vc4_irq_install(struct drm_device *dev, int irq) struct vc4_dev *vc4 = to_vc4_dev(dev); int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (irq == IRQ_NOTCONNECTED) @@ -324,7 +324,7 @@ void vc4_irq_uninstall(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; vc4_irq_disable(dev); @@ -337,7 +337,7 @@ void vc4_irq_reset(struct drm_device *dev) struct vc4_dev *vc4 = to_vc4_dev(dev); unsigned long irqflags; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; /* Acknowledge any stale IRQs. */ diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index bddfcad10950..58bbb9efc2df 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -461,7 +461,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_mode_fb_cmd2 mode_cmd_local; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return ERR_PTR(-ENODEV); /* If the user didn't specify a modifier, use the diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c index 31ee7ef80274..4cd3643c3ba7 100644 --- a/drivers/gpu/drm/vc4/vc4_perfmon.c +++ b/drivers/gpu/drm/vc4/vc4_perfmon.c @@ -23,7 +23,7 @@ void vc4_perfmon_get(struct vc4_perfmon *perfmon) return; vc4 = perfmon->dev; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; refcount_inc(&perfmon->refcnt); @@ -37,7 +37,7 @@ void vc4_perfmon_put(struct vc4_perfmon *perfmon) return; vc4 = perfmon->dev; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; if (refcount_dec_and_test(&perfmon->refcnt)) @@ -49,7 +49,7 @@ void vc4_perfmon_start(struct vc4_dev *vc4, struct vc4_perfmon *perfmon) unsigned int i; u32 mask; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon)) @@ -69,7 +69,7 @@ void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon, { unsigned int i; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; if (WARN_ON_ONCE(!vc4->active_perfmon || @@ -90,7 +90,7 @@ struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id) struct vc4_dev *vc4 = vc4file->dev; struct vc4_perfmon *perfmon; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return NULL; mutex_lock(&vc4file->perfmon.lock); @@ -105,7 +105,7 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) { struct vc4_dev *vc4 = vc4file->dev; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; mutex_init(&vc4file->perfmon.lock); @@ -126,7 +126,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file) { struct vc4_dev *vc4 = vc4file->dev; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; mutex_lock(&vc4file->perfmon.lock); @@ -146,7 +146,7 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, unsigned int i; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!vc4->v3d) { @@ -200,7 +200,7 @@ int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data, struct drm_vc4_perfmon_destroy *req = data; struct vc4_perfmon *perfmon; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!vc4->v3d) { @@ -228,7 +228,7 @@ int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, struct vc4_perfmon *perfmon; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (!vc4->v3d) { diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c index ae4ad956f04f..14079853338e 100644 --- a/drivers/gpu/drm/vc4/vc4_render_cl.c +++ b/drivers/gpu/drm/vc4/vc4_render_cl.c @@ -599,7 +599,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec) bool has_bin = args->bin_cl_size != 0; int ret; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; if (args->min_x_tile > args->max_x_tile || diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index 43f69d74e876..2423826c89eb 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -127,7 +127,7 @@ static int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused) int vc4_v3d_pm_get(struct vc4_dev *vc4) { - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; mutex_lock(&vc4->power_lock); @@ -148,7 +148,7 @@ vc4_v3d_pm_get(struct vc4_dev *vc4) void vc4_v3d_pm_put(struct vc4_dev *vc4) { - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; mutex_lock(&vc4->power_lock); @@ -178,7 +178,7 @@ int vc4_v3d_get_bin_slot(struct vc4_dev *vc4) uint64_t seqno = 0; struct vc4_exec_info *exec; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; try_again: @@ -325,7 +325,7 @@ int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used) { int ret = 0; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; mutex_lock(&vc4->bin_bo_lock); @@ -360,7 +360,7 @@ static void bin_bo_release(struct kref *ref) void vc4_v3d_bin_bo_put(struct vc4_dev *vc4) { - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return; mutex_lock(&vc4->bin_bo_lock); diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c index f3d7fdbe9083..5bf134968ade 100644 --- a/drivers/gpu/drm/vc4/vc4_validate.c +++ b/drivers/gpu/drm/vc4/vc4_validate.c @@ -109,7 +109,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) struct drm_gem_dma_object *obj; struct vc4_bo *bo; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return NULL; if (hindex >= exec->bo_count) { @@ -169,7 +169,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_dma_object *fbo, uint32_t utile_w = utile_width(cpp); uint32_t utile_h = utile_height(cpp); - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return false; /* The shaded vertex format stores signed 12.4 fixed point @@ -495,7 +495,7 @@ vc4_validate_bin_cl(struct drm_device *dev, uint32_t dst_offset = 0; uint32_t src_offset = 0; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; while (src_offset < len) { @@ -942,7 +942,7 @@ vc4_validate_shader_recs(struct drm_device *dev, uint32_t i; int ret = 0; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; for (i = 0; i < exec->shader_state_count; i++) { diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index afb1a4d82684..2d74e786914c 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -786,7 +786,7 @@ vc4_validate_shader(struct drm_gem_dma_object *shader_obj) struct vc4_validated_shader_info *validated_shader = NULL; struct vc4_shader_validation_state validation_state; - if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5)) + if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return NULL; memset(&validation_state, 0, sizeof(validation_state)); -- GitLab From c157ff40a485f8adecd874c3df5fbf2f8bf00d9b Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:46 +0100 Subject: [PATCH 098/970] drm/vc4: hvs: Use switch statement to simplify vc4_hvs_get_fifo_from_output Since we'll support BCM2712 soon, let's move the logic behind vc4_hvs_get_fifo_from_output() to a switch to extend it more easily. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-23-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 77 +++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 4ca6587d5a55..bf0e59de04d4 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -296,53 +296,60 @@ int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output) u32 reg; int ret; - if (vc4->gen == VC4_GEN_4) + switch (vc4->gen) { + case VC4_GEN_4: return output; - /* - * NOTE: We should probably use drm_dev_enter()/drm_dev_exit() - * here, but this function is only used during the DRM device - * initialization, so we should be fine. - */ + case VC4_GEN_5: + /* + * NOTE: We should probably use + * drm_dev_enter()/drm_dev_exit() here, but this + * function is only used during the DRM device + * initialization, so we should be fine. + */ - switch (output) { - case 0: - return 0; + switch (output) { + case 0: + return 0; - case 1: - return 1; + case 1: + return 1; - case 2: - reg = HVS_READ(SCALER_DISPECTRL); - ret = FIELD_GET(SCALER_DISPECTRL_DSP2_MUX_MASK, reg); - if (ret == 0) - return 2; + case 2: + reg = HVS_READ(SCALER_DISPECTRL); + ret = FIELD_GET(SCALER_DISPECTRL_DSP2_MUX_MASK, reg); + if (ret == 0) + return 2; - return 0; + return 0; - case 3: - reg = HVS_READ(SCALER_DISPCTRL); - ret = FIELD_GET(SCALER_DISPCTRL_DSP3_MUX_MASK, reg); - if (ret == 3) - return -EPIPE; + case 3: + reg = HVS_READ(SCALER_DISPCTRL); + ret = FIELD_GET(SCALER_DISPCTRL_DSP3_MUX_MASK, reg); + if (ret == 3) + return -EPIPE; - return ret; + return ret; - case 4: - reg = HVS_READ(SCALER_DISPEOLN); - ret = FIELD_GET(SCALER_DISPEOLN_DSP4_MUX_MASK, reg); - if (ret == 3) - return -EPIPE; + case 4: + reg = HVS_READ(SCALER_DISPEOLN); + ret = FIELD_GET(SCALER_DISPEOLN_DSP4_MUX_MASK, reg); + if (ret == 3) + return -EPIPE; - return ret; + return ret; - case 5: - reg = HVS_READ(SCALER_DISPDITHER); - ret = FIELD_GET(SCALER_DISPDITHER_DSP5_MUX_MASK, reg); - if (ret == 3) - return -EPIPE; + case 5: + reg = HVS_READ(SCALER_DISPDITHER); + ret = FIELD_GET(SCALER_DISPDITHER_DSP5_MUX_MASK, reg); + if (ret == 3) + return -EPIPE; - return ret; + return ret; + + default: + return -EPIPE; + } default: return -EPIPE; -- GitLab From 2fa4ef5fb9433b7b43d76433201f394728803681 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:47 +0100 Subject: [PATCH 099/970] drm/vc4: hvs: Create hw_init function Since the BCM2712 will feature a significantly different HVS, let's move the hardware initialisation part of our bind function into a separate function. That way, it will be easier to extend in the future. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-24-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 155 ++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index bf0e59de04d4..041f3ba23757 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -852,79 +852,10 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde return hvs; } -static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) +static int vc4_hvs_hw_init(struct vc4_hvs *hvs) { - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = to_vc4_dev(drm); - struct vc4_hvs *hvs = NULL; - int ret; - u32 dispctrl; - u32 reg, top; - - hvs = __vc4_hvs_alloc(vc4, NULL); - if (IS_ERR(hvs)) - return PTR_ERR(hvs); - - hvs->regs = vc4_ioremap_regs(pdev, 0); - if (IS_ERR(hvs->regs)) - return PTR_ERR(hvs->regs); - - hvs->regset.base = hvs->regs; - hvs->regset.regs = hvs_regs; - hvs->regset.nregs = ARRAY_SIZE(hvs_regs); - - if (vc4->gen == VC4_GEN_5) { - struct rpi_firmware *firmware; - struct device_node *node; - unsigned int max_rate; - - node = rpi_firmware_find_node(); - if (!node) - return -EINVAL; - - firmware = rpi_firmware_get(node); - of_node_put(node); - if (!firmware) - return -EPROBE_DEFER; - - hvs->core_clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(hvs->core_clk)) { - dev_err(&pdev->dev, "Couldn't get core clock\n"); - return PTR_ERR(hvs->core_clk); - } - - max_rate = rpi_firmware_clk_get_max_rate(firmware, - RPI_FIRMWARE_CORE_CLK_ID); - rpi_firmware_put(firmware); - if (max_rate >= 550000000) - hvs->vc5_hdmi_enable_hdmi_20 = true; - - if (max_rate >= 600000000) - hvs->vc5_hdmi_enable_4096by2160 = true; - - hvs->max_core_rate = max_rate; - - ret = clk_prepare_enable(hvs->core_clk); - if (ret) { - dev_err(&pdev->dev, "Couldn't enable the core clock\n"); - return ret; - } - } - - if (vc4->gen == VC4_GEN_4) - hvs->dlist = hvs->regs + SCALER_DLIST_START; - else - hvs->dlist = hvs->regs + SCALER5_DLIST_START; - - /* Upload filter kernels. We only have the one for now, so we - * keep it around for the lifetime of the driver. - */ - ret = vc4_hvs_upload_linear_kernel(hvs, - &hvs->mitchell_netravali_filter, - mitchell_netravali_1_3_1_3_kernel); - if (ret) - return ret; + struct vc4_dev *vc4 = hvs->vc4; + u32 dispctrl, reg; reg = HVS_READ(SCALER_DISPECTRL); reg &= ~SCALER_DISPECTRL_DSP2_MUX_MASK; @@ -1006,6 +937,86 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) HVS_WRITE(SCALER_DISPCTRL, dispctrl); + return 0; +} + +static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct drm_device *drm = dev_get_drvdata(master); + struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_hvs *hvs = NULL; + int ret; + u32 reg, top; + + hvs = __vc4_hvs_alloc(vc4, NULL); + if (IS_ERR(hvs)) + return PTR_ERR(hvs); + + hvs->regs = vc4_ioremap_regs(pdev, 0); + if (IS_ERR(hvs->regs)) + return PTR_ERR(hvs->regs); + + hvs->regset.base = hvs->regs; + hvs->regset.regs = hvs_regs; + hvs->regset.nregs = ARRAY_SIZE(hvs_regs); + + if (vc4->gen == VC4_GEN_5) { + struct rpi_firmware *firmware; + struct device_node *node; + unsigned int max_rate; + + node = rpi_firmware_find_node(); + if (!node) + return -EINVAL; + + firmware = rpi_firmware_get(node); + of_node_put(node); + if (!firmware) + return -EPROBE_DEFER; + + hvs->core_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(hvs->core_clk)) { + dev_err(&pdev->dev, "Couldn't get core clock\n"); + return PTR_ERR(hvs->core_clk); + } + + max_rate = rpi_firmware_clk_get_max_rate(firmware, + RPI_FIRMWARE_CORE_CLK_ID); + rpi_firmware_put(firmware); + if (max_rate >= 550000000) + hvs->vc5_hdmi_enable_hdmi_20 = true; + + if (max_rate >= 600000000) + hvs->vc5_hdmi_enable_4096by2160 = true; + + hvs->max_core_rate = max_rate; + + ret = clk_prepare_enable(hvs->core_clk); + if (ret) { + dev_err(&pdev->dev, "Couldn't enable the core clock\n"); + return ret; + } + } + + if (vc4->gen == VC4_GEN_4) + hvs->dlist = hvs->regs + SCALER_DLIST_START; + else + hvs->dlist = hvs->regs + SCALER5_DLIST_START; + + /* Upload filter kernels. We only have the one for now, so we + * keep it around for the lifetime of the driver. + */ + ret = vc4_hvs_upload_linear_kernel(hvs, + &hvs->mitchell_netravali_filter, + mitchell_netravali_1_3_1_3_kernel); + if (ret) + return ret; + + ret = vc4_hvs_hw_init(hvs); + if (ret) + return ret; + /* Recompute Composite Output Buffer (COB) allocations for the displays */ if (vc4->gen == VC4_GEN_4) { -- GitLab From 808f4055a10685664237a4771d6f579ea263edc1 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:48 +0100 Subject: [PATCH 100/970] drm/vc4: hvs: Create cob_init function Just like the HVS itself, the COB parameters will be fairly different in the BCM2712. Let's move the COB parameters computation and its initialisation to a separate function that will be easier to extend in the future. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-25-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 128 ++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 041f3ba23757..5bda9525cffe 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -940,6 +940,77 @@ static int vc4_hvs_hw_init(struct vc4_hvs *hvs) return 0; } +static int vc4_hvs_cob_init(struct vc4_hvs *hvs) +{ + struct vc4_dev *vc4 = hvs->vc4; + u32 reg, top; + + /* + * Recompute Composite Output Buffer (COB) allocations for the + * displays + */ + switch (vc4->gen) { + case VC4_GEN_4: + /* The COB is 20736 pixels, or just over 10 lines at 2048 wide. + * The bottom 2048 pixels are full 32bpp RGBA (intended for the + * TXP composing RGBA to memory), whilst the remainder are only + * 24bpp RGB. + * + * Assign 3 lines to channels 1 & 2, and just over 4 lines to + * channel 0. + */ + #define VC4_COB_SIZE 20736 + #define VC4_COB_LINE_WIDTH 2048 + #define VC4_COB_NUM_LINES 3 + reg = 0; + top = VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES; + reg |= (top - 1) << 16; + HVS_WRITE(SCALER_DISPBASE2, reg); + reg = top; + top += VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES; + reg |= (top - 1) << 16; + HVS_WRITE(SCALER_DISPBASE1, reg); + reg = top; + top = VC4_COB_SIZE; + reg |= (top - 1) << 16; + HVS_WRITE(SCALER_DISPBASE0, reg); + break; + + case VC4_GEN_5: + /* The COB is 44416 pixels, or 10.8 lines at 4096 wide. + * The bottom 4096 pixels are full RGBA (intended for the TXP + * composing RGBA to memory), whilst the remainder are only + * RGB. Addressing is always pixel wide. + * + * Assign 3 lines of 4096 to channels 1 & 2, and just over 4 + * lines. to channel 0. + */ + #define VC5_COB_SIZE 44416 + #define VC5_COB_LINE_WIDTH 4096 + #define VC5_COB_NUM_LINES 3 + reg = 0; + top = VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES; + reg |= top << 16; + HVS_WRITE(SCALER_DISPBASE2, reg); + top += 16; + reg = top; + top += VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES; + reg |= top << 16; + HVS_WRITE(SCALER_DISPBASE1, reg); + top += 16; + reg = top; + top = VC5_COB_SIZE; + reg |= top << 16; + HVS_WRITE(SCALER_DISPBASE0, reg); + break; + + default: + return -EINVAL; + } + + return 0; +} + static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); @@ -947,7 +1018,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_hvs *hvs = NULL; int ret; - u32 reg, top; hvs = __vc4_hvs_alloc(vc4, NULL); if (IS_ERR(hvs)) @@ -1017,59 +1087,9 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - /* Recompute Composite Output Buffer (COB) allocations for the displays - */ - if (vc4->gen == VC4_GEN_4) { - /* The COB is 20736 pixels, or just over 10 lines at 2048 wide. - * The bottom 2048 pixels are full 32bpp RGBA (intended for the - * TXP composing RGBA to memory), whilst the remainder are only - * 24bpp RGB. - * - * Assign 3 lines to channels 1 & 2, and just over 4 lines to - * channel 0. - */ - #define VC4_COB_SIZE 20736 - #define VC4_COB_LINE_WIDTH 2048 - #define VC4_COB_NUM_LINES 3 - reg = 0; - top = VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES; - reg |= (top - 1) << 16; - HVS_WRITE(SCALER_DISPBASE2, reg); - reg = top; - top += VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES; - reg |= (top - 1) << 16; - HVS_WRITE(SCALER_DISPBASE1, reg); - reg = top; - top = VC4_COB_SIZE; - reg |= (top - 1) << 16; - HVS_WRITE(SCALER_DISPBASE0, reg); - } else { - /* The COB is 44416 pixels, or 10.8 lines at 4096 wide. - * The bottom 4096 pixels are full RGBA (intended for the TXP - * composing RGBA to memory), whilst the remainder are only - * RGB. Addressing is always pixel wide. - * - * Assign 3 lines of 4096 to channels 1 & 2, and just over 4 - * lines. to channel 0. - */ - #define VC5_COB_SIZE 44416 - #define VC5_COB_LINE_WIDTH 4096 - #define VC5_COB_NUM_LINES 3 - reg = 0; - top = VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES; - reg |= top << 16; - HVS_WRITE(SCALER_DISPBASE2, reg); - top += 16; - reg = top; - top += VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES; - reg |= top << 16; - HVS_WRITE(SCALER_DISPBASE1, reg); - top += 16; - reg = top; - top = VC5_COB_SIZE; - reg |= top << 16; - HVS_WRITE(SCALER_DISPBASE0, reg); - } + ret = vc4_hvs_cob_init(hvs); + if (ret) + return ret; ret = devm_request_irq(dev, platform_get_irq(pdev, 0), vc4_hvs_irq_handler, 0, "vc4 hvs", drm); -- GitLab From 295fbb059f4abbcc69bd3640de23fe0e058e2444 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:49 +0100 Subject: [PATCH 101/970] drm/vc4: hvs: Rename hvs_regs list The HVS register set has been heavily modified in the BCM2712, and we'll thus need a separate debugfs_reg32 array for it. The name hvs_regs is thus a bit too generic, so let's rename it to something more specific. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-26-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 5bda9525cffe..ecba1f7bc1e0 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -33,7 +33,7 @@ #include "vc4_drv.h" #include "vc4_regs.h" -static const struct debugfs_reg32 hvs_regs[] = { +static const struct debugfs_reg32 vc4_hvs_regs[] = { VC4_REG32(SCALER_DISPCTRL), VC4_REG32(SCALER_DISPSTAT), VC4_REG32(SCALER_DISPID), @@ -1028,8 +1028,8 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(hvs->regs); hvs->regset.base = hvs->regs; - hvs->regset.regs = hvs_regs; - hvs->regset.nregs = ARRAY_SIZE(hvs_regs); + hvs->regset.regs = vc4_hvs_regs; + hvs->regset.nregs = ARRAY_SIZE(vc4_hvs_regs); if (vc4->gen == VC4_GEN_5) { struct rpi_firmware *firmware; -- GitLab From efbc7b9c21f244b7374a5cbb23fb8206cfb46f56 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:50 +0100 Subject: [PATCH 102/970] drm/vc4: plane: Change ptr0_offset to an array The BCM2712 will have a fairly different dlist, that will feature one Pointer 0 word for each plane. Let's prepare by changing the ptr0_offset variable that holds the offset in a dlist of the pointer 0 word to an array. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-27-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_drv.h | 3 ++- drivers/gpu/drm/vc4/vc4_plane.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 294858d59e27..559118824bf7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -15,6 +15,7 @@ #include <drm/drm_debugfs.h> #include <drm/drm_device.h> #include <drm/drm_encoder.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_managed.h> #include <drm/drm_mm.h> @@ -400,7 +401,7 @@ struct vc4_plane_state { */ u32 pos0_offset; u32 pos2_offset; - u32 ptr0_offset; + u32 ptr0_offset[DRM_FORMAT_MAX_PLANES]; u32 lbm_offset; /* Offset where the plane's dlist was last stored in the diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index a61a29f02be0..a4965226595d 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -1256,7 +1256,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * * The pointers may be any byte address. */ - vc4_state->ptr0_offset = vc4_state->dlist_count; + vc4_state->ptr0_offset[0] = vc4_state->dlist_count; for (i = 0; i < num_planes; i++) vc4_dlist_write(vc4_state, vc4_state->offsets[i]); @@ -1460,13 +1460,13 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) * scanout will start from this address as soon as the FIFO * needs to refill with pixels. */ - writel(addr, &vc4_state->hw_dlist[vc4_state->ptr0_offset]); + writel(addr, &vc4_state->hw_dlist[vc4_state->ptr0_offset[0]]); /* Also update the CPU-side dlist copy, so that any later * atomic updates that don't do a new modeset on our plane * also use our updated address. */ - vc4_state->dlist[vc4_state->ptr0_offset] = addr; + vc4_state->dlist[vc4_state->ptr0_offset[0]] = addr; drm_dev_exit(idx); } @@ -1530,8 +1530,8 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, new_vc4_state->dlist[vc4_state->pos0_offset]; vc4_state->dlist[vc4_state->pos2_offset] = new_vc4_state->dlist[vc4_state->pos2_offset]; - vc4_state->dlist[vc4_state->ptr0_offset] = - new_vc4_state->dlist[vc4_state->ptr0_offset]; + vc4_state->dlist[vc4_state->ptr0_offset[0]] = + new_vc4_state->dlist[vc4_state->ptr0_offset[0]]; /* Note that we can't just call vc4_plane_write_dlist() * because that would smash the context data that the HVS is @@ -1541,8 +1541,8 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, &vc4_state->hw_dlist[vc4_state->pos0_offset]); writel(vc4_state->dlist[vc4_state->pos2_offset], &vc4_state->hw_dlist[vc4_state->pos2_offset]); - writel(vc4_state->dlist[vc4_state->ptr0_offset], - &vc4_state->hw_dlist[vc4_state->ptr0_offset]); + writel(vc4_state->dlist[vc4_state->ptr0_offset[0]], + &vc4_state->hw_dlist[vc4_state->ptr0_offset[0]]); drm_dev_exit(idx); } @@ -1569,7 +1569,7 @@ static int vc4_plane_atomic_async_check(struct drm_plane *plane, 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 || + old_vc4_state->ptr0_offset[0] != new_vc4_state->ptr0_offset[0] || vc4_lbm_size(plane->state) != vc4_lbm_size(new_plane_state)) return -EINVAL; @@ -1579,7 +1579,7 @@ static int vc4_plane_atomic_async_check(struct drm_plane *plane, for (i = 0; i < new_vc4_state->dlist_count; i++) { if (i == new_vc4_state->pos0_offset || i == new_vc4_state->pos2_offset || - i == new_vc4_state->ptr0_offset || + i == new_vc4_state->ptr0_offset[0] || (new_vc4_state->lbm_offset && i == new_vc4_state->lbm_offset)) continue; -- GitLab From 74c3b7c63b5e718a97881f8d80bef02f8a94a2b2 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:51 +0100 Subject: [PATCH 103/970] drm/vc4: hvs: Rework LBM alignment With the introduction of the support for BCM2712, the check of whether we're running on vc5 or not to compute the LBM alignment requirement doesn't work anymore. Moreover, the LBM size will need to be computed in words for the BCM2712, while we've had sizes in bytes so far. Aligning on either 64 or 32 words is thus fairly harmful on BCM2712, so let's just explicitly align the size when needed, and then call drm_mm_insert_node_generic() with an alignment of 1. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-28-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_plane.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index a4965226595d..4c61ef4f4142 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -756,6 +756,11 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) if (!lbm_size) return 0; + if (vc4->gen == VC4_GEN_5) + lbm_size = ALIGN(lbm_size, 64); + else if (vc4->gen == VC4_GEN_4) + lbm_size = ALIGN(lbm_size, 32); + drm_dbg_driver(drm, "[PLANE:%d:%s] LBM Allocation Size: %u\n", plane->base.id, plane->name, lbm_size); @@ -771,8 +776,7 @@ static int vc4_plane_allocate_lbm(struct drm_plane_state *state) spin_lock_irqsave(&vc4->hvs->mm_lock, irqflags); ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm, &vc4_state->lbm, - lbm_size, - vc4->gen == VC4_GEN_5 ? 64 : 32, + lbm_size, 1, 0, 0); spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags); -- GitLab From 7621db4d40217e6309a4c747a0c3e9a22a742337 Mon Sep 17 00:00:00 2001 From: Maxime Ripard <mripard@kernel.org> Date: Fri, 21 Jun 2024 16:20:52 +0100 Subject: [PATCH 104/970] drm/vc4: hvs: Change prototype of __vc4_hvs_alloc to pass registers The BCM2712 HVS has registers to report the size of the various SRAM the driver uses, and their size actually differ depending on the stepping. The initialisation of the memory pools happen in the __vc4_hvs_alloc() function that also allocates the main HVS structure, that will then hold the pointer to the memory mapping of the registers. This creates some kind of circular dependency that we can break by passing the mapping pointer as an argument for __vc4_hvs_alloc() to use to query to get the SRAM sizes and initialise the memory pools accordingly. Signed-off-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-29-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/tests/vc4_mock.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 4 +++- drivers/gpu/drm/vc4/vc4_hvs.c | 16 ++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c index 922849dd4b47..6527fb1db71e 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock.c +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c @@ -175,7 +175,7 @@ static struct vc4_dev *__mock_device(struct kunit *test, enum vc4_gen gen) vc4->dev = dev; vc4->gen = gen; - vc4->hvs = __vc4_hvs_alloc(vc4, NULL); + vc4->hvs = __vc4_hvs_alloc(vc4, NULL, NULL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs); drm = &vc4->base; diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 559118824bf7..7a9faea748e6 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -1004,7 +1004,9 @@ void vc4_irq_reset(struct drm_device *dev); /* vc4_hvs.c */ extern struct platform_driver vc4_hvs_driver; -struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pdev); +struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, + void __iomem *regs, + struct platform_device *pdev); void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int output); int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output); u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo); diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index ecba1f7bc1e0..8e6327910d9f 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -811,7 +811,9 @@ int vc4_hvs_debugfs_init(struct drm_minor *minor) return 0; } -struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pdev) +struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, + void __iomem *regs, + struct platform_device *pdev) { struct drm_device *drm = &vc4->base; struct vc4_hvs *hvs; @@ -821,6 +823,7 @@ struct vc4_hvs *__vc4_hvs_alloc(struct vc4_dev *vc4, struct platform_device *pde return ERR_PTR(-ENOMEM); hvs->vc4 = vc4; + hvs->regs = regs; hvs->pdev = pdev; spin_lock_init(&hvs->mm_lock); @@ -1017,16 +1020,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) struct drm_device *drm = dev_get_drvdata(master); struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_hvs *hvs = NULL; + void __iomem *regs; int ret; - hvs = __vc4_hvs_alloc(vc4, NULL); + regs = vc4_ioremap_regs(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + hvs = __vc4_hvs_alloc(vc4, regs, pdev); if (IS_ERR(hvs)) return PTR_ERR(hvs); - hvs->regs = vc4_ioremap_regs(pdev, 0); - if (IS_ERR(hvs->regs)) - return PTR_ERR(hvs->regs); - hvs->regset.base = hvs->regs; hvs->regset.regs = vc4_hvs_regs; hvs->regset.nregs = ARRAY_SIZE(vc4_hvs_regs); -- GitLab From 8e7eb0c54a93dc767ce602186f98018e33dda427 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:53 +0100 Subject: [PATCH 105/970] drm/vc4: plane: Move the buffer offset out of the vc4_plane_state The offset fields in vc4_plane_state are described as being the offset for each buffer in the bo, however it is used to store the complete DMA address that is then written into the register. The DMA address including the fb ofset can be retrieved using drm_fb_dma_get_gem_addr, and the offset adjustment due to clipping is local to vc4_plane_mode_set. Drop the offset field from the state, and compute the complete DMA address in vc4_plane_mode_set. Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-30-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_drv.h | 5 ---- drivers/gpu/drm/vc4/vc4_plane.c | 51 +++++++++++++-------------------- 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 7a9faea748e6..c6be1997f1c7 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -421,11 +421,6 @@ struct vc4_plane_state { bool is_unity; bool is_yuv; - /* Offset to start scanning out from the start of the plane's - * BO. - */ - u32 offsets[3]; - /* Our allocation in LBM for temporary storage during scaling. */ struct drm_mm_node lbm; diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 4c61ef4f4142..ba6e86d62a77 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -450,12 +450,11 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); struct drm_framebuffer *fb = state->fb; - struct drm_gem_dma_object *bo; int num_planes = fb->format->num_planes; struct drm_crtc_state *crtc_state; u32 h_subsample = fb->format->hsub; u32 v_subsample = fb->format->vsub; - int i, ret; + int ret; crtc_state = drm_atomic_get_existing_crtc_state(state->state, state->crtc); @@ -469,11 +468,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) if (ret) return ret; - for (i = 0; i < num_planes; i++) { - bo = drm_fb_dma_get_gem_obj(fb, i); - vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i]; - } - vc4_state->src_x = state->src.x1; vc4_state->src_y = state->src.y1; vc4_state->src_w[0] = state->src.x2 - vc4_state->src_x; @@ -902,6 +896,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, u32 width, height; u32 hvs_format = format->hvs; unsigned int rotation; + u32 offsets[3] = { 0 }; int ret, i; if (vc4_state->dlist_initialized) @@ -949,13 +944,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * out. */ for (i = 0; i < num_planes; i++) { - vc4_state->offsets[i] += src_y / - (i ? v_subsample : 1) * - fb->pitches[i]; - - vc4_state->offsets[i] += src_x / - (i ? h_subsample : 1) * - fb->format->cpp[i]; + offsets[i] += src_y / (i ? v_subsample : 1) * fb->pitches[i]; + offsets[i] += src_x / (i ? h_subsample : 1) * fb->format->cpp[i]; } break; @@ -1010,19 +1000,18 @@ static int vc4_plane_mode_set(struct drm_plane *plane, VC4_SET_FIELD(y_off, SCALER_PITCH0_TILE_Y_OFFSET) | VC4_SET_FIELD(tiles_l, SCALER_PITCH0_TILE_WIDTH_L) | VC4_SET_FIELD(tiles_r, SCALER_PITCH0_TILE_WIDTH_R)); - vc4_state->offsets[0] += tiles_t * (tiles_w << tile_size_shift); - vc4_state->offsets[0] += subtile_y << 8; - vc4_state->offsets[0] += utile_y << 4; + offsets[0] += tiles_t * (tiles_w << tile_size_shift); + offsets[0] += subtile_y << 8; + offsets[0] += utile_y << 4; /* Rows of tiles alternate left-to-right and right-to-left. */ if (tiles_t & 1) { pitch0 |= SCALER_PITCH0_TILE_INITIAL_LINE_DIR; - vc4_state->offsets[0] += (tiles_w - tiles_l) << - tile_size_shift; - vc4_state->offsets[0] -= (1 + !tile_y) << 10; + offsets[0] += (tiles_w - tiles_l) << tile_size_shift; + offsets[0] -= (1 + !tile_y) << 10; } else { - vc4_state->offsets[0] += tiles_l << tile_size_shift; - vc4_state->offsets[0] += tile_y << 10; + offsets[0] += tiles_l << tile_size_shift; + offsets[0] += tile_y << 10; } break; @@ -1111,11 +1100,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane, tile = src_x / pix_per_tile; - vc4_state->offsets[i] += param * tile_w * tile; - vc4_state->offsets[i] += src_y / - (i ? v_subsample : 1) * - tile_w; - vc4_state->offsets[i] += x_off & ~(i ? 1 : 0); + offsets[i] += param * tile_w * tile; + offsets[i] += src_y / (i ? v_subsample : 1) * tile_w; + offsets[i] += x_off & ~(i ? 1 : 0); } pitch0 = VC4_SET_FIELD(param, SCALER_TILE_HEIGHT); @@ -1261,8 +1248,12 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * The pointers may be any byte address. */ vc4_state->ptr0_offset[0] = vc4_state->dlist_count; - for (i = 0; i < num_planes; i++) - vc4_dlist_write(vc4_state, vc4_state->offsets[i]); + + for (i = 0; i < num_planes; i++) { + struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, i); + + vc4_dlist_write(vc4_state, bo->dma_addr + fb->offsets[i] + offsets[i]); + } /* Pointer Context Word 0/1/2: Written by the HVS */ for (i = 0; i < num_planes; i++) @@ -1525,8 +1516,6 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, sizeof(vc4_state->y_scaling)); vc4_state->is_unity = new_vc4_state->is_unity; vc4_state->is_yuv = new_vc4_state->is_yuv; - memcpy(vc4_state->offsets, new_vc4_state->offsets, - sizeof(vc4_state->offsets)); vc4_state->needs_bg_fill = new_vc4_state->needs_bg_fill; /* Update the current vc4_state pos0, pos2 and ptr0 dlist entries. */ -- GitLab From 886a79237ecfd6c5376a1d76bef8209c486390b7 Mon Sep 17 00:00:00 2001 From: Tim Gover <tim.gover@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:54 +0100 Subject: [PATCH 106/970] drm/vc4: hvs: Enable SCALER_CONTROL early in HVS init Always enable SCALER_CONTROL before attempting other HVS operations. It's safe to write to some parts of the HVS but in general it's dangerous to do this because it can cause bus lockups. Signed-off-by: Tim Gover <tim.gover@raspberrypi.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-31-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 8e6327910d9f..93e7edd8b084 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -860,6 +860,10 @@ static int vc4_hvs_hw_init(struct vc4_hvs *hvs) struct vc4_dev *vc4 = hvs->vc4; u32 dispctrl, reg; + dispctrl = HVS_READ(SCALER_DISPCTRL); + dispctrl |= SCALER_DISPCTRL_ENABLE; + HVS_WRITE(SCALER_DISPCTRL, dispctrl); + reg = HVS_READ(SCALER_DISPECTRL); reg &= ~SCALER_DISPECTRL_DSP2_MUX_MASK; HVS_WRITE(SCALER_DISPECTRL, @@ -881,8 +885,6 @@ static int vc4_hvs_hw_init(struct vc4_hvs *hvs) reg | VC4_SET_FIELD(3, SCALER_DISPDITHER_DSP5_MUX)); dispctrl = HVS_READ(SCALER_DISPCTRL); - - dispctrl |= SCALER_DISPCTRL_ENABLE; dispctrl |= SCALER_DISPCTRL_DISPEIRQ(0) | SCALER_DISPCTRL_DISPEIRQ(1) | SCALER_DISPCTRL_DISPEIRQ(2); @@ -1078,6 +1080,10 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) else hvs->dlist = hvs->regs + SCALER5_DLIST_START; + ret = vc4_hvs_hw_init(hvs); + if (ret) + return ret; + /* Upload filter kernels. We only have the one for now, so we * keep it around for the lifetime of the driver. */ @@ -1087,10 +1093,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - ret = vc4_hvs_hw_init(hvs); - if (ret) - return ret; - ret = vc4_hvs_cob_init(hvs); if (ret) return ret; -- GitLab From 7ab6512e7942889c0962588355cb92424a690be6 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Fri, 21 Jun 2024 16:20:55 +0100 Subject: [PATCH 107/970] drm/vc4: hvs: Correct logic on stopping an HVS channel When factoring out __vc4_hvs_stop_channel, the logic got inverted from if (condition) // stop channel to if (condition) goto out //stop channel out: and also changed the exact register writes used to stop the channel. Correct the logic so that the channel is actually stopped, and revert to the original register writes. Fixes: 6d01a106b4c8 ("drm/vc4: crtc: Move HVS init and close to a function") Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-32-dave.stevenson@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 93e7edd8b084..2a366a607fcc 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -427,13 +427,11 @@ void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int chan) if (!drm_dev_enter(drm, &idx)) return; - if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE) + if (!(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE)) goto out; - HVS_WRITE(SCALER_DISPCTRLX(chan), - HVS_READ(SCALER_DISPCTRLX(chan)) | SCALER_DISPCTRLX_RESET); - HVS_WRITE(SCALER_DISPCTRLX(chan), - HVS_READ(SCALER_DISPCTRLX(chan)) & ~SCALER_DISPCTRLX_ENABLE); + HVS_WRITE(SCALER_DISPCTRLX(chan), SCALER_DISPCTRLX_RESET); + HVS_WRITE(SCALER_DISPCTRLX(chan), 0); /* Once we leave, the scaler should be disabled and its fifo empty. */ WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET); -- GitLab From ceb29504dd80ebdfc09adb942c9ef8d12d4612ca Mon Sep 17 00:00:00 2001 From: Lucas De Marchi <lucas.demarchi@intel.com> Date: Thu, 5 Sep 2024 20:25:07 -0700 Subject: [PATCH 108/970] drm/xe: Fix arg to pci_iomap() Commit 2d8865b27724 ("drm/xe: Move BAR definitions to dedicated file") moved the BAR definition to the header, but replaced the wrong arg in the pci_iomap() function - the last arg is actuall the length, not the BAR. Luckily GTTMMADR_BAR == 0, so it still works. Fix the argument to avoid confusion. Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906032507.2952859-1-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_mmio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 3fd462fda625..4aae30880bc6 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -157,15 +157,14 @@ int xe_mmio_init(struct xe_device *xe) { struct xe_tile *root_tile = xe_device_get_root_tile(xe); struct pci_dev *pdev = to_pci_dev(xe->drm.dev); - const int mmio_bar = 0; /* * Map the entire BAR. * The first 16MB of the BAR, belong to the root tile, and include: * registers (0-4MB), reserved space (4MB-8MB) and GGTT (8MB-16MB). */ - xe->mmio.size = pci_resource_len(pdev, mmio_bar); - xe->mmio.regs = pci_iomap(pdev, mmio_bar, GTTMMADR_BAR); + xe->mmio.size = pci_resource_len(pdev, GTTMMADR_BAR); + xe->mmio.regs = pci_iomap(pdev, GTTMMADR_BAR, 0); if (xe->mmio.regs == NULL) { drm_err(&xe->drm, "failed to map registers\n"); return -EIO; -- GitLab From 3fe62f7bfd1b1bf829d53c39c76fa2efc8a5c108 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi <lucas.demarchi@intel.com> Date: Fri, 6 Sep 2024 13:56:09 -0700 Subject: [PATCH 109/970] drm/xe: Mark reserved engines in snapshot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When printing <debufs>/gt*/hw_engines, it's useful to mark what engines are reserved so it doesn't mislead developers while debugging. Cc: José Roberto de Souza <jose.souza@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: José Roberto de Souza <jose.souza@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906205609.3131330-1-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_hw_engine.c | 3 +++ drivers/gpu/drm/xe/xe_hw_engine_types.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index c9c3beb3ce8d..ce180faf2592 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -903,6 +903,7 @@ xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe) snapshot->forcewake.ref = xe_force_wake_ref(gt_to_fw(hwe->gt), hwe->domain); snapshot->mmio_base = hwe->mmio_base; + snapshot->kernel_reserved = xe_hw_engine_is_reserved(hwe); /* no more VF accessible data below this point */ if (IS_SRIOV_VF(gt_to_xe(hwe->gt))) @@ -1025,6 +1026,8 @@ void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, snapshot->logical_instance); drm_printf(p, "\tForcewake: domain 0x%x, ref %d\n", snapshot->forcewake.domain, snapshot->forcewake.ref); + drm_printf(p, "\tReserved: %s\n", + str_yes_no(snapshot->kernel_reserved)); drm_printf(p, "\tHWSTAM: 0x%08x\n", snapshot->reg.ring_hwstam); drm_printf(p, "\tRING_HWS_PGA: 0x%08x\n", snapshot->reg.ring_hws_pga); drm_printf(p, "\tRING_EXECLIST_STATUS: 0x%016llx\n", diff --git a/drivers/gpu/drm/xe/xe_hw_engine_types.h b/drivers/gpu/drm/xe/xe_hw_engine_types.h index 8be6d420ece4..be60edb3e673 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine_types.h +++ b/drivers/gpu/drm/xe/xe_hw_engine_types.h @@ -173,6 +173,8 @@ struct xe_hw_engine_snapshot { } forcewake; /** @mmio_base: MMIO base address of this hw engine*/ u32 mmio_base; + /** @kernel_reserved: Engine reserved, can't be used by userspace */ + bool kernel_reserved; /** @reg: Useful MMIO register snapshot */ struct { /** @reg.ring_execlist_status: RING_EXECLIST_STATUS */ -- GitLab From f2710d95724ebbfa35d6d4b82017eeab70994509 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Sat, 7 Sep 2024 00:03:48 +0200 Subject: [PATCH 110/970] drm/xe: Don't keep stale pointer to bo->ggtt_node When we fail to map a BO in the GGTT, we release our GGTT node placeholder, but leave stale bo->ggtt_node pointer to it, which triggers an assert immediately followed by a crash, due to UAF: [ ] xe 0000:00:02.0: [drm] Assertion `bo->ggtt_node->base.size == bo->size` failed! [ ] WARNING: CPU: 4 PID: 126 at drivers/gpu/drm/xe/xe_ggtt.c:689 xe_ggtt_remove_bo+0x1d9/0x250 [xe] [ ] RIP: 0010:xe_ggtt_remove_bo+0x1d9/0x250 [xe] [ ] Call Trace: [ ] <TASK> [ ] ? __warn+0x88/0x190 [ ] ? xe_ggtt_remove_bo+0x1d9/0x250 [xe] [ ] ? report_bug+0x1c3/0x1d0 [ ] ? handle_bug+0x42/0x70 [ ] ? exc_invalid_op+0x14/0x70 [ ] ? asm_exc_invalid_op+0x16/0x20 [ ] ? xe_ggtt_remove_bo+0x1d9/0x250 [xe] [ ] ? xe_ggtt_remove_bo+0x1d9/0x250 [xe] [ ] xe_ttm_bo_destroy+0x11f/0x260 [xe] [ ] ? ttm_bo_release+0x31c/0x350 [ttm] [ ] ? __mutex_unlock_slowpath+0x35/0x270 [ ] __xe_bo_create_locked+0x4a0/0x550 [xe] [ ] ? mark_held_locks+0x49/0x80 [ ] xe_bo_create_pin_map_at+0x37/0x200 [xe] [ ] xe_bo_create_pin_map+0x11/0x20 [xe] While around, for similar reason, also don't keep an error pointer if we fail to allocate ggtt_node placeholder. Fixes: 34e804220f69 ("drm/xe: Make xe_ggtt_node struct independent") Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906220348.1836-1-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_ggtt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index f3fca5565d32..2895f154654c 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -619,16 +619,19 @@ static int __xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo, bo->ggtt_node = xe_ggtt_node_init(ggtt); if (IS_ERR(bo->ggtt_node)) { err = PTR_ERR(bo->ggtt_node); + bo->ggtt_node = NULL; goto out; } mutex_lock(&ggtt->lock); err = drm_mm_insert_node_in_range(&ggtt->mm, &bo->ggtt_node->base, bo->size, alignment, 0, start, end, 0); - if (err) + if (err) { xe_ggtt_node_fini(bo->ggtt_node); - else + bo->ggtt_node = NULL; + } else { xe_ggtt_map_bo(ggtt, bo); + } mutex_unlock(&ggtt->lock); if (!err && bo->flags & XE_BO_FLAG_GGTT_INVALIDATE) -- GitLab From addf89774e48c992316449ffab4f29c2309ebefb Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 9 Sep 2024 21:17:40 +0800 Subject: [PATCH 111/970] ieee802154: Fix build error If REGMAP_SPI is m and IEEE802154_MCR20A is y, mcr20a.c:(.text+0x3ed6c5b): undefined reference to `__devm_regmap_init_spi' ld: mcr20a.c:(.text+0x3ed6cb5): undefined reference to `__devm_regmap_init_spi' Select REGMAP_SPI for IEEE802154_MCR20A to fix it. Fixes: 8c6ad9cc5157 ("ieee802154: Add NXP MCR20A IEEE 802.15.4 transceiver driver") Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Link: https://lore.kernel.org/20240909131740.1296608-1-ruanjinjie@huawei.com Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org> --- drivers/net/ieee802154/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig index 95da876c5613..1075e24b11de 100644 --- a/drivers/net/ieee802154/Kconfig +++ b/drivers/net/ieee802154/Kconfig @@ -101,6 +101,7 @@ config IEEE802154_CA8210_DEBUGFS config IEEE802154_MCR20A tristate "MCR20A transceiver driver" + select REGMAP_SPI depends on IEEE802154_DRIVERS && MAC802154 depends on SPI help -- GitLab From 1c129ed07de47684ff2471e32b52fa823533aa06 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Mon, 9 Sep 2024 20:25:08 +0000 Subject: [PATCH 112/970] drm/xe: fix build warning with CONFIG_PM=n The 'runtime_status' field is an implementation detail of the power management code, so a device driver should not normally touch this: drivers/gpu/drm/xe/xe_pm.c: In function 'xe_pm_suspending_or_resuming': drivers/gpu/drm/xe/xe_pm.c:606:26: error: 'struct dev_pm_info' has no member named 'runtime_status' 606 | return dev->power.runtime_status == RPM_SUSPENDING || | ^ drivers/gpu/drm/xe/xe_pm.c:607:27: error: 'struct dev_pm_info' has no member named 'runtime_status' 607 | dev->power.runtime_status == RPM_RESUMING; | ^ drivers/gpu/drm/xe/xe_pm.c:608:1: error: control reaches end of non-void function [-Werror=return-type] Add an #ifdef check to avoid the build regression. Fixes: cb85e39dc5d1 ("drm/xe: Suppress missing outer rpm protection warning") Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240909202521.1018439-1-arnd@kernel.org Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_pm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index 9c59a30d7646..a3d1509066f7 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -601,10 +601,14 @@ bool xe_pm_runtime_get_if_in_use(struct xe_device *xe) */ static bool xe_pm_suspending_or_resuming(struct xe_device *xe) { +#ifdef CONFIG_PM struct device *dev = xe->drm.dev; return dev->power.runtime_status == RPM_SUSPENDING || dev->power.runtime_status == RPM_RESUMING; +#else + return false; +#endif } /** -- GitLab From f327bfdbf6c6d7d8e5402795c7c97fb97c2dcf79 Mon Sep 17 00:00:00 2001 From: Tejas Vipin <tejasvipin76@gmail.com> Date: Mon, 2 Sep 2024 12:40:19 +0530 Subject: [PATCH 113/970] drm/panel: samsung-s6e3fa7: transition to mipi_dsi wrapped functions Changes the samsung-s6e3fa7 panel to use multi style functions for improved error handling. Signed-off-by: Tejas Vipin <tejasvipin76@gmail.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240902071019.351158-1-tejasvipin76@gmail.com --- drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c | 71 ++++++------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c b/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c index 10bc8fb5f1f9..27a059b55ae5 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3fa7.c @@ -38,57 +38,38 @@ static void s6e3fa7_panel_reset(struct s6e3fa7_panel *ctx) usleep_range(10000, 11000); } -static int s6e3fa7_panel_on(struct s6e3fa7_panel *ctx) +static int s6e3fa7_panel_on(struct mipi_dsi_device *dsi) { - struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to exit sleep mode: %d\n", ret); - return ret; - } - msleep(120); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - if (ret < 0) { - dev_err(dev, "Failed to set tear on: %d\n", ret); - return ret; - } + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, + 0xbb, 0x23, 0x19, 0x3a, 0x9f, 0x0f, 0x09, 0xc0, + 0x00, 0xb4, 0x37, 0x70, 0x79, 0x69); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a); - mipi_dsi_dcs_write_seq(dsi, 0xf4, - 0xbb, 0x23, 0x19, 0x3a, 0x9f, 0x0f, 0x09, 0xc0, - 0x00, 0xb4, 0x37, 0x70, 0x79, 0x69); - mipi_dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5); - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display on: %d\n", ret); - return ret; - } - - return 0; + return dsi_ctx.accum_err; } static int s6e3fa7_panel_prepare(struct drm_panel *panel) { struct s6e3fa7_panel *ctx = to_s6e3fa7_panel(panel); - struct device *dev = &ctx->dsi->dev; int ret; s6e3fa7_panel_reset(ctx); - ret = s6e3fa7_panel_on(ctx); - if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); + ret = s6e3fa7_panel_on(ctx->dsi); + if (ret < 0) gpiod_set_value_cansleep(ctx->reset_gpio, 1); - return ret; - } - return 0; + return ret; } static int s6e3fa7_panel_unprepare(struct drm_panel *panel) @@ -104,23 +85,13 @@ static int s6e3fa7_panel_disable(struct drm_panel *panel) { struct s6e3fa7_panel *ctx = to_s6e3fa7_panel(panel); struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; - - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); - return ret; - } + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); - return ret; - } - msleep(120); + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); - return 0; + return dsi_ctx.accum_err; } static const struct drm_display_mode s6e3fa7_panel_mode = { -- GitLab From 5a90b60db5e6765367d9bb2c03f66b14d72946d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom@linux.intel.com> Date: Mon, 9 Sep 2024 10:56:54 +0200 Subject: [PATCH 114/970] drm/xe: Add a xe_bo subtest for shrinking / swapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a subtest that tries to allocate twice the amount of buffer object memory available, write data to it and then read all the data back verifying data integrity. In order to be able to do this on systems that have no or not enough swap-space available, allocate some memory as purgeable, and introduce a function to purge such memory from the TTM swap_notify path. this test is intended to add test coverage to the current bo swap path and upcoming shrinking path. The test has previously been part of the xe bo shrinker series. v2: - Skip test if the execution time is expected to be too long. - Minor code cleanups. v3: - Print random seed. (Matthew Auld) Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240909085654.5064-1-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/xe/tests/xe_bo.c | 239 +++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_bo.c | 32 ++++- 2 files changed, 270 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c index 8dac069483e8..7d3fd720478b 100644 --- a/drivers/gpu/drm/xe/tests/xe_bo.c +++ b/drivers/gpu/drm/xe/tests/xe_bo.c @@ -6,6 +6,12 @@ #include <kunit/test.h> #include <kunit/visibility.h> +#include <linux/iosys-map.h> +#include <linux/random.h> +#include <linux/swap.h> + +#include <uapi/linux/sysinfo.h> + #include "tests/xe_kunit_helpers.h" #include "tests/xe_pci_test.h" #include "tests/xe_test.h" @@ -358,9 +364,242 @@ static void xe_bo_evict_kunit(struct kunit *test) evict_test_run_device(xe); } +struct xe_bo_link { + struct list_head link; + struct xe_bo *bo; + u32 val; +}; + +#define XE_BO_SHRINK_SIZE ((unsigned long)SZ_64M) + +static int shrink_test_fill_random(struct xe_bo *bo, struct rnd_state *state, + struct xe_bo_link *link) +{ + struct iosys_map map; + int ret = ttm_bo_vmap(&bo->ttm, &map); + size_t __maybe_unused i; + + if (ret) + return ret; + + for (i = 0; i < bo->ttm.base.size; i += sizeof(u32)) { + u32 val = prandom_u32_state(state); + + iosys_map_wr(&map, i, u32, val); + if (i == 0) + link->val = val; + } + + ttm_bo_vunmap(&bo->ttm, &map); + return 0; +} + +static bool shrink_test_verify(struct kunit *test, struct xe_bo *bo, + unsigned int bo_nr, struct rnd_state *state, + struct xe_bo_link *link) +{ + struct iosys_map map; + int ret = ttm_bo_vmap(&bo->ttm, &map); + size_t i; + bool failed = false; + + if (ret) { + KUNIT_FAIL(test, "Error mapping bo %u for content check.\n", bo_nr); + return true; + } + + for (i = 0; i < bo->ttm.base.size; i += sizeof(u32)) { + u32 val = prandom_u32_state(state); + + if (iosys_map_rd(&map, i, u32) != val) { + KUNIT_FAIL(test, "Content not preserved, bo %u offset 0x%016llx", + bo_nr, (unsigned long long)i); + kunit_info(test, "Failed value is 0x%08x, recorded 0x%08x\n", + (unsigned int)iosys_map_rd(&map, i, u32), val); + if (i == 0 && val != link->val) + kunit_info(test, "Looks like PRNG is out of sync.\n"); + failed = true; + break; + } + } + + ttm_bo_vunmap(&bo->ttm, &map); + + return failed; +} + +/* + * Try to create system bos corresponding to twice the amount + * of available system memory to test shrinker functionality. + * If no swap space is available to accommodate the + * memory overcommit, mark bos purgeable. + */ +static int shrink_test_run_device(struct xe_device *xe) +{ + struct kunit *test = kunit_get_current_test(); + LIST_HEAD(bos); + struct xe_bo_link *link, *next; + struct sysinfo si; + size_t ram, ram_and_swap, purgeable, alloced, to_alloc, limit; + unsigned int interrupted = 0, successful = 0, count = 0; + struct rnd_state prng; + u64 rand_seed; + bool failed = false; + + rand_seed = get_random_u64(); + prandom_seed_state(&prng, rand_seed); + kunit_info(test, "Random seed is 0x%016llx.\n", + (unsigned long long)rand_seed); + + /* Skip if execution time is expected to be too long. */ + + limit = SZ_32G; + /* IGFX with flat CCS needs to copy when swapping / shrinking */ + if (!IS_DGFX(xe) && xe_device_has_flat_ccs(xe)) + limit = SZ_16G; + + si_meminfo(&si); + ram = (size_t)si.freeram * si.mem_unit; + if (ram > limit) { + kunit_skip(test, "Too long expected execution time.\n"); + return 0; + } + to_alloc = ram * 2; + + ram_and_swap = ram + get_nr_swap_pages() * PAGE_SIZE; + if (to_alloc > ram_and_swap) + purgeable = to_alloc - ram_and_swap; + purgeable += purgeable / 5; + + kunit_info(test, "Free ram is %lu bytes. Will allocate twice of that.\n", + (unsigned long)ram); + for (alloced = 0; alloced < to_alloc; alloced += XE_BO_SHRINK_SIZE) { + struct xe_bo *bo; + unsigned int mem_type; + struct xe_ttm_tt *xe_tt; + + link = kzalloc(sizeof(*link), GFP_KERNEL); + if (!link) { + KUNIT_FAIL(test, "Unexpected link allocation failure\n"); + failed = true; + break; + } + + INIT_LIST_HEAD(&link->link); + + /* We can create bos using WC caching here. But it is slower. */ + bo = xe_bo_create_user(xe, NULL, NULL, XE_BO_SHRINK_SIZE, + DRM_XE_GEM_CPU_CACHING_WB, + XE_BO_FLAG_SYSTEM); + if (IS_ERR(bo)) { + if (bo != ERR_PTR(-ENOMEM) && bo != ERR_PTR(-ENOSPC) && + bo != ERR_PTR(-EINTR) && bo != ERR_PTR(-ERESTARTSYS)) + KUNIT_FAIL(test, "Error creating bo: %pe\n", bo); + kfree(link); + failed = true; + break; + } + xe_bo_lock(bo, false); + xe_tt = container_of(bo->ttm.ttm, typeof(*xe_tt), ttm); + + /* + * Allocate purgeable bos first, because if we do it the + * other way around, they may not be subject to swapping... + */ + if (alloced < purgeable) { + xe_tt->purgeable = true; + bo->ttm.priority = 0; + } else { + int ret = shrink_test_fill_random(bo, &prng, link); + + if (ret) { + xe_bo_unlock(bo); + xe_bo_put(bo); + KUNIT_FAIL(test, "Error filling bo with random data: %pe\n", + ERR_PTR(ret)); + kfree(link); + failed = true; + break; + } + } + + mem_type = bo->ttm.resource->mem_type; + xe_bo_unlock(bo); + link->bo = bo; + list_add_tail(&link->link, &bos); + + if (mem_type != XE_PL_TT) { + KUNIT_FAIL(test, "Bo in incorrect memory type: %u\n", + bo->ttm.resource->mem_type); + failed = true; + } + cond_resched(); + if (signal_pending(current)) + break; + } + + /* + * Read back and destroy bos. Reset the pseudo-random seed to get an + * identical pseudo-random number sequence for readback. + */ + prandom_seed_state(&prng, rand_seed); + list_for_each_entry_safe(link, next, &bos, link) { + static struct ttm_operation_ctx ctx = {.interruptible = true}; + struct xe_bo *bo = link->bo; + struct xe_ttm_tt *xe_tt; + int ret; + + count++; + if (!signal_pending(current) && !failed) { + bool purgeable, intr = false; + + xe_bo_lock(bo, NULL); + + /* xe_tt->purgeable is cleared on validate. */ + xe_tt = container_of(bo->ttm.ttm, typeof(*xe_tt), ttm); + purgeable = xe_tt->purgeable; + do { + ret = ttm_bo_validate(&bo->ttm, &tt_placement, &ctx); + if (ret == -EINTR) + intr = true; + } while (ret == -EINTR && !signal_pending(current)); + + if (!ret && !purgeable) + failed = shrink_test_verify(test, bo, count, &prng, link); + + xe_bo_unlock(bo); + if (ret) { + KUNIT_FAIL(test, "Validation failed: %pe\n", + ERR_PTR(ret)); + failed = true; + } else if (intr) { + interrupted++; + } else { + successful++; + } + } + xe_bo_put(link->bo); + list_del(&link->link); + kfree(link); + } + kunit_info(test, "Readbacks interrupted: %u successful: %u\n", + interrupted, successful); + + return 0; +} + +static void xe_bo_shrink_kunit(struct kunit *test) +{ + struct xe_device *xe = test->priv; + + shrink_test_run_device(xe); +} + static struct kunit_case xe_bo_tests[] = { KUNIT_CASE_PARAM(xe_ccs_migrate_kunit, xe_pci_live_device_gen_param), KUNIT_CASE_PARAM(xe_bo_evict_kunit, xe_pci_live_device_gen_param), + KUNIT_CASE_PARAM_ATTR(xe_bo_shrink_kunit, xe_pci_live_device_gen_param, + {.speed = KUNIT_SPEED_SLOW}), {} }; diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 3a9653e33481..0dc8ebcf8389 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -283,6 +283,8 @@ struct xe_ttm_tt { struct device *dev; struct sg_table sgt; struct sg_table *sg; + /** @purgeable: Whether the content of the pages of @ttm is purgeable. */ + bool purgeable; }; static int xe_tt_map_sg(struct ttm_tt *tt) @@ -761,7 +763,7 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict, if (xe_rpm_reclaim_safe(xe)) { /* * We might be called through swapout in the validation path of - * another TTM device, so unconditionally acquire rpm here. + * another TTM device, so acquire rpm here. */ xe_pm_runtime_get(xe); } else { @@ -1082,6 +1084,33 @@ static void xe_ttm_bo_delete_mem_notify(struct ttm_buffer_object *ttm_bo) } } +static void xe_ttm_bo_purge(struct ttm_buffer_object *ttm_bo, struct ttm_operation_ctx *ctx) +{ + struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev); + + if (ttm_bo->ttm) { + struct ttm_placement place = {}; + int ret = ttm_bo_validate(ttm_bo, &place, ctx); + + drm_WARN_ON(&xe->drm, ret); + } +} + +static void xe_ttm_bo_swap_notify(struct ttm_buffer_object *ttm_bo) +{ + struct ttm_operation_ctx ctx = { + .interruptible = false + }; + + if (ttm_bo->ttm) { + struct xe_ttm_tt *xe_tt = + container_of(ttm_bo->ttm, struct xe_ttm_tt, ttm); + + if (xe_tt->purgeable) + xe_ttm_bo_purge(ttm_bo, &ctx); + } +} + const struct ttm_device_funcs xe_ttm_funcs = { .ttm_tt_create = xe_ttm_tt_create, .ttm_tt_populate = xe_ttm_tt_populate, @@ -1094,6 +1123,7 @@ const struct ttm_device_funcs xe_ttm_funcs = { .release_notify = xe_ttm_bo_release_notify, .eviction_valuable = ttm_bo_eviction_valuable, .delete_mem_notify = xe_ttm_bo_delete_mem_notify, + .swap_notify = xe_ttm_bo_swap_notify, }; static void xe_ttm_bo_destroy(struct ttm_buffer_object *ttm_bo) -- GitLab From 970b867d5bd483c4879a343fb894972ca5678d22 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 3 Sep 2024 15:25:29 +0200 Subject: [PATCH 115/970] drm/ast: Remove TX-chip bitmask The CRTC has only one output attached to it. Store the output's type of TX chip in a single field and remove the related bitmask. Turn the type-less output field in struct ast_device into a union, as only one of its fields will be used at a time. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240903132601.91618-1-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp501.c | 2 +- drivers/gpu/drm/ast/ast_drv.h | 10 +++------- drivers/gpu/drm/ast/ast_main.c | 27 +++++++++++++-------------- drivers/gpu/drm/ast/ast_mode.c | 26 +++++++++++--------------- drivers/gpu/drm/ast/ast_post.c | 4 ++-- 5 files changed, 30 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index e4c636f45082..99bf44eec7b3 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -466,7 +466,7 @@ void ast_init_3rdtx(struct drm_device *dev) ast_init_dvo(dev); break; default: - if (ast->tx_chip_types & BIT(AST_TX_SIL164)) + if (ast->tx_chip == AST_TX_SIL164) ast_init_dvo(dev); else ast_init_analog(dev); diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 91fe07cf7b07..b6ca14a3b967 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -91,11 +91,6 @@ enum ast_tx_chip { AST_TX_ASTDP, }; -#define AST_TX_NONE_BIT BIT(AST_TX_NONE) -#define AST_TX_SIL164_BIT BIT(AST_TX_SIL164) -#define AST_TX_DP501_BIT BIT(AST_TX_DP501) -#define AST_TX_ASTDP_BIT BIT(AST_TX_ASTDP) - enum ast_config_mode { ast_use_p2a, ast_use_dt, @@ -187,10 +182,12 @@ struct ast_device { struct mutex modeset_lock; /* Protects access to modeset I/O registers in ioregs */ + enum ast_tx_chip tx_chip; + struct ast_plane primary_plane; struct ast_plane cursor_plane; struct drm_crtc crtc; - struct { + union { struct { struct drm_encoder encoder; struct ast_connector connector; @@ -211,7 +208,6 @@ struct ast_device { bool support_wide_screen; - unsigned long tx_chip_types; /* bitfield of enum ast_chip_type */ u8 *dp501_fw_addr; const struct firmware *dp501_fw; /* dp501 fw */ }; diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index d836f2a4f9f3..d7d503e78e25 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -68,11 +68,18 @@ static void ast_detect_widescreen(struct ast_device *ast) static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) { + static const char * const info_str[] = { + "analog VGA", + "Sil164 TMDS transmitter", + "DP501 DisplayPort transmitter", + "ASPEED DisplayPort transmitter", + }; + struct drm_device *dev = &ast->base; u8 jreg; /* Check 3rd Tx option (digital output afaik) */ - ast->tx_chip_types |= AST_TX_NONE_BIT; + ast->tx_chip = AST_TX_NONE; /* * VGACRA3 Enhanced Color Mode Register, check if DVO is already @@ -85,7 +92,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) if (!need_post) { jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff); if (jreg & 0x80) - ast->tx_chip_types = AST_TX_SIL164_BIT; + ast->tx_chip = AST_TX_SIL164; } if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) { @@ -97,7 +104,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg) { case 0x04: - ast->tx_chip_types = AST_TX_SIL164_BIT; + ast->tx_chip = AST_TX_SIL164; break; case 0x08: ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL); @@ -110,7 +117,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) } fallthrough; case 0x0c: - ast->tx_chip_types = AST_TX_DP501_BIT; + ast->tx_chip = AST_TX_DP501; } } else if (IS_AST_GEN7(ast)) { if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) == @@ -118,19 +125,11 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) int ret = ast_dp_launch(ast); if (!ret) - ast->tx_chip_types = AST_TX_ASTDP_BIT; + ast->tx_chip = AST_TX_ASTDP; } } - /* Print stuff for diagnostic purposes */ - if (ast->tx_chip_types & AST_TX_NONE_BIT) - drm_info(dev, "Using analog VGA\n"); - if (ast->tx_chip_types & AST_TX_SIL164_BIT) - drm_info(dev, "Using Sil164 TMDS transmitter\n"); - if (ast->tx_chip_types & AST_TX_DP501_BIT) - drm_info(dev, "Using DP501 DisplayPort transmitter\n"); - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) - drm_info(dev, "Using ASPEED DisplayPort transmitter\n"); + drm_info(dev, "Using %s\n", info_str[ast->tx_chip]); } static int ast_get_dram_info(struct drm_device *dev) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index ed496fb32bf3..784e8ac0e668 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1398,26 +1398,22 @@ int ast_mode_config_init(struct ast_device *ast) ast_crtc_init(dev); - if (ast->tx_chip_types & AST_TX_NONE_BIT) { + switch (ast->tx_chip) { + case AST_TX_NONE: ret = ast_vga_output_init(ast); - if (ret) - return ret; - } - if (ast->tx_chip_types & AST_TX_SIL164_BIT) { + break; + case AST_TX_SIL164: ret = ast_sil164_output_init(ast); - if (ret) - return ret; - } - if (ast->tx_chip_types & AST_TX_DP501_BIT) { + break; + case AST_TX_DP501: ret = ast_dp501_output_init(ast); - if (ret) - return ret; - } - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { + break; + case AST_TX_ASTDP: ret = ast_astdp_output_init(ast); - if (ret) - return ret; + break; } + if (ret) + return ret; drm_mode_config_reset(dev); diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 65755798ab94..902bf8114b6e 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -350,7 +350,7 @@ void ast_post_gpu(struct drm_device *dev) ast_set_def_ext_reg(dev); if (IS_AST_GEN7(ast)) { - if (ast->tx_chip_types & AST_TX_ASTDP_BIT) + if (ast->tx_chip == AST_TX_ASTDP) ast_dp_launch(ast); } else if (ast->config_mode == ast_use_p2a) { if (IS_AST_GEN6(ast)) @@ -362,7 +362,7 @@ void ast_post_gpu(struct drm_device *dev) ast_init_3rdtx(dev); } else { - if (ast->tx_chip_types & AST_TX_SIL164_BIT) + if (ast->tx_chip == AST_TX_SIL164) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */ } } -- GitLab From 9db969b36b2fbca13ad4088aff725ebd5e8142f5 Mon Sep 17 00:00:00 2001 From: Tejas Upadhyay <tejas.upadhyay@intel.com> Date: Wed, 4 Sep 2024 15:43:33 +0530 Subject: [PATCH 116/970] drm/xe/xe2hpg: Add Wa_15016589081 Wa_15016589081 applies to xe2_hpg renderCS V2(Gustavo) - rename bit macro Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240904101333.2049655-1-tejas.upadhyay@intel.com Signed-off-by: Nirmoy Das <nirmoy.das@intel.com> --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 1 + drivers/gpu/drm/xe/xe_wa.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index cbead3f75fad..cf21de3adca6 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -105,6 +105,7 @@ #define CHICKEN_RASTER_1 XE_REG_MCR(0x6204, XE_REG_OPTION_MASKED) #define DIS_SF_ROUND_NEAREST_EVEN REG_BIT(8) +#define DIS_CLIP_NEGATIVE_BOUNDING_BOX REG_BIT(6) #define CHICKEN_RASTER_2 XE_REG_MCR(0x6208, XE_REG_OPTION_MASKED) #define TBIMR_FAST_CLIP REG_BIT(5) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 28b7f95b6c2f..d424992514a4 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -733,6 +733,10 @@ static const struct xe_rtp_entry_sr lrc_was[] = { DIS_PARTIAL_AUTOSTRIP | DIS_AUTOSTRIP)) }, + { XE_RTP_NAME("15016589081"), + XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX)) + }, {} }; -- GitLab From 96d068ea0d77e3bec79cf8199fce1aaa28cd256e Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:26 -0300 Subject: [PATCH 117/970] drm/tests: Stop using deprecated dev_private member on drm_framebuffer tests The dev_private member of drm_device is deprecated and its use should be avoided. Stop using it by embedding the drm_device onto a mock struct. The new mock struct allows to share variables and even further mocks over the tests in a cleaner way than using dev_private void pointer. Also start using drm_kunit_helper_alloc_drm_device() for allocating the drm_device mock. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-2-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 54 ++++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 06f03b78c9c4..3882a88b6631 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -8,8 +8,10 @@ #include <kunit/test.h> #include <drm/drm_device.h> +#include <drm/drm_drv.h> #include <drm/drm_mode.h> #include <drm/drm_fourcc.h> +#include <drm/drm_kunit_helpers.h> #include <drm/drm_print.h> #include "../drm_crtc_internal.h" @@ -317,12 +319,25 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { }, }; +/* + * This struct is intended to provide a way to mocked functions communicate + * with the outer test when it can't be achieved by using its return value. In + * this way, the functions that receive the mocked drm_device, for example, can + * grab a reference to this and actually return something to be used on some + * expectation. + */ +struct drm_framebuffer_test_priv { + struct drm_device dev; + bool buffer_created; +}; + static struct drm_framebuffer *fb_create_mock(struct drm_device *dev, struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) { - int *buffer_created = dev->dev_private; - *buffer_created = 1; + struct drm_framebuffer_test_priv *priv = container_of(dev, typeof(*priv), dev); + + priv->buffer_created = true; return ERR_PTR(-EINVAL); } @@ -332,30 +347,37 @@ static struct drm_mode_config_funcs mock_config_funcs = { static int drm_framebuffer_test_init(struct kunit *test) { - struct drm_device *mock; + struct device *parent; + struct drm_framebuffer_test_priv *priv; + struct drm_device *dev; + + parent = drm_kunit_helper_alloc_device(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); - mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock); + priv = drm_kunit_helper_alloc_drm_device(test, parent, typeof(*priv), + dev, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + dev = &priv->dev; - mock->mode_config.min_width = MIN_WIDTH; - mock->mode_config.max_width = MAX_WIDTH; - mock->mode_config.min_height = MIN_HEIGHT; - mock->mode_config.max_height = MAX_HEIGHT; - mock->mode_config.funcs = &mock_config_funcs; + dev->mode_config.min_width = MIN_WIDTH; + dev->mode_config.max_width = MAX_WIDTH; + dev->mode_config.min_height = MIN_HEIGHT; + dev->mode_config.max_height = MAX_HEIGHT; + dev->mode_config.funcs = &mock_config_funcs; - test->priv = mock; + test->priv = priv; return 0; } static void drm_test_framebuffer_create(struct kunit *test) { const struct drm_framebuffer_test *params = test->param_value; - struct drm_device *mock = test->priv; - int buffer_created = 0; + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; - mock->dev_private = &buffer_created; - drm_internal_framebuffer_create(mock, ¶ms->cmd, NULL); - KUNIT_EXPECT_EQ(test, params->buffer_created, buffer_created); + priv->buffer_created = false; + drm_internal_framebuffer_create(dev, ¶ms->cmd, NULL); + KUNIT_EXPECT_EQ(test, params->buffer_created, priv->buffer_created); } static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, char *desc) -- GitLab From e2b5f1da5fb9c899468067d859e604ae922664b1 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:27 -0300 Subject: [PATCH 118/970] drm/tests: Add parameters to the drm_test_framebuffer_create test Extend the existing test case to cover: 1. Invalid flag atribute in the struct drm_mode_fb_cmd2. 2. Pixel format which requires non-linear modifier with DRM_FORMAT_MOD_LINEAR set. 3. Buffer offset for inexistent plane Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-3-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 3882a88b6631..3ed987423322 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -21,6 +21,8 @@ #define MIN_HEIGHT 4 #define MAX_HEIGHT 4096 +#define DRM_MODE_FB_INVALID BIT(2) + struct drm_framebuffer_test { int buffer_created; struct drm_mode_fb_cmd2 cmd; @@ -85,6 +87,24 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { .pitches = { 4 * MAX_WIDTH, 0, 0 }, } }, + +/* + * All entries in members that represents per-plane values (@modifier, @handles, + * @pitches and @offsets) must be zero when unused. + */ +{ .buffer_created = 0, .name = "ABGR8888 Buffer offset for inexistent plane", + .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, + .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, UINT_MAX / 2, 0 }, + .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, + } +}, + +{ .buffer_created = 0, .name = "ABGR8888 Invalid flag", + .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, + .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, + .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_INVALID, + } +}, { .buffer_created = 1, .name = "ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers", .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, @@ -264,6 +284,13 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, } }, +{ .buffer_created = 0, .name = "YUV420_10BIT Invalid modifier(DRM_FORMAT_MOD_LINEAR)", + .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YUV420_10BIT, + .handles = { 1, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, + .modifier = { DRM_FORMAT_MOD_LINEAR, 0, 0 }, + .pitches = { MAX_WIDTH, 0, 0 }, + } +}, { .buffer_created = 1, .name = "X0L2 Normal sizes", .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_X0L2, .handles = { 1, 0, 0 }, .pitches = { 1200, 0, 0 } -- GitLab From 80f48b7d77fc82b5f7b7f4ab14b4bbcb618c5e53 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:28 -0300 Subject: [PATCH 119/970] drm/tests: Replace strcpy to strscpy on drm_test_framebuffer_create test Replace the use of strcpy to strscpy on the test_to_desc of the drm_test_framebuffer_create test for better security and reliability. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-4-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 3ed987423322..4b1884be9d7a 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -409,7 +409,7 @@ static void drm_test_framebuffer_create(struct kunit *test) static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, char *desc) { - strcpy(desc, t->name); + strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); } KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases, -- GitLab From fa90bc49882841b4985dd01f37a8d7703e832a6a Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:29 -0300 Subject: [PATCH 120/970] drm/tests: Add test case for drm_internal_framebuffer_create() Introduce a test to cover the creation of framebuffer with modifier on a device that doesn't support it. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-5-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 4b1884be9d7a..2ea3abfd5e7a 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -415,8 +415,32 @@ static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, c KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases, drm_framebuffer_test_to_desc); +/* Tries to create a framebuffer with modifiers without drm_device supporting it */ +static void drm_test_framebuffer_modifiers_not_supported(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct drm_framebuffer *fb; + + /* A valid cmd with modifier */ + struct drm_mode_fb_cmd2 cmd = { + .width = MAX_WIDTH, .height = MAX_HEIGHT, + .pixel_format = DRM_FORMAT_ABGR8888, .handles = { 1, 0, 0 }, + .offsets = { UINT_MAX / 2, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, + .flags = DRM_MODE_FB_MODIFIERS, + }; + + priv->buffer_created = false; + dev->mode_config.fb_modifiers_not_supported = 1; + + fb = drm_internal_framebuffer_create(dev, &cmd, NULL); + KUNIT_EXPECT_EQ(test, priv->buffer_created, false); + KUNIT_EXPECT_EQ(test, PTR_ERR(fb), -EINVAL); +} + static struct kunit_case drm_framebuffer_tests[] = { KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), + KUNIT_CASE(drm_test_framebuffer_modifiers_not_supported), { } }; -- GitLab From 49cdbcbad6142bd738d27cbd8dc063ac9a35a464 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:30 -0300 Subject: [PATCH 121/970] drm/tests: Add test for drm_framebuffer_check_src_coords() Add a parametrized test for the drm_framebuffer_check_src_coords function. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-6-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/drm_framebuffer.c | 1 + drivers/gpu/drm/tests/drm_framebuffer_test.c | 61 ++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 888aadb6a4ac..9cd85ac789bb 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -99,6 +99,7 @@ int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y, return 0; } +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_check_src_coords); /** * drm_mode_addfb - add an FB to the graphics configuration diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 2ea3abfd5e7a..1924e3f9538e 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -10,6 +10,7 @@ #include <drm/drm_device.h> #include <drm/drm_drv.h> #include <drm/drm_mode.h> +#include <drm/drm_framebuffer.h> #include <drm/drm_fourcc.h> #include <drm/drm_kunit_helpers.h> #include <drm/drm_print.h> @@ -438,7 +439,67 @@ static void drm_test_framebuffer_modifiers_not_supported(struct kunit *test) KUNIT_EXPECT_EQ(test, PTR_ERR(fb), -EINVAL); } +/* Parameters for testing drm_framebuffer_check_src_coords function */ +struct drm_framebuffer_check_src_coords_case { + const char *name; + const int expect; + const unsigned int fb_size; + const uint32_t src_x; + const uint32_t src_y; + + /* Deltas to be applied on source */ + const uint32_t dsrc_w; + const uint32_t dsrc_h; +}; + +static const struct drm_framebuffer_check_src_coords_case +drm_framebuffer_check_src_coords_cases[] = { + { .name = "Success: source fits into fb", + .expect = 0, + }, + { .name = "Fail: overflowing fb with x-axis coordinate", + .expect = -ENOSPC, .src_x = 1, .fb_size = UINT_MAX, + }, + { .name = "Fail: overflowing fb with y-axis coordinate", + .expect = -ENOSPC, .src_y = 1, .fb_size = UINT_MAX, + }, + { .name = "Fail: overflowing fb with source width", + .expect = -ENOSPC, .dsrc_w = 1, .fb_size = UINT_MAX - 1, + }, + { .name = "Fail: overflowing fb with source height", + .expect = -ENOSPC, .dsrc_h = 1, .fb_size = UINT_MAX - 1, + }, +}; + +static void drm_test_framebuffer_check_src_coords(struct kunit *test) +{ + const struct drm_framebuffer_check_src_coords_case *params = test->param_value; + const uint32_t src_x = params->src_x; + const uint32_t src_y = params->src_y; + const uint32_t src_w = (params->fb_size << 16) + params->dsrc_w; + const uint32_t src_h = (params->fb_size << 16) + params->dsrc_h; + const struct drm_framebuffer fb = { + .width = params->fb_size, + .height = params->fb_size + }; + int ret; + + ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, &fb); + KUNIT_EXPECT_EQ(test, ret, params->expect); +} + +static void +check_src_coords_test_to_desc(const struct drm_framebuffer_check_src_coords_case *t, + char *desc) +{ + strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); +} + +KUNIT_ARRAY_PARAM(check_src_coords, drm_framebuffer_check_src_coords_cases, + check_src_coords_test_to_desc); + static struct kunit_case drm_framebuffer_tests[] = { + KUNIT_CASE_PARAM(drm_test_framebuffer_check_src_coords, check_src_coords_gen_params), KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), KUNIT_CASE(drm_test_framebuffer_modifiers_not_supported), { } -- GitLab From 1bb74f6cc3d593fff7c96314ec4901a4055cbf17 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:31 -0300 Subject: [PATCH 122/970] drm/tests: Add test for drm_framebuffer_cleanup() Add a single KUnit test case for the drm_framebuffer_cleanup function. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-7-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 1924e3f9538e..908583d74b20 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -498,8 +498,40 @@ check_src_coords_test_to_desc(const struct drm_framebuffer_check_src_coords_case KUNIT_ARRAY_PARAM(check_src_coords, drm_framebuffer_check_src_coords_cases, check_src_coords_test_to_desc); +/* + * Test if drm_framebuffer_cleanup() really pops out the framebuffer object + * from device's fb_list and decrement the number of framebuffers for that + * device, which is the only things it does. + */ +static void drm_test_framebuffer_cleanup(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct list_head *fb_list = &dev->mode_config.fb_list; + struct drm_format_info format = { }; + struct drm_framebuffer fb1 = { .dev = dev, .format = &format }; + struct drm_framebuffer fb2 = { .dev = dev, .format = &format }; + + /* This will result on [fb_list] -> fb2 -> fb1 */ + drm_framebuffer_init(dev, &fb1, NULL); + drm_framebuffer_init(dev, &fb2, NULL); + + drm_framebuffer_cleanup(&fb1); + + /* Now fb2 is the only one element on fb_list */ + KUNIT_ASSERT_TRUE(test, list_is_singular(&fb2.head)); + KUNIT_ASSERT_EQ(test, dev->mode_config.num_fb, 1); + + drm_framebuffer_cleanup(&fb2); + + /* Now fb_list is empty */ + KUNIT_ASSERT_TRUE(test, list_empty(fb_list)); + KUNIT_ASSERT_EQ(test, dev->mode_config.num_fb, 0); +} + static struct kunit_case drm_framebuffer_tests[] = { KUNIT_CASE_PARAM(drm_test_framebuffer_check_src_coords, check_src_coords_gen_params), + KUNIT_CASE(drm_test_framebuffer_cleanup), KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), KUNIT_CASE(drm_test_framebuffer_modifiers_not_supported), { } -- GitLab From 3b3732b0d30fa2bb07c2b7f95df9b33b75e32d07 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:32 -0300 Subject: [PATCH 123/970] drm/tests: Add test for drm_framebuffer_lookup() Add two KUnit test cases for the drm_framebuffer_lookup function, one for the base case, that tests if the lookup finds the correct framebuffer object and another that tests the lookup for an inexistent framebuffer. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-8-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 908583d74b20..e11b5bc9a105 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -529,10 +529,51 @@ static void drm_test_framebuffer_cleanup(struct kunit *test) KUNIT_ASSERT_EQ(test, dev->mode_config.num_fb, 0); } +/* + * Initialize a framebuffer, lookup its id and test if the returned reference + * matches. + */ +static void drm_test_framebuffer_lookup(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct drm_format_info format = { }; + struct drm_framebuffer expected_fb = { .dev = dev, .format = &format }; + struct drm_framebuffer *returned_fb; + uint32_t id = 0; + int ret; + + ret = drm_framebuffer_init(dev, &expected_fb, NULL); + KUNIT_ASSERT_EQ(test, ret, 0); + id = expected_fb.base.id; + + /* Looking for expected_fb */ + returned_fb = drm_framebuffer_lookup(dev, NULL, id); + KUNIT_EXPECT_PTR_EQ(test, returned_fb, &expected_fb); + drm_framebuffer_put(returned_fb); + + drm_framebuffer_cleanup(&expected_fb); +} + +/* Try to lookup an id that is not linked to a framebuffer */ +static void drm_test_framebuffer_lookup_inexistent(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct drm_framebuffer *fb; + uint32_t id = 0; + + /* Looking for an inexistent framebuffer */ + fb = drm_framebuffer_lookup(dev, NULL, id); + KUNIT_EXPECT_NULL(test, fb); +} + static struct kunit_case drm_framebuffer_tests[] = { KUNIT_CASE_PARAM(drm_test_framebuffer_check_src_coords, check_src_coords_gen_params), KUNIT_CASE(drm_test_framebuffer_cleanup), KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), + KUNIT_CASE(drm_test_framebuffer_lookup), + KUNIT_CASE(drm_test_framebuffer_lookup_inexistent), KUNIT_CASE(drm_test_framebuffer_modifiers_not_supported), { } }; -- GitLab From 2735d5e4060960c7bd06698b0a1990c7d42c762e Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:33 -0300 Subject: [PATCH 124/970] drm/tests: Add test for drm_framebuffer_init() Add three KUnit test cases for the drm_framebuffer_init function: 1. Test if expected values are being set after drm_framebuffer_init() call. 2. Try to init a framebuffer without setting its format. 3. Try calling drm_framebuffer_init() with mismatch of the drm_device passed at the first argument and the one pointed by fb->dev. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-9-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/drm_framebuffer.c | 1 + drivers/gpu/drm/tests/drm_framebuffer_test.c | 84 ++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 9cd85ac789bb..47e6e8577b62 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -839,6 +839,7 @@ void drm_framebuffer_free(struct kref *kref) fb->funcs->destroy(fb); } +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free); /** * drm_framebuffer_init - initialize a framebuffer diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index e11b5bc9a105..72314805839d 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -5,6 +5,7 @@ * Copyright (c) 2022 MaÃra Canal <mairacanal@riseup.net> */ +#include <kunit/device.h> #include <kunit/test.h> #include <drm/drm_device.h> @@ -568,10 +569,93 @@ static void drm_test_framebuffer_lookup_inexistent(struct kunit *test) KUNIT_EXPECT_NULL(test, fb); } +/* + * Test if drm_framebuffer_init initializes the framebuffer successfully, + * asserting that its modeset object struct and its refcount are correctly + * set and that strictly one framebuffer is initialized. + */ +static void drm_test_framebuffer_init(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct drm_format_info format = { }; + struct drm_framebuffer fb1 = { .dev = dev, .format = &format }; + struct drm_framebuffer_funcs funcs = { }; + int ret; + + ret = drm_framebuffer_init(dev, &fb1, &funcs); + KUNIT_ASSERT_EQ(test, ret, 0); + + /* Check if fb->funcs is actually set to the drm_framebuffer_funcs passed on */ + KUNIT_EXPECT_PTR_EQ(test, fb1.funcs, &funcs); + + /* The fb->comm must be set to the current running process */ + KUNIT_EXPECT_STREQ(test, fb1.comm, current->comm); + + /* The fb->base must be successfully initialized */ + KUNIT_EXPECT_NE(test, fb1.base.id, 0); + KUNIT_EXPECT_EQ(test, fb1.base.type, DRM_MODE_OBJECT_FB); + KUNIT_EXPECT_EQ(test, kref_read(&fb1.base.refcount), 1); + KUNIT_EXPECT_PTR_EQ(test, fb1.base.free_cb, &drm_framebuffer_free); + + /* There must be just that one fb initialized */ + KUNIT_EXPECT_EQ(test, dev->mode_config.num_fb, 1); + KUNIT_EXPECT_PTR_EQ(test, dev->mode_config.fb_list.prev, &fb1.head); + KUNIT_EXPECT_PTR_EQ(test, dev->mode_config.fb_list.next, &fb1.head); + + drm_framebuffer_cleanup(&fb1); +} + +/* Try to init a framebuffer without setting its format */ +static void drm_test_framebuffer_init_bad_format(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct drm_framebuffer fb1 = { .dev = dev, .format = NULL }; + struct drm_framebuffer_funcs funcs = { }; + int ret; + + /* Fails if fb.format isn't set */ + ret = drm_framebuffer_init(dev, &fb1, &funcs); + KUNIT_EXPECT_EQ(test, ret, -EINVAL); +} + +/* + * Test calling drm_framebuffer_init() passing a framebuffer linked to a + * different drm_device parent from the one passed on the first argument, which + * must fail. + */ +static void drm_test_framebuffer_init_dev_mismatch(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *right_dev = &priv->dev; + struct drm_device *wrong_dev; + struct device *wrong_dev_parent; + struct drm_format_info format = { }; + struct drm_framebuffer fb1 = { .dev = right_dev, .format = &format }; + struct drm_framebuffer_funcs funcs = { }; + int ret; + + wrong_dev_parent = kunit_device_register(test, "drm-kunit-wrong-device-mock"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, wrong_dev_parent); + + wrong_dev = __drm_kunit_helper_alloc_drm_device(test, wrong_dev_parent, + sizeof(struct drm_device), + 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, wrong_dev); + + /* Fails if fb->dev doesn't point to the drm_device passed on first arg */ + ret = drm_framebuffer_init(wrong_dev, &fb1, &funcs); + KUNIT_EXPECT_EQ(test, ret, -EINVAL); +} + static struct kunit_case drm_framebuffer_tests[] = { KUNIT_CASE_PARAM(drm_test_framebuffer_check_src_coords, check_src_coords_gen_params), KUNIT_CASE(drm_test_framebuffer_cleanup), KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), + KUNIT_CASE(drm_test_framebuffer_init), + KUNIT_CASE(drm_test_framebuffer_init_bad_format), + KUNIT_CASE(drm_test_framebuffer_init_dev_mismatch), KUNIT_CASE(drm_test_framebuffer_lookup), KUNIT_CASE(drm_test_framebuffer_lookup_inexistent), KUNIT_CASE(drm_test_framebuffer_modifiers_not_supported), -- GitLab From d2194256049910d286cd6c308c2689df521d8842 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Date: Tue, 10 Sep 2024 21:15:34 -0300 Subject: [PATCH 125/970] drm/tests: Add test for drm_framebuffer_free() Add a single KUnit test case for the drm_framebuffer_free function. Signed-off-by: Carlos Eduardo Gallo Filho <gcarlos@disroot.org> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911001559.28284-10-gcarlos@disroot.org Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/drm_mode_object.c | 1 + drivers/gpu/drm/tests/drm_framebuffer_test.c | 50 ++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index df4cc0e8e263..e943205a2394 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -81,6 +81,7 @@ int drm_mode_object_add(struct drm_device *dev, { return __drm_mode_object_add(dev, obj, obj_type, true, NULL); } +EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_mode_object_add); void drm_mode_object_register(struct drm_device *dev, struct drm_mode_object *obj) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 72314805839d..6ea04cc8f324 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -358,6 +358,7 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { struct drm_framebuffer_test_priv { struct drm_device dev; bool buffer_created; + bool buffer_freed; }; static struct drm_framebuffer *fb_create_mock(struct drm_device *dev, @@ -649,10 +650,59 @@ static void drm_test_framebuffer_init_dev_mismatch(struct kunit *test) KUNIT_EXPECT_EQ(test, ret, -EINVAL); } +static void destroy_free_mock(struct drm_framebuffer *fb) +{ + struct drm_framebuffer_test_priv *priv = container_of(fb->dev, typeof(*priv), dev); + + priv->buffer_freed = true; +} + +static struct drm_framebuffer_funcs framebuffer_funcs_free_mock = { + .destroy = destroy_free_mock, +}; + +/* + * In summary, the drm_framebuffer_free() function must implicitly call + * fb->funcs->destroy() and garantee that the framebufer object is unregistered + * from the drm_device idr pool. + */ +static void drm_test_framebuffer_free(struct kunit *test) +{ + struct drm_framebuffer_test_priv *priv = test->priv; + struct drm_device *dev = &priv->dev; + struct drm_mode_object *obj; + struct drm_framebuffer fb = { + .dev = dev, + .funcs = &framebuffer_funcs_free_mock, + }; + int id, ret; + + priv->buffer_freed = false; + + /* + * Mock a framebuffer that was not unregistered at the moment of the + * drm_framebuffer_free() call. + */ + ret = drm_mode_object_add(dev, &fb.base, DRM_MODE_OBJECT_FB); + KUNIT_ASSERT_EQ(test, ret, 0); + id = fb.base.id; + + drm_framebuffer_free(&fb.base.refcount); + + /* The framebuffer object must be unregistered */ + obj = drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_FB); + KUNIT_EXPECT_PTR_EQ(test, obj, NULL); + KUNIT_EXPECT_EQ(test, fb.base.id, 0); + + /* Test if fb->funcs->destroy() was called */ + KUNIT_EXPECT_EQ(test, priv->buffer_freed, true); +} + static struct kunit_case drm_framebuffer_tests[] = { KUNIT_CASE_PARAM(drm_test_framebuffer_check_src_coords, check_src_coords_gen_params), KUNIT_CASE(drm_test_framebuffer_cleanup), KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), + KUNIT_CASE(drm_test_framebuffer_free), KUNIT_CASE(drm_test_framebuffer_init), KUNIT_CASE(drm_test_framebuffer_init_bad_format), KUNIT_CASE(drm_test_framebuffer_init_dev_mismatch), -- GitLab From 474f64cb988a410db8a0b779d6afdaa2a7fc5759 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Date: Thu, 5 Sep 2024 17:00:49 +0200 Subject: [PATCH 126/970] drm/xe: Fix missing conversion to xe_display_pm_runtime_resume This error path was missed when converting away from xe_display_pm_resume with second argument. Fixes: 66a0f6b9f5fc ("drm/xe/display: handle HPD polling in display runtime suspend/resume") Cc: Arun R Murthy <arun.r.murthy@intel.com> Cc: Vinod Govindapillai <vinod.govindapillai@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Vinod Govindapillai <vinod.govindapillai@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905150052.174895-2-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/xe/xe_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index a3d1509066f7..7cf2160fe040 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -416,7 +416,7 @@ int xe_pm_runtime_suspend(struct xe_device *xe) xe_display_pm_suspend_late(xe); out: if (err) - xe_display_pm_resume(xe, true); + xe_display_pm_runtime_resume(xe); xe_rpm_lockmap_release(xe); xe_pm_write_callback_task(xe, NULL); return err; -- GitLab From f90491d4b64e302e940133103d3d9908e70e454f Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Date: Thu, 5 Sep 2024 17:00:50 +0200 Subject: [PATCH 127/970] drm/xe: Remove runtime argument from display s/r functions The previous change ensures that pm_suspend is only called when suspending or resuming. This ensures no further bugs like those in the previous commit. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Vinod Govindapillai <vinod.govindapillai@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905150052.174895-3-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/xe/display/xe_display.c | 53 +++++++++++++++---------- drivers/gpu/drm/xe/display/xe_display.h | 8 ++-- drivers/gpu/drm/xe/xe_pm.c | 6 +-- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 75736faf2a80..1c25c4f6a53b 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -309,18 +309,7 @@ static void xe_display_flush_cleanup_work(struct xe_device *xe) } /* TODO: System and runtime suspend/resume sequences will be sanitized as a follow-up. */ -void xe_display_pm_runtime_suspend(struct xe_device *xe) -{ - if (!xe->info.probe_display) - return; - - if (xe->d3cold.allowed) - xe_display_pm_suspend(xe, true); - - intel_hpd_poll_enable(xe); -} - -void xe_display_pm_suspend(struct xe_device *xe, bool runtime) +static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime) { struct intel_display *display = &xe->display; bool s2idle = suspend_to_idle(); @@ -355,26 +344,31 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime) intel_dmc_suspend(xe); } -void xe_display_pm_suspend_late(struct xe_device *xe) +void xe_display_pm_suspend(struct xe_device *xe) +{ + __xe_display_pm_suspend(xe, false); +} + +void xe_display_pm_runtime_suspend(struct xe_device *xe) { - bool s2idle = suspend_to_idle(); if (!xe->info.probe_display) return; - intel_power_domains_suspend(xe, s2idle); + if (xe->d3cold.allowed) + __xe_display_pm_suspend(xe, true); - intel_display_power_suspend_late(xe); + intel_hpd_poll_enable(xe); } -void xe_display_pm_runtime_resume(struct xe_device *xe) +void xe_display_pm_suspend_late(struct xe_device *xe) { + bool s2idle = suspend_to_idle(); if (!xe->info.probe_display) return; - intel_hpd_poll_disable(xe); + intel_power_domains_suspend(xe, s2idle); - if (xe->d3cold.allowed) - xe_display_pm_resume(xe, true); + intel_display_power_suspend_late(xe); } void xe_display_pm_resume_early(struct xe_device *xe) @@ -387,7 +381,7 @@ void xe_display_pm_resume_early(struct xe_device *xe) intel_power_domains_resume(xe); } -void xe_display_pm_resume(struct xe_device *xe, bool runtime) +static void __xe_display_pm_resume(struct xe_device *xe, bool runtime) { struct intel_display *display = &xe->display; @@ -421,6 +415,23 @@ void xe_display_pm_resume(struct xe_device *xe, bool runtime) intel_power_domains_enable(xe); } +void xe_display_pm_resume(struct xe_device *xe) +{ + __xe_display_pm_resume(xe, false); +} + +void xe_display_pm_runtime_resume(struct xe_device *xe) +{ + if (!xe->info.probe_display) + return; + + intel_hpd_poll_disable(xe); + + if (xe->d3cold.allowed) + __xe_display_pm_resume(xe, true); +} + + static void display_device_remove(struct drm_device *dev, void *arg) { struct xe_device *xe = arg; diff --git a/drivers/gpu/drm/xe/display/xe_display.h b/drivers/gpu/drm/xe/display/xe_display.h index 53d727fd792b..bed55fd26f30 100644 --- a/drivers/gpu/drm/xe/display/xe_display.h +++ b/drivers/gpu/drm/xe/display/xe_display.h @@ -34,10 +34,10 @@ void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir); void xe_display_irq_reset(struct xe_device *xe); void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt); -void xe_display_pm_suspend(struct xe_device *xe, bool runtime); +void xe_display_pm_suspend(struct xe_device *xe); void xe_display_pm_suspend_late(struct xe_device *xe); void xe_display_pm_resume_early(struct xe_device *xe); -void xe_display_pm_resume(struct xe_device *xe, bool runtime); +void xe_display_pm_resume(struct xe_device *xe); void xe_display_pm_runtime_suspend(struct xe_device *xe); void xe_display_pm_runtime_resume(struct xe_device *xe); @@ -65,10 +65,10 @@ static inline void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir) static inline void xe_display_irq_reset(struct xe_device *xe) {} static inline void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt) {} -static inline void xe_display_pm_suspend(struct xe_device *xe, bool runtime) {} +static inline void xe_display_pm_suspend(struct xe_device *xe) {} static inline void xe_display_pm_suspend_late(struct xe_device *xe) {} static inline void xe_display_pm_resume_early(struct xe_device *xe) {} -static inline void xe_display_pm_resume(struct xe_device *xe, bool runtime) {} +static inline void xe_display_pm_resume(struct xe_device *xe) {} static inline void xe_display_pm_runtime_suspend(struct xe_device *xe) {} static inline void xe_display_pm_runtime_resume(struct xe_device *xe) {} diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index 7cf2160fe040..33eb039053e4 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -123,7 +123,7 @@ int xe_pm_suspend(struct xe_device *xe) for_each_gt(gt, xe, id) xe_gt_suspend_prepare(gt); - xe_display_pm_suspend(xe, false); + xe_display_pm_suspend(xe); /* FIXME: Super racey... */ err = xe_bo_evict_all(xe); @@ -133,7 +133,7 @@ int xe_pm_suspend(struct xe_device *xe) for_each_gt(gt, xe, id) { err = xe_gt_suspend(gt); if (err) { - xe_display_pm_resume(xe, false); + xe_display_pm_resume(xe); goto err; } } @@ -187,7 +187,7 @@ int xe_pm_resume(struct xe_device *xe) for_each_gt(gt, xe, id) xe_gt_resume(gt); - xe_display_pm_resume(xe, false); + xe_display_pm_resume(xe); err = xe_bo_restore_user(xe); if (err) -- GitLab From 501d799a47e2b83b4e41d5306c2266ea5c100a08 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Date: Thu, 5 Sep 2024 17:00:51 +0200 Subject: [PATCH 128/970] drm/xe: Wire up device shutdown handler The system is turning off, and we should probably put the device in a safe power state. We don't need to evict VRAM or suspend running jobs to a safe state, as the device is rebooted anyway. This does not imply the system is necessarily reset, as we can kexec into a new kernel. Without shutting down, things like USB Type-C may mysteriously start failing. References: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/3500 Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> [mlankhorst: Add !xe_driver_flr_disabled assert] Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905150052.174895-4-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/xe/display/xe_display.c | 43 +++++++++++++++++++++++++ drivers/gpu/drm/xe/display/xe_display.h | 4 +++ drivers/gpu/drm/xe/xe_device.c | 40 +++++++++++++++++++---- drivers/gpu/drm/xe/xe_gt.c | 7 ++++ drivers/gpu/drm/xe/xe_gt.h | 1 + 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 1c25c4f6a53b..86009a17e4c2 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -349,6 +349,36 @@ void xe_display_pm_suspend(struct xe_device *xe) __xe_display_pm_suspend(xe, false); } +void xe_display_pm_shutdown(struct xe_device *xe) +{ + struct intel_display *display = &xe->display; + + if (!xe->info.probe_display) + return; + + intel_power_domains_disable(xe); + intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_SUSPENDED, true); + if (has_display(xe)) { + drm_kms_helper_poll_disable(&xe->drm); + intel_display_driver_disable_user_access(xe); + intel_display_driver_suspend(xe); + } + + xe_display_flush_cleanup_work(xe); + intel_dp_mst_suspend(xe); + intel_hpd_cancel_work(xe); + + if (has_display(xe)) + intel_display_driver_suspend_access(xe); + + intel_encoder_suspend_all(display); + intel_encoder_shutdown_all(display); + + intel_opregion_suspend(display, PCI_D3cold); + + intel_dmc_suspend(xe); +} + void xe_display_pm_runtime_suspend(struct xe_device *xe) { if (!xe->info.probe_display) @@ -371,6 +401,19 @@ void xe_display_pm_suspend_late(struct xe_device *xe) intel_display_power_suspend_late(xe); } +void xe_display_pm_shutdown_late(struct xe_device *xe) +{ + if (!xe->info.probe_display) + return; + + /* + * The only requirement is to reboot with display DC states disabled, + * for now leaving all display power wells in the INIT power domain + * enabled. + */ + intel_power_domains_driver_remove(xe); +} + void xe_display_pm_resume_early(struct xe_device *xe) { if (!xe->info.probe_display) diff --git a/drivers/gpu/drm/xe/display/xe_display.h b/drivers/gpu/drm/xe/display/xe_display.h index bed55fd26f30..17afa537aee5 100644 --- a/drivers/gpu/drm/xe/display/xe_display.h +++ b/drivers/gpu/drm/xe/display/xe_display.h @@ -35,7 +35,9 @@ void xe_display_irq_reset(struct xe_device *xe); void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt); void xe_display_pm_suspend(struct xe_device *xe); +void xe_display_pm_shutdown(struct xe_device *xe); void xe_display_pm_suspend_late(struct xe_device *xe); +void xe_display_pm_shutdown_late(struct xe_device *xe); void xe_display_pm_resume_early(struct xe_device *xe); void xe_display_pm_resume(struct xe_device *xe); void xe_display_pm_runtime_suspend(struct xe_device *xe); @@ -66,7 +68,9 @@ static inline void xe_display_irq_reset(struct xe_device *xe) {} static inline void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt) {} static inline void xe_display_pm_suspend(struct xe_device *xe) {} +static inline void xe_display_pm_shutdown(struct xe_device *xe) {} static inline void xe_display_pm_suspend_late(struct xe_device *xe) {} +static inline void xe_display_pm_shutdown_late(struct xe_device *xe) {} static inline void xe_display_pm_resume_early(struct xe_device *xe) {} static inline void xe_display_pm_resume(struct xe_device *xe) {} static inline void xe_display_pm_runtime_suspend(struct xe_device *xe) {} diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 449b85035d3a..fdb3a4133f43 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -383,6 +383,11 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, return ERR_PTR(err); } +static bool xe_driver_flr_disabled(struct xe_device *xe) +{ + return xe_mmio_read32(xe_root_mmio_gt(xe), GU_CNTL_PROTECTED) & DRIVERINT_FLR_DIS; +} + /* * The driver-initiated FLR is the highest level of reset that we can trigger * from within the driver. It is different from the PCI FLR in that it doesn't @@ -396,17 +401,12 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, * if/when a new instance of i915 is bound to the device it will do a full * re-init anyway. */ -static void xe_driver_flr(struct xe_device *xe) +static void __xe_driver_flr(struct xe_device *xe) { const unsigned int flr_timeout = 3 * MICRO; /* specs recommend a 3s wait */ struct xe_gt *gt = xe_root_mmio_gt(xe); int ret; - if (xe_mmio_read32(gt, GU_CNTL_PROTECTED) & DRIVERINT_FLR_DIS) { - drm_info_once(&xe->drm, "BIOS Disabled Driver-FLR\n"); - return; - } - drm_dbg(&xe->drm, "Triggering Driver-FLR\n"); /* @@ -447,6 +447,16 @@ static void xe_driver_flr(struct xe_device *xe) xe_mmio_write32(gt, GU_DEBUG, DRIVERFLR_STATUS); } +static void xe_driver_flr(struct xe_device *xe) +{ + if (xe_driver_flr_disabled(xe)) { + drm_info_once(&xe->drm, "BIOS Disabled Driver-FLR\n"); + return; + } + + __xe_driver_flr(xe); +} + static void xe_driver_flr_fini(void *arg) { struct xe_device *xe = arg; @@ -800,6 +810,24 @@ void xe_device_remove(struct xe_device *xe) void xe_device_shutdown(struct xe_device *xe) { + struct xe_gt *gt; + u8 id; + + drm_dbg(&xe->drm, "Shutting down device\n"); + + if (xe_driver_flr_disabled(xe)) { + xe_display_pm_shutdown(xe); + + xe_irq_suspend(xe); + + for_each_gt(gt, xe, id) + xe_gt_shutdown(gt); + + xe_display_pm_shutdown_late(xe); + } else { + /* BOOM! */ + __xe_driver_flr(xe); + } } /** diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index f0dc2bf24c7b..9e338f4e5fb2 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -862,6 +862,13 @@ int xe_gt_suspend(struct xe_gt *gt) return err; } +void xe_gt_shutdown(struct xe_gt *gt) +{ + xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); + do_gt_reset(gt); + xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); +} + /** * xe_gt_sanitize_freq() - Restore saved frequencies if necessary. * @gt: the GT object diff --git a/drivers/gpu/drm/xe/xe_gt.h b/drivers/gpu/drm/xe/xe_gt.h index 8b1a5027dcf2..97def44afa4c 100644 --- a/drivers/gpu/drm/xe/xe_gt.h +++ b/drivers/gpu/drm/xe/xe_gt.h @@ -54,6 +54,7 @@ void xe_gt_record_user_engines(struct xe_gt *gt); void xe_gt_suspend_prepare(struct xe_gt *gt); int xe_gt_suspend(struct xe_gt *gt); +void xe_gt_shutdown(struct xe_gt *gt); int xe_gt_resume(struct xe_gt *gt); void xe_gt_reset_async(struct xe_gt *gt); void xe_gt_sanitize(struct xe_gt *gt); -- GitLab From fb2551a0e93897aec7fb3d4f473ebc06b146d160 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit <ashutosh.dixit@intel.com> Date: Mon, 9 Sep 2024 09:59:33 -0700 Subject: [PATCH 129/970] drm/xe/oa: Enable Xe2+ PES disaggregation Enable Xe2+ PES disaggregation (for OAG) to retrieve disaggregated metrics when disaggregated data is needed. Userspace can select whether to receive aggregated or disaggregated metrics via the particular OA configuration it uses (programmed via DRM_XE_OBSERVATION_OP_ADD_CONFIG). Bspec: 61101 Fixes: e936f885f1e9 ("drm/xe/oa/uapi: Expose OA stream fd") Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240909165933.2638765-1-ashutosh.dixit@intel.com Cc: stable@vger.kernel.org --- drivers/gpu/drm/xe/regs/xe_oa_regs.h | 1 + drivers/gpu/drm/xe/xe_oa.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_oa_regs.h b/drivers/gpu/drm/xe/regs/xe_oa_regs.h index 1189f5a540a8..a9b0091cb7ee 100644 --- a/drivers/gpu/drm/xe/regs/xe_oa_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_oa_regs.h @@ -52,6 +52,7 @@ #define OAG_OABUFFER_MEMORY_SELECT REG_BIT(0) /* 0: PPGTT, 1: GGTT */ #define OAG_OACONTROL XE_REG(0xdaf4) +#define OAG_OACONTROL_OA_PES_DISAG_EN REG_GENMASK(27, 22) #define OAG_OACONTROL_OA_CCS_SELECT_MASK REG_GENMASK(18, 16) #define OAG_OACONTROL_OA_COUNTER_SEL_MASK REG_GENMASK(4, 2) #define OAG_OACONTROL_OA_COUNTER_ENABLE REG_BIT(0) diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 63286ed8457f..0369cc016f6a 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -440,6 +440,10 @@ static void xe_oa_enable(struct xe_oa_stream *stream) val = __format_to_oactrl(format, regs->oa_ctrl_counter_select_mask) | __oa_ccs_select(stream) | OAG_OACONTROL_OA_COUNTER_ENABLE; + if (GRAPHICS_VER(stream->oa->xe) >= 20 && + stream->hwe->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG) + val |= OAG_OACONTROL_OA_PES_DISAG_EN; + xe_mmio_write32(stream->gt, regs->oa_ctrl, val); } -- GitLab From 32e5666b8a4d0f2aee39a0b2f8386cf9f86a8225 Mon Sep 17 00:00:00 2001 From: Tejas Vipin <tejasvipin76@gmail.com> Date: Wed, 4 Sep 2024 19:45:21 +0530 Subject: [PATCH 130/970] drm/panel: himax-hx83112a: transition to mipi_dsi wrapped functions Changes the himax-hx83112a panel to use multi style functions for improved error handling. Signed-off-by: Tejas Vipin <tejasvipin76@gmail.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240904141521.554451-1-tejasvipin76@gmail.com --- drivers/gpu/drm/panel/panel-himax-hx83112a.c | 297 +++++++++---------- 1 file changed, 136 insertions(+), 161 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-himax-hx83112a.c b/drivers/gpu/drm/panel/panel-himax-hx83112a.c index 466c27012abf..47bce087e339 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx83112a.c +++ b/drivers/gpu/drm/panel/panel-himax-hx83112a.c @@ -56,198 +56,173 @@ static void hx83112a_reset(struct hx83112a_panel *ctx) msleep(50); } -static int hx83112a_on(struct hx83112a_panel *ctx) +static int hx83112a_on(struct mipi_dsi_device *dsi) { - struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags |= MIPI_DSI_MODE_LPM; - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETEXTC, 0x83, 0x11, 0x2a); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETPOWER1, - 0x08, 0x28, 0x28, 0x83, 0x83, 0x4c, 0x4f, 0x33); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDISP, - 0x00, 0x02, 0x00, 0x90, 0x24, 0x00, 0x08, 0x19, - 0xea, 0x11, 0x11, 0x00, 0x11, 0xa3); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDRV, - 0x58, 0x68, 0x58, 0x68, 0x0f, 0xef, 0x0b, 0xc0, - 0x0b, 0xc0, 0x0b, 0xc0, 0x00, 0xff, 0x00, 0xff, - 0x00, 0x00, 0x14, 0x15, 0x00, 0x29, 0x11, 0x07, - 0x12, 0x00, 0x29); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x02); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDRV, - 0x00, 0x12, 0x12, 0x11, 0x88, 0x12, 0x12, 0x00, - 0x53); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x03); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDGCLUT, - 0xff, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, 0xed, 0xe6, - 0xe2, 0xde, 0xdb, 0xd6, 0xd3, 0xcf, 0xca, 0xc6, - 0xc2, 0xbe, 0xb9, 0xb0, 0xa7, 0x9e, 0x96, 0x8d, - 0x84, 0x7c, 0x74, 0x6b, 0x62, 0x5a, 0x51, 0x49, - 0x41, 0x39, 0x31, 0x29, 0x21, 0x19, 0x12, 0x0a, - 0x06, 0x05, 0x02, 0x01, 0x00, 0x00, 0xc9, 0xb3, - 0x08, 0x0e, 0xf2, 0xe1, 0x59, 0xf4, 0x22, 0xad, - 0x40); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x02); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDGCLUT, - 0xff, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, 0xed, 0xe6, - 0xe2, 0xde, 0xdb, 0xd6, 0xd3, 0xcf, 0xca, 0xc6, - 0xc2, 0xbe, 0xb9, 0xb0, 0xa7, 0x9e, 0x96, 0x8d, - 0x84, 0x7c, 0x74, 0x6b, 0x62, 0x5a, 0x51, 0x49, - 0x41, 0x39, 0x31, 0x29, 0x21, 0x19, 0x12, 0x0a, - 0x06, 0x05, 0x02, 0x01, 0x00, 0x00, 0xc9, 0xb3, - 0x08, 0x0e, 0xf2, 0xe1, 0x59, 0xf4, 0x22, 0xad, - 0x40); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x01); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDGCLUT, - 0xff, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, 0xed, 0xe6, - 0xe2, 0xde, 0xdb, 0xd6, 0xd3, 0xcf, 0xca, 0xc6, - 0xc2, 0xbe, 0xb9, 0xb0, 0xa7, 0x9e, 0x96, 0x8d, - 0x84, 0x7c, 0x74, 0x6b, 0x62, 0x5a, 0x51, 0x49, - 0x41, 0x39, 0x31, 0x29, 0x21, 0x19, 0x12, 0x0a, - 0x06, 0x05, 0x02, 0x01, 0x00, 0x00, 0xc9, 0xb3, - 0x08, 0x0e, 0xf2, 0xe1, 0x59, 0xf4, 0x22, 0xad, - 0x40); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETDGCLUT, 0x01); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETTCON, - 0x70, 0x00, 0x04, 0xe0, 0x33, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETPANEL, 0x08); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETPOWER2, 0x2b, 0x2b); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP0, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, - 0x08, 0x03, 0x03, 0x22, 0x18, 0x07, 0x07, 0x07, - 0x07, 0x32, 0x10, 0x06, 0x00, 0x06, 0x32, 0x10, - 0x07, 0x00, 0x07, 0x32, 0x19, 0x31, 0x09, 0x31, - 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x09, 0x30, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x00, - 0x0f); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x01); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP0, - 0x00, 0x00, 0x19, 0x10, 0x00, 0x0a, 0x00, 0x81); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP1, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xc0, 0xc0, 0x18, 0x18, 0x19, 0x19, 0x18, 0x18, - 0x40, 0x40, 0x18, 0x18, 0x18, 0x18, 0x3f, 0x3f, - 0x28, 0x28, 0x24, 0x24, 0x02, 0x03, 0x02, 0x03, - 0x00, 0x01, 0x00, 0x01, 0x31, 0x31, 0x31, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP2, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x40, 0x40, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, - 0x40, 0x40, 0x18, 0x18, 0x18, 0x18, 0x3f, 0x3f, - 0x24, 0x24, 0x28, 0x28, 0x01, 0x00, 0x01, 0x00, - 0x03, 0x02, 0x03, 0x02, 0x31, 0x31, 0x31, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP3, - 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xab, 0xaa, - 0xaa, 0xaa, 0xaa, 0xea, 0xab, 0xaa, 0xaa, 0xaa); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x01); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP3, - 0xaa, 0x2e, 0x28, 0x00, 0x00, 0x00, 0xaa, 0x2e, - 0x28, 0x00, 0x00, 0x00, 0xaa, 0xee, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xee, 0xaa, 0xaa, 0xaa, 0xaa); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x02); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP3, - 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xff, - 0xff, 0xff, 0xff, 0xff); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x03); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETGIP3, - 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETTP1, - 0x0e, 0x0e, 0x1e, 0x65, 0x1c, 0x65, 0x00, 0x50, - 0x20, 0x20, 0x00, 0x00, 0x02, 0x02, 0x02, 0x05, - 0x14, 0x14, 0x32, 0xb9, 0x23, 0xb9, 0x08); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x01); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETTP1, - 0x02, 0x00, 0xa8, 0x01, 0xa8, 0x0d, 0xa4, 0x0e); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x02); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETTP1, - 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETBANK, 0x00); - mipi_dsi_dcs_write_seq(dsi, HX83112A_UNKNOWN1, 0xc3); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETCLOCK, 0xd1, 0xd6); - mipi_dsi_dcs_write_seq(dsi, HX83112A_UNKNOWN1, 0x3f); - mipi_dsi_dcs_write_seq(dsi, HX83112A_UNKNOWN1, 0xc6); - mipi_dsi_dcs_write_seq(dsi, HX83112A_SETPTBA, 0x37); - mipi_dsi_dcs_write_seq(dsi, HX83112A_UNKNOWN1, 0x3f); - - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to exit sleep mode: %d\n", ret); - return ret; - } - msleep(150); - - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display on: %d\n", ret); - return ret; - } - msleep(50); - - return 0; + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETEXTC, 0x83, 0x11, 0x2a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETPOWER1, + 0x08, 0x28, 0x28, 0x83, 0x83, 0x4c, 0x4f, 0x33); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDISP, + 0x00, 0x02, 0x00, 0x90, 0x24, 0x00, 0x08, 0x19, + 0xea, 0x11, 0x11, 0x00, 0x11, 0xa3); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDRV, + 0x58, 0x68, 0x58, 0x68, 0x0f, 0xef, 0x0b, 0xc0, + 0x0b, 0xc0, 0x0b, 0xc0, 0x00, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x14, 0x15, 0x00, 0x29, 0x11, 0x07, + 0x12, 0x00, 0x29); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDRV, + 0x00, 0x12, 0x12, 0x11, 0x88, 0x12, 0x12, 0x00, + 0x53); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDGCLUT, + 0xff, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, 0xed, 0xe6, + 0xe2, 0xde, 0xdb, 0xd6, 0xd3, 0xcf, 0xca, 0xc6, + 0xc2, 0xbe, 0xb9, 0xb0, 0xa7, 0x9e, 0x96, 0x8d, + 0x84, 0x7c, 0x74, 0x6b, 0x62, 0x5a, 0x51, 0x49, + 0x41, 0x39, 0x31, 0x29, 0x21, 0x19, 0x12, 0x0a, + 0x06, 0x05, 0x02, 0x01, 0x00, 0x00, 0xc9, 0xb3, + 0x08, 0x0e, 0xf2, 0xe1, 0x59, 0xf4, 0x22, 0xad, + 0x40); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDGCLUT, + 0xff, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, 0xed, 0xe6, + 0xe2, 0xde, 0xdb, 0xd6, 0xd3, 0xcf, 0xca, 0xc6, + 0xc2, 0xbe, 0xb9, 0xb0, 0xa7, 0x9e, 0x96, 0x8d, + 0x84, 0x7c, 0x74, 0x6b, 0x62, 0x5a, 0x51, 0x49, + 0x41, 0x39, 0x31, 0x29, 0x21, 0x19, 0x12, 0x0a, + 0x06, 0x05, 0x02, 0x01, 0x00, 0x00, 0xc9, 0xb3, + 0x08, 0x0e, 0xf2, 0xe1, 0x59, 0xf4, 0x22, 0xad, + 0x40); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDGCLUT, + 0xff, 0xfe, 0xfb, 0xf8, 0xf4, 0xf1, 0xed, 0xe6, + 0xe2, 0xde, 0xdb, 0xd6, 0xd3, 0xcf, 0xca, 0xc6, + 0xc2, 0xbe, 0xb9, 0xb0, 0xa7, 0x9e, 0x96, 0x8d, + 0x84, 0x7c, 0x74, 0x6b, 0x62, 0x5a, 0x51, 0x49, + 0x41, 0x39, 0x31, 0x29, 0x21, 0x19, 0x12, 0x0a, + 0x06, 0x05, 0x02, 0x01, 0x00, 0x00, 0xc9, 0xb3, + 0x08, 0x0e, 0xf2, 0xe1, 0x59, 0xf4, 0x22, 0xad, + 0x40); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETDGCLUT, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETTCON, + 0x70, 0x00, 0x04, 0xe0, 0x33, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETPANEL, 0x08); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETPOWER2, 0x2b, 0x2b); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP0, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, + 0x08, 0x03, 0x03, 0x22, 0x18, 0x07, 0x07, 0x07, + 0x07, 0x32, 0x10, 0x06, 0x00, 0x06, 0x32, 0x10, + 0x07, 0x00, 0x07, 0x32, 0x19, 0x31, 0x09, 0x31, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x09, 0x30, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x00, + 0x0f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP0, + 0x00, 0x00, 0x19, 0x10, 0x00, 0x0a, 0x00, 0x81); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP1, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xc0, 0xc0, 0x18, 0x18, 0x19, 0x19, 0x18, 0x18, + 0x40, 0x40, 0x18, 0x18, 0x18, 0x18, 0x3f, 0x3f, + 0x28, 0x28, 0x24, 0x24, 0x02, 0x03, 0x02, 0x03, + 0x00, 0x01, 0x00, 0x01, 0x31, 0x31, 0x31, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP2, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x40, 0x40, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, + 0x40, 0x40, 0x18, 0x18, 0x18, 0x18, 0x3f, 0x3f, + 0x24, 0x24, 0x28, 0x28, 0x01, 0x00, 0x01, 0x00, + 0x03, 0x02, 0x03, 0x02, 0x31, 0x31, 0x31, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP3, + 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0xab, 0xaa, + 0xaa, 0xaa, 0xaa, 0xea, 0xab, 0xaa, 0xaa, 0xaa); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP3, + 0xaa, 0x2e, 0x28, 0x00, 0x00, 0x00, 0xaa, 0x2e, + 0x28, 0x00, 0x00, 0x00, 0xaa, 0xee, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xee, 0xaa, 0xaa, 0xaa, 0xaa); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP3, + 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xff, + 0xff, 0xff, 0xff, 0xff); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETGIP3, + 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETTP1, + 0x0e, 0x0e, 0x1e, 0x65, 0x1c, 0x65, 0x00, 0x50, + 0x20, 0x20, 0x00, 0x00, 0x02, 0x02, 0x02, 0x05, + 0x14, 0x14, 0x32, 0xb9, 0x23, 0xb9, 0x08); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETTP1, + 0x02, 0x00, 0xa8, 0x01, 0xa8, 0x0d, 0xa4, 0x0e); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETTP1, + 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETBANK, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_UNKNOWN1, 0xc3); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETCLOCK, 0xd1, 0xd6); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_UNKNOWN1, 0x3f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_UNKNOWN1, 0xc6); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_SETPTBA, 0x37); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83112A_UNKNOWN1, 0x3f); + + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 150); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 50); + + return dsi_ctx.accum_err; } static int hx83112a_disable(struct drm_panel *panel) { struct hx83112a_panel *ctx = to_hx83112a_panel(panel); struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); - return ret; - } - msleep(20); - - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); - return ret; - } - msleep(120); + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); - return 0; + return dsi_ctx.accum_err; } static int hx83112a_prepare(struct drm_panel *panel) { struct hx83112a_panel *ctx = to_hx83112a_panel(panel); - struct device *dev = &ctx->dsi->dev; int ret; ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators: %d\n", ret); + if (ret < 0) return ret; - } hx83112a_reset(ctx); - ret = hx83112a_on(ctx); + ret = hx83112a_on(ctx->dsi); if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); gpiod_set_value_cansleep(ctx->reset_gpio, 1); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - return ret; } - return 0; + return ret; } static int hx83112a_unprepare(struct drm_panel *panel) -- GitLab From 868cd000c19f77e4c25ce87c47b6f951facf4394 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Tue, 10 Sep 2024 13:03:40 +0300 Subject: [PATCH 131/970] drm/bridge: ti-sn65dsi86: annotate ti_sn_pwm_pin_{request, release} with __maybe_unused Building with clang, W=1, CONFIG_PM=n and CONFIG_OF_GPIO=n leads to warning about unused ti_sn_pwm_pin_request() and ti_sn_pwm_pin_release(). Fix by annotating them with __maybe_unused. See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static inline functions for W=1 build"). Signed-off-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/136ecd978aedd7df39d1b1c37b70596027ff0a3e.1725962479.git.jani.nikula@intel.com --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 84698a0b27a8..0fd4cb400e81 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -1635,8 +1635,8 @@ static void ti_sn_pwm_unregister(void) } #else -static inline int ti_sn_pwm_pin_request(struct ti_sn65dsi86 *pdata) { return 0; } -static inline void ti_sn_pwm_pin_release(struct ti_sn65dsi86 *pdata) {} +static inline int __maybe_unused ti_sn_pwm_pin_request(struct ti_sn65dsi86 *pdata) { return 0; } +static inline void __maybe_unused ti_sn_pwm_pin_release(struct ti_sn65dsi86 *pdata) {} static inline int ti_sn_pwm_register(void) { return 0; } static inline void ti_sn_pwm_unregister(void) {} -- GitLab From 998fde0647671c82f637e299026d951f9b155b37 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:21 -0700 Subject: [PATCH 132/970] drm/xe: Move forcewake to 'gt.pm' substructure Forcewake is a general GT power management concept that isn't specific to MMIO register access. Move the forcewake information for a GT out of the 'mmio' substruct and into a 'pm' substruct. Also use the gt_to_fw() helper in a few more places where it was being open-coded. v2: - Kerneldoc tweaks. (Lucas) Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-46-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device.h | 2 +- drivers/gpu/drm/xe/xe_gt_types.h | 15 ++++++++++++--- drivers/gpu/drm/xe/xe_reg_sr.c | 9 +++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h index 894f04770454..ec726dcd5f99 100644 --- a/drivers/gpu/drm/xe/xe_device.h +++ b/drivers/gpu/drm/xe/xe_device.h @@ -138,7 +138,7 @@ static inline bool xe_device_uc_enabled(struct xe_device *xe) static inline struct xe_force_wake *gt_to_fw(struct xe_gt *gt) { - return >->mmio.fw; + return >->pm.fw; } void xe_device_assert_mem_access(struct xe_device *xe); diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h index 3d1c51de0268..dd6bbef0bbcd 100644 --- a/drivers/gpu/drm/xe/xe_gt_types.h +++ b/drivers/gpu/drm/xe/xe_gt_types.h @@ -145,11 +145,9 @@ struct xe_gt { /** * @mmio: mmio info for GT. All GTs within a tile share the same * register space, but have their own copy of GSI registers at a - * specific offset, as well as their own forcewake handling. + * specific offset. */ struct { - /** @mmio.fw: force wake for GT */ - struct xe_force_wake fw; /** * @mmio.adj_limit: adjust MMIO address if address is below this * value @@ -159,6 +157,17 @@ struct xe_gt { u32 adj_offset; } mmio; + /** + * @pm: power management info for GT. The driver uses the GT's + * "force wake" interface to wake up specific parts of the GT hardware + * from C6 sleep states and ensure the hardware remains awake while it + * is being actively used. + */ + struct { + /** @pm.fw: force wake for GT */ + struct xe_force_wake fw; + } pm; + /** @sriov: virtualization data related to GT */ union { /** @sriov.pf: PF data. Valid only if driver is running as PF */ diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c index 440ac572f6e5..fb209f1e0f1e 100644 --- a/drivers/gpu/drm/xe/xe_reg_sr.c +++ b/drivers/gpu/drm/xe/xe_reg_sr.c @@ -15,6 +15,7 @@ #include "regs/xe_engine_regs.h" #include "regs/xe_gt_regs.h" +#include "xe_device.h" #include "xe_device_types.h" #include "xe_force_wake.h" #include "xe_gt.h" @@ -194,14 +195,14 @@ void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt) xe_gt_dbg(gt, "Applying %s save-restore MMIOs\n", sr->name); - err = xe_force_wake_get(>->mmio.fw, XE_FORCEWAKE_ALL); + err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); if (err) goto err_force_wake; xa_for_each(&sr->xa, reg, entry) apply_one_mmio(gt, entry); - err = xe_force_wake_put(>->mmio.fw, XE_FORCEWAKE_ALL); + err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); XE_WARN_ON(err); return; @@ -227,7 +228,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe) drm_dbg(&xe->drm, "Whitelisting %s registers\n", sr->name); - err = xe_force_wake_get(>->mmio.fw, XE_FORCEWAKE_ALL); + err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); if (err) goto err_force_wake; @@ -253,7 +254,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe) xe_mmio_write32(gt, RING_FORCE_TO_NONPRIV(mmio_base, slot), addr); } - err = xe_force_wake_put(>->mmio.fw, XE_FORCEWAKE_ALL); + err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); XE_WARN_ON(err); return; -- GitLab From 34953ee349dde9d1733d4af75e929f7fd5fab539 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:22 -0700 Subject: [PATCH 133/970] drm/xe: Create dedicated xe_mmio structure Pull the 'mmio' substructure from xe_tile out into a dedicated type. Future patches will expand this structure and then eventually move MMIO read/write operations over to using this type. v2: - Fix kerneldoc of 'size' field. The rename/refocusing of this field got moved to the next patch of the series. (Lucas) - Correct commit message; it's the tile, not the device, mmio that's been pulled out to a separate type. (Michal) Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-47-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device_types.h | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index ec7eb7811126..5d5b7a9199d8 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -107,6 +107,22 @@ struct xe_mem_region { void __iomem *mapping; }; +/** + * struct xe_mmio - register mmio structure + * + * Represents an MMIO region that the CPU may use to access registers. A + * region may share its IO map with other regions (e.g., all GTs within a + * tile share the same map with their parent tile, but represent different + * subregions of the overall IO space). + */ +struct xe_mmio { + /** @regs: Map used to access registers. */ + void __iomem *regs; + + /** @size: Size of the map. */ + size_t size; +}; + /** * struct xe_tile - hardware tile structure * @@ -148,13 +164,7 @@ struct xe_tile { * * 4MB-8MB: reserved * * 8MB-16MB: global GTT */ - struct { - /** @mmio.size: size of tile's MMIO space */ - size_t size; - - /** @mmio.regs: pointer to tile's MMIO space (starting with registers) */ - void __iomem *regs; - } mmio; + struct xe_mmio mmio; /** * @mmio_ext: MMIO-extension info for a tile. -- GitLab From d4aff99aefa2a3c8999a98f0d52a977b284b9ec9 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:23 -0700 Subject: [PATCH 134/970] drm/xe: Clarify size of MMIO region xe_mmio currently has a size parameter that is assigned but never used anywhere. The current values assigned appear to be the size of the BAR region assigned for the tile (both for registers and other purposes such as the GGTT). Since the current field isn't being used for anything, change the assignments to 4MB (the size of the register region on all current platform) and rename the field to 'regs_size' to more clearly describe what it represents. We can use this value in later patches to help ensure no register accesses accidentally go past the end of the desired register space (which might not be caught easily if they still fall within the iomap). v2: - s/regs_length/regs_size/ (Lucas) - Clarify kerneldoc description (Lucas) Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-48-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device_types.h | 10 ++++++++-- drivers/gpu/drm/xe/xe_mmio.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 5d5b7a9199d8..ecf95801743d 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -119,8 +119,14 @@ struct xe_mmio { /** @regs: Map used to access registers. */ void __iomem *regs; - /** @size: Size of the map. */ - size_t size; + /** + * @regs_size: Length of the register region within the map. + * + * The size of the iomap set in *regs is generally larger than the + * register mmio space since it includes unused regions and/or + * non-register regions such as the GGTT PTEs. + */ + size_t regs_size; }; /** diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 4aae30880bc6..781555bbe449 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -36,13 +36,19 @@ static void tiles_fini(void *arg) /* * On multi-tile devices, partition the BAR space for MMIO on each tile, * possibly accounting for register override on the number of tiles available. + * tile_mmio_size contains both the tile's 4MB register space, as well as + * additional space for the GTT and other (possibly unused) regions). * Resulting memory layout is like below: * * .----------------------. <- tile_count * tile_mmio_size * | .... | * |----------------------| <- 2 * tile_mmio_size + * | tile1 GTT + other | + * |----------------------| <- 1 * tile_mmio_size + 4MB * | tile1->mmio.regs | * |----------------------| <- 1 * tile_mmio_size + * | tile0 GTT + other | + * |----------------------| <- 4MB * | tile0->mmio.regs | * '----------------------' <- 0MB */ @@ -90,7 +96,7 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size) regs = xe->mmio.regs; for_each_tile(tile, xe, id) { - tile->mmio.size = tile_mmio_size; + tile->mmio.regs_size = SZ_4M; tile->mmio.regs = regs; regs += tile_mmio_size; } @@ -171,7 +177,7 @@ int xe_mmio_init(struct xe_device *xe) } /* Setup first tile; other tiles (if present) will be setup later. */ - root_tile->mmio.size = SZ_16M; + root_tile->mmio.regs_size = SZ_4M; root_tile->mmio.regs = xe->mmio.regs; return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); -- GitLab From 9d383916a552784ec35e6d25469fc2da9bcd9948 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:24 -0700 Subject: [PATCH 135/970] drm/xe: Move GSI offset adjustment fields into 'struct xe_mmio' By moving the GSI adjustment fields into 'struct xe_mmio' we can replace the GT's MMIO substructure with another instance of xe_mmio. At the moment this means MMIO operations wind up pulling information from two different places (the tile's xe_mmio for the iomap and the GT's xe_mmio for the adjustment), but we'll address that in future patches. The type headers change a bit with this change, meaning that various files should be including xe_device_types.h instead of (or in addition to) xe_gt_types.h. v2: - Fix pre-existing kerneldoc typo while moving the fields (Lucas) v3: - Add missing '@' in kerneldoc. (Rodrigo) Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-49-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_assert.h | 2 +- drivers/gpu/drm/xe/xe_device.h | 1 + drivers/gpu/drm/xe/xe_device_types.h | 7 ++++++- drivers/gpu/drm/xe/xe_gt_freq.c | 2 +- drivers/gpu/drm/xe/xe_gt_printk.h | 2 +- drivers/gpu/drm/xe/xe_gt_types.h | 11 ++--------- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_assert.h b/drivers/gpu/drm/xe/xe_assert.h index e22bbf57fca7..04d6b95c6d87 100644 --- a/drivers/gpu/drm/xe/xe_assert.h +++ b/drivers/gpu/drm/xe/xe_assert.h @@ -10,7 +10,7 @@ #include <drm/drm_print.h> -#include "xe_device_types.h" +#include "xe_gt_types.h" #include "xe_step.h" /** diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h index ec726dcd5f99..ca8d8ef6342b 100644 --- a/drivers/gpu/drm/xe/xe_device.h +++ b/drivers/gpu/drm/xe/xe_device.h @@ -9,6 +9,7 @@ #include <drm/drm_util.h> #include "xe_device_types.h" +#include "xe_gt_types.h" static inline struct xe_device *to_xe_device(const struct drm_device *dev) { diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index ecf95801743d..347fc5ec55e1 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -14,7 +14,6 @@ #include "xe_devcoredump_types.h" #include "xe_heci_gsc.h" -#include "xe_gt_types.h" #include "xe_lmtt_types.h" #include "xe_memirq_types.h" #include "xe_oa.h" @@ -127,6 +126,12 @@ struct xe_mmio { * non-register regions such as the GGTT PTEs. */ size_t regs_size; + + /** @adj_limit: adjust MMIO address if address is below this value */ + u32 adj_limit; + + /** @adj_offset: offset to add to MMIO address when adjusting */ + u32 adj_offset; }; /** diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c index 68a5778b4319..552435951f11 100644 --- a/drivers/gpu/drm/xe/xe_gt_freq.c +++ b/drivers/gpu/drm/xe/xe_gt_freq.c @@ -11,9 +11,9 @@ #include <drm/drm_managed.h> #include <drm/drm_print.h> -#include "xe_device_types.h" #include "xe_gt_sysfs.h" #include "xe_gt_throttle.h" +#include "xe_gt_types.h" #include "xe_guc_pc.h" #include "xe_pm.h" diff --git a/drivers/gpu/drm/xe/xe_gt_printk.h b/drivers/gpu/drm/xe/xe_gt_printk.h index d6228baaff1e..5dc71394372d 100644 --- a/drivers/gpu/drm/xe/xe_gt_printk.h +++ b/drivers/gpu/drm/xe/xe_gt_printk.h @@ -8,7 +8,7 @@ #include <drm/drm_print.h> -#include "xe_device_types.h" +#include "xe_gt_types.h" #define xe_gt_printk(_gt, _level, _fmt, ...) \ drm_##_level(>_to_xe(_gt)->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__) diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h index dd6bbef0bbcd..a287b98ee70b 100644 --- a/drivers/gpu/drm/xe/xe_gt_types.h +++ b/drivers/gpu/drm/xe/xe_gt_types.h @@ -6,6 +6,7 @@ #ifndef _XE_GT_TYPES_H_ #define _XE_GT_TYPES_H_ +#include "xe_device_types.h" #include "xe_force_wake_types.h" #include "xe_gt_idle_types.h" #include "xe_gt_sriov_pf_types.h" @@ -147,15 +148,7 @@ struct xe_gt { * register space, but have their own copy of GSI registers at a * specific offset. */ - struct { - /** - * @mmio.adj_limit: adjust MMIO address if address is below this - * value - */ - u32 adj_limit; - /** @mmio.adj_offset: offect to add to MMIO address when adjusting */ - u32 adj_offset; - } mmio; + struct xe_mmio mmio; /** * @pm: power management info for GT. The driver uses the GT's -- GitLab From fa599b8c95a7070430703f4908a50141f2c7088c Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:25 -0700 Subject: [PATCH 136/970] drm/xe: Populate GT's mmio iomap from tile during init Each GT should share the same register iomap as its parent tile. Future patches will switch to access the iomap through the GT's mmio substruct rather than through the tile. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-50-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index cc4fadb01051..935f56c7f457 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -711,6 +711,8 @@ static int xe_info_init(struct xe_device *xe, gt->info.type = XE_GT_TYPE_MAIN; gt->info.has_indirect_ring_state = graphics_desc->has_indirect_ring_state; gt->info.engine_mask = graphics_desc->hw_engine_mask; + gt->mmio.regs = tile->mmio.regs; + gt->mmio.regs_size = tile->mmio.regs_size; if (MEDIA_VER(xe) < 13 && media_desc) gt->info.engine_mask |= media_desc->hw_engine_mask; @@ -729,6 +731,8 @@ static int xe_info_init(struct xe_device *xe, gt->info.type = XE_GT_TYPE_MEDIA; gt->info.has_indirect_ring_state = media_desc->has_indirect_ring_state; gt->info.engine_mask = media_desc->hw_engine_mask; + gt->mmio.regs = tile->mmio.regs; + gt->mmio.regs_size = tile->mmio.regs_size; gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; -- GitLab From 960a83799f5bb8634755f0593c591c53ff4acee8 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:26 -0700 Subject: [PATCH 137/970] drm/xe: Switch mmio_ext to use 'struct xe_mmio' The mmio_ext stuff is completely unused right now, but it isn't providing any functionality that couldn't be treated as a regular mmio space. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-51-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device_types.h | 8 +------- drivers/gpu/drm/xe/xe_mmio.c | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 347fc5ec55e1..e5af3f5fe78c 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -182,13 +182,7 @@ struct xe_tile { * * Each tile has its own additional 256MB (28-bit) MMIO-extension space. */ - struct { - /** @mmio_ext.size: size of tile's additional MMIO-extension space */ - size_t size; - - /** @mmio_ext.regs: pointer to tile's additional MMIO-extension space */ - void __iomem *regs; - } mmio_ext; + struct xe_mmio mmio_ext; /** @mem: memory management info for tile */ struct { diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 781555bbe449..d271ff45e90c 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -132,7 +132,7 @@ static void mmio_extension_setup(struct xe_device *xe, size_t tile_mmio_size, regs = xe->mmio.regs + tile_mmio_size * xe->info.tile_count; for_each_tile(tile, xe, id) { - tile->mmio_ext.size = tile_mmio_ext_size; + tile->mmio_ext.regs_size = tile_mmio_ext_size; tile->mmio_ext.regs = regs; regs += tile_mmio_ext_size; } -- GitLab From 1877c88fa9b9bdbce7a65d7cbd2aa4e29bb514af Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:27 -0700 Subject: [PATCH 138/970] drm/xe: Add xe_tile backpointer to xe_mmio Once MMIO operations stop being (incorrectly) tied to a GT, we'll still need a backpointer for feature checks, message logging, and tracepoints. Use a tile backpointer since that may allow the most useful debugging output, while also providing access to the xe_device. v2: - Make backpointer an xe_tile instead of xe_device. (Michal) Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> # v1 Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-52-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device_types.h | 3 +++ drivers/gpu/drm/xe/xe_mmio.c | 3 +++ drivers/gpu/drm/xe/xe_pci.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index e5af3f5fe78c..3a23083ec3cf 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -115,6 +115,9 @@ struct xe_mem_region { * subregions of the overall IO space). */ struct xe_mmio { + /** @tile: Backpointer to tile, used for tracing */ + struct xe_tile *tile; + /** @regs: Map used to access registers. */ void __iomem *regs; diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index d271ff45e90c..47b505aa8282 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -98,6 +98,7 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size) for_each_tile(tile, xe, id) { tile->mmio.regs_size = SZ_4M; tile->mmio.regs = regs; + tile->mmio.tile = tile; regs += tile_mmio_size; } } @@ -134,6 +135,7 @@ static void mmio_extension_setup(struct xe_device *xe, size_t tile_mmio_size, for_each_tile(tile, xe, id) { tile->mmio_ext.regs_size = tile_mmio_ext_size; tile->mmio_ext.regs = regs; + tile->mmio_ext.tile = tile; regs += tile_mmio_ext_size; } } @@ -179,6 +181,7 @@ int xe_mmio_init(struct xe_device *xe) /* Setup first tile; other tiles (if present) will be setup later. */ root_tile->mmio.regs_size = SZ_4M; root_tile->mmio.regs = xe->mmio.regs; + root_tile->mmio.tile = root_tile; return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); } diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 935f56c7f457..d68f5685071d 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -713,6 +713,7 @@ static int xe_info_init(struct xe_device *xe, gt->info.engine_mask = graphics_desc->hw_engine_mask; gt->mmio.regs = tile->mmio.regs; gt->mmio.regs_size = tile->mmio.regs_size; + gt->mmio.tile = tile; if (MEDIA_VER(xe) < 13 && media_desc) gt->info.engine_mask |= media_desc->hw_engine_mask; @@ -735,6 +736,7 @@ static int xe_info_init(struct xe_device *xe, gt->mmio.regs_size = tile->mmio.regs_size; gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; + gt->mmio.tile = tile; /* * FIXME: At the moment multi-tile and standalone media are -- GitLab From 6fb5d1a1d376910700d054d13cefbf0812b444a9 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:28 -0700 Subject: [PATCH 139/970] drm/xe: Adjust mmio code to pass VF substructure to SRIOV code Although we want to break the GT-centric nature of the MMIO code in the general driver, the SRIOV handling still relies on data in a VF substructure of the GT. So add a GT backpointer, but name it sriov_vf_gt to make it clear that it's only for this one specific special case and will not be set or usable for anything else. v2: - Store backpointer to the GT itself rather than the SRIOV-specific substructure. (Michal) Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> # v1 Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-53-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device_types.h | 8 ++++++++ drivers/gpu/drm/xe/xe_pci.c | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 3a23083ec3cf..c92df0a2423f 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -121,6 +121,14 @@ struct xe_mmio { /** @regs: Map used to access registers. */ void __iomem *regs; + /** + * @sriov_vf_gt: Backpointer to GT. + * + * This pointer is only set for GT MMIO regions and only when running + * as an SRIOV VF structure + */ + struct xe_gt *sriov_vf_gt; + /** * @regs_size: Length of the register region within the map. * diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index d68f5685071d..d045ea68c808 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -714,6 +714,9 @@ static int xe_info_init(struct xe_device *xe, gt->mmio.regs = tile->mmio.regs; gt->mmio.regs_size = tile->mmio.regs_size; gt->mmio.tile = tile; + if (IS_SRIOV_VF(xe)) + gt->mmio.sriov_vf_gt = gt; + if (MEDIA_VER(xe) < 13 && media_desc) gt->info.engine_mask |= media_desc->hw_engine_mask; @@ -737,6 +740,8 @@ static int xe_info_init(struct xe_device *xe, gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; gt->mmio.tile = tile; + if (IS_SRIOV_VF(xe)) + gt->mmio.sriov_vf_gt = gt; /* * FIXME: At the moment multi-tile and standalone media are -- GitLab From a84590c5ceb354d2e9f7f6812cfb3a9709e14afa Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:29 -0700 Subject: [PATCH 140/970] drm/xe: Switch MMIO interface to take xe_mmio instead of xe_gt Since much of the MMIO register access done by the driver is to non-GT registers, use of 'xe_gt' in these interfaces has been a long-standing design flaw that's been hard to disentangle. To avoid a flag day across the whole driver, munge the function names and add temporary compatibility macros with the original function names that can accept either the new xe_mmio or the old xe_gt structure as a parameter. This will allow us to slowly convert parts of the driver over to the new interface independently. Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-54-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_mmio.c | 131 ++++++++++++++++------------------ drivers/gpu/drm/xe/xe_mmio.h | 76 +++++++++++++++----- drivers/gpu/drm/xe/xe_trace.h | 7 +- 3 files changed, 126 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 47b505aa8282..392105ba8311 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -67,16 +67,16 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size) /* Possibly override number of tile based on configuration register */ if (!xe->info.skip_mtcfg) { - struct xe_gt *gt = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); u8 tile_count; u32 mtcfg; /* * Although the per-tile mmio regs are not yet initialized, this - * is fine as it's going to the root gt, that's guaranteed to be - * initialized earlier in xe_mmio_init() + * is fine as it's going to the root tile's mmio, that's + * guaranteed to be initialized earlier in xe_mmio_init() */ - mtcfg = xe_mmio_read64_2x32(gt, XEHP_MTCFG_ADDR); + mtcfg = xe_mmio_read64_2x32(mmio, XEHP_MTCFG_ADDR); tile_count = REG_FIELD_GET(TILE_COUNT, mtcfg) + 1; if (tile_count < xe->info.tile_count) { @@ -186,116 +186,111 @@ int xe_mmio_init(struct xe_device *xe) return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe); } -static void mmio_flush_pending_writes(struct xe_gt *gt) +static void mmio_flush_pending_writes(struct xe_mmio *mmio) { #define DUMMY_REG_OFFSET 0x130030 - struct xe_tile *tile = gt_to_tile(gt); int i; - if (tile->xe->info.platform != XE_LUNARLAKE) + if (mmio->tile->xe->info.platform != XE_LUNARLAKE) return; /* 4 dummy writes */ for (i = 0; i < 4; i++) - writel(0, tile->mmio.regs + DUMMY_REG_OFFSET); + writel(0, mmio->regs + DUMMY_REG_OFFSET); } -u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg) +u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg) { - struct xe_tile *tile = gt_to_tile(gt); - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); u8 val; /* Wa_15015404425 */ - mmio_flush_pending_writes(gt); + mmio_flush_pending_writes(mmio); - val = readb((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); - trace_xe_reg_rw(gt, false, addr, val, sizeof(val)); + val = readb(mmio->regs + addr); + trace_xe_reg_rw(mmio, false, addr, val, sizeof(val)); return val; } -u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg) +u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg) { - struct xe_tile *tile = gt_to_tile(gt); - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); u16 val; /* Wa_15015404425 */ - mmio_flush_pending_writes(gt); + mmio_flush_pending_writes(mmio); - val = readw((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); - trace_xe_reg_rw(gt, false, addr, val, sizeof(val)); + val = readw(mmio->regs + addr); + trace_xe_reg_rw(mmio, false, addr, val, sizeof(val)); return val; } -void xe_mmio_write32(struct xe_gt *gt, struct xe_reg reg, u32 val) +void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val) { - struct xe_tile *tile = gt_to_tile(gt); - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); - trace_xe_reg_rw(gt, true, addr, val, sizeof(val)); + trace_xe_reg_rw(mmio, true, addr, val, sizeof(val)); - if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt))) - xe_gt_sriov_vf_write32(gt, reg, val); + if (!reg.vf && mmio->sriov_vf_gt) + xe_gt_sriov_vf_write32(mmio->sriov_vf_gt, reg, val); else - writel(val, (reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); + writel(val, mmio->regs + addr); } -u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg) +u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg) { - struct xe_tile *tile = gt_to_tile(gt); - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); u32 val; /* Wa_15015404425 */ - mmio_flush_pending_writes(gt); + mmio_flush_pending_writes(mmio); - if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt))) - val = xe_gt_sriov_vf_read32(gt, reg); + if (!reg.vf && mmio->sriov_vf_gt) + val = xe_gt_sriov_vf_read32(mmio->sriov_vf_gt, reg); else - val = readl((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr); + val = readl(mmio->regs + addr); - trace_xe_reg_rw(gt, false, addr, val, sizeof(val)); + trace_xe_reg_rw(mmio, false, addr, val, sizeof(val)); return val; } -u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr, u32 set) +u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set) { u32 old, reg_val; - old = xe_mmio_read32(gt, reg); + old = xe_mmio_read32(mmio, reg); reg_val = (old & ~clr) | set; - xe_mmio_write32(gt, reg, reg_val); + xe_mmio_write32(mmio, reg, reg_val); return old; } -int xe_mmio_write32_and_verify(struct xe_gt *gt, - struct xe_reg reg, u32 val, u32 mask, u32 eval) +int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, + struct xe_reg reg, u32 val, u32 mask, u32 eval) { u32 reg_val; - xe_mmio_write32(gt, reg, val); - reg_val = xe_mmio_read32(gt, reg); + xe_mmio_write32(mmio, reg, val); + reg_val = xe_mmio_read32(mmio, reg); return (reg_val & mask) != eval ? -EINVAL : 0; } -bool xe_mmio_in_range(const struct xe_gt *gt, - const struct xe_mmio_range *range, - struct xe_reg reg) +bool __xe_mmio_in_range(const struct xe_mmio *mmio, + const struct xe_mmio_range *range, + struct xe_reg reg) { - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); return range && addr >= range->start && addr <= range->end; } /** * xe_mmio_read64_2x32() - Read a 64-bit register as two 32-bit reads - * @gt: MMIO target GT + * @mmio: MMIO target * @reg: register to read value from * * Although Intel GPUs have some 64-bit registers, the hardware officially @@ -315,21 +310,21 @@ bool xe_mmio_in_range(const struct xe_gt *gt, * * Returns the value of the 64-bit register. */ -u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg) +u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) { struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; u32 ldw, udw, oldudw, retries; - reg.addr = xe_mmio_adjusted_addr(gt, reg.addr); - reg_udw.addr = xe_mmio_adjusted_addr(gt, reg_udw.addr); + reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); + reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); /* we shouldn't adjust just one register address */ - xe_gt_assert(gt, reg_udw.addr == reg.addr + 0x4); + xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); - oldudw = xe_mmio_read32(gt, reg_udw); + oldudw = xe_mmio_read32(mmio, reg_udw); for (retries = 5; retries; --retries) { - ldw = xe_mmio_read32(gt, reg); - udw = xe_mmio_read32(gt, reg_udw); + ldw = xe_mmio_read32(mmio, reg); + udw = xe_mmio_read32(mmio, reg_udw); if (udw == oldudw) break; @@ -337,14 +332,14 @@ u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg) oldudw = udw; } - xe_gt_WARN(gt, retries == 0, - "64-bit read of %#x did not stabilize\n", reg.addr); + drm_WARN(&mmio->tile->xe->drm, retries == 0, + "64-bit read of %#x did not stabilize\n", reg.addr); return (u64)udw << 32 | ldw; } -static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic, bool expect_match) +static int ____xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, + u32 *out_val, bool atomic, bool expect_match) { ktime_t cur = ktime_get_raw(); const ktime_t end = ktime_add_us(cur, timeout_us); @@ -354,7 +349,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v bool check; for (;;) { - read = xe_mmio_read32(gt, reg); + read = xe_mmio_read32(mmio, reg); check = (read & mask) == val; if (!expect_match) @@ -380,7 +375,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v } if (ret != 0) { - read = xe_mmio_read32(gt, reg); + read = xe_mmio_read32(mmio, reg); check = (read & mask) == val; if (!expect_match) @@ -398,7 +393,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v /** * xe_mmio_wait32() - Wait for a register to match the desired masked value - * @gt: MMIO target GT + * @mmio: MMIO target * @reg: register to read value from * @mask: mask to be applied to the value read from the register * @val: desired value after applying the mask @@ -415,15 +410,15 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v * @timeout_us for different reasons, specially in non-atomic contexts. Thus, * it is possible that this function succeeds even after @timeout_us has passed. */ -int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic) +int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, + u32 *out_val, bool atomic) { - return __xe_mmio_wait32(gt, reg, mask, val, timeout_us, out_val, atomic, true); + return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, true); } /** * xe_mmio_wait32_not() - Wait for a register to return anything other than the given masked value - * @gt: MMIO target GT + * @mmio: MMIO target * @reg: register to read value from * @mask: mask to be applied to the value read from the register * @val: value not to be matched after applying the mask @@ -434,8 +429,8 @@ int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 t * This function works exactly like xe_mmio_wait32() with the exception that * @val is expected not to be matched. */ -int xe_mmio_wait32_not(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic) +int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, + u32 *out_val, bool atomic) { - return __xe_mmio_wait32(gt, reg, mask, val, timeout_us, out_val, atomic, false); + return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, false); } diff --git a/drivers/gpu/drm/xe/xe_mmio.h b/drivers/gpu/drm/xe/xe_mmio.h index 26551410ecc8..ac6846447c52 100644 --- a/drivers/gpu/drm/xe/xe_mmio.h +++ b/drivers/gpu/drm/xe/xe_mmio.h @@ -14,25 +14,67 @@ struct xe_reg; int xe_mmio_init(struct xe_device *xe); int xe_mmio_probe_tiles(struct xe_device *xe); -u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg); -u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg); -void xe_mmio_write32(struct xe_gt *gt, struct xe_reg reg, u32 val); -u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg); -u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr, u32 set); -int xe_mmio_write32_and_verify(struct xe_gt *gt, struct xe_reg reg, u32 val, u32 mask, u32 eval); -bool xe_mmio_in_range(const struct xe_gt *gt, const struct xe_mmio_range *range, struct xe_reg reg); - -u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg); -int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic); -int xe_mmio_wait32_not(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic); - -static inline u32 xe_mmio_adjusted_addr(const struct xe_gt *gt, u32 addr) +/* + * Temporary transition helper for xe_gt -> xe_mmio conversion. Allows + * continued usage of xe_gt as a parameter to MMIO operations which now + * take an xe_mmio structure instead. Will be removed once the driver-wide + * conversion is complete. + */ +#define __to_xe_mmio(ptr) \ + _Generic(ptr, \ + const struct xe_gt *: (&((const struct xe_gt *)(ptr))->mmio), \ + struct xe_gt *: (&((struct xe_gt *)(ptr))->mmio), \ + const struct xe_mmio *: (ptr), \ + struct xe_mmio *: (ptr)) + +u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg); +#define xe_mmio_read8(p, reg) __xe_mmio_read8(__to_xe_mmio(p), reg) + +u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg); +#define xe_mmio_read16(p, reg) __xe_mmio_read16(__to_xe_mmio(p), reg) + +void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val); +#define xe_mmio_write32(p, reg, val) __xe_mmio_write32(__to_xe_mmio(p), reg, val) + +u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg); +#define xe_mmio_read32(p, reg) __xe_mmio_read32(__to_xe_mmio(p), reg) + +u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set); +#define xe_mmio_rmw32(p, reg, clr, set) __xe_mmio_rmw32(__to_xe_mmio(p), reg, clr, set) + +int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, struct xe_reg reg, + u32 val, u32 mask, u32 eval); +#define xe_mmio_write32_and_verify(p, reg, val, mask, eval) \ + __xe_mmio_write32_and_verify(__to_xe_mmio(p), reg, val, mask, eval) + +bool __xe_mmio_in_range(const struct xe_mmio *mmio, + const struct xe_mmio_range *range, struct xe_reg reg); +#define xe_mmio_in_range(p, range, reg) __xe_mmio_in_range(__to_xe_mmio(p), range, reg) + +u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg); +#define xe_mmio_read64_2x32(p, reg) __xe_mmio_read64_2x32(__to_xe_mmio(p), reg) + +int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, + u32 timeout_us, u32 *out_val, bool atomic); +#define xe_mmio_wait32(p, reg, mask, val, timeout_us, out_val, atomic) \ + __xe_mmio_wait32(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic) + +int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, + u32 val, u32 timeout_us, u32 *out_val, bool atomic); +#define xe_mmio_wait32_not(p, reg, mask, val, timeout_us, out_val, atomic) \ + __xe_mmio_wait32_not(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic) + +static inline u32 __xe_mmio_adjusted_addr(const struct xe_mmio *mmio, u32 addr) { - if (addr < gt->mmio.adj_limit) - addr += gt->mmio.adj_offset; + if (addr < mmio->adj_limit) + addr += mmio->adj_offset; return addr; } +#define xe_mmio_adjusted_addr(p, addr) __xe_mmio_adjusted_addr(__to_xe_mmio(p), addr) + +static inline struct xe_mmio *xe_root_tile_mmio(struct xe_device *xe) +{ + return &xe->tiles[0].mmio; +} #endif diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h index 8573d7a87d84..91130ad8999c 100644 --- a/drivers/gpu/drm/xe/xe_trace.h +++ b/drivers/gpu/drm/xe/xe_trace.h @@ -21,6 +21,7 @@ #include "xe_vm.h" #define __dev_name_xe(xe) dev_name((xe)->drm.dev) +#define __dev_name_tile(tile) __dev_name_xe(tile_to_xe((tile))) #define __dev_name_gt(gt) __dev_name_xe(gt_to_xe((gt))) #define __dev_name_eq(q) __dev_name_gt((q)->gt) @@ -342,12 +343,12 @@ DEFINE_EVENT(xe_hw_fence, xe_hw_fence_try_signal, ); TRACE_EVENT(xe_reg_rw, - TP_PROTO(struct xe_gt *gt, bool write, u32 reg, u64 val, int len), + TP_PROTO(struct xe_mmio *mmio, bool write, u32 reg, u64 val, int len), - TP_ARGS(gt, write, reg, val, len), + TP_ARGS(mmio, write, reg, val, len), TP_STRUCT__entry( - __string(dev, __dev_name_gt(gt)) + __string(dev, __dev_name_tile(mmio->tile)) __field(u64, val) __field(u32, reg) __field(u16, write) -- GitLab From a7945ef770dbabea7bac270872391907174c17a9 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:30 -0700 Subject: [PATCH 141/970] drm/xe/irq: Convert register access to use xe_mmio Stop using GT pointers for register access. This misusage has been especially confusing in interrupt code because even though some of the interrupts are related to GTs (or engines within GTs), the interrupt registers themselves live outside the GT, in the sgunit. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-55-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_irq.c | 63 +++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 14c3a476597a..07577b418205 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -30,14 +30,14 @@ #define IIR(offset) XE_REG(offset + 0x8) #define IER(offset) XE_REG(offset + 0xc) -static void assert_iir_is_zero(struct xe_gt *mmio, struct xe_reg reg) +static void assert_iir_is_zero(struct xe_mmio *mmio, struct xe_reg reg) { u32 val = xe_mmio_read32(mmio, reg); if (val == 0) return; - drm_WARN(>_to_xe(mmio)->drm, 1, + drm_WARN(&mmio->tile->xe->drm, 1, "Interrupt register 0x%x is not zero: 0x%08x\n", reg.addr, val); xe_mmio_write32(mmio, reg, 0xffffffff); @@ -52,7 +52,7 @@ static void assert_iir_is_zero(struct xe_gt *mmio, struct xe_reg reg) */ static void unmask_and_enable(struct xe_tile *tile, u32 irqregs, u32 bits) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; /* * If we're just enabling an interrupt now, it shouldn't already @@ -70,7 +70,7 @@ static void unmask_and_enable(struct xe_tile *tile, u32 irqregs, u32 bits) /* Mask and disable all interrupts. */ static void mask_and_disable(struct xe_tile *tile, u32 irqregs) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; xe_mmio_write32(mmio, IMR(irqregs), ~0); /* Posting read */ @@ -87,7 +87,7 @@ static void mask_and_disable(struct xe_tile *tile, u32 irqregs) static u32 xelp_intr_disable(struct xe_device *xe) { - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); xe_mmio_write32(mmio, GFX_MSTR_IRQ, 0); @@ -103,7 +103,7 @@ static u32 xelp_intr_disable(struct xe_device *xe) static u32 gu_misc_irq_ack(struct xe_device *xe, const u32 master_ctl) { - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); u32 iir; if (!(master_ctl & GU_MISC_IRQ)) @@ -118,7 +118,7 @@ gu_misc_irq_ack(struct xe_device *xe, const u32 master_ctl) static inline void xelp_intr_enable(struct xe_device *xe, bool stall) { - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); xe_mmio_write32(mmio, GFX_MSTR_IRQ, MASTER_IRQ); if (stall) @@ -129,6 +129,7 @@ static inline void xelp_intr_enable(struct xe_device *xe, bool stall) void xe_irq_enable_hwe(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); + struct xe_mmio *mmio = >->mmio; u32 ccs_mask, bcs_mask; u32 irqs, dmask, smask; u32 gsc_mask = 0; @@ -155,35 +156,35 @@ void xe_irq_enable_hwe(struct xe_gt *gt) if (!xe_gt_is_media_type(gt)) { /* Enable interrupts for each engine class */ - xe_mmio_write32(gt, RENDER_COPY_INTR_ENABLE, dmask); + xe_mmio_write32(mmio, RENDER_COPY_INTR_ENABLE, dmask); if (ccs_mask) - xe_mmio_write32(gt, CCS_RSVD_INTR_ENABLE, smask); + xe_mmio_write32(mmio, CCS_RSVD_INTR_ENABLE, smask); /* Unmask interrupts for each engine instance */ - xe_mmio_write32(gt, RCS0_RSVD_INTR_MASK, ~smask); - xe_mmio_write32(gt, BCS_RSVD_INTR_MASK, ~smask); + xe_mmio_write32(mmio, RCS0_RSVD_INTR_MASK, ~smask); + xe_mmio_write32(mmio, BCS_RSVD_INTR_MASK, ~smask); if (bcs_mask & (BIT(1)|BIT(2))) - xe_mmio_write32(gt, XEHPC_BCS1_BCS2_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, XEHPC_BCS1_BCS2_INTR_MASK, ~dmask); if (bcs_mask & (BIT(3)|BIT(4))) - xe_mmio_write32(gt, XEHPC_BCS3_BCS4_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, XEHPC_BCS3_BCS4_INTR_MASK, ~dmask); if (bcs_mask & (BIT(5)|BIT(6))) - xe_mmio_write32(gt, XEHPC_BCS5_BCS6_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, XEHPC_BCS5_BCS6_INTR_MASK, ~dmask); if (bcs_mask & (BIT(7)|BIT(8))) - xe_mmio_write32(gt, XEHPC_BCS7_BCS8_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, XEHPC_BCS7_BCS8_INTR_MASK, ~dmask); if (ccs_mask & (BIT(0)|BIT(1))) - xe_mmio_write32(gt, CCS0_CCS1_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, CCS0_CCS1_INTR_MASK, ~dmask); if (ccs_mask & (BIT(2)|BIT(3))) - xe_mmio_write32(gt, CCS2_CCS3_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, CCS2_CCS3_INTR_MASK, ~dmask); } if (xe_gt_is_media_type(gt) || MEDIA_VER(xe) < 13) { /* Enable interrupts for each engine class */ - xe_mmio_write32(gt, VCS_VECS_INTR_ENABLE, dmask); + xe_mmio_write32(mmio, VCS_VECS_INTR_ENABLE, dmask); /* Unmask interrupts for each engine instance */ - xe_mmio_write32(gt, VCS0_VCS1_INTR_MASK, ~dmask); - xe_mmio_write32(gt, VCS2_VCS3_INTR_MASK, ~dmask); - xe_mmio_write32(gt, VECS0_VECS1_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, VCS0_VCS1_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, VCS2_VCS3_INTR_MASK, ~dmask); + xe_mmio_write32(mmio, VECS0_VECS1_INTR_MASK, ~dmask); /* * the heci2 interrupt is enabled via the same register as the @@ -197,17 +198,17 @@ void xe_irq_enable_hwe(struct xe_gt *gt) } if (gsc_mask) { - xe_mmio_write32(gt, GUNIT_GSC_INTR_ENABLE, gsc_mask | heci_mask); - xe_mmio_write32(gt, GUNIT_GSC_INTR_MASK, ~gsc_mask); + xe_mmio_write32(mmio, GUNIT_GSC_INTR_ENABLE, gsc_mask | heci_mask); + xe_mmio_write32(mmio, GUNIT_GSC_INTR_MASK, ~gsc_mask); } if (heci_mask) - xe_mmio_write32(gt, HECI2_RSVD_INTR_MASK, ~(heci_mask << 16)); + xe_mmio_write32(mmio, HECI2_RSVD_INTR_MASK, ~(heci_mask << 16)); } } static u32 gt_engine_identity(struct xe_device *xe, - struct xe_gt *mmio, + struct xe_mmio *mmio, const unsigned int bank, const unsigned int bit) { @@ -291,7 +292,7 @@ static void gt_irq_handler(struct xe_tile *tile, u32 *identity) { struct xe_device *xe = tile_to_xe(tile); - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; unsigned int bank, bit; u16 instance, intr_vec; enum xe_engine_class class; @@ -376,7 +377,7 @@ static irqreturn_t xelp_irq_handler(int irq, void *arg) static u32 dg1_intr_disable(struct xe_device *xe) { - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); u32 val; /* First disable interrupts */ @@ -394,7 +395,7 @@ static u32 dg1_intr_disable(struct xe_device *xe) static void dg1_intr_enable(struct xe_device *xe, bool stall) { - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); xe_mmio_write32(mmio, DG1_MSTR_TILE_INTR, DG1_MSTR_IRQ); if (stall) @@ -431,7 +432,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) } for_each_tile(tile, xe, id) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; if ((master_tile_ctl & DG1_MSTR_TILE(tile->id)) == 0) continue; @@ -474,7 +475,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) static void gt_irq_reset(struct xe_tile *tile) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; u32 ccs_mask = xe_hw_engine_mask_per_class(tile->primary_gt, XE_ENGINE_CLASS_COMPUTE); @@ -547,7 +548,7 @@ static void dg1_irq_reset(struct xe_tile *tile) static void dg1_irq_reset_mstr(struct xe_tile *tile) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; xe_mmio_write32(mmio, GFX_MSTR_IRQ, ~0); } -- GitLab From a3e7fcef52ea737902f32281e271f03ee0a2afa2 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:31 -0700 Subject: [PATCH 142/970] drm/xe/pcode: Convert register access to use xe_mmio Stop using GT pointers for register access. Although some of the pcode mailboxes are related to GTs, pcode itself (and the register interface to access it) are outside the GT and should be accessed through the tile's MMIO. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-56-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_pcode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_pcode.c b/drivers/gpu/drm/xe/xe_pcode.c index 7397d556996a..d95d9835de42 100644 --- a/drivers/gpu/drm/xe/xe_pcode.c +++ b/drivers/gpu/drm/xe/xe_pcode.c @@ -44,7 +44,7 @@ static int pcode_mailbox_status(struct xe_tile *tile) [PCODE_ERROR_MASK] = {-EPROTO, "Unknown"}, }; - err = xe_mmio_read32(tile->primary_gt, PCODE_MAILBOX) & PCODE_ERROR_MASK; + err = xe_mmio_read32(&tile->mmio, PCODE_MAILBOX) & PCODE_ERROR_MASK; if (err) { drm_err(&tile_to_xe(tile)->drm, "PCODE Mailbox failed: %d %s", err, err_decode[err].str ?: "Unknown"); @@ -58,7 +58,7 @@ static int __pcode_mailbox_rw(struct xe_tile *tile, u32 mbox, u32 *data0, u32 *d unsigned int timeout_ms, bool return_data, bool atomic) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; int err; if (tile_to_xe(tile)->info.skip_pcode) -- GitLab From 1f7468c8b67f536fe8ea6fc99f327dfd5b2755f1 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:32 -0700 Subject: [PATCH 143/970] drm/xe/hwmon: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-57-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_hwmon.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c index aa11728e7e79..fde56dad3ab7 100644 --- a/drivers/gpu/drm/xe/xe_hwmon.c +++ b/drivers/gpu/drm/xe/xe_hwmon.c @@ -149,7 +149,7 @@ static void xe_hwmon_power_max_read(struct xe_hwmon *hwmon, int channel, long *v u64 reg_val, min, max; struct xe_device *xe = hwmon->xe; struct xe_reg rapl_limit, pkg_power_sku; - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); rapl_limit = xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT, channel); pkg_power_sku = xe_hwmon_get_reg(hwmon, REG_PKG_POWER_SKU, channel); @@ -190,7 +190,7 @@ static void xe_hwmon_power_max_read(struct xe_hwmon *hwmon, int channel, long *v static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, int channel, long value) { - struct xe_gt *mmio = xe_root_mmio_gt(hwmon->xe); + struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); int ret = 0; u64 reg_val; struct xe_reg rapl_limit; @@ -222,7 +222,7 @@ static int xe_hwmon_power_max_write(struct xe_hwmon *hwmon, int channel, long va static void xe_hwmon_power_rated_max_read(struct xe_hwmon *hwmon, int channel, long *value) { - struct xe_gt *mmio = xe_root_mmio_gt(hwmon->xe); + struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); struct xe_reg reg = xe_hwmon_get_reg(hwmon, REG_PKG_POWER_SKU, channel); u64 reg_val; @@ -259,7 +259,7 @@ static void xe_hwmon_power_rated_max_read(struct xe_hwmon *hwmon, int channel, l static void xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy) { - struct xe_gt *mmio = xe_root_mmio_gt(hwmon->xe); + struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); struct xe_hwmon_energy_info *ei = &hwmon->ei[channel]; u64 reg_val; @@ -282,7 +282,7 @@ xe_hwmon_power_max_interval_show(struct device *dev, struct device_attribute *at char *buf) { struct xe_hwmon *hwmon = dev_get_drvdata(dev); - struct xe_gt *mmio = xe_root_mmio_gt(hwmon->xe); + struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); u32 x, y, x_w = 2; /* 2 bits */ u64 r, tau4, out; int sensor_index = to_sensor_dev_attr(attr)->index; @@ -323,7 +323,7 @@ xe_hwmon_power_max_interval_store(struct device *dev, struct device_attribute *a const char *buf, size_t count) { struct xe_hwmon *hwmon = dev_get_drvdata(dev); - struct xe_gt *mmio = xe_root_mmio_gt(hwmon->xe); + struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); u32 x, y, rxy, x_w = 2; /* 2 bits */ u64 tau4, r, max_win; unsigned long val; @@ -498,7 +498,7 @@ static int xe_hwmon_power_curr_crit_write(struct xe_hwmon *hwmon, int channel, static void xe_hwmon_get_voltage(struct xe_hwmon *hwmon, int channel, long *value) { - struct xe_gt *mmio = xe_root_mmio_gt(hwmon->xe); + struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe); u64 reg_val; reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_GT_PERF_STATUS, channel)); @@ -781,7 +781,7 @@ static const struct hwmon_chip_info hwmon_chip_info = { static void xe_hwmon_get_preregistration_info(struct xe_device *xe) { - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); struct xe_hwmon *hwmon = xe->hwmon; long energy; u64 val_sku_unit = 0; -- GitLab From 02f017cc13ae54b513d0322a6f5f80b379179b96 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:33 -0700 Subject: [PATCH 144/970] drm/xe/vram: Convert register access to use xe_mmio Stop using GT pointers for register access. Note that MIRROR_FUSE3 is a GT register and is accessed via gt->mmio, whereas GSMBASE is an sgunit register so it is accessed via tile->mmio. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-58-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_vram.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c index 5bcd59190353..7e765b1499b1 100644 --- a/drivers/gpu/drm/xe/xe_vram.c +++ b/drivers/gpu/drm/xe/xe_vram.c @@ -169,7 +169,7 @@ static inline u64 get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size) u64 offset_hi, offset_lo; u32 nodes, num_enabled; - reg = xe_mmio_read32(gt, MIRROR_FUSE3); + reg = xe_mmio_read32(>->mmio, MIRROR_FUSE3); nodes = REG_FIELD_GET(XE2_NODE_ENABLE_MASK, reg); num_enabled = hweight32(nodes); /* Number of enabled l3 nodes */ @@ -184,7 +184,8 @@ static inline u64 get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size) offset *= num_enabled; /* convert to SW view */ /* We don't expect any holes */ - xe_assert_msg(xe, offset == (xe_mmio_read64_2x32(gt, GSMBASE) - ccs_size), + xe_assert_msg(xe, offset == (xe_mmio_read64_2x32(>_to_tile(gt)->mmio, GSMBASE) - + ccs_size), "Hole between CCS and GSM.\n"); } else { reg = xe_gt_mcr_unicast_read_any(gt, XEHP_FLAT_CCS_BASE_ADDR); @@ -256,7 +257,7 @@ static int tile_vram_size(struct xe_tile *tile, u64 *vram_size, if (xe->info.has_flat_ccs) { offset = get_flat_ccs_offset(gt, *tile_size); } else { - offset = xe_mmio_read64_2x32(gt, GSMBASE); + offset = xe_mmio_read64_2x32(&tile->mmio, GSMBASE); } /* remove the tile offset so we have just the available size */ -- GitLab From ab069ad85ff214035a6393f31863bade28dd7572 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:34 -0700 Subject: [PATCH 145/970] drm/xe/compat-i915: Convert register access to use xe_mmio Stop using GT pointers for register access. v2: - Don't remove _Generic wrappers for 8/16-bit yet; save that for the last patch of the series. (Rodrigo) Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-59-matthew.d.roper@intel.com --- .../drm/xe/compat-i915-headers/intel_uncore.h | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h index eb5b5f0e4bd9..ee3469d4ae73 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h @@ -10,11 +10,11 @@ #include "xe_device_types.h" #include "xe_mmio.h" -static inline struct xe_gt *__compat_uncore_to_gt(struct intel_uncore *uncore) +static inline struct xe_mmio *__compat_uncore_to_mmio(struct intel_uncore *uncore) { struct xe_device *xe = container_of(uncore, struct xe_device, uncore); - return xe_root_mmio_gt(xe); + return xe_root_tile_mmio(xe); } static inline struct xe_tile *__compat_uncore_to_tile(struct intel_uncore *uncore) @@ -29,7 +29,7 @@ static inline u32 intel_uncore_read(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_read32(__compat_uncore_to_gt(uncore), reg); + return xe_mmio_read32(__compat_uncore_to_mmio(uncore), reg); } static inline u8 intel_uncore_read8(struct intel_uncore *uncore, @@ -37,7 +37,7 @@ static inline u8 intel_uncore_read8(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_read8(__compat_uncore_to_gt(uncore), reg); + return xe_mmio_read8(__compat_uncore_to_mmio(uncore), reg); } static inline u16 intel_uncore_read16(struct intel_uncore *uncore, @@ -45,7 +45,7 @@ static inline u16 intel_uncore_read16(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_read16(__compat_uncore_to_gt(uncore), reg); + return xe_mmio_read16(__compat_uncore_to_mmio(uncore), reg); } static inline u64 @@ -57,11 +57,11 @@ intel_uncore_read64_2x32(struct intel_uncore *uncore, u32 upper, lower, old_upper; int loop = 0; - upper = xe_mmio_read32(__compat_uncore_to_gt(uncore), upper_reg); + upper = xe_mmio_read32(__compat_uncore_to_mmio(uncore), upper_reg); do { old_upper = upper; - lower = xe_mmio_read32(__compat_uncore_to_gt(uncore), lower_reg); - upper = xe_mmio_read32(__compat_uncore_to_gt(uncore), upper_reg); + lower = xe_mmio_read32(__compat_uncore_to_mmio(uncore), lower_reg); + upper = xe_mmio_read32(__compat_uncore_to_mmio(uncore), upper_reg); } while (upper != old_upper && loop++ < 2); return (u64)upper << 32 | lower; @@ -72,7 +72,7 @@ static inline void intel_uncore_posting_read(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - xe_mmio_read32(__compat_uncore_to_gt(uncore), reg); + xe_mmio_read32(__compat_uncore_to_mmio(uncore), reg); } static inline void intel_uncore_write(struct intel_uncore *uncore, @@ -80,7 +80,7 @@ static inline void intel_uncore_write(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - xe_mmio_write32(__compat_uncore_to_gt(uncore), reg, val); + xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val); } static inline u32 intel_uncore_rmw(struct intel_uncore *uncore, @@ -88,7 +88,7 @@ static inline u32 intel_uncore_rmw(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_rmw32(__compat_uncore_to_gt(uncore), reg, clear, set); + return xe_mmio_rmw32(__compat_uncore_to_mmio(uncore), reg, clear, set); } static inline int intel_wait_for_register(struct intel_uncore *uncore, @@ -97,7 +97,7 @@ static inline int intel_wait_for_register(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_wait32(__compat_uncore_to_gt(uncore), reg, mask, value, + return xe_mmio_wait32(__compat_uncore_to_mmio(uncore), reg, mask, value, timeout * USEC_PER_MSEC, NULL, false); } @@ -107,7 +107,7 @@ static inline int intel_wait_for_register_fw(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_wait32(__compat_uncore_to_gt(uncore), reg, mask, value, + return xe_mmio_wait32(__compat_uncore_to_mmio(uncore), reg, mask, value, timeout * USEC_PER_MSEC, NULL, false); } @@ -118,7 +118,7 @@ __intel_wait_for_register(struct intel_uncore *uncore, i915_reg_t i915_reg, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_wait32(__compat_uncore_to_gt(uncore), reg, mask, value, + return xe_mmio_wait32(__compat_uncore_to_mmio(uncore), reg, mask, value, fast_timeout_us + 1000 * slow_timeout_ms, out_value, false); } @@ -128,7 +128,7 @@ static inline u32 intel_uncore_read_fw(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_read32(__compat_uncore_to_gt(uncore), reg); + return xe_mmio_read32(__compat_uncore_to_mmio(uncore), reg); } static inline void intel_uncore_write_fw(struct intel_uncore *uncore, @@ -136,7 +136,7 @@ static inline void intel_uncore_write_fw(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - xe_mmio_write32(__compat_uncore_to_gt(uncore), reg, val); + xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val); } static inline u32 intel_uncore_read_notrace(struct intel_uncore *uncore, @@ -144,7 +144,7 @@ static inline u32 intel_uncore_read_notrace(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - return xe_mmio_read32(__compat_uncore_to_gt(uncore), reg); + return xe_mmio_read32(__compat_uncore_to_mmio(uncore), reg); } static inline void intel_uncore_write_notrace(struct intel_uncore *uncore, @@ -152,7 +152,7 @@ static inline void intel_uncore_write_notrace(struct intel_uncore *uncore, { struct xe_reg reg = XE_REG(i915_mmio_reg_offset(i915_reg)); - xe_mmio_write32(__compat_uncore_to_gt(uncore), reg, val); + xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val); } static inline void __iomem *intel_uncore_regs(struct intel_uncore *uncore) -- GitLab From b4237bb4f5b5c46dc69310da1ba59f79352b9b09 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:35 -0700 Subject: [PATCH 146/970] drm/xe/lmtt: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-60-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_lmtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_lmtt.c b/drivers/gpu/drm/xe/xe_lmtt.c index 8999ac511555..a60ceae4c6dd 100644 --- a/drivers/gpu/drm/xe/xe_lmtt.c +++ b/drivers/gpu/drm/xe/xe_lmtt.c @@ -193,7 +193,7 @@ static void lmtt_setup_dir_ptr(struct xe_lmtt *lmtt) lmtt_assert(lmtt, xe_bo_is_vram(lmtt->pd->bo)); lmtt_assert(lmtt, IS_ALIGNED(offset, SZ_64K)); - xe_mmio_write32(tile->primary_gt, + xe_mmio_write32(&tile->mmio, GRAPHICS_VER(xe) >= 20 ? XE2_LMEM_CFG : LMEM_CFG, LMEM_EN | REG_FIELD_PREP(LMTT_DIR_PTR, offset / SZ_64K)); } -- GitLab From 8217669bd8950429861cc05f875412a314315996 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:36 -0700 Subject: [PATCH 147/970] drm/xe/stolen: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-61-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c index f7113cf6109d..423856cc18d4 100644 --- a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c @@ -60,7 +60,7 @@ bool xe_ttm_stolen_cpu_access_needs_ggtt(struct xe_device *xe) static s64 detect_bar2_dgfx(struct xe_device *xe, struct xe_ttm_stolen_mgr *mgr) { struct xe_tile *tile = xe_device_get_root_tile(xe); - struct xe_gt *mmio = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); struct pci_dev *pdev = to_pci_dev(xe->drm.dev); u64 stolen_size; u64 tile_offset; @@ -94,7 +94,7 @@ static u32 get_wopcm_size(struct xe_device *xe) u32 wopcm_size; u64 val; - val = xe_mmio_read64_2x32(xe_root_mmio_gt(xe), STOLEN_RESERVED); + val = xe_mmio_read64_2x32(xe_root_tile_mmio(xe), STOLEN_RESERVED); val = REG_FIELD_GET64(WOPCM_SIZE_MASK, val); switch (val) { @@ -119,7 +119,7 @@ static u32 detect_bar2_integrated(struct xe_device *xe, struct xe_ttm_stolen_mgr u32 stolen_size, wopcm_size; u32 ggc, gms; - ggc = xe_mmio_read32(xe_root_mmio_gt(xe), GGC); + ggc = xe_mmio_read32(xe_root_tile_mmio(xe), GGC); /* * Check GGMS: it should be fixed 0x3 (8MB), which corresponds to the @@ -159,7 +159,7 @@ static u32 detect_bar2_integrated(struct xe_device *xe, struct xe_ttm_stolen_mgr stolen_size -= wopcm_size; if (media_gt && XE_WA(media_gt, 14019821291)) { - u64 gscpsmi_base = xe_mmio_read64_2x32(media_gt, GSCPSMI_BASE) + u64 gscpsmi_base = xe_mmio_read64_2x32(&media_gt->mmio, GSCPSMI_BASE) & ~GENMASK_ULL(5, 0); /* -- GitLab From 10a0575c2ff625eecdb8e7533ce212d6a76c1eab Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:37 -0700 Subject: [PATCH 148/970] drm/xe/device: Convert register access to use xe_mmio Stop using GT pointers for register access. Since a GT was passed as a parameter to verify_lmem_ready() solely as a way to do MMIO accesses, change the parameter to xe_device, which more accurately reflects that this is a device-wide operation. v2: - Expand commit message to explain why verify_lmem_ready()'s parameter changes. (Rodrigo) Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-62-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device.c | 37 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index fdb3a4133f43..4d3c794f134c 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -385,7 +385,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, static bool xe_driver_flr_disabled(struct xe_device *xe) { - return xe_mmio_read32(xe_root_mmio_gt(xe), GU_CNTL_PROTECTED) & DRIVERINT_FLR_DIS; + return xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL_PROTECTED) & DRIVERINT_FLR_DIS; } /* @@ -404,7 +404,7 @@ static bool xe_driver_flr_disabled(struct xe_device *xe) static void __xe_driver_flr(struct xe_device *xe) { const unsigned int flr_timeout = 3 * MICRO; /* specs recommend a 3s wait */ - struct xe_gt *gt = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); int ret; drm_dbg(&xe->drm, "Triggering Driver-FLR\n"); @@ -418,25 +418,25 @@ static void __xe_driver_flr(struct xe_device *xe) * is still pending (unless the HW is totally dead), but better to be * safe in case something unexpected happens */ - ret = xe_mmio_wait32(gt, GU_CNTL, DRIVERFLR, 0, flr_timeout, NULL, false); + ret = xe_mmio_wait32(mmio, GU_CNTL, DRIVERFLR, 0, flr_timeout, NULL, false); if (ret) { drm_err(&xe->drm, "Driver-FLR-prepare wait for ready failed! %d\n", ret); return; } - xe_mmio_write32(gt, GU_DEBUG, DRIVERFLR_STATUS); + xe_mmio_write32(mmio, GU_DEBUG, DRIVERFLR_STATUS); /* Trigger the actual Driver-FLR */ - xe_mmio_rmw32(gt, GU_CNTL, 0, DRIVERFLR); + xe_mmio_rmw32(mmio, GU_CNTL, 0, DRIVERFLR); /* Wait for hardware teardown to complete */ - ret = xe_mmio_wait32(gt, GU_CNTL, DRIVERFLR, 0, flr_timeout, NULL, false); + ret = xe_mmio_wait32(mmio, GU_CNTL, DRIVERFLR, 0, flr_timeout, NULL, false); if (ret) { drm_err(&xe->drm, "Driver-FLR-teardown wait completion failed! %d\n", ret); return; } /* Wait for hardware/firmware re-init to complete */ - ret = xe_mmio_wait32(gt, GU_DEBUG, DRIVERFLR_STATUS, DRIVERFLR_STATUS, + ret = xe_mmio_wait32(mmio, GU_DEBUG, DRIVERFLR_STATUS, DRIVERFLR_STATUS, flr_timeout, NULL, false); if (ret) { drm_err(&xe->drm, "Driver-FLR-reinit wait completion failed! %d\n", ret); @@ -444,7 +444,7 @@ static void __xe_driver_flr(struct xe_device *xe) } /* Clear sticky completion status */ - xe_mmio_write32(gt, GU_DEBUG, DRIVERFLR_STATUS); + xe_mmio_write32(mmio, GU_DEBUG, DRIVERFLR_STATUS); } static void xe_driver_flr(struct xe_device *xe) @@ -497,16 +497,15 @@ static int xe_set_dma_info(struct xe_device *xe) return err; } -static bool verify_lmem_ready(struct xe_gt *gt) +static bool verify_lmem_ready(struct xe_device *xe) { - u32 val = xe_mmio_read32(gt, GU_CNTL) & LMEM_INIT; + u32 val = xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL) & LMEM_INIT; return !!val; } static int wait_for_lmem_ready(struct xe_device *xe) { - struct xe_gt *gt = xe_root_mmio_gt(xe); unsigned long timeout, start; if (!IS_DGFX(xe)) @@ -515,7 +514,7 @@ static int wait_for_lmem_ready(struct xe_device *xe) if (IS_SRIOV_VF(xe)) return 0; - if (verify_lmem_ready(gt)) + if (verify_lmem_ready(xe)) return 0; drm_dbg(&xe->drm, "Waiting for lmem initialization\n"); @@ -544,7 +543,7 @@ static int wait_for_lmem_ready(struct xe_device *xe) msleep(20); - } while (!verify_lmem_ready(gt)); + } while (!verify_lmem_ready(xe)); drm_dbg(&xe->drm, "lmem ready after %ums", jiffies_to_msecs(jiffies - start)); @@ -841,11 +840,9 @@ void xe_device_shutdown(struct xe_device *xe) */ void xe_device_wmb(struct xe_device *xe) { - struct xe_gt *gt = xe_root_mmio_gt(xe); - wmb(); if (IS_DGFX(xe)) - xe_mmio_write32(gt, VF_CAP_REG, 0); + xe_mmio_write32(xe_root_tile_mmio(xe), VF_CAP_REG, 0); } /** @@ -886,7 +883,7 @@ void xe_device_td_flush(struct xe_device *xe) if (xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)) return; - xe_mmio_write32(gt, XE2_TDF_CTRL, TRANSIENT_FLUSH_REQUEST); + xe_mmio_write32(>->mmio, XE2_TDF_CTRL, TRANSIENT_FLUSH_REQUEST); /* * FIXME: We can likely do better here with our choice of * timeout. Currently we just assume the worst case, i.e. 150us, @@ -894,7 +891,7 @@ void xe_device_td_flush(struct xe_device *xe) * scenario on current platforms if all cache entries are * transient and need to be flushed.. */ - if (xe_mmio_wait32(gt, XE2_TDF_CTRL, TRANSIENT_FLUSH_REQUEST, 0, + if (xe_mmio_wait32(>->mmio, XE2_TDF_CTRL, TRANSIENT_FLUSH_REQUEST, 0, 150, NULL, false)) xe_gt_err_once(gt, "TD flush timeout\n"); @@ -917,9 +914,9 @@ void xe_device_l2_flush(struct xe_device *xe) return; spin_lock(>->global_invl_lock); - xe_mmio_write32(gt, XE2_GLOBAL_INVAL, 0x1); + xe_mmio_write32(>->mmio, XE2_GLOBAL_INVAL, 0x1); - if (xe_mmio_wait32(gt, XE2_GLOBAL_INVAL, 0x1, 0x0, 150, NULL, true)) + if (xe_mmio_wait32(>->mmio, XE2_GLOBAL_INVAL, 0x1, 0x0, 150, NULL, true)) xe_gt_err_once(gt, "Global invalidation timeout\n"); spin_unlock(>->global_invl_lock); -- GitLab From 0afda5d7bba49957cd79e1a19bef77356c99b09b Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:38 -0700 Subject: [PATCH 149/970] drm/xe/pci: Convert register access to use xe_mmio Stop using GT pointers for register access. v2: - Clarify comment about manual GSI offset handling. (Rodrigo) Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-63-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index d045ea68c808..a1d08e20cd34 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -468,13 +468,15 @@ enum xe_gmdid_type { static void read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, u32 *ver, u32 *revid) { - struct xe_gt *gt = xe_root_mmio_gt(xe); + struct xe_mmio *mmio = xe_root_tile_mmio(xe); struct xe_reg gmdid_reg = GMD_ID; u32 val; KUNIT_STATIC_STUB_REDIRECT(read_gmdid, xe, type, ver, revid); if (IS_SRIOV_VF(xe)) { + struct xe_gt *gt = xe_root_mmio_gt(xe); + /* * To get the value of the GMDID register, VFs must obtain it * from the GuC using MMIO communication. @@ -510,14 +512,17 @@ static void read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, u32 *ver, gt->info.type = XE_GT_TYPE_UNINITIALIZED; } else { /* - * We need to apply the GSI offset explicitly here as at this - * point the xe_gt is not fully uninitialized and only basic - * access to MMIO registers is possible. + * GMD_ID is a GT register, but at this point in the driver + * init we haven't fully initialized the GT yet so we need to + * read the register with the tile's MMIO accessor. That means + * we need to apply the GSI offset manually since it won't get + * automatically added as it would if we were using a GT mmio + * accessor. */ if (type == GMDID_MEDIA) gmdid_reg.addr += MEDIA_GT_GSI_OFFSET; - val = xe_mmio_read32(gt, gmdid_reg); + val = xe_mmio_read32(mmio, gmdid_reg); } *ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val) * 100 + REG_FIELD_GET(GMD_ID_RELEASE_MASK, val); -- GitLab From 260ec0014ac4055743cd45acfb977a6bc1189cee Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:39 -0700 Subject: [PATCH 150/970] drm/xe/wa: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-64-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_wa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index d424992514a4..22c148b1e996 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -887,11 +887,11 @@ void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p) */ void xe_wa_apply_tile_workarounds(struct xe_tile *tile) { - struct xe_gt *mmio = tile->primary_gt; + struct xe_mmio *mmio = &tile->mmio; if (IS_SRIOV_VF(tile->xe)) return; - if (XE_WA(mmio, 22010954014)) + if (XE_WA(tile->primary_gt, 22010954014)) xe_mmio_rmw32(mmio, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS); } -- GitLab From 2dd21a9b5e6f48f0a824a13bc9a5bd67397929a9 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:40 -0700 Subject: [PATCH 151/970] drm/xe/uc: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-65-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_uc_fw.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c index d431d0031185..d339f636f4d5 100644 --- a/drivers/gpu/drm/xe/xe_uc_fw.c +++ b/drivers/gpu/drm/xe/xe_uc_fw.c @@ -806,6 +806,7 @@ static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags) { struct xe_device *xe = uc_fw_to_xe(uc_fw); struct xe_gt *gt = uc_fw_to_gt(uc_fw); + struct xe_mmio *mmio = >->mmio; u64 src_offset; u32 dma_ctrl; int ret; @@ -814,34 +815,34 @@ static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags) /* Set the source address for the uCode */ src_offset = uc_fw_ggtt_offset(uc_fw) + uc_fw->css_offset; - xe_mmio_write32(gt, DMA_ADDR_0_LOW, lower_32_bits(src_offset)); - xe_mmio_write32(gt, DMA_ADDR_0_HIGH, + xe_mmio_write32(mmio, DMA_ADDR_0_LOW, lower_32_bits(src_offset)); + xe_mmio_write32(mmio, DMA_ADDR_0_HIGH, upper_32_bits(src_offset) | DMA_ADDRESS_SPACE_GGTT); /* Set the DMA destination */ - xe_mmio_write32(gt, DMA_ADDR_1_LOW, offset); - xe_mmio_write32(gt, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); + xe_mmio_write32(mmio, DMA_ADDR_1_LOW, offset); + xe_mmio_write32(mmio, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); /* * Set the transfer size. The header plus uCode will be copied to WOPCM * via DMA, excluding any other components */ - xe_mmio_write32(gt, DMA_COPY_SIZE, + xe_mmio_write32(mmio, DMA_COPY_SIZE, sizeof(struct uc_css_header) + uc_fw->ucode_size); /* Start the DMA */ - xe_mmio_write32(gt, DMA_CTRL, + xe_mmio_write32(mmio, DMA_CTRL, _MASKED_BIT_ENABLE(dma_flags | START_DMA)); /* Wait for DMA to finish */ - ret = xe_mmio_wait32(gt, DMA_CTRL, START_DMA, 0, 100000, &dma_ctrl, + ret = xe_mmio_wait32(mmio, DMA_CTRL, START_DMA, 0, 100000, &dma_ctrl, false); if (ret) drm_err(&xe->drm, "DMA for %s fw failed, DMA_CTRL=%u\n", xe_uc_fw_type_repr(uc_fw->type), dma_ctrl); /* Disable the bits once DMA is over */ - xe_mmio_write32(gt, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags)); + xe_mmio_write32(mmio, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags)); return ret; } -- GitLab From c18d4193b53be70e4713c74c712b8663594661f1 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:41 -0700 Subject: [PATCH 152/970] drm/xe/guc: Convert register access to use xe_mmio Stop using GT pointers for register access. v2: - Don't drop the _Generic wrapper macro for xe_mmio_wait32_not() yet. Defer that to the final patch of the series instead. (Rodrigo) Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-66-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_guc.c | 60 ++++++++++++++++++--------------- drivers/gpu/drm/xe/xe_guc_ads.c | 2 +- drivers/gpu/drm/xe/xe_guc_pc.c | 34 +++++++++---------- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index 5599464013bd..1eb5bb7e8771 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -236,10 +236,10 @@ static void guc_write_params(struct xe_guc *guc) xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT); - xe_mmio_write32(gt, SOFT_SCRATCH(0), 0); + xe_mmio_write32(>->mmio, SOFT_SCRATCH(0), 0); for (i = 0; i < GUC_CTL_MAX_DWORDS; i++) - xe_mmio_write32(gt, SOFT_SCRATCH(1 + i), guc->params[i]); + xe_mmio_write32(>->mmio, SOFT_SCRATCH(1 + i), guc->params[i]); } static void guc_fini_hw(void *arg) @@ -425,6 +425,7 @@ int xe_guc_post_load_init(struct xe_guc *guc) int xe_guc_reset(struct xe_guc *guc) { struct xe_gt *gt = guc_to_gt(guc); + struct xe_mmio *mmio = >->mmio; u32 guc_status, gdrst; int ret; @@ -433,15 +434,15 @@ int xe_guc_reset(struct xe_guc *guc) if (IS_SRIOV_VF(gt_to_xe(gt))) return xe_gt_sriov_vf_bootstrap(gt); - xe_mmio_write32(gt, GDRST, GRDOM_GUC); + xe_mmio_write32(mmio, GDRST, GRDOM_GUC); - ret = xe_mmio_wait32(gt, GDRST, GRDOM_GUC, 0, 5000, &gdrst, false); + ret = xe_mmio_wait32(mmio, GDRST, GRDOM_GUC, 0, 5000, &gdrst, false); if (ret) { xe_gt_err(gt, "GuC reset timed out, GDRST=%#x\n", gdrst); goto err_out; } - guc_status = xe_mmio_read32(gt, GUC_STATUS); + guc_status = xe_mmio_read32(mmio, GUC_STATUS); if (!(guc_status & GS_MIA_IN_RESET)) { xe_gt_err(gt, "GuC status: %#x, MIA core expected to be in reset\n", guc_status); @@ -459,6 +460,7 @@ int xe_guc_reset(struct xe_guc *guc) static void guc_prepare_xfer(struct xe_guc *guc) { struct xe_gt *gt = guc_to_gt(guc); + struct xe_mmio *mmio = >->mmio; struct xe_device *xe = guc_to_xe(guc); u32 shim_flags = GUC_ENABLE_READ_CACHE_LOGIC | GUC_ENABLE_READ_CACHE_FOR_SRAM_DATA | @@ -473,12 +475,12 @@ static void guc_prepare_xfer(struct xe_guc *guc) shim_flags |= REG_FIELD_PREP(GUC_MOCS_INDEX_MASK, gt->mocs.uc_index); /* Must program this register before loading the ucode with DMA */ - xe_mmio_write32(gt, GUC_SHIM_CONTROL, shim_flags); + xe_mmio_write32(mmio, GUC_SHIM_CONTROL, shim_flags); - xe_mmio_write32(gt, GT_PM_CONFIG, GT_DOORBELL_ENABLE); + xe_mmio_write32(mmio, GT_PM_CONFIG, GT_DOORBELL_ENABLE); /* Make sure GuC receives ARAT interrupts */ - xe_mmio_rmw32(gt, PMINTRMSK, ARAT_EXPIRED_INTRMSK, 0); + xe_mmio_rmw32(mmio, PMINTRMSK, ARAT_EXPIRED_INTRMSK, 0); } /* @@ -494,7 +496,7 @@ static int guc_xfer_rsa(struct xe_guc *guc) if (guc->fw.rsa_size > 256) { u32 rsa_ggtt_addr = xe_bo_ggtt_addr(guc->fw.bo) + xe_uc_fw_rsa_offset(&guc->fw); - xe_mmio_write32(gt, UOS_RSA_SCRATCH(0), rsa_ggtt_addr); + xe_mmio_write32(>->mmio, UOS_RSA_SCRATCH(0), rsa_ggtt_addr); return 0; } @@ -503,7 +505,7 @@ static int guc_xfer_rsa(struct xe_guc *guc) return -ENOMEM; for (i = 0; i < UOS_RSA_SCRATCH_COUNT; i++) - xe_mmio_write32(gt, UOS_RSA_SCRATCH(i), rsa[i]); + xe_mmio_write32(>->mmio, UOS_RSA_SCRATCH(i), rsa[i]); return 0; } @@ -593,6 +595,7 @@ static s32 guc_pc_get_cur_freq(struct xe_guc_pc *guc_pc) static void guc_wait_ucode(struct xe_guc *guc) { struct xe_gt *gt = guc_to_gt(guc); + struct xe_mmio *mmio = >->mmio; struct xe_guc_pc *guc_pc = >->uc.guc.pc; ktime_t before, after, delta; int load_done; @@ -619,7 +622,7 @@ static void guc_wait_ucode(struct xe_guc *guc) * timeouts rather than allowing a huge timeout each time. So basically, need * to treat a timeout no different to a value change. */ - ret = xe_mmio_wait32_not(gt, GUC_STATUS, GS_UKERNEL_MASK | GS_BOOTROM_MASK, + ret = xe_mmio_wait32_not(mmio, GUC_STATUS, GS_UKERNEL_MASK | GS_BOOTROM_MASK, last_status, 1000 * 1000, &status, false); if (ret < 0) count++; @@ -657,7 +660,7 @@ static void guc_wait_ucode(struct xe_guc *guc) switch (bootrom) { case XE_BOOTROM_STATUS_NO_KEY_FOUND: xe_gt_err(gt, "invalid key requested, header = 0x%08X\n", - xe_mmio_read32(gt, GUC_HEADER_INFO)); + xe_mmio_read32(mmio, GUC_HEADER_INFO)); break; case XE_BOOTROM_STATUS_RSA_FAILED: @@ -672,7 +675,7 @@ static void guc_wait_ucode(struct xe_guc *guc) switch (ukernel) { case XE_GUC_LOAD_STATUS_EXCEPTION: xe_gt_err(gt, "firmware exception. EIP: %#x\n", - xe_mmio_read32(gt, SOFT_SCRATCH(13))); + xe_mmio_read32(mmio, SOFT_SCRATCH(13))); break; case XE_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID: @@ -824,10 +827,10 @@ static void guc_handle_mmio_msg(struct xe_guc *guc) xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT); - msg = xe_mmio_read32(gt, SOFT_SCRATCH(15)); + msg = xe_mmio_read32(>->mmio, SOFT_SCRATCH(15)); msg &= XE_GUC_RECV_MSG_EXCEPTION | XE_GUC_RECV_MSG_CRASH_DUMP_POSTED; - xe_mmio_write32(gt, SOFT_SCRATCH(15), 0); + xe_mmio_write32(>->mmio, SOFT_SCRATCH(15), 0); if (msg & XE_GUC_RECV_MSG_CRASH_DUMP_POSTED) xe_gt_err(gt, "Received early GuC crash dump notification!\n"); @@ -844,14 +847,14 @@ static void guc_enable_irq(struct xe_guc *guc) REG_FIELD_PREP(ENGINE1_MASK, GUC_INTR_GUC2HOST); /* Primary GuC and media GuC share a single enable bit */ - xe_mmio_write32(gt, GUC_SG_INTR_ENABLE, + xe_mmio_write32(>->mmio, GUC_SG_INTR_ENABLE, REG_FIELD_PREP(ENGINE1_MASK, GUC_INTR_GUC2HOST)); /* * There are separate mask bits for primary and media GuCs, so use * a RMW operation to avoid clobbering the other GuC's setting. */ - xe_mmio_rmw32(gt, GUC_SG_INTR_MASK, events, 0); + xe_mmio_rmw32(>->mmio, GUC_SG_INTR_MASK, events, 0); } int xe_guc_enable_communication(struct xe_guc *guc) @@ -907,7 +910,7 @@ void xe_guc_notify(struct xe_guc *guc) * additional payload data to the GuC but this capability is not * used by the firmware yet. Use default value in the meantime. */ - xe_mmio_write32(gt, guc->notify_reg, default_notify_data); + xe_mmio_write32(>->mmio, guc->notify_reg, default_notify_data); } int xe_guc_auth_huc(struct xe_guc *guc, u32 rsa_addr) @@ -925,6 +928,7 @@ int xe_guc_mmio_send_recv(struct xe_guc *guc, const u32 *request, { struct xe_device *xe = guc_to_xe(guc); struct xe_gt *gt = guc_to_gt(guc); + struct xe_mmio *mmio = >->mmio; u32 header, reply; struct xe_reg reply_reg = xe_gt_is_media_type(gt) ? MED_VF_SW_FLAG(0) : VF_SW_FLAG(0); @@ -947,19 +951,19 @@ int xe_guc_mmio_send_recv(struct xe_guc *guc, const u32 *request, /* Not in critical data-path, just do if else for GT type */ if (xe_gt_is_media_type(gt)) { for (i = 0; i < len; ++i) - xe_mmio_write32(gt, MED_VF_SW_FLAG(i), + xe_mmio_write32(mmio, MED_VF_SW_FLAG(i), request[i]); - xe_mmio_read32(gt, MED_VF_SW_FLAG(LAST_INDEX)); + xe_mmio_read32(mmio, MED_VF_SW_FLAG(LAST_INDEX)); } else { for (i = 0; i < len; ++i) - xe_mmio_write32(gt, VF_SW_FLAG(i), + xe_mmio_write32(mmio, VF_SW_FLAG(i), request[i]); - xe_mmio_read32(gt, VF_SW_FLAG(LAST_INDEX)); + xe_mmio_read32(mmio, VF_SW_FLAG(LAST_INDEX)); } xe_guc_notify(guc); - ret = xe_mmio_wait32(gt, reply_reg, GUC_HXG_MSG_0_ORIGIN, + ret = xe_mmio_wait32(mmio, reply_reg, GUC_HXG_MSG_0_ORIGIN, FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC), 50000, &reply, false); if (ret) { @@ -969,7 +973,7 @@ int xe_guc_mmio_send_recv(struct xe_guc *guc, const u32 *request, return ret; } - header = xe_mmio_read32(gt, reply_reg); + header = xe_mmio_read32(mmio, reply_reg); if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) == GUC_HXG_TYPE_NO_RESPONSE_BUSY) { /* @@ -985,7 +989,7 @@ int xe_guc_mmio_send_recv(struct xe_guc *guc, const u32 *request, BUILD_BUG_ON(FIELD_MAX(GUC_HXG_MSG_0_TYPE) != GUC_HXG_TYPE_RESPONSE_SUCCESS); BUILD_BUG_ON((GUC_HXG_TYPE_RESPONSE_SUCCESS ^ GUC_HXG_TYPE_RESPONSE_FAILURE) != 1); - ret = xe_mmio_wait32(gt, reply_reg, resp_mask, resp_mask, + ret = xe_mmio_wait32(mmio, reply_reg, resp_mask, resp_mask, 1000000, &header, false); if (unlikely(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, header) != @@ -1032,7 +1036,7 @@ int xe_guc_mmio_send_recv(struct xe_guc *guc, const u32 *request, for (i = 1; i < VF_SW_FLAG_COUNT; i++) { reply_reg.addr += sizeof(u32); - response_buf[i] = xe_mmio_read32(gt, reply_reg); + response_buf[i] = xe_mmio_read32(mmio, reply_reg); } } @@ -1155,7 +1159,7 @@ void xe_guc_print_info(struct xe_guc *guc, struct drm_printer *p) if (err) return; - status = xe_mmio_read32(gt, GUC_STATUS); + status = xe_mmio_read32(>->mmio, GUC_STATUS); drm_printf(p, "\nGuC status 0x%08x:\n", status); drm_printf(p, "\tBootrom status = 0x%x\n", @@ -1170,7 +1174,7 @@ void xe_guc_print_info(struct xe_guc *guc, struct drm_printer *p) drm_puts(p, "\nScratch registers:\n"); for (i = 0; i < SOFT_SCRATCH_COUNT; i++) { drm_printf(p, "\t%2d: \t0x%x\n", - i, xe_mmio_read32(gt, SOFT_SCRATCH(i))); + i, xe_mmio_read32(>->mmio, SOFT_SCRATCH(i))); } xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c index d1902a8581ca..66d4e5e95abd 100644 --- a/drivers/gpu/drm/xe/xe_guc_ads.c +++ b/drivers/gpu/drm/xe/xe_guc_ads.c @@ -684,7 +684,7 @@ static void guc_doorbell_init(struct xe_guc_ads *ads) if (GRAPHICS_VER(xe) >= 12 && !IS_DGFX(xe)) { u32 distdbreg = - xe_mmio_read32(gt, DIST_DBS_POPULATED); + xe_mmio_read32(>->mmio, DIST_DBS_POPULATED); ads_blob_write(ads, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI], diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c index 034b29984d5e..2b654f820ae2 100644 --- a/drivers/gpu/drm/xe/xe_guc_pc.c +++ b/drivers/gpu/drm/xe/xe_guc_pc.c @@ -262,7 +262,7 @@ static void pc_set_manual_rp_ctrl(struct xe_guc_pc *pc, bool enable) u32 state = enable ? RPSWCTL_ENABLE : RPSWCTL_DISABLE; /* Allow/Disallow punit to process software freq requests */ - xe_mmio_write32(gt, RP_CONTROL, state); + xe_mmio_write32(>->mmio, RP_CONTROL, state); } static void pc_set_cur_freq(struct xe_guc_pc *pc, u32 freq) @@ -274,7 +274,7 @@ static void pc_set_cur_freq(struct xe_guc_pc *pc, u32 freq) /* Req freq is in units of 16.66 Mhz */ rpnswreq = REG_FIELD_PREP(REQ_RATIO_MASK, encode_freq(freq)); - xe_mmio_write32(gt, RPNSWREQ, rpnswreq); + xe_mmio_write32(>->mmio, RPNSWREQ, rpnswreq); /* Sleep for a small time to allow pcode to respond */ usleep_range(100, 300); @@ -334,9 +334,9 @@ static void mtl_update_rpe_value(struct xe_guc_pc *pc) u32 reg; if (xe_gt_is_media_type(gt)) - reg = xe_mmio_read32(gt, MTL_MPE_FREQUENCY); + reg = xe_mmio_read32(>->mmio, MTL_MPE_FREQUENCY); else - reg = xe_mmio_read32(gt, MTL_GT_RPE_FREQUENCY); + reg = xe_mmio_read32(>->mmio, MTL_GT_RPE_FREQUENCY); pc->rpe_freq = decode_freq(REG_FIELD_GET(MTL_RPE_MASK, reg)); } @@ -353,9 +353,9 @@ static void tgl_update_rpe_value(struct xe_guc_pc *pc) * PCODE at a different register */ if (xe->info.platform == XE_PVC) - reg = xe_mmio_read32(gt, PVC_RP_STATE_CAP); + reg = xe_mmio_read32(>->mmio, PVC_RP_STATE_CAP); else - reg = xe_mmio_read32(gt, FREQ_INFO_REC); + reg = xe_mmio_read32(>->mmio, FREQ_INFO_REC); pc->rpe_freq = REG_FIELD_GET(RPE_MASK, reg) * GT_FREQUENCY_MULTIPLIER; } @@ -392,10 +392,10 @@ u32 xe_guc_pc_get_act_freq(struct xe_guc_pc *pc) /* When in RC6, actual frequency reported will be 0. */ if (GRAPHICS_VERx100(xe) >= 1270) { - freq = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1); + freq = xe_mmio_read32(>->mmio, MTL_MIRROR_TARGET_WP1); freq = REG_FIELD_GET(MTL_CAGF_MASK, freq); } else { - freq = xe_mmio_read32(gt, GT_PERF_STATUS); + freq = xe_mmio_read32(>->mmio, GT_PERF_STATUS); freq = REG_FIELD_GET(CAGF_MASK, freq); } @@ -425,7 +425,7 @@ int xe_guc_pc_get_cur_freq(struct xe_guc_pc *pc, u32 *freq) if (ret) return ret; - *freq = xe_mmio_read32(gt, RPNSWREQ); + *freq = xe_mmio_read32(>->mmio, RPNSWREQ); *freq = REG_FIELD_GET(REQ_RATIO_MASK, *freq); *freq = decode_freq(*freq); @@ -612,10 +612,10 @@ enum xe_gt_idle_state xe_guc_pc_c_status(struct xe_guc_pc *pc) u32 reg, gt_c_state; if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) { - reg = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1); + reg = xe_mmio_read32(>->mmio, MTL_MIRROR_TARGET_WP1); gt_c_state = REG_FIELD_GET(MTL_CC_MASK, reg); } else { - reg = xe_mmio_read32(gt, GT_CORE_STATUS); + reg = xe_mmio_read32(>->mmio, GT_CORE_STATUS); gt_c_state = REG_FIELD_GET(RCN_MASK, reg); } @@ -638,7 +638,7 @@ u64 xe_guc_pc_rc6_residency(struct xe_guc_pc *pc) struct xe_gt *gt = pc_to_gt(pc); u32 reg; - reg = xe_mmio_read32(gt, GT_GFX_RC6); + reg = xe_mmio_read32(>->mmio, GT_GFX_RC6); return reg; } @@ -652,7 +652,7 @@ u64 xe_guc_pc_mc6_residency(struct xe_guc_pc *pc) struct xe_gt *gt = pc_to_gt(pc); u64 reg; - reg = xe_mmio_read32(gt, MTL_MEDIA_MC6); + reg = xe_mmio_read32(>->mmio, MTL_MEDIA_MC6); return reg; } @@ -665,9 +665,9 @@ static void mtl_init_fused_rp_values(struct xe_guc_pc *pc) xe_device_assert_mem_access(pc_to_xe(pc)); if (xe_gt_is_media_type(gt)) - reg = xe_mmio_read32(gt, MTL_MEDIAP_STATE_CAP); + reg = xe_mmio_read32(>->mmio, MTL_MEDIAP_STATE_CAP); else - reg = xe_mmio_read32(gt, MTL_RP_STATE_CAP); + reg = xe_mmio_read32(>->mmio, MTL_RP_STATE_CAP); pc->rp0_freq = decode_freq(REG_FIELD_GET(MTL_RP0_CAP_MASK, reg)); @@ -683,9 +683,9 @@ static void tgl_init_fused_rp_values(struct xe_guc_pc *pc) xe_device_assert_mem_access(pc_to_xe(pc)); if (xe->info.platform == XE_PVC) - reg = xe_mmio_read32(gt, PVC_RP_STATE_CAP); + reg = xe_mmio_read32(>->mmio, PVC_RP_STATE_CAP); else - reg = xe_mmio_read32(gt, RP_STATE_CAP); + reg = xe_mmio_read32(>->mmio, RP_STATE_CAP); pc->rp0_freq = REG_FIELD_GET(RP0_MASK, reg) * GT_FREQUENCY_MULTIPLIER; pc->rpn_freq = REG_FIELD_GET(RPN_MASK, reg) * GT_FREQUENCY_MULTIPLIER; } -- GitLab From 3db6c1b1e2461330de6bbef83a8ff4fa8cda61ae Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:42 -0700 Subject: [PATCH 153/970] drm/xe/huc: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-67-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_huc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_huc.c b/drivers/gpu/drm/xe/xe_huc.c index f5459f97af23..77c5830309cf 100644 --- a/drivers/gpu/drm/xe/xe_huc.c +++ b/drivers/gpu/drm/xe/xe_huc.c @@ -229,7 +229,7 @@ bool xe_huc_is_authenticated(struct xe_huc *huc, enum xe_huc_auth_types type) { struct xe_gt *gt = huc_to_gt(huc); - return xe_mmio_read32(gt, huc_auth_modes[type].reg) & huc_auth_modes[type].val; + return xe_mmio_read32(>->mmio, huc_auth_modes[type].reg) & huc_auth_modes[type].val; } int xe_huc_auth(struct xe_huc *huc, enum xe_huc_auth_types type) @@ -268,7 +268,7 @@ int xe_huc_auth(struct xe_huc *huc, enum xe_huc_auth_types type) goto fail; } - ret = xe_mmio_wait32(gt, huc_auth_modes[type].reg, huc_auth_modes[type].val, + ret = xe_mmio_wait32(>->mmio, huc_auth_modes[type].reg, huc_auth_modes[type].val, huc_auth_modes[type].val, 100000, NULL, false); if (ret) { xe_gt_err(gt, "HuC: firmware not verified: %pe\n", ERR_PTR(ret)); @@ -308,7 +308,7 @@ void xe_huc_print_info(struct xe_huc *huc, struct drm_printer *p) return; drm_printf(p, "\nHuC status: 0x%08x\n", - xe_mmio_read32(gt, HUC_KERNEL_LOAD_INFO)); + xe_mmio_read32(>->mmio, HUC_KERNEL_LOAD_INFO)); xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); } -- GitLab From 3b093ad2ac16d3764d8a4c91dd8dd5c926f4127f Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:43 -0700 Subject: [PATCH 154/970] drm/xe/gsc: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-68-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gsc.c | 23 ++++++++++++----------- drivers/gpu/drm/xe/xe_gsc_proxy.c | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c index 6fbea70d3d36..9cb326af5931 100644 --- a/drivers/gpu/drm/xe/xe_gsc.c +++ b/drivers/gpu/drm/xe/xe_gsc.c @@ -179,7 +179,7 @@ static int query_compatibility_version(struct xe_gsc *gsc) static int gsc_fw_is_loaded(struct xe_gt *gt) { - return xe_mmio_read32(gt, HECI_FWSTS1(MTL_GSC_HECI1_BASE)) & + return xe_mmio_read32(>->mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE)) & HECI1_FWSTS1_INIT_COMPLETE; } @@ -190,7 +190,7 @@ static int gsc_fw_wait(struct xe_gt *gt) * executed by the GSCCS. To account for possible submission delays or * other issues, we use a 500ms timeout in the wait here. */ - return xe_mmio_wait32(gt, HECI_FWSTS1(MTL_GSC_HECI1_BASE), + return xe_mmio_wait32(>->mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE), HECI1_FWSTS1_INIT_COMPLETE, HECI1_FWSTS1_INIT_COMPLETE, 500 * USEC_PER_MSEC, NULL, false); @@ -330,7 +330,7 @@ static int gsc_er_complete(struct xe_gt *gt) * so in that scenario we're always guaranteed to find the correct * value. */ - er_status = xe_mmio_read32(gt, GSCI_TIMER_STATUS) & GSCI_TIMER_STATUS_VALUE; + er_status = xe_mmio_read32(>->mmio, GSCI_TIMER_STATUS) & GSCI_TIMER_STATUS_VALUE; if (er_status == GSCI_TIMER_STATUS_TIMER_EXPIRED) { /* @@ -581,11 +581,11 @@ void xe_gsc_wa_14015076503(struct xe_gt *gt, bool prep) if (!XE_WA(gt, 14015076503) || !gsc_fw_is_loaded(gt)) return; - xe_mmio_rmw32(gt, HECI_H_GS1(MTL_GSC_HECI2_BASE), gs1_clr, gs1_set); + xe_mmio_rmw32(>->mmio, HECI_H_GS1(MTL_GSC_HECI2_BASE), gs1_clr, gs1_set); if (prep) { /* make sure the reset bit is clear when writing the CSR reg */ - xe_mmio_rmw32(gt, HECI_H_CSR(MTL_GSC_HECI2_BASE), + xe_mmio_rmw32(>->mmio, HECI_H_CSR(MTL_GSC_HECI2_BASE), HECI_H_CSR_RST, HECI_H_CSR_IG); msleep(200); } @@ -599,6 +599,7 @@ void xe_gsc_wa_14015076503(struct xe_gt *gt, bool prep) void xe_gsc_print_info(struct xe_gsc *gsc, struct drm_printer *p) { struct xe_gt *gt = gsc_to_gt(gsc); + struct xe_mmio *mmio = >->mmio; int err; xe_uc_fw_print(&gsc->fw, p); @@ -613,12 +614,12 @@ void xe_gsc_print_info(struct xe_gsc *gsc, struct drm_printer *p) return; drm_printf(p, "\nHECI1 FWSTS: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", - xe_mmio_read32(gt, HECI_FWSTS1(MTL_GSC_HECI1_BASE)), - xe_mmio_read32(gt, HECI_FWSTS2(MTL_GSC_HECI1_BASE)), - xe_mmio_read32(gt, HECI_FWSTS3(MTL_GSC_HECI1_BASE)), - xe_mmio_read32(gt, HECI_FWSTS4(MTL_GSC_HECI1_BASE)), - xe_mmio_read32(gt, HECI_FWSTS5(MTL_GSC_HECI1_BASE)), - xe_mmio_read32(gt, HECI_FWSTS6(MTL_GSC_HECI1_BASE))); + xe_mmio_read32(mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE)), + xe_mmio_read32(mmio, HECI_FWSTS2(MTL_GSC_HECI1_BASE)), + xe_mmio_read32(mmio, HECI_FWSTS3(MTL_GSC_HECI1_BASE)), + xe_mmio_read32(mmio, HECI_FWSTS4(MTL_GSC_HECI1_BASE)), + xe_mmio_read32(mmio, HECI_FWSTS5(MTL_GSC_HECI1_BASE)), + xe_mmio_read32(mmio, HECI_FWSTS6(MTL_GSC_HECI1_BASE))); xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC); } diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c b/drivers/gpu/drm/xe/xe_gsc_proxy.c index 2d6ea8c01445..6d89c22ae811 100644 --- a/drivers/gpu/drm/xe/xe_gsc_proxy.c +++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c @@ -65,7 +65,7 @@ gsc_to_gt(struct xe_gsc *gsc) bool xe_gsc_proxy_init_done(struct xe_gsc *gsc) { struct xe_gt *gt = gsc_to_gt(gsc); - u32 fwsts1 = xe_mmio_read32(gt, HECI_FWSTS1(MTL_GSC_HECI1_BASE)); + u32 fwsts1 = xe_mmio_read32(>->mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE)); return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fwsts1) == HECI1_FWSTS1_PROXY_STATE_NORMAL; @@ -78,7 +78,7 @@ static void __gsc_proxy_irq_rmw(struct xe_gsc *gsc, u32 clr, u32 set) /* make sure we never accidentally write the RST bit */ clr |= HECI_H_CSR_RST; - xe_mmio_rmw32(gt, HECI_H_CSR(MTL_GSC_HECI2_BASE), clr, set); + xe_mmio_rmw32(>->mmio, HECI_H_CSR(MTL_GSC_HECI2_BASE), clr, set); } static void gsc_proxy_irq_clear(struct xe_gsc *gsc) -- GitLab From b6f2f7be3a22b8cd05d10b0d79a8244c5077e480 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:44 -0700 Subject: [PATCH 155/970] drm/xe/query: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-69-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_query.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c index 28d9bb3b825d..5246a4a2740e 100644 --- a/drivers/gpu/drm/xe/xe_query.c +++ b/drivers/gpu/drm/xe/xe_query.c @@ -91,16 +91,17 @@ __read_timestamps(struct xe_gt *gt, u64 *cpu_delta, __ktime_func_t cpu_clock) { + struct xe_mmio *mmio = >->mmio; u32 upper, lower, old_upper, loop = 0; - upper = xe_mmio_read32(gt, upper_reg); + upper = xe_mmio_read32(mmio, upper_reg); do { *cpu_delta = local_clock(); *cpu_ts = cpu_clock(); - lower = xe_mmio_read32(gt, lower_reg); + lower = xe_mmio_read32(mmio, lower_reg); *cpu_delta = local_clock() - *cpu_delta; old_upper = upper; - upper = xe_mmio_read32(gt, upper_reg); + upper = xe_mmio_read32(mmio, upper_reg); } while (upper != old_upper && loop++ < 2); *engine_ts = (u64)upper << 32 | lower; -- GitLab From 04a6de7203a2a08f3e5ba331bba9e201f1d7ed39 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:45 -0700 Subject: [PATCH 156/970] drm/xe/mcr: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-70-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_mcr.c | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index 7d7bd0be6233..2671ce6b1a76 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -239,11 +239,13 @@ static const struct xe_mmio_range xe2lpm_instance0_steering_table[] = { static void init_steering_l3bank(struct xe_gt *gt) { + struct xe_mmio *mmio = >->mmio; + if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) { u32 mslice_mask = REG_FIELD_GET(MEML3_EN_MASK, - xe_mmio_read32(gt, MIRROR_FUSE3)); + xe_mmio_read32(mmio, MIRROR_FUSE3)); u32 bank_mask = REG_FIELD_GET(GT_L3_EXC_MASK, - xe_mmio_read32(gt, XEHP_FUSE4)); + xe_mmio_read32(mmio, XEHP_FUSE4)); /* * Group selects mslice, instance selects bank within mslice. @@ -254,7 +256,7 @@ static void init_steering_l3bank(struct xe_gt *gt) bank_mask & BIT(0) ? 0 : 2; } else if (gt_to_xe(gt)->info.platform == XE_DG2) { u32 mslice_mask = REG_FIELD_GET(MEML3_EN_MASK, - xe_mmio_read32(gt, MIRROR_FUSE3)); + xe_mmio_read32(mmio, MIRROR_FUSE3)); u32 bank = __ffs(mslice_mask) * 8; /* @@ -266,7 +268,7 @@ static void init_steering_l3bank(struct xe_gt *gt) gt->steering[L3BANK].instance_target = bank & 0x3; } else { u32 fuse = REG_FIELD_GET(L3BANK_MASK, - ~xe_mmio_read32(gt, MIRROR_FUSE3)); + ~xe_mmio_read32(mmio, MIRROR_FUSE3)); gt->steering[L3BANK].group_target = 0; /* unused */ gt->steering[L3BANK].instance_target = __ffs(fuse); @@ -276,7 +278,7 @@ static void init_steering_l3bank(struct xe_gt *gt) static void init_steering_mslice(struct xe_gt *gt) { u32 mask = REG_FIELD_GET(MEML3_EN_MASK, - xe_mmio_read32(gt, MIRROR_FUSE3)); + xe_mmio_read32(>->mmio, MIRROR_FUSE3)); /* * mslice registers are valid (not terminated) if either the meml3 @@ -380,7 +382,7 @@ static void init_steering_oaddrm(struct xe_gt *gt) static void init_steering_sqidi_psmi(struct xe_gt *gt) { u32 mask = REG_FIELD_GET(XE2_NODE_ENABLE_MASK, - xe_mmio_read32(gt, MIRROR_FUSE3)); + xe_mmio_read32(>->mmio, MIRROR_FUSE3)); u32 select = __ffs(mask); gt->steering[SQIDI_PSMI].group_target = select >> 1; @@ -494,8 +496,8 @@ void xe_gt_mcr_set_implicit_defaults(struct xe_gt *gt) u32 steer_val = REG_FIELD_PREP(MCR_SLICE_MASK, 0) | REG_FIELD_PREP(MCR_SUBSLICE_MASK, 2); - xe_mmio_write32(gt, MCFG_MCR_SELECTOR, steer_val); - xe_mmio_write32(gt, SF_MCR_SELECTOR, steer_val); + xe_mmio_write32(>->mmio, MCFG_MCR_SELECTOR, steer_val); + xe_mmio_write32(>->mmio, SF_MCR_SELECTOR, steer_val); /* * For GAM registers, all reads should be directed to instance 1 * (unicast reads against other instances are not allowed), @@ -533,7 +535,7 @@ static bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, continue; for (int i = 0; gt->steering[type].ranges[i].end > 0; i++) { - if (xe_mmio_in_range(gt, >->steering[type].ranges[i], reg)) { + if (xe_mmio_in_range(>->mmio, >->steering[type].ranges[i], reg)) { *group = gt->steering[type].group_target; *instance = gt->steering[type].instance_target; return true; @@ -544,7 +546,7 @@ static bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, implicit_ranges = gt->steering[IMPLICIT_STEERING].ranges; if (implicit_ranges) for (int i = 0; implicit_ranges[i].end > 0; i++) - if (xe_mmio_in_range(gt, &implicit_ranges[i], reg)) + if (xe_mmio_in_range(>->mmio, &implicit_ranges[i], reg)) return false; /* @@ -579,7 +581,7 @@ static void mcr_lock(struct xe_gt *gt) __acquires(>->mcr_lock) * when a read to the relevant register returns 1. */ if (GRAPHICS_VERx100(xe) >= 1270) - ret = xe_mmio_wait32(gt, STEER_SEMAPHORE, 0x1, 0x1, 10, NULL, + ret = xe_mmio_wait32(>->mmio, STEER_SEMAPHORE, 0x1, 0x1, 10, NULL, true); drm_WARN_ON_ONCE(&xe->drm, ret == -ETIMEDOUT); @@ -589,7 +591,7 @@ static void mcr_unlock(struct xe_gt *gt) __releases(>->mcr_lock) { /* Release hardware semaphore - this is done by writing 1 to the register */ if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) - xe_mmio_write32(gt, STEER_SEMAPHORE, 0x1); + xe_mmio_write32(>->mmio, STEER_SEMAPHORE, 0x1); spin_unlock(>->mcr_lock); } @@ -603,6 +605,7 @@ static u32 rw_with_mcr_steering(struct xe_gt *gt, struct xe_reg_mcr reg_mcr, u8 rw_flag, int group, int instance, u32 value) { const struct xe_reg reg = to_xe_reg(reg_mcr); + struct xe_mmio *mmio = >->mmio; struct xe_reg steer_reg; u32 steer_val, val = 0; @@ -635,12 +638,12 @@ static u32 rw_with_mcr_steering(struct xe_gt *gt, struct xe_reg_mcr reg_mcr, if (rw_flag == MCR_OP_READ) steer_val |= MCR_MULTICAST; - xe_mmio_write32(gt, steer_reg, steer_val); + xe_mmio_write32(mmio, steer_reg, steer_val); if (rw_flag == MCR_OP_READ) - val = xe_mmio_read32(gt, reg); + val = xe_mmio_read32(mmio, reg); else - xe_mmio_write32(gt, reg, value); + xe_mmio_write32(mmio, reg, value); /* * If we turned off the multicast bit (during a write) we're required @@ -649,7 +652,7 @@ static u32 rw_with_mcr_steering(struct xe_gt *gt, struct xe_reg_mcr reg_mcr, * operation. */ if (rw_flag == MCR_OP_WRITE) - xe_mmio_write32(gt, steer_reg, MCR_MULTICAST); + xe_mmio_write32(mmio, steer_reg, MCR_MULTICAST); return val; } @@ -684,7 +687,7 @@ u32 xe_gt_mcr_unicast_read_any(struct xe_gt *gt, struct xe_reg_mcr reg_mcr) group, instance, 0); mcr_unlock(gt); } else { - val = xe_mmio_read32(gt, reg); + val = xe_mmio_read32(>->mmio, reg); } return val; @@ -757,7 +760,7 @@ void xe_gt_mcr_multicast_write(struct xe_gt *gt, struct xe_reg_mcr reg_mcr, * to touch the steering register. */ mcr_lock(gt); - xe_mmio_write32(gt, reg, value); + xe_mmio_write32(>->mmio, reg, value); mcr_unlock(gt); } -- GitLab From 2e3a28963a9b296bce2d86b9438bf7504a3fe0ae Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:46 -0700 Subject: [PATCH 157/970] drm/xe/mocs: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-71-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/tests/xe_mocs.c | 4 ++-- drivers/gpu/drm/xe/xe_mocs.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/xe/tests/xe_mocs.c b/drivers/gpu/drm/xe/tests/xe_mocs.c index 79be73b4a02b..ea932c051cc7 100644 --- a/drivers/gpu/drm/xe/tests/xe_mocs.c +++ b/drivers/gpu/drm/xe/tests/xe_mocs.c @@ -55,7 +55,7 @@ static void read_l3cc_table(struct xe_gt *gt, if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i >> 1)); else - reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i >> 1)); + reg_val = xe_mmio_read32(>->mmio, XELP_LNCFCMOCS(i >> 1)); mocs_dbg(gt, "reg_val=0x%x\n", reg_val); } else { @@ -94,7 +94,7 @@ static void read_mocs_table(struct xe_gt *gt, if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_GLOBAL_MOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_GLOBAL_MOCS(i)); mocs_expected = get_entry_control(info, i); mocs = reg_val; diff --git a/drivers/gpu/drm/xe/xe_mocs.c b/drivers/gpu/drm/xe/xe_mocs.c index 7ff0ac5b799a..8df41cd12d51 100644 --- a/drivers/gpu/drm/xe/xe_mocs.c +++ b/drivers/gpu/drm/xe/xe_mocs.c @@ -278,7 +278,7 @@ static void xelp_lncf_dump(struct xe_mocs_info *info, struct xe_gt *gt, struct d if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_LNCFCMOCS(i)); drm_printf(p, "LNCFCMOCS[%2d] = [%u, %u, %u] (%#8x)\n", j++, @@ -310,7 +310,7 @@ static void xelp_mocs_dump(struct xe_mocs_info *info, unsigned int flags, if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_GLOBAL_MOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_GLOBAL_MOCS(i)); drm_printf(p, "GLOB_MOCS[%2d] = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u ] (%#8x)\n", i, @@ -383,7 +383,7 @@ static void xehp_lncf_dump(struct xe_mocs_info *info, unsigned int flags, if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_LNCFCMOCS(i)); drm_printf(p, "LNCFCMOCS[%2d] = [%u, %u, %u] (%#8x)\n", j++, @@ -428,7 +428,7 @@ static void pvc_mocs_dump(struct xe_mocs_info *info, unsigned int flags, struct if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_LNCFCMOCS(i)); drm_printf(p, "LNCFCMOCS[%2d] = [ %u ] (%#8x)\n", j++, @@ -510,7 +510,7 @@ static void mtl_mocs_dump(struct xe_mocs_info *info, unsigned int flags, if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_GLOBAL_MOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_GLOBAL_MOCS(i)); drm_printf(p, "GLOB_MOCS[%2d] = [%u, %u] (%#8x)\n", i, @@ -553,7 +553,7 @@ static void xe2_mocs_dump(struct xe_mocs_info *info, unsigned int flags, if (regs_are_mcr(gt)) reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i)); else - reg_val = xe_mmio_read32(gt, XELP_GLOBAL_MOCS(i)); + reg_val = xe_mmio_read32(>->mmio, XELP_GLOBAL_MOCS(i)); drm_printf(p, "GLOB_MOCS[%2d] = [%u, %u, %u] (%#8x)\n", i, @@ -690,7 +690,7 @@ static void __init_mocs_table(struct xe_gt *gt, if (regs_are_mcr(gt)) xe_gt_mcr_multicast_write(gt, XEHP_GLOBAL_MOCS(i), mocs); else - xe_mmio_write32(gt, XELP_GLOBAL_MOCS(i), mocs); + xe_mmio_write32(>->mmio, XELP_GLOBAL_MOCS(i), mocs); } } @@ -730,7 +730,7 @@ static void init_l3cc_table(struct xe_gt *gt, if (regs_are_mcr(gt)) xe_gt_mcr_multicast_write(gt, XEHP_LNCFCMOCS(i), l3cc); else - xe_mmio_write32(gt, XELP_LNCFCMOCS(i), l3cc); + xe_mmio_write32(>->mmio, XELP_LNCFCMOCS(i), l3cc); } } -- GitLab From 4570c090a43bb66fc0bcec4eb452b45537dcc5ca Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:47 -0700 Subject: [PATCH 158/970] drm/xe/hw_engine: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-72-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_hw_engine.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index ce180faf2592..a7abc4b67e67 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -295,7 +295,7 @@ void xe_hw_engine_mmio_write32(struct xe_hw_engine *hwe, reg.addr += hwe->mmio_base; - xe_mmio_write32(hwe->gt, reg, val); + xe_mmio_write32(&hwe->gt->mmio, reg, val); } /** @@ -315,7 +315,7 @@ u32 xe_hw_engine_mmio_read32(struct xe_hw_engine *hwe, struct xe_reg reg) reg.addr += hwe->mmio_base; - return xe_mmio_read32(hwe->gt, reg); + return xe_mmio_read32(&hwe->gt->mmio, reg); } void xe_hw_engine_enable_ring(struct xe_hw_engine *hwe) @@ -324,7 +324,7 @@ void xe_hw_engine_enable_ring(struct xe_hw_engine *hwe) xe_hw_engine_mask_per_class(hwe->gt, XE_ENGINE_CLASS_COMPUTE); if (hwe->class == XE_ENGINE_CLASS_COMPUTE && ccs_mask) - xe_mmio_write32(hwe->gt, RCU_MODE, + xe_mmio_write32(&hwe->gt->mmio, RCU_MODE, _MASKED_BIT_ENABLE(RCU_MODE_CCS_ENABLE)); xe_hw_engine_mmio_write32(hwe, RING_HWSTAM(0), ~0x0); @@ -354,7 +354,7 @@ static bool xe_rtp_cfeg_wmtp_disabled(const struct xe_gt *gt, hwe->class != XE_ENGINE_CLASS_RENDER) return false; - return xe_mmio_read32(hwe->gt, XEHP_FUSE4) & CFEG_WMTP_DISABLE; + return xe_mmio_read32(&hwe->gt->mmio, XEHP_FUSE4) & CFEG_WMTP_DISABLE; } void @@ -612,7 +612,7 @@ static void read_media_fuses(struct xe_gt *gt) xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT); - media_fuse = xe_mmio_read32(gt, GT_VEBOX_VDBOX_DISABLE); + media_fuse = xe_mmio_read32(>->mmio, GT_VEBOX_VDBOX_DISABLE); /* * Pre-Xe_HP platforms had register bits representing absent engines, @@ -657,7 +657,7 @@ static void read_copy_fuses(struct xe_gt *gt) xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT); - bcs_mask = xe_mmio_read32(gt, MIRROR_FUSE3); + bcs_mask = xe_mmio_read32(>->mmio, MIRROR_FUSE3); bcs_mask = REG_FIELD_GET(MEML3_EN_MASK, bcs_mask); /* BCS0 is always present; only BCS1-BCS8 may be fused off */ @@ -704,7 +704,7 @@ static void read_compute_fuses_from_reg(struct xe_gt *gt) struct xe_device *xe = gt_to_xe(gt); u32 ccs_mask; - ccs_mask = xe_mmio_read32(gt, XEHP_FUSE4); + ccs_mask = xe_mmio_read32(>->mmio, XEHP_FUSE4); ccs_mask = REG_FIELD_GET(CCS_EN_MASK, ccs_mask); for (int i = XE_HW_ENGINE_CCS0, j = 0; i <= XE_HW_ENGINE_CCS3; ++i, ++j) { @@ -742,8 +742,8 @@ static void check_gsc_availability(struct xe_gt *gt) gt->info.engine_mask &= ~BIT(XE_HW_ENGINE_GSCCS0); /* interrupts where previously enabled, so turn them off */ - xe_mmio_write32(gt, GUNIT_GSC_INTR_ENABLE, 0); - xe_mmio_write32(gt, GUNIT_GSC_INTR_MASK, ~0); + xe_mmio_write32(>->mmio, GUNIT_GSC_INTR_ENABLE, 0); + xe_mmio_write32(>->mmio, GUNIT_GSC_INTR_MASK, ~0); drm_info(&xe->drm, "gsccs disabled due to lack of FW\n"); } @@ -809,6 +809,7 @@ xe_hw_engine_snapshot_instdone_capture(struct xe_hw_engine *hwe, struct xe_hw_engine_snapshot *snapshot) { struct xe_gt *gt = hwe->gt; + struct xe_mmio *mmio = >->mmio; struct xe_device *xe = gt_to_xe(gt); unsigned int dss; u16 group, instance; @@ -820,11 +821,11 @@ xe_hw_engine_snapshot_instdone_capture(struct xe_hw_engine *hwe, if (is_slice_common_per_gslice(xe) == false) { snapshot->reg.instdone.slice_common[0] = - xe_mmio_read32(gt, SC_INSTDONE); + xe_mmio_read32(mmio, SC_INSTDONE); snapshot->reg.instdone.slice_common_extra[0] = - xe_mmio_read32(gt, SC_INSTDONE_EXTRA); + xe_mmio_read32(mmio, SC_INSTDONE_EXTRA); snapshot->reg.instdone.slice_common_extra2[0] = - xe_mmio_read32(gt, SC_INSTDONE_EXTRA2); + xe_mmio_read32(mmio, SC_INSTDONE_EXTRA2); } else { for_each_geometry_dss(dss, gt, group, instance) { snapshot->reg.instdone.slice_common[dss] = @@ -960,7 +961,7 @@ xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe) xe_hw_engine_snapshot_instdone_capture(hwe, snapshot); if (snapshot->hwe->class == XE_ENGINE_CLASS_COMPUTE) - snapshot->reg.rcu_mode = xe_mmio_read32(hwe->gt, RCU_MODE); + snapshot->reg.rcu_mode = xe_mmio_read32(&hwe->gt->mmio, RCU_MODE); return snapshot; } @@ -1153,7 +1154,7 @@ const char *xe_hw_engine_class_to_str(enum xe_engine_class class) u64 xe_hw_engine_read_timestamp(struct xe_hw_engine *hwe) { - return xe_mmio_read64_2x32(hwe->gt, RING_TIMESTAMP(hwe->mmio_base)); + return xe_mmio_read64_2x32(&hwe->gt->mmio, RING_TIMESTAMP(hwe->mmio_base)); } enum xe_force_wake_domains xe_hw_engine_to_fw_domain(struct xe_hw_engine *hwe) -- GitLab From f99947ad35fd96f63ad61e30cb8d84d3230d40e1 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:48 -0700 Subject: [PATCH 159/970] drm/xe/gt_throttle: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-73-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_throttle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_throttle.c b/drivers/gpu/drm/xe/xe_gt_throttle.c index 25963e33a383..03b225364101 100644 --- a/drivers/gpu/drm/xe/xe_gt_throttle.c +++ b/drivers/gpu/drm/xe/xe_gt_throttle.c @@ -41,9 +41,9 @@ u32 xe_gt_throttle_get_limit_reasons(struct xe_gt *gt) xe_pm_runtime_get(gt_to_xe(gt)); if (xe_gt_is_media_type(gt)) - reg = xe_mmio_read32(gt, MTL_MEDIA_PERF_LIMIT_REASONS); + reg = xe_mmio_read32(>->mmio, MTL_MEDIA_PERF_LIMIT_REASONS); else - reg = xe_mmio_read32(gt, GT0_PERF_LIMIT_REASONS); + reg = xe_mmio_read32(>->mmio, GT0_PERF_LIMIT_REASONS); xe_pm_runtime_put(gt_to_xe(gt)); return reg; -- GitLab From 0a3dee92f2fdff97649d4663c85c74b119841168 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:49 -0700 Subject: [PATCH 160/970] drm/xe/pat: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-74-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_pat.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c index 5bf48e99c939..6bd6adfdfc74 100644 --- a/drivers/gpu/drm/xe/xe_pat.c +++ b/drivers/gpu/drm/xe/xe_pat.c @@ -165,7 +165,7 @@ static void program_pat(struct xe_gt *gt, const struct xe_pat_table_entry table[ for (int i = 0; i < n_entries; i++) { struct xe_reg reg = XE_REG(_PAT_INDEX(i)); - xe_mmio_write32(gt, reg, table[i].value); + xe_mmio_write32(>->mmio, reg, table[i].value); } } @@ -191,7 +191,7 @@ static void xelp_dump(struct xe_gt *gt, struct drm_printer *p) drm_printf(p, "PAT table:\n"); for (i = 0; i < xe->pat.n_entries; i++) { - u32 pat = xe_mmio_read32(gt, XE_REG(_PAT_INDEX(i))); + u32 pat = xe_mmio_read32(>->mmio, XE_REG(_PAT_INDEX(i))); u8 mem_type = REG_FIELD_GET(XELP_MEM_TYPE_MASK, pat); drm_printf(p, "PAT[%2d] = %s (%#8x)\n", i, @@ -283,7 +283,7 @@ static void xelpg_dump(struct xe_gt *gt, struct drm_printer *p) u32 pat; if (xe_gt_is_media_type(gt)) - pat = xe_mmio_read32(gt, XE_REG(_PAT_INDEX(i))); + pat = xe_mmio_read32(>->mmio, XE_REG(_PAT_INDEX(i))); else pat = xe_gt_mcr_unicast_read_any(gt, XE_REG_MCR(_PAT_INDEX(i))); @@ -321,10 +321,10 @@ static void xe2lpm_program_pat(struct xe_gt *gt, const struct xe_pat_table_entry int n_entries) { program_pat(gt, table, n_entries); - xe_mmio_write32(gt, XE_REG(_PAT_ATS), xe2_pat_ats.value); + xe_mmio_write32(>->mmio, XE_REG(_PAT_ATS), xe2_pat_ats.value); if (IS_DGFX(gt_to_xe(gt))) - xe_mmio_write32(gt, XE_REG(_PAT_PTA), xe2_pat_pta.value); + xe_mmio_write32(>->mmio, XE_REG(_PAT_PTA), xe2_pat_pta.value); } static void xe2_dump(struct xe_gt *gt, struct drm_printer *p) @@ -341,7 +341,7 @@ static void xe2_dump(struct xe_gt *gt, struct drm_printer *p) for (i = 0; i < xe->pat.n_entries; i++) { if (xe_gt_is_media_type(gt)) - pat = xe_mmio_read32(gt, XE_REG(_PAT_INDEX(i))); + pat = xe_mmio_read32(>->mmio, XE_REG(_PAT_INDEX(i))); else pat = xe_gt_mcr_unicast_read_any(gt, XE_REG_MCR(_PAT_INDEX(i))); @@ -360,7 +360,7 @@ static void xe2_dump(struct xe_gt *gt, struct drm_printer *p) * PPGTT entries. */ if (xe_gt_is_media_type(gt)) - pat = xe_mmio_read32(gt, XE_REG(_PAT_PTA)); + pat = xe_mmio_read32(>->mmio, XE_REG(_PAT_PTA)); else pat = xe_gt_mcr_unicast_read_any(gt, XE_REG_MCR(_PAT_PTA)); -- GitLab From 70f02a2c38b041b7af1630a941f75646c458609d Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:50 -0700 Subject: [PATCH 161/970] drm/xe/wopcm: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-75-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_wopcm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_wopcm.c b/drivers/gpu/drm/xe/xe_wopcm.c index d3a99157e523..93c82825d896 100644 --- a/drivers/gpu/drm/xe/xe_wopcm.c +++ b/drivers/gpu/drm/xe/xe_wopcm.c @@ -123,8 +123,8 @@ static bool __check_layout(struct xe_device *xe, u32 wopcm_size, static bool __wopcm_regs_locked(struct xe_gt *gt, u32 *guc_wopcm_base, u32 *guc_wopcm_size) { - u32 reg_base = xe_mmio_read32(gt, DMA_GUC_WOPCM_OFFSET); - u32 reg_size = xe_mmio_read32(gt, GUC_WOPCM_SIZE); + u32 reg_base = xe_mmio_read32(>->mmio, DMA_GUC_WOPCM_OFFSET); + u32 reg_size = xe_mmio_read32(>->mmio, GUC_WOPCM_SIZE); if (!(reg_size & GUC_WOPCM_SIZE_LOCKED) || !(reg_base & GUC_WOPCM_OFFSET_VALID)) @@ -150,13 +150,13 @@ static int __wopcm_init_regs(struct xe_device *xe, struct xe_gt *gt, XE_WARN_ON(size & ~GUC_WOPCM_SIZE_MASK); mask = GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED; - err = xe_mmio_write32_and_verify(gt, GUC_WOPCM_SIZE, size, mask, + err = xe_mmio_write32_and_verify(>->mmio, GUC_WOPCM_SIZE, size, mask, size | GUC_WOPCM_SIZE_LOCKED); if (err) goto err_out; mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent; - err = xe_mmio_write32_and_verify(gt, DMA_GUC_WOPCM_OFFSET, + err = xe_mmio_write32_and_verify(>->mmio, DMA_GUC_WOPCM_OFFSET, base | huc_agent, mask, base | huc_agent | GUC_WOPCM_OFFSET_VALID); @@ -169,10 +169,10 @@ static int __wopcm_init_regs(struct xe_device *xe, struct xe_gt *gt, drm_notice(&xe->drm, "Failed to init uC WOPCM registers!\n"); drm_notice(&xe->drm, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET", DMA_GUC_WOPCM_OFFSET.addr, - xe_mmio_read32(gt, DMA_GUC_WOPCM_OFFSET)); + xe_mmio_read32(>->mmio, DMA_GUC_WOPCM_OFFSET)); drm_notice(&xe->drm, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE", GUC_WOPCM_SIZE.addr, - xe_mmio_read32(gt, GUC_WOPCM_SIZE)); + xe_mmio_read32(>->mmio, GUC_WOPCM_SIZE)); return err; } -- GitLab From 9bc649b30f39ad0c1d0bcca31d98bff46fd5a056 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:51 -0700 Subject: [PATCH 162/970] drm/xe/oa: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-76-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_oa.c | 48 +++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 0369cc016f6a..354ee9045efc 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -176,7 +176,7 @@ static const struct xe_oa_regs *__oa_regs(struct xe_oa_stream *stream) static u32 xe_oa_hw_tail_read(struct xe_oa_stream *stream) { - return xe_mmio_read32(stream->gt, __oa_regs(stream)->oa_tail_ptr) & + return xe_mmio_read32(&stream->gt->mmio, __oa_regs(stream)->oa_tail_ptr) & OAG_OATAILPTR_MASK; } @@ -366,7 +366,7 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf, struct xe_reg oaheadptr = __oa_regs(stream)->oa_head_ptr; spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags); - xe_mmio_write32(stream->gt, oaheadptr, + xe_mmio_write32(&stream->gt->mmio, oaheadptr, (head + gtt_offset) & OAG_OAHEADPTR_MASK); stream->oa_buffer.head = head; spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags); @@ -377,22 +377,23 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf, static void xe_oa_init_oa_buffer(struct xe_oa_stream *stream) { + struct xe_mmio *mmio = &stream->gt->mmio; u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); u32 oa_buf = gtt_offset | OABUFFER_SIZE_16M | OAG_OABUFFER_MEMORY_SELECT; unsigned long flags; spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags); - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_status, 0); - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_head_ptr, + xe_mmio_write32(mmio, __oa_regs(stream)->oa_status, 0); + xe_mmio_write32(mmio, __oa_regs(stream)->oa_head_ptr, gtt_offset & OAG_OAHEADPTR_MASK); stream->oa_buffer.head = 0; /* * PRM says: "This MMIO must be set before the OATAILPTR register and after the * OAHEADPTR register. This is to enable proper functionality of the overflow bit". */ - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_buffer, oa_buf); - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_tail_ptr, + xe_mmio_write32(mmio, __oa_regs(stream)->oa_buffer, oa_buf); + xe_mmio_write32(mmio, __oa_regs(stream)->oa_tail_ptr, gtt_offset & OAG_OATAILPTR_MASK); /* Mark that we need updated tail pointer to read from */ @@ -444,21 +445,23 @@ static void xe_oa_enable(struct xe_oa_stream *stream) stream->hwe->oa_unit->type == DRM_XE_OA_UNIT_TYPE_OAG) val |= OAG_OACONTROL_OA_PES_DISAG_EN; - xe_mmio_write32(stream->gt, regs->oa_ctrl, val); + xe_mmio_write32(&stream->gt->mmio, regs->oa_ctrl, val); } static void xe_oa_disable(struct xe_oa_stream *stream) { - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_ctrl, 0); - if (xe_mmio_wait32(stream->gt, __oa_regs(stream)->oa_ctrl, + struct xe_mmio *mmio = &stream->gt->mmio; + + xe_mmio_write32(mmio, __oa_regs(stream)->oa_ctrl, 0); + if (xe_mmio_wait32(mmio, __oa_regs(stream)->oa_ctrl, OAG_OACONTROL_OA_COUNTER_ENABLE, 0, 50000, NULL, false)) drm_err(&stream->oa->xe->drm, "wait for OA to be disabled timed out\n"); if (GRAPHICS_VERx100(stream->oa->xe) <= 1270 && GRAPHICS_VERx100(stream->oa->xe) != 1260) { /* <= XE_METEORLAKE except XE_PVC */ - xe_mmio_write32(stream->gt, OA_TLB_INV_CR, 1); - if (xe_mmio_wait32(stream->gt, OA_TLB_INV_CR, 1, 0, 50000, NULL, false)) + xe_mmio_write32(mmio, OA_TLB_INV_CR, 1); + if (xe_mmio_wait32(mmio, OA_TLB_INV_CR, 1, 0, 50000, NULL, false)) drm_err(&stream->oa->xe->drm, "wait for OA tlb invalidate timed out\n"); } @@ -481,7 +484,7 @@ static int __xe_oa_read(struct xe_oa_stream *stream, char __user *buf, size_t count, size_t *offset) { /* Only clear our bits to avoid side-effects */ - stream->oa_status = xe_mmio_rmw32(stream->gt, __oa_regs(stream)->oa_status, + stream->oa_status = xe_mmio_rmw32(&stream->gt->mmio, __oa_regs(stream)->oa_status, OASTATUS_RELEVANT_BITS, 0); /* * Signal to userspace that there is non-zero OA status to read via @@ -752,7 +755,8 @@ static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable) int err; /* Set ccs select to enable programming of OAC_OACONTROL */ - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_ctrl, __oa_ccs_select(stream)); + xe_mmio_write32(&stream->gt->mmio, __oa_regs(stream)->oa_ctrl, + __oa_ccs_select(stream)); /* Modify stream hwe context image with regs_context */ err = xe_oa_modify_ctx_image(stream, stream->exec_q->lrc[0], @@ -788,6 +792,7 @@ static u32 oag_configure_mmio_trigger(const struct xe_oa_stream *stream, bool en static void xe_oa_disable_metric_set(struct xe_oa_stream *stream) { + struct xe_mmio *mmio = &stream->gt->mmio; u32 sqcnt1; /* @@ -801,7 +806,7 @@ static void xe_oa_disable_metric_set(struct xe_oa_stream *stream) _MASKED_BIT_DISABLE(DISABLE_DOP_GATING)); } - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_debug, + xe_mmio_write32(mmio, __oa_regs(stream)->oa_debug, oag_configure_mmio_trigger(stream, false)); /* disable the context save/restore or OAR counters */ @@ -809,13 +814,13 @@ static void xe_oa_disable_metric_set(struct xe_oa_stream *stream) xe_oa_configure_oa_context(stream, false); /* Make sure we disable noa to save power. */ - xe_mmio_rmw32(stream->gt, RPM_CONFIG1, GT_NOA_ENABLE, 0); + xe_mmio_rmw32(mmio, RPM_CONFIG1, GT_NOA_ENABLE, 0); sqcnt1 = SQCNT1_PMON_ENABLE | (HAS_OA_BPC_REPORTING(stream->oa->xe) ? SQCNT1_OABPC : 0); /* Reset PMON Enable to save power. */ - xe_mmio_rmw32(stream->gt, XELPMP_SQCNT1, sqcnt1, 0); + xe_mmio_rmw32(mmio, XELPMP_SQCNT1, sqcnt1, 0); } static void xe_oa_stream_destroy(struct xe_oa_stream *stream) @@ -943,6 +948,7 @@ static u32 oag_report_ctx_switches(const struct xe_oa_stream *stream) static int xe_oa_enable_metric_set(struct xe_oa_stream *stream) { + struct xe_mmio *mmio = &stream->gt->mmio; u32 oa_debug, sqcnt1; int ret; @@ -969,12 +975,12 @@ static int xe_oa_enable_metric_set(struct xe_oa_stream *stream) OAG_OA_DEBUG_DISABLE_START_TRG_2_COUNT_QUAL | OAG_OA_DEBUG_DISABLE_START_TRG_1_COUNT_QUAL; - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_debug, + xe_mmio_write32(mmio, __oa_regs(stream)->oa_debug, _MASKED_BIT_ENABLE(oa_debug) | oag_report_ctx_switches(stream) | oag_configure_mmio_trigger(stream, true)); - xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_ctx_ctrl, stream->periodic ? + xe_mmio_write32(mmio, __oa_regs(stream)->oa_ctx_ctrl, stream->periodic ? (OAG_OAGLBCTXCTRL_COUNTER_RESUME | OAG_OAGLBCTXCTRL_TIMER_ENABLE | REG_FIELD_PREP(OAG_OAGLBCTXCTRL_TIMER_PERIOD_MASK, @@ -988,7 +994,7 @@ static int xe_oa_enable_metric_set(struct xe_oa_stream *stream) sqcnt1 = SQCNT1_PMON_ENABLE | (HAS_OA_BPC_REPORTING(stream->oa->xe) ? SQCNT1_OABPC : 0); - xe_mmio_rmw32(stream->gt, XELPMP_SQCNT1, 0, sqcnt1); + xe_mmio_rmw32(mmio, XELPMP_SQCNT1, 0, sqcnt1); /* Configure OAR/OAC */ if (stream->exec_q) { @@ -1537,7 +1543,7 @@ u32 xe_oa_timestamp_frequency(struct xe_gt *gt) case XE_PVC: case XE_METEORLAKE: xe_pm_runtime_get(gt_to_xe(gt)); - reg = xe_mmio_read32(gt, RPM_CONFIG0); + reg = xe_mmio_read32(>->mmio, RPM_CONFIG0); xe_pm_runtime_put(gt_to_xe(gt)); shift = REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, reg); @@ -2353,7 +2359,7 @@ static void __xe_oa_init_oa_units(struct xe_gt *gt) } /* Ensure MMIO trigger remains disabled till there is a stream */ - xe_mmio_write32(gt, u->regs.oa_debug, + xe_mmio_write32(>->mmio, u->regs.oa_debug, oag_configure_mmio_trigger(NULL, false)); /* Set oa_unit_ids now to ensure ids remain contiguous */ -- GitLab From a2fcaef35fe34ef32df1637f4d6440f52c6c28ab Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:52 -0700 Subject: [PATCH 163/970] drm/xe/topology: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-77-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_topology.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_topology.c b/drivers/gpu/drm/xe/xe_gt_topology.c index 0662f71c6ede..651ba53623e5 100644 --- a/drivers/gpu/drm/xe/xe_gt_topology.c +++ b/drivers/gpu/drm/xe/xe_gt_topology.c @@ -25,7 +25,7 @@ load_dss_mask(struct xe_gt *gt, xe_dss_mask_t mask, int numregs, ...) va_start(argp, numregs); for (i = 0; i < numregs; i++) - fuse_val[i] = xe_mmio_read32(gt, va_arg(argp, struct xe_reg)); + fuse_val[i] = xe_mmio_read32(>->mmio, va_arg(argp, struct xe_reg)); va_end(argp); bitmap_from_arr32(mask, fuse_val, numregs * 32); @@ -35,7 +35,7 @@ static void load_eu_mask(struct xe_gt *gt, xe_eu_mask_t mask, enum xe_gt_eu_type *eu_type) { struct xe_device *xe = gt_to_xe(gt); - u32 reg_val = xe_mmio_read32(gt, XELP_EU_ENABLE); + u32 reg_val = xe_mmio_read32(>->mmio, XELP_EU_ENABLE); u32 val = 0; int i; @@ -127,7 +127,7 @@ static void load_l3_bank_mask(struct xe_gt *gt, xe_l3_bank_mask_t l3_bank_mask) { struct xe_device *xe = gt_to_xe(gt); - u32 fuse3 = xe_mmio_read32(gt, MIRROR_FUSE3); + u32 fuse3 = xe_mmio_read32(>->mmio, MIRROR_FUSE3); if (GRAPHICS_VER(xe) >= 20) { xe_l3_bank_mask_t per_node = {}; @@ -141,7 +141,7 @@ load_l3_bank_mask(struct xe_gt *gt, xe_l3_bank_mask_t l3_bank_mask) xe_l3_bank_mask_t per_node = {}; xe_l3_bank_mask_t per_mask_bit = {}; u32 meml3_en = REG_FIELD_GET(MEML3_EN_MASK, fuse3); - u32 fuse4 = xe_mmio_read32(gt, XEHP_FUSE4); + u32 fuse4 = xe_mmio_read32(>->mmio, XEHP_FUSE4); u32 bank_val = REG_FIELD_GET(GT_L3_EXC_MASK, fuse4); bitmap_set_value8(per_mask_bit, 0x3, 0); -- GitLab From ef6a09220bef4d1f4eecb7882c2d6291023a6118 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:53 -0700 Subject: [PATCH 164/970] drm/xe/execlist: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-78-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_execlist.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_execlist.c b/drivers/gpu/drm/xe/xe_execlist.c index 6a59165b9569..f3b71fe7a96d 100644 --- a/drivers/gpu/drm/xe/xe_execlist.c +++ b/drivers/gpu/drm/xe/xe_execlist.c @@ -44,6 +44,7 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc, u32 ctx_id) { struct xe_gt *gt = hwe->gt; + struct xe_mmio *mmio = >->mmio; struct xe_device *xe = gt_to_xe(gt); u64 lrc_desc; @@ -58,7 +59,7 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc, } if (hwe->class == XE_ENGINE_CLASS_COMPUTE) - xe_mmio_write32(hwe->gt, RCU_MODE, + xe_mmio_write32(mmio, RCU_MODE, _MASKED_BIT_ENABLE(RCU_MODE_CCS_ENABLE)); xe_lrc_write_ctx_reg(lrc, CTX_RING_TAIL, lrc->ring.tail); @@ -76,17 +77,17 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc, */ wmb(); - xe_mmio_write32(gt, RING_HWS_PGA(hwe->mmio_base), + xe_mmio_write32(mmio, RING_HWS_PGA(hwe->mmio_base), xe_bo_ggtt_addr(hwe->hwsp)); - xe_mmio_read32(gt, RING_HWS_PGA(hwe->mmio_base)); - xe_mmio_write32(gt, RING_MODE(hwe->mmio_base), + xe_mmio_read32(mmio, RING_HWS_PGA(hwe->mmio_base)); + xe_mmio_write32(mmio, RING_MODE(hwe->mmio_base), _MASKED_BIT_ENABLE(GFX_DISABLE_LEGACY_MODE)); - xe_mmio_write32(gt, RING_EXECLIST_SQ_CONTENTS_LO(hwe->mmio_base), + xe_mmio_write32(mmio, RING_EXECLIST_SQ_CONTENTS_LO(hwe->mmio_base), lower_32_bits(lrc_desc)); - xe_mmio_write32(gt, RING_EXECLIST_SQ_CONTENTS_HI(hwe->mmio_base), + xe_mmio_write32(mmio, RING_EXECLIST_SQ_CONTENTS_HI(hwe->mmio_base), upper_32_bits(lrc_desc)); - xe_mmio_write32(gt, RING_EXECLIST_CONTROL(hwe->mmio_base), + xe_mmio_write32(mmio, RING_EXECLIST_CONTROL(hwe->mmio_base), EL_CTRL_LOAD); } @@ -168,8 +169,8 @@ static u64 read_execlist_status(struct xe_hw_engine *hwe) struct xe_gt *gt = hwe->gt; u32 hi, lo; - lo = xe_mmio_read32(gt, RING_EXECLIST_STATUS_LO(hwe->mmio_base)); - hi = xe_mmio_read32(gt, RING_EXECLIST_STATUS_HI(hwe->mmio_base)); + lo = xe_mmio_read32(>->mmio, RING_EXECLIST_STATUS_LO(hwe->mmio_base)); + hi = xe_mmio_read32(>->mmio, RING_EXECLIST_STATUS_HI(hwe->mmio_base)); return lo | (u64)hi << 32; } -- GitLab From 7227cbc2febc5a5e37c2142e983b31d6e8a680c0 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:54 -0700 Subject: [PATCH 165/970] drm/xe/gt_clock: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-79-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_clock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_clock.c b/drivers/gpu/drm/xe/xe_gt_clock.c index 86c2d62b4bdc..cc2ae159298e 100644 --- a/drivers/gpu/drm/xe/xe_gt_clock.c +++ b/drivers/gpu/drm/xe/xe_gt_clock.c @@ -17,7 +17,7 @@ static u32 read_reference_ts_freq(struct xe_gt *gt) { - u32 ts_override = xe_mmio_read32(gt, TIMESTAMP_OVERRIDE); + u32 ts_override = xe_mmio_read32(>->mmio, TIMESTAMP_OVERRIDE); u32 base_freq, frac_freq; base_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK, @@ -57,7 +57,7 @@ static u32 get_crystal_clock_freq(u32 rpm_config_reg) int xe_gt_clock_init(struct xe_gt *gt) { - u32 ctc_reg = xe_mmio_read32(gt, CTC_MODE); + u32 ctc_reg = xe_mmio_read32(>->mmio, CTC_MODE); u32 freq = 0; /* Assuming gen11+ so assert this assumption is correct */ @@ -66,7 +66,7 @@ int xe_gt_clock_init(struct xe_gt *gt) if (ctc_reg & CTC_SOURCE_DIVIDE_LOGIC) { freq = read_reference_ts_freq(gt); } else { - u32 c0 = xe_mmio_read32(gt, RPM_CONFIG0); + u32 c0 = xe_mmio_read32(>->mmio, RPM_CONFIG0); freq = get_crystal_clock_freq(c0); -- GitLab From 344c96b7fd46c8ca9a21c0fca33cbee544871a1f Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:55 -0700 Subject: [PATCH 166/970] drm/xe/reg_sr: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-80-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_reg_sr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c index fb209f1e0f1e..191cb4121acd 100644 --- a/drivers/gpu/drm/xe/xe_reg_sr.c +++ b/drivers/gpu/drm/xe/xe_reg_sr.c @@ -165,7 +165,7 @@ static void apply_one_mmio(struct xe_gt *gt, struct xe_reg_sr_entry *entry) else if (entry->clr_bits + 1) val = (reg.mcr ? xe_gt_mcr_unicast_read_any(gt, reg_mcr) : - xe_mmio_read32(gt, reg)) & (~entry->clr_bits); + xe_mmio_read32(>->mmio, reg)) & (~entry->clr_bits); else val = 0; @@ -181,7 +181,7 @@ static void apply_one_mmio(struct xe_gt *gt, struct xe_reg_sr_entry *entry) if (entry->reg.mcr) xe_gt_mcr_multicast_write(gt, reg_mcr, val); else - xe_mmio_write32(gt, reg, val); + xe_mmio_write32(>->mmio, reg, val); } void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt) @@ -242,7 +242,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe) } xe_reg_whitelist_print_entry(&p, 0, reg, entry); - xe_mmio_write32(gt, RING_FORCE_TO_NONPRIV(mmio_base, slot), + xe_mmio_write32(>->mmio, RING_FORCE_TO_NONPRIV(mmio_base, slot), reg | entry->set_bits); slot++; } @@ -251,7 +251,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe) for (; slot < RING_MAX_NONPRIV_SLOTS; slot++) { u32 addr = RING_NOPID(mmio_base).addr; - xe_mmio_write32(gt, RING_FORCE_TO_NONPRIV(mmio_base, slot), addr); + xe_mmio_write32(>->mmio, RING_FORCE_TO_NONPRIV(mmio_base, slot), addr); } err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); -- GitLab From 498ecc54add06939b7e63fd6f3e52632f2272e20 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:56 -0700 Subject: [PATCH 167/970] drm/xe/gt: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-81-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 522f10f163c8..935d1dfd9459 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -110,7 +110,7 @@ static void xe_gt_enable_host_l2_vram(struct xe_gt *gt) return; if (!xe_gt_is_media_type(gt)) { - xe_mmio_write32(gt, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH); + xe_mmio_write32(>->mmio, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH); reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL); reg |= CG_DIS_CNTLBUS; xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg); @@ -247,7 +247,7 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) else if (entry->clr_bits + 1) val = (reg.mcr ? xe_gt_mcr_unicast_read_any(gt, reg_mcr) : - xe_mmio_read32(gt, reg)) & (~entry->clr_bits); + xe_mmio_read32(>->mmio, reg)) & (~entry->clr_bits); else val = 0; @@ -442,7 +442,7 @@ static int gt_fw_domain_init(struct xe_gt *gt) * Stash hardware-reported version. Since this register does not exist * on pre-MTL platforms, reading it there will (correctly) return 0. */ - gt->info.gmdid = xe_mmio_read32(gt, GMD_ID); + gt->info.gmdid = xe_mmio_read32(>->mmio, GMD_ID); err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); XE_WARN_ON(err); @@ -652,8 +652,8 @@ static int do_gt_reset(struct xe_gt *gt) xe_gsc_wa_14015076503(gt, true); - xe_mmio_write32(gt, GDRST, GRDOM_FULL); - err = xe_mmio_wait32(gt, GDRST, GRDOM_FULL, 0, 5000, NULL, false); + xe_mmio_write32(>->mmio, GDRST, GRDOM_FULL); + err = xe_mmio_wait32(>->mmio, GDRST, GRDOM_FULL, 0, 5000, NULL, false); if (err) xe_gt_err(gt, "failed to clear GRDOM_FULL (%pe)\n", ERR_PTR(err)); -- GitLab From f9bcd59ac8bff99bc73da85644230c55cc7b952b Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:57 -0700 Subject: [PATCH 168/970] drm/xe/sriov: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-82-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 6 +++--- drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c | 6 +++--- drivers/gpu/drm/xe/xe_gt_sriov_vf.c | 4 ++-- drivers/gpu/drm/xe/xe_sriov.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c index 919d960165d5..065a9878f8e9 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c @@ -74,7 +74,7 @@ static bool pf_needs_enable_ggtt_guest_update(struct xe_device *xe) static void pf_enable_ggtt_guest_update(struct xe_gt *gt) { - xe_mmio_write32(gt, VIRTUAL_CTRL_REG, GUEST_GTT_UPDATE_EN); + xe_mmio_write32(>->mmio, VIRTUAL_CTRL_REG, GUEST_GTT_UPDATE_EN); } /** @@ -116,13 +116,13 @@ static void pf_clear_vf_scratch_regs(struct xe_gt *gt, unsigned int vfid) count = MED_VF_SW_FLAG_COUNT; for (n = 0; n < count; n++) { scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride); - xe_mmio_write32(gt, scratch, 0); + xe_mmio_write32(>->mmio, scratch, 0); } } else { count = VF_SW_FLAG_COUNT; for (n = 0; n < count; n++) { scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride); - xe_mmio_write32(gt, scratch, 0); + xe_mmio_write32(>->mmio, scratch, 0); } } } diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c index 0e23b7ea4f3e..924e75b94aec 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c @@ -237,7 +237,7 @@ static void read_many(struct xe_gt *gt, unsigned int count, const struct xe_reg *regs, u32 *values) { while (count--) - *values++ = xe_mmio_read32(gt, *regs++); + *values++ = xe_mmio_read32(>->mmio, *regs++); } static void pf_prepare_runtime_info(struct xe_gt *gt) @@ -402,7 +402,7 @@ static int pf_service_runtime_query(struct xe_gt *gt, u32 start, u32 limit, for (i = 0; i < count; ++i, ++data) { addr = runtime->regs[start + i].addr; - data->offset = xe_mmio_adjusted_addr(gt, addr); + data->offset = xe_mmio_adjusted_addr(>->mmio, addr); data->value = runtime->values[start + i]; } @@ -513,7 +513,7 @@ int xe_gt_sriov_pf_service_print_runtime(struct xe_gt *gt, struct drm_printer *p for (; size--; regs++, values++) { drm_printf(p, "reg[%#x] = %#x\n", - xe_mmio_adjusted_addr(gt, regs->addr), *values); + xe_mmio_adjusted_addr(>->mmio, regs->addr), *values); } return 0; diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c index 4ebc82e607af..d3baba50f085 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c @@ -881,7 +881,7 @@ static struct vf_runtime_reg *vf_lookup_reg(struct xe_gt *gt, u32 addr) */ u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg) { - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(>->mmio, reg.addr); struct vf_runtime_reg *rr; xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt))); @@ -917,7 +917,7 @@ u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg) */ void xe_gt_sriov_vf_write32(struct xe_gt *gt, struct xe_reg reg, u32 val) { - u32 addr = xe_mmio_adjusted_addr(gt, reg.addr); + u32 addr = xe_mmio_adjusted_addr(>->mmio, reg.addr); xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt))); xe_gt_assert(gt, !reg.vf); diff --git a/drivers/gpu/drm/xe/xe_sriov.c b/drivers/gpu/drm/xe/xe_sriov.c index 5a1d65e4f19f..69a066ef20c0 100644 --- a/drivers/gpu/drm/xe/xe_sriov.c +++ b/drivers/gpu/drm/xe/xe_sriov.c @@ -35,7 +35,7 @@ const char *xe_sriov_mode_to_string(enum xe_sriov_mode mode) static bool test_is_vf(struct xe_device *xe) { - u32 value = xe_mmio_read32(xe_root_mmio_gt(xe), VF_CAP_REG); + u32 value = xe_mmio_read32(xe_root_tile_mmio(xe), VF_CAP_REG); return value & VF_CAP; } -- GitLab From 5fd12cc4449ef9299214217896b07b287263013e Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:58 -0700 Subject: [PATCH 169/970] drm/xe/tlb: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-83-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c index cca9cf536f76..98616de0c5bb 100644 --- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c +++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c @@ -274,17 +274,19 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt) xe_gt_tlb_invalidation_fence_wait(&fence); } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) { + struct xe_mmio *mmio = >->mmio; + if (IS_SRIOV_VF(xe)) return 0; xe_gt_WARN_ON(gt, xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); if (xe->info.platform == XE_PVC || GRAPHICS_VER(xe) >= 20) { - xe_mmio_write32(gt, PVC_GUC_TLB_INV_DESC1, + xe_mmio_write32(mmio, PVC_GUC_TLB_INV_DESC1, PVC_GUC_TLB_INV_DESC1_INVALIDATE); - xe_mmio_write32(gt, PVC_GUC_TLB_INV_DESC0, + xe_mmio_write32(mmio, PVC_GUC_TLB_INV_DESC0, PVC_GUC_TLB_INV_DESC0_VALID); } else { - xe_mmio_write32(gt, GUC_TLB_INV_CR, + xe_mmio_write32(mmio, GUC_TLB_INV_CR, GUC_TLB_INV_CR_INVALIDATE); } xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); -- GitLab From 50089a9534e25846e7501c58e80a0bf3d3aee618 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:47:59 -0700 Subject: [PATCH 170/970] drm/xe/gt_idle: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-84-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_idle.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c index 85a35ed153a3..531924b6c0a1 100644 --- a/drivers/gpu/drm/xe/xe_gt_idle.c +++ b/drivers/gpu/drm/xe/xe_gt_idle.c @@ -104,6 +104,7 @@ void xe_gt_idle_enable_pg(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); struct xe_gt_idle *gtidle = >->gtidle; + struct xe_mmio *mmio = >->mmio; u32 vcs_mask, vecs_mask; int i, j; @@ -137,11 +138,11 @@ void xe_gt_idle_enable_pg(struct xe_gt *gt) * GuC sets the hysteresis value when GuC PC is enabled * else set it to 25 (25 * 1.28us) */ - xe_mmio_write32(gt, MEDIA_POWERGATE_IDLE_HYSTERESIS, 25); - xe_mmio_write32(gt, RENDER_POWERGATE_IDLE_HYSTERESIS, 25); + xe_mmio_write32(mmio, MEDIA_POWERGATE_IDLE_HYSTERESIS, 25); + xe_mmio_write32(mmio, RENDER_POWERGATE_IDLE_HYSTERESIS, 25); } - xe_mmio_write32(gt, POWERGATE_ENABLE, gtidle->powergate_enable); + xe_mmio_write32(mmio, POWERGATE_ENABLE, gtidle->powergate_enable); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); } @@ -156,7 +157,7 @@ void xe_gt_idle_disable_pg(struct xe_gt *gt) gtidle->powergate_enable = 0; XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); - xe_mmio_write32(gt, POWERGATE_ENABLE, gtidle->powergate_enable); + xe_mmio_write32(>->mmio, POWERGATE_ENABLE, gtidle->powergate_enable); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); } @@ -216,8 +217,8 @@ int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p) if (err) return err; - pg_enabled = xe_mmio_read32(gt, POWERGATE_ENABLE); - pg_status = xe_mmio_read32(gt, POWERGATE_DOMAIN_STATUS); + pg_enabled = xe_mmio_read32(>->mmio, POWERGATE_ENABLE); + pg_status = xe_mmio_read32(>->mmio, POWERGATE_DOMAIN_STATUS); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FW_GT)); } @@ -361,9 +362,9 @@ void xe_gt_idle_enable_c6(struct xe_gt *gt) return; /* Units of 1280 ns for a total of 5s */ - xe_mmio_write32(gt, RC_IDLE_HYSTERSIS, 0x3B9ACA); + xe_mmio_write32(>->mmio, RC_IDLE_HYSTERSIS, 0x3B9ACA); /* Enable RC6 */ - xe_mmio_write32(gt, RC_CONTROL, + xe_mmio_write32(>->mmio, RC_CONTROL, RC_CTL_HW_ENABLE | RC_CTL_TO_MODE | RC_CTL_RC6_ENABLE); } @@ -375,6 +376,6 @@ void xe_gt_idle_disable_c6(struct xe_gt *gt) if (IS_SRIOV_VF(gt_to_xe(gt))) return; - xe_mmio_write32(gt, RC_CONTROL, 0); - xe_mmio_write32(gt, RC_STATE, 0); + xe_mmio_write32(>->mmio, RC_CONTROL, 0); + xe_mmio_write32(>->mmio, RC_STATE, 0); } -- GitLab From c86894b5197d7ce4d5462f6f07cbaadd23735624 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:48:00 -0700 Subject: [PATCH 171/970] drm/xe/forcewake: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-85-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_force_wake.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_force_wake.c b/drivers/gpu/drm/xe/xe_force_wake.c index b263fff15273..a64c14757c84 100644 --- a/drivers/gpu/drm/xe/xe_force_wake.c +++ b/drivers/gpu/drm/xe/xe_force_wake.c @@ -100,7 +100,7 @@ static void __domain_ctl(struct xe_gt *gt, struct xe_force_wake_domain *domain, if (IS_SRIOV_VF(gt_to_xe(gt))) return; - xe_mmio_write32(gt, domain->reg_ctl, domain->mask | (wake ? domain->val : 0)); + xe_mmio_write32(>->mmio, domain->reg_ctl, domain->mask | (wake ? domain->val : 0)); } static int __domain_wait(struct xe_gt *gt, struct xe_force_wake_domain *domain, bool wake) @@ -111,7 +111,7 @@ static int __domain_wait(struct xe_gt *gt, struct xe_force_wake_domain *domain, if (IS_SRIOV_VF(gt_to_xe(gt))) return 0; - ret = xe_mmio_wait32(gt, domain->reg_ack, domain->val, wake ? domain->val : 0, + ret = xe_mmio_wait32(>->mmio, domain->reg_ack, domain->val, wake ? domain->val : 0, XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC, &value, true); if (ret) -- GitLab From d8507423d43a7db1d4d51f99bd63787300d1a9ab Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:48:01 -0700 Subject: [PATCH 172/970] drm/xe/ggtt: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-86-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_ggtt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index 2895f154654c..f68af56c3f86 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -107,8 +107,10 @@ static unsigned int probe_gsm_size(struct pci_dev *pdev) static void ggtt_update_access_counter(struct xe_ggtt *ggtt) { - struct xe_gt *gt = XE_WA(ggtt->tile->primary_gt, 22019338487) ? ggtt->tile->primary_gt : - ggtt->tile->media_gt; + struct xe_tile *tile = ggtt->tile; + struct xe_gt *affected_gt = XE_WA(tile->primary_gt, 22019338487) ? + tile->primary_gt : tile->media_gt; + struct xe_mmio *mmio = &affected_gt->mmio; u32 max_gtt_writes = XE_WA(ggtt->tile->primary_gt, 22019338487) ? 1100 : 63; /* * Wa_22019338487: GMD_ID is a RO register, a dummy write forces gunit @@ -118,7 +120,7 @@ static void ggtt_update_access_counter(struct xe_ggtt *ggtt) lockdep_assert_held(&ggtt->lock); if ((++ggtt->access_count % max_gtt_writes) == 0) { - xe_mmio_write32(gt, GMD_ID, 0x0); + xe_mmio_write32(mmio, GMD_ID, 0x0); ggtt->access_count = 0; } } -- GitLab From a851edc457ed74e8f5c9d5f4cd2829754e1c7c94 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:48:02 -0700 Subject: [PATCH 173/970] drm/xe/ccs_mode: Convert register access to use xe_mmio Stop using GT pointers for register access. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-87-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_ccs_mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c index d2e4dc3aaf61..9360ac4de489 100644 --- a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c +++ b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c @@ -68,7 +68,7 @@ static void __xe_gt_apply_ccs_mode(struct xe_gt *gt, u32 num_engines) } } - xe_mmio_write32(gt, CCS_MODE, mode); + xe_mmio_write32(>->mmio, CCS_MODE, mode); xe_gt_dbg(gt, "CCS_MODE=%x config:%08x, num_engines:%d, num_slices:%d\n", mode, config, num_engines, num_slices); -- GitLab From 793a135214a81488066fb8ccecbd4f182c416326 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 10 Sep 2024 16:48:03 -0700 Subject: [PATCH 174/970] drm/xe/mmio: Drop compatibility macros Now that all parts of the driver have switched over to using xe_mmio for direct register access, we can drop the compatibility macros that allow continued xe_gt usage. v2: - Move removal of 8/16-bit read and xe_mmio_wait32_not() wrappers to this patch rather than removing them in earlier patches when last caller was removed. (Rodrigo) Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-88-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_mmio.c | 38 ++++++++++---------- drivers/gpu/drm/xe/xe_mmio.h | 67 ++++++++---------------------------- 2 files changed, 34 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index 392105ba8311..a48f239cad1c 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -199,7 +199,7 @@ static void mmio_flush_pending_writes(struct xe_mmio *mmio) writel(0, mmio->regs + DUMMY_REG_OFFSET); } -u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg) +u8 xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg) { u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); u8 val; @@ -213,7 +213,7 @@ u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg) return val; } -u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg) +u16 xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg) { u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); u16 val; @@ -227,7 +227,7 @@ u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg) return val; } -void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val) +void xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val) { u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); @@ -239,7 +239,7 @@ void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val) writel(val, mmio->regs + addr); } -u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg) +u32 xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg) { u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); u32 val; @@ -257,7 +257,7 @@ u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg) return val; } -u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set) +u32 xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set) { u32 old, reg_val; @@ -268,8 +268,8 @@ u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set) return old; } -int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, - struct xe_reg reg, u32 val, u32 mask, u32 eval) +int xe_mmio_write32_and_verify(struct xe_mmio *mmio, + struct xe_reg reg, u32 val, u32 mask, u32 eval) { u32 reg_val; @@ -279,9 +279,9 @@ int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, return (reg_val & mask) != eval ? -EINVAL : 0; } -bool __xe_mmio_in_range(const struct xe_mmio *mmio, - const struct xe_mmio_range *range, - struct xe_reg reg) +bool xe_mmio_in_range(const struct xe_mmio *mmio, + const struct xe_mmio_range *range, + struct xe_reg reg) { u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr); @@ -310,7 +310,7 @@ bool __xe_mmio_in_range(const struct xe_mmio *mmio, * * Returns the value of the 64-bit register. */ -u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) +u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) { struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; u32 ldw, udw, oldudw, retries; @@ -338,8 +338,8 @@ u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) return (u64)udw << 32 | ldw; } -static int ____xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic, bool expect_match) +static int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, + u32 *out_val, bool atomic, bool expect_match) { ktime_t cur = ktime_get_raw(); const ktime_t end = ktime_add_us(cur, timeout_us); @@ -410,10 +410,10 @@ static int ____xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, * @timeout_us for different reasons, specially in non-atomic contexts. Thus, * it is possible that this function succeeds even after @timeout_us has passed. */ -int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic) +int xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, + u32 *out_val, bool atomic) { - return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, true); + return __xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, true); } /** @@ -429,8 +429,8 @@ int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, * This function works exactly like xe_mmio_wait32() with the exception that * @val is expected not to be matched. */ -int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, - u32 *out_val, bool atomic) +int xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us, + u32 *out_val, bool atomic) { - return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, false); + return __xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, false); } diff --git a/drivers/gpu/drm/xe/xe_mmio.h b/drivers/gpu/drm/xe/xe_mmio.h index ac6846447c52..8a46f4006a84 100644 --- a/drivers/gpu/drm/xe/xe_mmio.h +++ b/drivers/gpu/drm/xe/xe_mmio.h @@ -14,63 +14,26 @@ struct xe_reg; int xe_mmio_init(struct xe_device *xe); int xe_mmio_probe_tiles(struct xe_device *xe); -/* - * Temporary transition helper for xe_gt -> xe_mmio conversion. Allows - * continued usage of xe_gt as a parameter to MMIO operations which now - * take an xe_mmio structure instead. Will be removed once the driver-wide - * conversion is complete. - */ -#define __to_xe_mmio(ptr) \ - _Generic(ptr, \ - const struct xe_gt *: (&((const struct xe_gt *)(ptr))->mmio), \ - struct xe_gt *: (&((struct xe_gt *)(ptr))->mmio), \ - const struct xe_mmio *: (ptr), \ - struct xe_mmio *: (ptr)) - -u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg); -#define xe_mmio_read8(p, reg) __xe_mmio_read8(__to_xe_mmio(p), reg) - -u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg); -#define xe_mmio_read16(p, reg) __xe_mmio_read16(__to_xe_mmio(p), reg) - -void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val); -#define xe_mmio_write32(p, reg, val) __xe_mmio_write32(__to_xe_mmio(p), reg, val) - -u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg); -#define xe_mmio_read32(p, reg) __xe_mmio_read32(__to_xe_mmio(p), reg) - -u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set); -#define xe_mmio_rmw32(p, reg, clr, set) __xe_mmio_rmw32(__to_xe_mmio(p), reg, clr, set) - -int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, struct xe_reg reg, - u32 val, u32 mask, u32 eval); -#define xe_mmio_write32_and_verify(p, reg, val, mask, eval) \ - __xe_mmio_write32_and_verify(__to_xe_mmio(p), reg, val, mask, eval) - -bool __xe_mmio_in_range(const struct xe_mmio *mmio, - const struct xe_mmio_range *range, struct xe_reg reg); -#define xe_mmio_in_range(p, range, reg) __xe_mmio_in_range(__to_xe_mmio(p), range, reg) - -u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg); -#define xe_mmio_read64_2x32(p, reg) __xe_mmio_read64_2x32(__to_xe_mmio(p), reg) - -int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, - u32 timeout_us, u32 *out_val, bool atomic); -#define xe_mmio_wait32(p, reg, mask, val, timeout_us, out_val, atomic) \ - __xe_mmio_wait32(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic) - -int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, - u32 val, u32 timeout_us, u32 *out_val, bool atomic); -#define xe_mmio_wait32_not(p, reg, mask, val, timeout_us, out_val, atomic) \ - __xe_mmio_wait32_not(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic) - -static inline u32 __xe_mmio_adjusted_addr(const struct xe_mmio *mmio, u32 addr) +u8 xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg); +u16 xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg); +void xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val); +u32 xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg); +u32 xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set); +int xe_mmio_write32_and_verify(struct xe_mmio *mmio, struct xe_reg reg, u32 val, u32 mask, u32 eval); +bool xe_mmio_in_range(const struct xe_mmio *mmio, const struct xe_mmio_range *range, struct xe_reg reg); + +u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg); +int xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, + u32 timeout_us, u32 *out_val, bool atomic); +int xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, + u32 val, u32 timeout_us, u32 *out_val, bool atomic); + +static inline u32 xe_mmio_adjusted_addr(const struct xe_mmio *mmio, u32 addr) { if (addr < mmio->adj_limit) addr += mmio->adj_offset; return addr; } -#define xe_mmio_adjusted_addr(p, addr) __xe_mmio_adjusted_addr(__to_xe_mmio(p), addr) static inline struct xe_mmio *xe_root_tile_mmio(struct xe_device *xe) { -- GitLab From 9d443deb0441b9dbb22a9aac3b471da05220df1b Mon Sep 17 00:00:00 2001 From: Steven Price <steven.price@arm.com> Date: Fri, 6 Sep 2024 10:40:25 +0100 Subject: [PATCH 175/970] drm/panthor: Display FW version information The version number output when loading the firmware is actually the interface version not the version of the firmware itself. Update the message to make this clearer. However, the firmware binary has a git SHA embedded into it which can be used to identify which firmware binary is being loaded. So output this as a drm_info() so that it's obvious from a dmesg log which firmware binary is being used. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Steven Price <steven.price@arm.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906094025.638173-1-steven.price@arm.com --- drivers/gpu/drm/panthor/panthor_fw.c | 57 +++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c index ef232c0c2049..631f639b8b86 100644 --- a/drivers/gpu/drm/panthor/panthor_fw.c +++ b/drivers/gpu/drm/panthor/panthor_fw.c @@ -78,6 +78,12 @@ enum panthor_fw_binary_entry_type { /** @CSF_FW_BINARY_ENTRY_TYPE_TIMELINE_METADATA: Timeline metadata interface. */ CSF_FW_BINARY_ENTRY_TYPE_TIMELINE_METADATA = 4, + + /** + * @CSF_FW_BINARY_ENTRY_TYPE_BUILD_INFO_METADATA: Metadata about how + * the FW binary was built. + */ + CSF_FW_BINARY_ENTRY_TYPE_BUILD_INFO_METADATA = 6 }; #define CSF_FW_BINARY_ENTRY_TYPE(ehdr) ((ehdr) & 0xff) @@ -132,6 +138,13 @@ struct panthor_fw_binary_section_entry_hdr { } data; }; +struct panthor_fw_build_info_hdr { + /** @meta_start: Offset of the build info data in the FW binary */ + u32 meta_start; + /** @meta_size: Size of the build info data in the FW binary */ + u32 meta_size; +}; + /** * struct panthor_fw_binary_iter - Firmware binary iterator * @@ -628,6 +641,46 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev, return 0; } +static int panthor_fw_read_build_info(struct panthor_device *ptdev, + const struct firmware *fw, + struct panthor_fw_binary_iter *iter, + u32 ehdr) +{ + struct panthor_fw_build_info_hdr hdr; + char header[9]; + const char git_sha_header[sizeof(header)] = "git_sha: "; + int ret; + + ret = panthor_fw_binary_iter_read(ptdev, iter, &hdr, sizeof(hdr)); + if (ret) + return ret; + + if (hdr.meta_start > fw->size || + hdr.meta_start + hdr.meta_size > fw->size) { + drm_err(&ptdev->base, "Firmware build info corrupt\n"); + /* We don't need the build info, so continue */ + return 0; + } + + if (memcmp(git_sha_header, fw->data + hdr.meta_start, + sizeof(git_sha_header))) { + /* Not the expected header, this isn't metadata we understand */ + return 0; + } + + /* Check that the git SHA is NULL terminated as expected */ + if (fw->data[hdr.meta_start + hdr.meta_size - 1] != '\0') { + drm_warn(&ptdev->base, "Firmware's git sha is not NULL terminated\n"); + /* Don't treat as fatal */ + return 0; + } + + drm_info(&ptdev->base, "Firmware git sha: %s\n", + fw->data + hdr.meta_start + sizeof(git_sha_header)); + + return 0; +} + static void panthor_reload_fw_sections(struct panthor_device *ptdev, bool full_reload) { @@ -672,6 +725,8 @@ static int panthor_fw_load_entry(struct panthor_device *ptdev, switch (CSF_FW_BINARY_ENTRY_TYPE(ehdr)) { case CSF_FW_BINARY_ENTRY_TYPE_IFACE: return panthor_fw_load_section_entry(ptdev, fw, &eiter, ehdr); + case CSF_FW_BINARY_ENTRY_TYPE_BUILD_INFO_METADATA: + return panthor_fw_read_build_info(ptdev, fw, &eiter, ehdr); /* FIXME: handle those entry types? */ case CSF_FW_BINARY_ENTRY_TYPE_CONFIG: @@ -921,7 +976,7 @@ static int panthor_fw_init_ifaces(struct panthor_device *ptdev) return ret; } - drm_info(&ptdev->base, "CSF FW v%d.%d.%d, Features %#x Instrumentation features %#x", + drm_info(&ptdev->base, "CSF FW using interface v%d.%d.%d, Features %#x Instrumentation features %#x", CSF_IFACE_VERSION_MAJOR(glb_iface->control->version), CSF_IFACE_VERSION_MINOR(glb_iface->control->version), CSF_IFACE_VERSION_PATCH(glb_iface->control->version), -- GitLab From 0083b8e6f11d7662283a267d4ce7c966812ffd8a Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 11 Sep 2024 16:55:27 +0100 Subject: [PATCH 176/970] drm/xe/client: fix deadlock in show_meminfo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a real deadlock as well as sleeping in atomic() bug in here, if the bo put happens to be the last ref, since bo destruction wants to grab the same spinlock and sleeping locks. Fix that by dropping the ref using xe_bo_put_deferred(), and moving the final commit outside of the lock. Dropping the lock around the put is tricky since the bo can go out of scope and delete itself from the list, making it difficult to navigate to the next list entry. Fixes: 0845233388f8 ("drm/xe: Implement fdinfo memory stats printing") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2727 Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911155527.178910-5-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_drm_client.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c index e64f4b645e2e..badfa045ead8 100644 --- a/drivers/gpu/drm/xe/xe_drm_client.c +++ b/drivers/gpu/drm/xe/xe_drm_client.c @@ -196,6 +196,7 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) struct xe_drm_client *client; struct drm_gem_object *obj; struct xe_bo *bo; + LLIST_HEAD(deferred); unsigned int id; u32 mem_type; @@ -215,11 +216,14 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) list_for_each_entry(bo, &client->bos_list, client_link) { if (!kref_get_unless_zero(&bo->ttm.base.refcount)) continue; + bo_meminfo(bo, stats); - xe_bo_put(bo); + xe_bo_put_deferred(bo, &deferred); } spin_unlock(&client->bos_lock); + xe_bo_put_commit(&deferred); + for (mem_type = XE_PL_SYSTEM; mem_type < TTM_NUM_MEM_TYPES; ++mem_type) { if (!xe_mem_type_to_name[mem_type]) continue; -- GitLab From 4f63d712fa104c3ebefcb289d1e733e86d8698c7 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 11 Sep 2024 16:55:28 +0100 Subject: [PATCH 177/970] drm/xe/client: add missing bo locking in show_meminfo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bo_meminfo() wants to inspect bo state like tt and the ttm resource, however this state can change at any point leading to stuff like NPD and UAF, if the bo lock is not held. Grab the bo lock when calling bo_meminfo(), ensuring we drop any spinlocks first. In the case of object_idr we now also need to hold a ref. v2 (MattB) - Also add xe_bo_assert_held() Fixes: 0845233388f8 ("drm/xe: Implement fdinfo memory stats printing") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911155527.178910-6-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_drm_client.c | 39 +++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c index badfa045ead8..95a05c5bc897 100644 --- a/drivers/gpu/drm/xe/xe_drm_client.c +++ b/drivers/gpu/drm/xe/xe_drm_client.c @@ -10,6 +10,7 @@ #include <linux/slab.h> #include <linux/types.h> +#include "xe_assert.h" #include "xe_bo.h" #include "xe_bo_types.h" #include "xe_device_types.h" @@ -151,10 +152,13 @@ void xe_drm_client_add_bo(struct xe_drm_client *client, */ void xe_drm_client_remove_bo(struct xe_bo *bo) { + struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev); struct xe_drm_client *client = bo->client; + xe_assert(xe, !kref_read(&bo->ttm.base.refcount)); + spin_lock(&client->bos_lock); - list_del(&bo->client_link); + list_del_init(&bo->client_link); spin_unlock(&client->bos_lock); xe_drm_client_put(client); @@ -166,6 +170,8 @@ static void bo_meminfo(struct xe_bo *bo, u64 sz = bo->size; u32 mem_type; + xe_bo_assert_held(bo); + if (bo->placement.placement) mem_type = bo->placement.placement->mem_type; else @@ -207,7 +213,20 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) idr_for_each_entry(&file->object_idr, obj, id) { struct xe_bo *bo = gem_to_xe_bo(obj); - bo_meminfo(bo, stats); + if (dma_resv_trylock(bo->ttm.base.resv)) { + bo_meminfo(bo, stats); + xe_bo_unlock(bo); + } else { + xe_bo_get(bo); + spin_unlock(&file->table_lock); + + xe_bo_lock(bo, false); + bo_meminfo(bo, stats); + xe_bo_unlock(bo); + + xe_bo_put(bo); + spin_lock(&file->table_lock); + } } spin_unlock(&file->table_lock); @@ -217,7 +236,21 @@ static void show_meminfo(struct drm_printer *p, struct drm_file *file) if (!kref_get_unless_zero(&bo->ttm.base.refcount)) continue; - bo_meminfo(bo, stats); + if (dma_resv_trylock(bo->ttm.base.resv)) { + bo_meminfo(bo, stats); + xe_bo_unlock(bo); + } else { + spin_unlock(&client->bos_lock); + + xe_bo_lock(bo, false); + bo_meminfo(bo, stats); + xe_bo_unlock(bo); + + spin_lock(&client->bos_lock); + /* The bo ref will prevent this bo from being removed from the list */ + xe_assert(xef->xe, !list_empty(&bo->client_link)); + } + xe_bo_put_deferred(bo, &deferred); } spin_unlock(&client->bos_lock); -- GitLab From fbd73b7d2ae29ef0f604f376bcc22b886a49329e Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 11 Sep 2024 16:55:29 +0100 Subject: [PATCH 178/970] drm/xe/client: use mem_type from the current resource MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather extract the mem_type from the current resource. Checking the first potential placement doesn't really tell us where the bo is currently allocated, especially if there are multiple potential placements. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911155527.178910-7-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_drm_client.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c index 95a05c5bc897..c4add8b38bbd 100644 --- a/drivers/gpu/drm/xe/xe_drm_client.c +++ b/drivers/gpu/drm/xe/xe_drm_client.c @@ -168,15 +168,10 @@ static void bo_meminfo(struct xe_bo *bo, struct drm_memory_stats stats[TTM_NUM_MEM_TYPES]) { u64 sz = bo->size; - u32 mem_type; + u32 mem_type = bo->ttm.resource->mem_type; xe_bo_assert_held(bo); - if (bo->placement.placement) - mem_type = bo->placement.placement->mem_type; - else - mem_type = XE_PL_TT; - if (drm_gem_object_is_shared_for_memory_stats(&bo->ttm.base)) stats[mem_type].shared += sz; else -- GitLab From 3b04c2cfd71c54117237c72f2a08ff0ae1f602e2 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 11 Sep 2024 16:55:30 +0100 Subject: [PATCH 179/970] drm/xe/bo: add some annotations in bo_put() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the put() triggers bo destroy then there is at least one potential sleeping lock. Also annotate bos_lock and ggtt lock. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911155527.178910-8-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_bo.c | 14 ++++++++++++++ drivers/gpu/drm/xe/xe_bo.h | 6 +----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index a4dadd5a424c..5f2f1ec46b57 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -2350,6 +2350,20 @@ void xe_bo_put_commit(struct llist_head *deferred) drm_gem_object_free(&bo->ttm.base.refcount); } +void xe_bo_put(struct xe_bo *bo) +{ + might_sleep(); + if (bo) { +#ifdef CONFIG_PROC_FS + if (bo->client) + might_lock(&bo->client->bos_lock); +#endif + if (bo->ggtt_node && bo->ggtt_node->ggtt) + might_lock(&bo->ggtt_node->ggtt->lock); + drm_gem_object_put(&bo->ttm.base); + } +} + /** * xe_bo_dumb_create - Create a dumb bo as backing for a fb * @file_priv: ... diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h index dbfb3209615d..6e4be52306df 100644 --- a/drivers/gpu/drm/xe/xe_bo.h +++ b/drivers/gpu/drm/xe/xe_bo.h @@ -126,11 +126,7 @@ static inline struct xe_bo *xe_bo_get(struct xe_bo *bo) return bo; } -static inline void xe_bo_put(struct xe_bo *bo) -{ - if (bo) - drm_gem_object_put(&bo->ttm.base); -} +void xe_bo_put(struct xe_bo *bo); static inline void __xe_bo_unset_bulk_move(struct xe_bo *bo) { -- GitLab From 70a6587dca37a3cf12ab323f7fd73266abfc274f Mon Sep 17 00:00:00 2001 From: Imre Deak <imre.deak@intel.com> Date: Mon, 9 Sep 2024 17:46:50 +0300 Subject: [PATCH 180/970] drm/dp_mst: Fix DSC decompression detection in Synaptics branch devices Atm it's assumed that all Synaptics MST branch devices support DSC, which is not exposed via a DP-to-DP peer device, rather a control flag in the branch device's UFP DPCD applying to all the streams going through it. This isn't true for all adapters with this branch device though (for instance the Cakitte USBC->2xHDMI adapter reported in the Closes link below doesn't support DSC). Fix the above by advertising the DSC decompression support only if the capability flag for this in the UFP DPCD is actually set. Cc: Lyude Paul <lyude@redhat.com> Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12047 Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240909144650.2931258-1-imre.deak@intel.com --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index fc2ceae61db2..ac5f1f34e51a 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -6057,6 +6057,7 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) struct drm_dp_aux *immediate_upstream_aux; struct drm_dp_mst_port *fec_port; struct drm_dp_desc desc = {}; + u8 upstream_dsc; u8 endpoint_fec; u8 endpoint_dsc; @@ -6083,8 +6084,6 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) /* DP-to-DP peer device */ if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) { - u8 upstream_dsc; - if (drm_dp_dpcd_read(&port->aux, DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1) return NULL; @@ -6130,6 +6129,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) { u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; + if (drm_dp_dpcd_read(immediate_upstream_aux, + DP_DSC_SUPPORT, &upstream_dsc, 1) != 1) + return NULL; + + if (!(upstream_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED)) + return NULL; + if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0) return NULL; -- GitLab From 4a33aa34e4ac2c2bd746a305d4b39fb60dedc091 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Wed, 11 Sep 2024 13:16:48 +0300 Subject: [PATCH 181/970] drm/display: fix kerneldocs references The commit 9da7ec9b19d8 ("drm/bridge-connector: move to DRM_DISPLAY_HELPER module") changed location of the drm_bridge_connector.c file, but didn't update the kerneldocs. Fix that. Fixes: 9da7ec9b19d8 ("drm/bridge-connector: move to DRM_DISPLAY_HELPER module") Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Closes: https://lore.kernel.org/dri-devel/20240904163018.214efaa7@canb.auug.org.au/ Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-By: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911-drm-fix-dbc-docs-v1-1-ae5cb82fce1e@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- Documentation/gpu/drm-kms-helpers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 8435e8621cc0..c3e58856f75b 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -181,7 +181,7 @@ Bridge Operations Bridge Connector Helper ----------------------- -.. kernel-doc:: drivers/gpu/drm/drm_bridge_connector.c +.. kernel-doc:: drivers/gpu/drm/display/drm_bridge_connector.c :doc: overview @@ -204,7 +204,7 @@ MIPI-DSI bridge operation Bridge Connector Helper Reference --------------------------------- -.. kernel-doc:: drivers/gpu/drm/drm_bridge_connector.c +.. kernel-doc:: drivers/gpu/drm/display/drm_bridge_connector.c :export: Panel-Bridge Helper Reference -- GitLab From f96dbf7c321d70834d46f3aedb75a671e839b51e Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Tue, 10 Sep 2024 18:18:20 -0700 Subject: [PATCH 182/970] drm/xe: Do not run GPU page fault handler on a closed VM Closing a VM removes page table memory thus we shouldn't touch page tables when a VM is closed. Do not run the GPU page fault handler once the VM is closed to avoid touching page tables. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911011820.825127-1-matthew.brost@intel.com --- drivers/gpu/drm/xe/xe_gt_pagefault.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c index 730eec07795e..00af059a8971 100644 --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c @@ -212,6 +212,12 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) * TODO: Change to read lock? Using write lock for simplicity. */ down_write(&vm->lock); + + if (xe_vm_is_closed(vm)) { + err = -ENOENT; + goto unlock_vm; + } + vma = lookup_vma(vm, pf->page_addr); if (!vma) { err = -EINVAL; -- GitLab From bbb1ed0b4437ef728569457a136540ce2e6b11c4 Mon Sep 17 00:00:00 2001 From: Yu Jiaoliang <yujiaoliang@vivo.com> Date: Fri, 6 Sep 2024 15:01:09 +0800 Subject: [PATCH 183/970] drm/xe: Use ERR_CAST to return an error-valued pointer Instead of directly casting and returning an error-valued pointer, use ERR_CAST to make the error handling more explicit and improve code clarity. Signed-off-by: Yu Jiaoliang <yujiaoliang@vivo.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906070109.1852860-1-yujiaoliang@vivo.com --- drivers/gpu/drm/xe/xe_sa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_sa.c b/drivers/gpu/drm/xe/xe_sa.c index fe2cb2a96f78..e055bed7ae55 100644 --- a/drivers/gpu/drm/xe/xe_sa.c +++ b/drivers/gpu/drm/xe/xe_sa.c @@ -53,7 +53,7 @@ struct xe_sa_manager *xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u32 if (IS_ERR(bo)) { drm_err(&xe->drm, "failed to allocate bo for sa manager: %ld\n", PTR_ERR(bo)); - return (struct xe_sa_manager *)bo; + return ERR_CAST(bo); } sa_manager->bo = bo; sa_manager->is_iomem = bo->vmap.is_iomem; -- GitLab From 9388ccf69925223223c87355a417ba39b13a5e8e Mon Sep 17 00:00:00 2001 From: Yan Zhao <yan.y.zhao@intel.com> Date: Mon, 9 Sep 2024 21:16:43 +0800 Subject: [PATCH 184/970] drm/bochs: use devm_ioremap_wc() to map framebuffer Opt for devm_ioremap_wc() over devm_ioremap() when mapping the framebuffer. Using devm_ioremap() results in the VA being mapped with PAT=UC-, which considerably slows down drm_fb_memcpy(). In contrast, devm_ioremap_wc() maps the VA with PAT set to WC, leading to better performance on platforms where access to UC memory is much slower than WC memory. Here's the performance data measured in a guest on the physical machine "Sapphire Rapids XCC". With host KVM honors guest PAT memory types, the effective memory type for this framebuffer range is - WC when devm_ioremap_wc() is used - UC- when devm_ioremap() is used. The data presented is an average from 10 execution runs. Cycles: Avg cycles of executed bochs_primary_plane_helper_atomic_update() from VM boot to GDM show up Cnt: Avg cnt of executed bochs_primary_plane_helper_atomic_update() from VM boot to GDM show up T: Avg time of each bochs_primary_plane_helper_atomic_update(). ------------------------------------------------- | | devm_ioremap() | devm_ioremap_wc() | |------------|----------------|-------------------| | Cycles | 211.545M | 0.157M | |------------|----------------|-------------------| | Cnt | 142 | 1917 | |------------|----------------|-------------------| | T | 0.1748s | 0.0004s | ------------------------------------------------- Note: Following the rebase to [3], the previously reported GDM failure on the VGA device [1] can no longer be reproduced, thanks to the memory management improvements made in [2]. Despite this, I have proceeded to submit this patch because of the noticeable performance improvements it provides. Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com> Closes: https://lore.kernel.org/all/87jzfutmfc.fsf@redhat.com/#t Cc: Sean Christopherson <seanjc@google.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Kevin Tian <kevin.tian@intel.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://lore.kernel.org/all/87jzfutmfc.fsf@redhat.com/#t [1] Link: https://patchwork.freedesktop.org/series/138086 [2] Link: https://gitlab.freedesktop.org/drm/misc/kernel/-/tree/drm-misc-next [3] Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Tested-by: Vitaly Kuznetsov <vkuznets@redhat.com> Tested-by: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240909131643.28915-1-yan.y.zhao@intel.com --- drivers/gpu/drm/tiny/bochs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 69c5f65e9853..9055b1dd66df 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -268,7 +268,7 @@ static int bochs_hw_init(struct bochs_device *bochs) if (!devm_request_mem_region(&pdev->dev, addr, size, "bochs-drm")) DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); - bochs->fb_map = devm_ioremap(&pdev->dev, addr, size); + bochs->fb_map = devm_ioremap_wc(&pdev->dev, addr, size); if (bochs->fb_map == NULL) { DRM_ERROR("Cannot map framebuffer\n"); return -ENOMEM; -- GitLab From 446967304b5671f9b9e5b1b7a620106b4fd6b1f2 Mon Sep 17 00:00:00 2001 From: Alexander Stein <alexander.stein@ew.tq-group.com> Date: Wed, 4 Sep 2024 14:05:43 +0200 Subject: [PATCH 185/970] drm/bridge: tc358767: Use dev_err_probe The function calls preceding these returns can return -EPROBE_DEFER. So use dev_err_probe to add some information to /sys/kernel/debug/devices_deferred Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://lore.kernel.org/r/20240904120546.1845856-2-alexander.stein@ew.tq-group.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240904120546.1845856-2-alexander.stein@ew.tq-group.com --- drivers/gpu/drm/bridge/tc358767.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 290e2532fab1..5ef33ce33dca 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -2298,7 +2298,8 @@ static int tc_probe_dpi_bridge_endpoint(struct tc_data *tc) /* port@1 is the DPI input/output port */ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, &bridge); if (ret && ret != -ENODEV) - return ret; + return dev_err_probe(dev, ret, + "Could not find DPI panel or bridge\n"); if (panel) { bridge = devm_drm_panel_bridge_add(dev, panel); @@ -2326,7 +2327,8 @@ static int tc_probe_edp_bridge_endpoint(struct tc_data *tc) /* port@2 is the output port */ ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, NULL); if (ret && ret != -ENODEV) - return ret; + return dev_err_probe(dev, ret, + "Could not find DSI panel or bridge\n"); if (panel) { struct drm_bridge *panel_bridge; @@ -2550,7 +2552,7 @@ static int tc_probe(struct i2c_client *client) ret = tc_mipi_dsi_host_attach(tc); if (ret) { drm_bridge_remove(&tc->bridge); - return ret; + return dev_err_probe(dev, ret, "Failed to attach DSI host\n"); } } -- GitLab From 31735a97cbd81bc3d858b44a56c8e8dc134a0a3c Mon Sep 17 00:00:00 2001 From: Alexander Stein <alexander.stein@ew.tq-group.com> Date: Wed, 4 Sep 2024 14:05:44 +0200 Subject: [PATCH 186/970] drm/bridge: tc358767: Only print GPIO debug output if they actually occur Currently the output the following output is printed upon each interrupt: tc358767 1-000f: GPIO0: This spams the kernel log while debugging an IRQ storm from the bridge. Only print the debug output if the GPIO hotplug event actually happened. Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Robert Foss <rfoss@kernel.org> Link: https://lore.kernel.org/r/20240904120546.1845856-3-alexander.stein@ew.tq-group.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240904120546.1845856-3-alexander.stein@ew.tq-group.com --- drivers/gpu/drm/bridge/tc358767.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 5ef33ce33dca..1c42c8c6e632 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -2229,11 +2229,11 @@ static irqreturn_t tc_irq_handler(int irq, void *arg) bool h = val & INT_GPIO_H(tc->hpd_pin); bool lc = val & INT_GPIO_LC(tc->hpd_pin); - dev_dbg(tc->dev, "GPIO%d: %s %s\n", tc->hpd_pin, - h ? "H" : "", lc ? "LC" : ""); - - if (h || lc) + if (h || lc) { + dev_dbg(tc->dev, "GPIO%d: %s %s\n", tc->hpd_pin, + h ? "H" : "", lc ? "LC" : ""); drm_kms_helper_hotplug_event(tc->bridge.dev); + } } regmap_write(tc->regmap, INTSTS_G, val); -- GitLab From 0d317e820d40963a63eb61732784f23ca0e82d23 Mon Sep 17 00:00:00 2001 From: Alexander Stein <alexander.stein@ew.tq-group.com> Date: Wed, 4 Sep 2024 14:05:45 +0200 Subject: [PATCH 187/970] drm/bridge: tc358767: Support write-only registers Most registers are read-writable, but some are only RO or even WO. regmap does not support using readable_reg and wr_table when outputting in debugfs, so switch to writeable_reg. First check for RO or WO registers and fallback tc_readable_reg() for the leftover RW registers. Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Robert Foss <rfoss@kernel.org> Link: https://lore.kernel.org/r/20240904120546.1845856-4-alexander.stein@ew.tq-group.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240904120546.1845856-4-alexander.stein@ew.tq-group.com --- drivers/gpu/drm/bridge/tc358767.c | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 1c42c8c6e632..159c95b26d33 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -2169,19 +2169,31 @@ static const struct regmap_access_table tc_precious_table = { .n_yes_ranges = ARRAY_SIZE(tc_precious_ranges), }; -static const struct regmap_range tc_non_writeable_ranges[] = { - regmap_reg_range(PPI_BUSYPPI, PPI_BUSYPPI), - regmap_reg_range(DSI_BUSYDSI, DSI_BUSYDSI), - regmap_reg_range(DSI_LANESTATUS0, DSI_INTSTATUS), - regmap_reg_range(TC_IDREG, SYSSTAT), - regmap_reg_range(GPIOI, GPIOI), - regmap_reg_range(DP0_LTSTAT, DP0_SNKLTCHGREQ), -}; - -static const struct regmap_access_table tc_writeable_table = { - .no_ranges = tc_non_writeable_ranges, - .n_no_ranges = ARRAY_SIZE(tc_non_writeable_ranges), -}; +static bool tc_writeable_reg(struct device *dev, unsigned int reg) +{ + /* RO reg */ + switch (reg) { + case PPI_BUSYPPI: + case DSI_BUSYDSI: + case DSI_LANESTATUS0: + case DSI_LANESTATUS1: + case DSI_INTSTATUS: + case TC_IDREG: + case SYSBOOT: + case SYSSTAT: + case GPIOI: + case DP0_LTSTAT: + case DP0_SNKLTCHGREQ: + return false; + } + /* WO reg */ + switch (reg) { + case DSI_STARTDSI: + case DSI_INTCLR: + return true; + } + return tc_readable_reg(dev, reg); +} static const struct regmap_config tc_regmap_config = { .name = "tc358767", @@ -2191,9 +2203,9 @@ static const struct regmap_config tc_regmap_config = { .max_register = PLL_DBG, .cache_type = REGCACHE_MAPLE, .readable_reg = tc_readable_reg, + .writeable_reg = tc_writeable_reg, .volatile_table = &tc_volatile_table, .precious_table = &tc_precious_table, - .wr_table = &tc_writeable_table, .reg_format_endian = REGMAP_ENDIAN_BIG, .val_format_endian = REGMAP_ENDIAN_LITTLE, }; -- GitLab From 017703370638c07cd6affe661118f697ee113881 Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Wed, 26 Jun 2024 20:06:59 -0300 Subject: [PATCH 188/970] drm/bridge: imx8mp-hdmi-tx: Switch to SYSTEM_SLEEP_PM_OPS() Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() alternative. The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626230704.708234-1-festevam@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626230704.708234-1-festevam@gmail.com --- drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c index 13bc570c5473..4a3a8a3ce250 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -111,12 +111,12 @@ static void imx8mp_dw_hdmi_remove(struct platform_device *pdev) dw_hdmi_remove(hdmi->dw_hdmi); } -static int __maybe_unused imx8mp_dw_hdmi_pm_suspend(struct device *dev) +static int imx8mp_dw_hdmi_pm_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) +static int imx8mp_dw_hdmi_pm_resume(struct device *dev) { struct imx8mp_hdmi *hdmi = dev_get_drvdata(dev); @@ -126,8 +126,7 @@ static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) } static const struct dev_pm_ops imx8mp_dw_hdmi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, - imx8mp_dw_hdmi_pm_resume) + SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, imx8mp_dw_hdmi_pm_resume) }; static const struct of_device_id imx8mp_dw_hdmi_of_table[] = { @@ -142,7 +141,7 @@ static struct platform_driver imx8mp_dw_hdmi_platform_driver = { .driver = { .name = "imx8mp-dw-hdmi-tx", .of_match_table = imx8mp_dw_hdmi_of_table, - .pm = &imx8mp_dw_hdmi_pm_ops, + .pm = pm_ptr(&imx8mp_dw_hdmi_pm_ops), }, }; -- GitLab From 02b16c5236e1823047f001b9496e59458c9a7482 Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Wed, 26 Jun 2024 20:07:00 -0300 Subject: [PATCH 189/970] drm/bridge: imx8qm-ldb: Switch to RUNTIME_PM_OPS() Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626230704.708234-2-festevam@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626230704.708234-2-festevam@gmail.com --- drivers/gpu/drm/bridge/imx/imx8qm-ldb.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c index 21471a9a28b2..c879e37f5811 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c @@ -542,12 +542,12 @@ static void imx8qm_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qm_ldb_runtime_suspend(struct device *dev) +static int imx8qm_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) +static int imx8qm_ldb_runtime_resume(struct device *dev) { struct imx8qm_ldb *imx8qm_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qm_ldb->base; @@ -559,8 +559,7 @@ static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qm_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, - imx8qm_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, imx8qm_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qm_ldb_dt_ids[] = { @@ -573,7 +572,7 @@ static struct platform_driver imx8qm_ldb_driver = { .probe = imx8qm_ldb_probe, .remove_new = imx8qm_ldb_remove, .driver = { - .pm = &imx8qm_ldb_pm_ops, + .pm = pm_ptr(&imx8qm_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qm_ldb_dt_ids, }, -- GitLab From be227772f7e957f98c3c828459b1221cae84de2e Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Wed, 26 Jun 2024 20:07:01 -0300 Subject: [PATCH 190/970] drm/bridge: imx8qxp-pixel-combiner: Switch to RUNTIME_PM_OPS() Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626230704.708234-3-festevam@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626230704.708234-3-festevam@gmail.com --- drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c index e6dbbdc87ce2..ce43e4069e21 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c @@ -371,7 +371,7 @@ static void imx8qxp_pc_bridge_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) +static int imx8qxp_pc_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -393,7 +393,7 @@ static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) return ret; } -static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) +static int imx8qxp_pc_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -415,8 +415,7 @@ static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_pc_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, - imx8qxp_pc_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, imx8qxp_pc_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_pc_dt_ids[] = { @@ -430,7 +429,7 @@ static struct platform_driver imx8qxp_pc_bridge_driver = { .probe = imx8qxp_pc_bridge_probe, .remove_new = imx8qxp_pc_bridge_remove, .driver = { - .pm = &imx8qxp_pc_pm_ops, + .pm = pm_ptr(&imx8qxp_pc_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_pc_dt_ids, }, -- GitLab From 5de3c40a1dc503bf915bbc048aa8f5efb369650c Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Wed, 26 Jun 2024 20:07:02 -0300 Subject: [PATCH 191/970] drm/bridge: samsung-dsim: Switch to RUNTIME_PM_OPS() Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626230704.708234-4-festevam@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626230704.708234-4-festevam@gmail.com --- drivers/gpu/drm/bridge/samsung-dsim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index e7e53a9e42af..73ccf21ae446 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -2043,7 +2043,7 @@ void samsung_dsim_remove(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(samsung_dsim_remove); -static int __maybe_unused samsung_dsim_suspend(struct device *dev) +static int samsung_dsim_suspend(struct device *dev) { struct samsung_dsim *dsi = dev_get_drvdata(dev); const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -2073,7 +2073,7 @@ static int __maybe_unused samsung_dsim_suspend(struct device *dev) return 0; } -static int __maybe_unused samsung_dsim_resume(struct device *dev) +static int samsung_dsim_resume(struct device *dev) { struct samsung_dsim *dsi = dev_get_drvdata(dev); const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -2108,7 +2108,7 @@ static int __maybe_unused samsung_dsim_resume(struct device *dev) } const struct dev_pm_ops samsung_dsim_pm_ops = { - SET_RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL) + RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; @@ -2142,7 +2142,7 @@ static struct platform_driver samsung_dsim_driver = { .remove_new = samsung_dsim_remove, .driver = { .name = "samsung-dsim", - .pm = &samsung_dsim_pm_ops, + .pm = pm_ptr(&samsung_dsim_pm_ops), .of_match_table = samsung_dsim_of_match, }, }; -- GitLab From 46fe7763c65674be67828cdbe3a72d6d9b8f8aa7 Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Wed, 26 Jun 2024 20:07:03 -0300 Subject: [PATCH 192/970] drm/bridge: dw-hdmi-cec: Switch to SYSTEM_SLEEP_PM_OPS() Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() alternative. The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626230704.708234-5-festevam@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626230704.708234-5-festevam@gmail.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c index 673661160e54..d4614de1ae1e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c @@ -312,7 +312,7 @@ static void dw_hdmi_cec_remove(struct platform_device *pdev) cec_unregister_adapter(cec->adap); } -static int __maybe_unused dw_hdmi_cec_resume(struct device *dev) +static int dw_hdmi_cec_resume(struct device *dev) { struct dw_hdmi_cec *cec = dev_get_drvdata(dev); @@ -328,7 +328,7 @@ static int __maybe_unused dw_hdmi_cec_resume(struct device *dev) return 0; } -static int __maybe_unused dw_hdmi_cec_suspend(struct device *dev) +static int dw_hdmi_cec_suspend(struct device *dev) { struct dw_hdmi_cec *cec = dev_get_drvdata(dev); @@ -341,7 +341,7 @@ static int __maybe_unused dw_hdmi_cec_suspend(struct device *dev) } static const struct dev_pm_ops dw_hdmi_cec_pm = { - SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume) + SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume) }; static struct platform_driver dw_hdmi_cec_driver = { @@ -349,7 +349,7 @@ static struct platform_driver dw_hdmi_cec_driver = { .remove_new = dw_hdmi_cec_remove, .driver = { .name = "dw-hdmi-cec", - .pm = &dw_hdmi_cec_pm, + .pm = pm_ptr(&dw_hdmi_cec_pm), }, }; module_platform_driver(dw_hdmi_cec_driver); -- GitLab From 8fdd9cb4f8c03a943090ef55ffb552e05c6defc6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Wed, 26 Jun 2024 20:07:04 -0300 Subject: [PATCH 193/970] drm/bridge: imx8qxp-ldb: Switch to RUNTIME_PM_OPS() Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626230704.708234-6-festevam@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626230704.708234-6-festevam@gmail.com --- drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c index 7984da9c0a35..b33011f397f0 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c @@ -678,12 +678,12 @@ static void imx8qxp_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_ldb_runtime_suspend(struct device *dev) +static int imx8qxp_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) +static int imx8qxp_ldb_runtime_resume(struct device *dev) { struct imx8qxp_ldb *imx8qxp_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qxp_ldb->base; @@ -695,8 +695,7 @@ static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, - imx8qxp_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, imx8qxp_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_ldb_dt_ids[] = { @@ -709,7 +708,7 @@ static struct platform_driver imx8qxp_ldb_driver = { .probe = imx8qxp_ldb_probe, .remove_new = imx8qxp_ldb_remove, .driver = { - .pm = &imx8qxp_ldb_pm_ops, + .pm = pm_ptr(&imx8qxp_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_ldb_dt_ids, }, -- GitLab From 0d4b950e03fb1c1873c51916fd01ebafbbc48222 Mon Sep 17 00:00:00 2001 From: Dominique Martinet <dominique.martinet@atmark-techno.com> Date: Sat, 7 Sep 2024 14:54:33 +0900 Subject: [PATCH 194/970] drm/bridge: imx8mp-hdmi-tx: allow 0.5% margin with selected clock This allows the hdmi driver to pick e.g. 64.8MHz instead of 65Mhz when we cannot output the exact frequency, enabling the imx8mp HDMI output to support more modes Tested-by: Adam Ford <aford173@gmail.com> #imx8mp-beacon Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de> Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de> Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240907-hdmi-tolerance-v2-1-b9d7abd89f5c@codewreck.org Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240907-hdmi-tolerance-v2-1-b9d7abd89f5c@codewreck.org --- drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c index 4a3a8a3ce250..8fcc6d18f4ab 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -23,6 +23,7 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, const struct drm_display_mode *mode) { struct imx8mp_hdmi *hdmi = (struct imx8mp_hdmi *)data; + long round_rate; if (mode->clock < 13500) return MODE_CLOCK_LOW; @@ -30,8 +31,14 @@ imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, if (mode->clock > 297000) return MODE_CLOCK_HIGH; - if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) != - mode->clock * 1000) + round_rate = clk_round_rate(hdmi->pixclk, mode->clock * 1000); + /* imx8mp's pixel clock generator (fsl-samsung-hdmi) cannot generate + * all possible frequencies, so allow some tolerance to support more + * modes. + * Allow 0.5% difference allowed in various standards (VESA, CEA861) + * 0.5% = 5/1000 tolerance (mode->clock is 1/1000) + */ + if (abs(round_rate - mode->clock * 1000) > mode->clock * 5) return MODE_CLOCK_RANGE; /* We don't support double-clocked and Interlaced modes */ -- GitLab From d5acba46ebf5a4fd9ea9ae5121dd381ce85e94ff Mon Sep 17 00:00:00 2001 From: Min-Hua Chen <minhuadotchen@gmail.com> Date: Sun, 8 Sep 2024 21:35:30 +0800 Subject: [PATCH 195/970] drm/panel: khadas-ts050: make ts050[v2]_panel_data static make ts050_panel_data and ts050v2_panel_data static because they are only used in drivers/gpu/drm/panel/panel-khadas-ts050.c, and fix the following sparse warnings: drivers/gpu/drm/panel/panel-khadas-ts050.c:620:32: sparse: warning: symbol 'ts050_panel_data' was not declared. Should it be static? drivers/gpu/drm/panel/panel-khadas-ts050.c:625:32: sparse: warning: symbol 'ts050v2_panel_data' was not declared. Should it be static? No functional changes intended. Signed-off-by: Min-Hua Chen <minhuadotchen@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240908133533.112894-1-minhuadotchen@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240908133533.112894-1-minhuadotchen@gmail.com --- drivers/gpu/drm/panel/panel-khadas-ts050.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c b/drivers/gpu/drm/panel/panel-khadas-ts050.c index 14932cb3defc..0e5e8e57bd1e 100644 --- a/drivers/gpu/drm/panel/panel-khadas-ts050.c +++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c @@ -617,12 +617,12 @@ static const struct khadas_ts050_panel_cmd ts050_init_code[] = { {0xd4, {0x04}, 0x01}, /* RGBMIPICTRL: VSYNC front porch = 4 */ }; -struct khadas_ts050_panel_data ts050_panel_data = { +static struct khadas_ts050_panel_data ts050_panel_data = { .init_code = (struct khadas_ts050_panel_cmd *)ts050_init_code, .len = ARRAY_SIZE(ts050_init_code) }; -struct khadas_ts050_panel_data ts050v2_panel_data = { +static struct khadas_ts050_panel_data ts050v2_panel_data = { .init_code = (struct khadas_ts050_panel_cmd *)ts050v2_init_code, .len = ARRAY_SIZE(ts050v2_init_code) }; -- GitLab From 62f6bc14bbd12c13abe08b5a1bd8e55c843b776b Mon Sep 17 00:00:00 2001 From: Jianhua Lu <lujianhua000@gmail.com> Date: Wed, 4 Sep 2024 22:29:07 +0800 Subject: [PATCH 196/970] drm: panel: nt36523: use devm_mipi_dsi_* function to register and attach dsi Switch to devm_mipi_dsi_* function, we don't need to detach and unregister dsi manually any more. Signed-off-by: Jianhua Lu <lujianhua000@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240904142907.367786-1-lujianhua000@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240904142907.367786-1-lujianhua000@gmail.com --- drivers/gpu/drm/panel/panel-novatek-nt36523.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index 18bd2ee71201..04f1d2676c78 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -1095,18 +1095,6 @@ static int nt36523_unprepare(struct drm_panel *panel) static void nt36523_remove(struct mipi_dsi_device *dsi) { struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi); - int ret; - - ret = mipi_dsi_detach(pinfo->dsi[0]); - if (ret < 0) - dev_err(&dsi->dev, "failed to detach from DSI0 host: %d\n", ret); - - if (pinfo->desc->is_dual_dsi) { - ret = mipi_dsi_detach(pinfo->dsi[1]); - if (ret < 0) - dev_err(&pinfo->dsi[1]->dev, "failed to detach from DSI1 host: %d\n", ret); - mipi_dsi_device_unregister(pinfo->dsi[1]); - } drm_panel_remove(&pinfo->panel); } @@ -1251,7 +1239,7 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) if (!dsi1_host) return dev_err_probe(dev, -EPROBE_DEFER, "cannot get secondary DSI host\n"); - pinfo->dsi[1] = mipi_dsi_device_register_full(dsi1_host, info); + pinfo->dsi[1] = devm_mipi_dsi_device_register_full(dev, dsi1_host, info); if (IS_ERR(pinfo->dsi[1])) { dev_err(dev, "cannot get secondary DSI device\n"); return PTR_ERR(pinfo->dsi[1]); @@ -1288,7 +1276,7 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) pinfo->dsi[i]->format = pinfo->desc->format; pinfo->dsi[i]->mode_flags = pinfo->desc->mode_flags; - ret = mipi_dsi_attach(pinfo->dsi[i]); + ret = devm_mipi_dsi_attach(dev, pinfo->dsi[i]); if (ret < 0) return dev_err_probe(dev, ret, "cannot attach to DSI%d host.\n", i); } -- GitLab From 9550e2394fc09bf105a246221660da980c2dbd66 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Date: Wed, 11 Sep 2024 23:01:25 +0300 Subject: [PATCH 197/970] drm/panel: sony-acx565akm: Use %*ph to print small buffer Use %*ph format to print small buffer as hex string. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240911200125.2886384-1-andriy.shevchenko@linux.intel.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240911200125.2886384-1-andriy.shevchenko@linux.intel.com --- drivers/gpu/drm/panel/panel-sony-acx565akm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c b/drivers/gpu/drm/panel/panel-sony-acx565akm.c index 217f03569494..d437f5c84f5f 100644 --- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c @@ -562,8 +562,7 @@ static int acx565akm_detect(struct acx565akm_panel *lcd) lcd->enabled ? "enabled" : "disabled ", status); acx565akm_read(lcd, MIPI_DCS_GET_DISPLAY_ID, lcd->display_id, 3); - dev_dbg(&lcd->spi->dev, "MIPI display ID: %02x%02x%02x\n", - lcd->display_id[0], lcd->display_id[1], lcd->display_id[2]); + dev_dbg(&lcd->spi->dev, "MIPI display ID: %3phN\n", lcd->display_id); switch (lcd->display_id[0]) { case 0x10: -- GitLab From 298766ac8ba73c3d672e01054c0874ed26d1d19d Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Tue, 10 Sep 2024 13:03:39 +0300 Subject: [PATCH 198/970] drm/kmb: annotate set_test_mode_src_osc_freq_target_{low, hi}_bits() with __maybe_unused Building with clang and and W=1 leads to warning about unused set_test_mode_src_osc_freq_target_low_bits() and set_test_mode_src_osc_freq_target_hi_bits(). Fix by annotating them with __maybe_unused. See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static inline functions for W=1 build"). Acked-by: Anitha Chrisanthus <anitha.chrisanthus@intel.com> Tested-by: Nathan Chancellor <nathan@kernel.org> # build Link: https://patchwork.freedesktop.org/patch/msgid/29a83771edd9b85032095ed3ecc1e91a77229b90.1725962479.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/kmb/kmb_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c index cf7cf0b07541..faf38ca9e44c 100644 --- a/drivers/gpu/drm/kmb/kmb_dsi.c +++ b/drivers/gpu/drm/kmb/kmb_dsi.c @@ -818,7 +818,7 @@ static void test_mode_send(struct kmb_dsi *kmb_dsi, u32 dphy_no, } } -static inline void +static inline __maybe_unused void set_test_mode_src_osc_freq_target_low_bits(struct kmb_dsi *kmb_dsi, u32 dphy_no, u32 freq) @@ -830,7 +830,7 @@ static inline void (freq & 0x7f)); } -static inline void +static inline __maybe_unused void set_test_mode_src_osc_freq_target_hi_bits(struct kmb_dsi *kmb_dsi, u32 dphy_no, u32 freq) -- GitLab From 60c174898dbdc7610f185079b5c9e5d2fa5a626e Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Tue, 10 Sep 2024 13:03:41 +0300 Subject: [PATCH 199/970] drm/imagination: annotate pvr_fw_version_packed() with __maybe_unused Building with clang and W=1 leads to warning about unused pvr_fw_version_packed(). Fix by annotating it with __maybe_unused. See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static inline functions for W=1 build"). Reviewed-by: Matt Coster <matt.coster@imgtec.com> Tested-by: Nathan Chancellor <nathan@kernel.org> # build Link: https://patchwork.freedesktop.org/patch/msgid/190e4eefef6c5e62052a01af0084c69361e216ef.1725962479.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/imagination/pvr_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index 1a0cb7aa9cea..684a9b9a2247 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -220,7 +220,7 @@ pvr_ioctl_get_bo_mmap_offset(struct drm_device *drm_dev, void *raw_args, return ret; } -static __always_inline u64 +static __always_inline __maybe_unused u64 pvr_fw_version_packed(u32 major, u32 minor) { return ((u64)major << 32) | minor; -- GitLab From e9c37f7b71ac28d32201f8674bd232081d8b071f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:19 +0200 Subject: [PATCH 200/970] drm/ast: astdp: Inline ast_astdp_connector_init() Inline ast_astdp_connector_init() into its only caller. The helper currently only does half of the connector-init work and is trivial enough to be inlined. Also set the local variables for encoder and connector as late as possible, so that the compiler warns if we use them before having initialized the instance. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-2-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp.c | 45 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index 00b364f9a71e..dab73dc6cb87 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -414,6 +414,10 @@ static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs .detect_ctx = ast_astdp_connector_helper_detect_ctx, }; +/* + * Output + */ + static const struct drm_connector_funcs ast_astdp_connector_funcs = { .reset = drm_atomic_helper_connector_reset, .fill_modes = drm_helper_probe_single_connector_modes, @@ -422,34 +426,18 @@ static const struct drm_connector_funcs ast_astdp_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector *connector) -{ - int ret; - - ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); - if (ret) - return ret; - - drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs); - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - - return 0; -} - int ast_astdp_output_init(struct ast_device *ast) { struct drm_device *dev = &ast->base; struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.astdp.encoder; - struct ast_connector *ast_connector = &ast->output.astdp.connector; - struct drm_connector *connector = &ast_connector->base; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* encoder */ + + encoder = &ast->output.astdp.encoder; ret = drm_encoder_init(dev, encoder, &ast_astdp_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) @@ -458,9 +446,20 @@ int ast_astdp_output_init(struct ast_device *ast) encoder->possible_crtcs = drm_crtc_mask(crtc); - ret = ast_astdp_connector_init(dev, connector); + /* connector */ + + ast_connector = &ast->output.astdp.connector; + connector = &ast_connector->base; + ret = drm_connector_init(dev, connector, &ast_astdp_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); if (ret) return ret; + drm_connector_helper_add(connector, &ast_astdp_connector_helper_funcs); + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); -- GitLab From 2fc2d1adbd273282eecf2343c2a77a6fb228bd97 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:20 +0200 Subject: [PATCH 201/970] drm/ast: astdp: Avoid upcasting to struct ast_device Several functions receive an instance of struct drm_device only to upcast it to struct ast_device. Improve type safety by passing the AST device directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-3-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index dab73dc6cb87..2b5129c6f8b0 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -158,9 +158,8 @@ static bool ast_dp_power_is_on(struct ast_device *ast) return !(vgacre3 & AST_DP_PHY_SLEEP); } -static void ast_dp_power_on_off(struct drm_device *dev, bool on) +static void ast_dp_power_on_off(struct ast_device *ast, bool on) { - struct ast_device *ast = to_ast_device(dev); // Read and Turn off DP PHY sleep u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE); @@ -192,9 +191,8 @@ static void ast_dp_link_training(struct ast_device *ast) drm_err(dev, "Link training failed\n"); } -static void ast_dp_set_on_off(struct drm_device *dev, bool on) +static void ast_dp_set_on_off(struct ast_device *ast, bool on) { - struct ast_device *ast = to_ast_device(dev); u8 video_on_off = on; u32 i = 0; @@ -317,26 +315,25 @@ static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; - struct ast_device *ast = to_ast_device(dev); + struct ast_device *ast = to_ast_device(encoder->dev); struct ast_connector *ast_connector = &ast->output.astdp.connector; if (ast_connector->physical_status == connector_status_connected) { - ast_dp_power_on_off(dev, AST_DP_POWER_ON); + ast_dp_power_on_off(ast, AST_DP_POWER_ON); ast_dp_link_training(ast); ast_wait_for_vretrace(ast); - ast_dp_set_on_off(dev, 1); + ast_dp_set_on_off(ast, 1); } } static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; + struct ast_device *ast = to_ast_device(encoder->dev); - ast_dp_set_on_off(dev, 0); - ast_dp_power_on_off(dev, AST_DP_POWER_OFF); + ast_dp_set_on_off(ast, 0); + ast_dp_power_on_off(ast, AST_DP_POWER_OFF); } static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = { @@ -383,7 +380,6 @@ static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector bool force) { struct ast_connector *ast_connector = to_ast_connector(connector); - struct drm_device *dev = connector->dev; struct ast_device *ast = to_ast_device(connector->dev); enum drm_connector_status status = connector_status_disconnected; bool power_is_on; @@ -392,13 +388,13 @@ static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector power_is_on = ast_dp_power_is_on(ast); if (!power_is_on) - ast_dp_power_on_off(dev, true); + ast_dp_power_on_off(ast, true); if (ast_astdp_is_connected(ast)) status = connector_status_connected; if (!power_is_on && status == connector_status_disconnected) - ast_dp_power_on_off(dev, false); + ast_dp_power_on_off(ast, false); mutex_unlock(&ast->modeset_lock); -- GitLab From c0acb5c541931618fbd0923e7d0b3803acf48888 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:21 +0200 Subject: [PATCH 202/970] drm/ast: astdp: Replace power_on helpers Replace the helper for controlling power on the physical connector, ast_dp_power_on_off(), with ast_dp_set_phy_sleep(). The new name reflects the effect of the operation. Simplify the implementation. The call now controls sleeping, hence semantics are inversed. Each 'on' becomes an 'off' operation and vice versa. Do the same for ast_dp_power_is_on() and also align naming of the register constant with the rest of the code. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-4-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp.c | 39 +++++++++++++++-------------------- drivers/gpu/drm/ast/ast_drv.h | 3 --- drivers/gpu/drm/ast/ast_reg.h | 2 +- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index 2b5129c6f8b0..d4362807d777 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -149,27 +149,22 @@ int ast_dp_launch(struct ast_device *ast) return 0; } -static bool ast_dp_power_is_on(struct ast_device *ast) +static bool ast_dp_get_phy_sleep(struct ast_device *ast) { - u8 vgacre3; + u8 vgacre3 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xe3); - vgacre3 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xe3); - - return !(vgacre3 & AST_DP_PHY_SLEEP); + return (vgacre3 & AST_IO_VGACRE3_DP_PHY_SLEEP); } -static void ast_dp_power_on_off(struct ast_device *ast, bool on) +static void ast_dp_set_phy_sleep(struct ast_device *ast, bool sleep) { - // Read and Turn off DP PHY sleep - u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE); - - // Turn on DP PHY sleep - if (!on) - bE3 |= AST_DP_PHY_SLEEP; + u8 vgacre3 = 0x00; - // DP Power on/off - ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); + if (sleep) + vgacre3 |= AST_IO_VGACRE3_DP_PHY_SLEEP; + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe3, (u8)~AST_IO_VGACRE3_DP_PHY_SLEEP, + vgacre3); msleep(50); } @@ -319,7 +314,7 @@ static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder, struct ast_connector *ast_connector = &ast->output.astdp.connector; if (ast_connector->physical_status == connector_status_connected) { - ast_dp_power_on_off(ast, AST_DP_POWER_ON); + ast_dp_set_phy_sleep(ast, false); ast_dp_link_training(ast); ast_wait_for_vretrace(ast); @@ -333,7 +328,7 @@ static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder, struct ast_device *ast = to_ast_device(encoder->dev); ast_dp_set_on_off(ast, 0); - ast_dp_power_on_off(ast, AST_DP_POWER_OFF); + ast_dp_set_phy_sleep(ast, true); } static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = { @@ -382,19 +377,19 @@ static int ast_astdp_connector_helper_detect_ctx(struct drm_connector *connector struct ast_connector *ast_connector = to_ast_connector(connector); struct ast_device *ast = to_ast_device(connector->dev); enum drm_connector_status status = connector_status_disconnected; - bool power_is_on; + bool phy_sleep; mutex_lock(&ast->modeset_lock); - power_is_on = ast_dp_power_is_on(ast); - if (!power_is_on) - ast_dp_power_on_off(ast, true); + phy_sleep = ast_dp_get_phy_sleep(ast); + if (phy_sleep) + ast_dp_set_phy_sleep(ast, false); if (ast_astdp_is_connected(ast)) status = connector_status_connected; - if (!power_is_on && status == connector_status_disconnected) - ast_dp_power_on_off(ast, false); + if (phy_sleep && status == connector_status_disconnected) + ast_dp_set_phy_sleep(ast, true); mutex_unlock(&ast->modeset_lock); diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index b6ca14a3b967..cafc4234e839 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -403,9 +403,6 @@ int ast_mode_config_init(struct ast_device *ast); #define AST_DP501_LINKRATE 0xf014 #define AST_DP501_EDID_DATA 0xf020 -#define AST_DP_POWER_ON true -#define AST_DP_POWER_OFF false - /* * ASTDP resoultion table: * EX: ASTDP_A_B_C: diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index 040961cc1a19..d7a22cea8271 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -41,6 +41,7 @@ #define AST_IO_VGACRD7_EDID_VALID_FLAG BIT(0) #define AST_IO_VGACRDC_LINK_SUCCESS BIT(0) #define AST_IO_VGACRDF_HPD BIT(0) +#define AST_IO_VGACRE3_DP_PHY_SLEEP BIT(4) #define AST_IO_VGACRE5_EDID_READ_DONE BIT(0) #define AST_IO_VGAIR1_R (0x5A) @@ -69,7 +70,6 @@ */ /* Define for Soc scratched reg used on ASTDP */ -#define AST_DP_PHY_SLEEP BIT(4) #define AST_DP_VIDEO_ENABLE BIT(0) /* -- GitLab From 4e29cc7c5c673299cfbaf4982fc8b6a72c9f706f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:22 +0200 Subject: [PATCH 203/970] drm/ast: astdp: Replace ast_dp_set_on_off() Replace ast_dp_set_on_off() with ast_dp_set_enable(). The helper's new name reflects the performed operation. If enabling fails, the new helper prints a warning. The code that waits for the programmed effect to take place is now located in __ast_dp_wait_enable(). Also align the register constants with the rest of the code. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-5-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp.c | 49 +++++++++++++++++++++++------------ drivers/gpu/drm/ast/ast_reg.h | 13 ++-------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index d4362807d777..0e282b7b167c 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -186,22 +186,39 @@ static void ast_dp_link_training(struct ast_device *ast) drm_err(dev, "Link training failed\n"); } -static void ast_dp_set_on_off(struct ast_device *ast, bool on) +static bool __ast_dp_wait_enable(struct ast_device *ast, bool enabled) { - u8 video_on_off = on; - u32 i = 0; - - // Video On/Off - ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); - - video_on_off <<= 4; - while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, - ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) { - // wait 1 ms - mdelay(1); - if (++i > 200) - break; + u8 vgacrdf_test = 0x00; + u8 vgacrdf; + unsigned int i; + + if (enabled) + vgacrdf_test |= AST_IO_VGACRDF_DP_VIDEO_ENABLE; + + for (i = 0; i < 200; ++i) { + if (i) + mdelay(1); + vgacrdf = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xdf, + AST_IO_VGACRDF_DP_VIDEO_ENABLE); + if (vgacrdf == vgacrdf_test) + return true; } + + return false; +} + +static void ast_dp_set_enable(struct ast_device *ast, bool enabled) +{ + struct drm_device *dev = &ast->base; + u8 vgacre3 = 0x00; + + if (enabled) + vgacre3 |= AST_IO_VGACRE3_DP_VIDEO_ENABLE; + + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe3, (u8)~AST_IO_VGACRE3_DP_VIDEO_ENABLE, + vgacre3); + + drm_WARN_ON(dev, !__ast_dp_wait_enable(ast, enabled)); } static void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode) @@ -318,7 +335,7 @@ static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder, ast_dp_link_training(ast); ast_wait_for_vretrace(ast); - ast_dp_set_on_off(ast, 1); + ast_dp_set_enable(ast, true); } } @@ -327,7 +344,7 @@ static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder, { struct ast_device *ast = to_ast_device(encoder->dev); - ast_dp_set_on_off(ast, 0); + ast_dp_set_enable(ast, false); ast_dp_set_phy_sleep(ast, true); } diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index d7a22cea8271..6a1f756650ab 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -41,6 +41,8 @@ #define AST_IO_VGACRD7_EDID_VALID_FLAG BIT(0) #define AST_IO_VGACRDC_LINK_SUCCESS BIT(0) #define AST_IO_VGACRDF_HPD BIT(0) +#define AST_IO_VGACRDF_DP_VIDEO_ENABLE BIT(4) /* mirrors AST_IO_VGACRE3_DP_VIDEO_ENABLE */ +#define AST_IO_VGACRE3_DP_VIDEO_ENABLE BIT(0) #define AST_IO_VGACRE3_DP_PHY_SLEEP BIT(4) #define AST_IO_VGACRE5_EDID_READ_DONE BIT(0) @@ -69,17 +71,6 @@ * AST DisplayPort */ -/* Define for Soc scratched reg used on ASTDP */ -#define AST_DP_VIDEO_ENABLE BIT(0) - -/* - * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE - * Precondition: A. ~AST_DP_PHY_SLEEP && - * B. DP_HPD && - * C. DP_LINK_SUCCESS - */ -#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) - /* * ASTDP setmode registers: * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) -- GitLab From 0b3d4b6f86357c1599f94be657b8295507950676 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:23 +0200 Subject: [PATCH 204/970] drm/ast: dp501: Inline ast_dp501_connector_init() Inline ast_dp501_connector_init() into its only caller. The helper currently only does half of the connector-init work and is trivial enough to be inlined. Also set the local variables for encoder and connector as late as possible, so that the compiler warns if we use them before having initialized the instance. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-6-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp501.c | 43 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index 99bf44eec7b3..abb03d14c338 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -567,34 +567,22 @@ static const struct drm_connector_funcs ast_dp501_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector *connector) -{ - int ret; - - ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); - if (ret) - return ret; - - drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - - return 0; -} +/* + * Output + */ int ast_dp501_output_init(struct ast_device *ast) { struct drm_device *dev = &ast->base; struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.dp501.encoder; - struct ast_connector *ast_connector = &ast->output.dp501.connector; - struct drm_connector *connector = &ast_connector->base; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* encoder */ + + encoder = &ast->output.dp501.encoder; ret = drm_encoder_init(dev, encoder, &ast_dp501_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret) @@ -603,9 +591,20 @@ int ast_dp501_output_init(struct ast_device *ast) encoder->possible_crtcs = drm_crtc_mask(crtc); - ret = ast_dp501_connector_init(dev, connector); + /* connector */ + + ast_connector = &ast->output.dp501.connector; + connector = &ast_connector->base; + ret = drm_connector_init(dev, connector, &ast_dp501_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); if (ret) return ret; + drm_connector_helper_add(connector, &ast_dp501_connector_helper_funcs); + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); -- GitLab From 620824660ec89c691b763faa406d93fc591a34a9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:24 +0200 Subject: [PATCH 205/970] drm/ast: dp501: Avoid upcasting to struct ast_device Several functions receive an instance of struct drm_device only to upcast it to struct ast_device. Improve type safety by passing the AST device directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-7-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp501.c | 53 ++++++++++++++------------------- drivers/gpu/drm/ast/ast_drv.h | 4 +-- drivers/gpu/drm/ast/ast_main.c | 2 +- drivers/gpu/drm/ast/ast_post.c | 2 +- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index abb03d14c338..e5553334bfde 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -21,9 +21,9 @@ static void ast_release_firmware(void *data) ast->dp501_fw = NULL; } -static int ast_load_dp501_microcode(struct drm_device *dev) +static int ast_load_dp501_microcode(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; int ret; ret = request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev); @@ -109,10 +109,10 @@ static bool wait_fw_ready(struct ast_device *ast) } #endif -static bool ast_write_cmd(struct drm_device *dev, u8 data) +static bool ast_write_cmd(struct ast_device *ast, u8 data) { - struct ast_device *ast = to_ast_device(dev); int retry = 0; + if (wait_nack(ast)) { send_nack(ast); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); @@ -131,10 +131,8 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) return false; } -static bool ast_write_data(struct drm_device *dev, u8 data) +static bool ast_write_data(struct ast_device *ast, u8 data) { - struct ast_device *ast = to_ast_device(dev); - if (wait_nack(ast)) { send_nack(ast); ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); @@ -175,10 +173,10 @@ static void clear_cmd(struct ast_device *ast) } #endif -static void ast_set_dp501_video_output(struct drm_device *dev, u8 mode) +static void ast_set_dp501_video_output(struct ast_device *ast, u8 mode) { - ast_write_cmd(dev, 0x40); - ast_write_data(dev, mode); + ast_write_cmd(ast, 0x40); + ast_write_data(ast, mode); msleep(10); } @@ -188,9 +186,8 @@ static u32 get_fw_base(struct ast_device *ast) return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff; } -bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) +bool ast_backup_fw(struct ast_device *ast, u8 *addr, u32 size) { - struct ast_device *ast = to_ast_device(dev); u32 i, data; u32 boot_address; @@ -207,9 +204,8 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) return false; } -static bool ast_launch_m68k(struct drm_device *dev) +static bool ast_launch_m68k(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u32 i, data, len = 0; u32 boot_address; u8 *fw_addr = NULL; @@ -226,7 +222,7 @@ static bool ast_launch_m68k(struct drm_device *dev) len = 32*1024; } else { if (!ast->dp501_fw && - ast_load_dp501_microcode(dev) < 0) + ast_load_dp501_microcode(ast) < 0) return false; fw_addr = (u8 *)ast->dp501_fw->data; @@ -348,9 +344,8 @@ static int ast_dp512_read_edid_block(void *data, u8 *buf, unsigned int block, si return true; } -static bool ast_init_dvo(struct drm_device *dev) +static bool ast_init_dvo(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 jreg; u32 data; ast_write32(ast, 0xf004, 0x1e6e0000); @@ -421,9 +416,8 @@ static bool ast_init_dvo(struct drm_device *dev) } -static void ast_init_analog(struct drm_device *dev) +static void ast_init_analog(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u32 data; /* @@ -448,28 +442,27 @@ static void ast_init_analog(struct drm_device *dev) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00); } -void ast_init_3rdtx(struct drm_device *dev) +void ast_init_3rdtx(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 jreg; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg & 0x0e) { case 0x04: - ast_init_dvo(dev); + ast_init_dvo(ast); break; case 0x08: - ast_launch_m68k(dev); + ast_launch_m68k(ast); break; case 0x0c: - ast_init_dvo(dev); + ast_init_dvo(ast); break; default: if (ast->tx_chip == AST_TX_SIL164) - ast_init_dvo(dev); + ast_init_dvo(ast); else - ast_init_analog(dev); + ast_init_analog(ast); } } } @@ -485,17 +478,17 @@ static const struct drm_encoder_funcs ast_dp501_encoder_funcs = { static void ast_dp501_encoder_helper_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; + struct ast_device *ast = to_ast_device(encoder->dev); - ast_set_dp501_video_output(dev, 1); + ast_set_dp501_video_output(ast, 1); } static void ast_dp501_encoder_helper_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { - struct drm_device *dev = encoder->dev; + struct ast_device *ast = to_ast_device(encoder->dev); - ast_set_dp501_video_output(dev, 0); + ast_set_dp501_video_output(ast, 0); } static const struct drm_encoder_helper_funcs ast_dp501_encoder_helper_funcs = { diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index cafc4234e839..e29db59bb7d8 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -455,8 +455,8 @@ int ast_vga_output_init(struct ast_device *ast); int ast_sil164_output_init(struct ast_device *ast); /* ast dp501 */ -bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); -void ast_init_3rdtx(struct drm_device *dev); +bool ast_backup_fw(struct ast_device *ast, u8 *addr, u32 size); +void ast_init_3rdtx(struct ast_device *ast); int ast_dp501_output_init(struct ast_device *ast); /* aspeed DP */ diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index d7d503e78e25..3aeb0f4b19d5 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -110,7 +110,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL); if (ast->dp501_fw_addr) { /* backup firmware */ - if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) { + if (ast_backup_fw(ast, ast->dp501_fw_addr, 32*1024)) { drmm_kfree(dev, ast->dp501_fw_addr); ast->dp501_fw_addr = NULL; } diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 902bf8114b6e..324778c72d23 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -360,7 +360,7 @@ void ast_post_gpu(struct drm_device *dev) else ast_init_dram_reg(dev); - ast_init_3rdtx(dev); + ast_init_3rdtx(ast); } else { if (ast->tx_chip == AST_TX_SIL164) ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */ -- GitLab From 6fefb82efb6c55ec279cbae378e4e49dcc82006c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:25 +0200 Subject: [PATCH 206/970] drm/ast: sil164: Inline ast_sil164_connector_init() Inline ast_sil164_connector_init() into its only caller. The helper currently only does half of the connector-init work and is trivial enough to be inlined. While at it, remove the error message from the call to ast_ddc_create(). The function already warns on errors. Also set the local variables for encoder and connector as late as possible, so that the compiler warns if we use them before having initialized the instance. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-8-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_sil164.c | 55 +++++++++++++++----------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_sil164.c b/drivers/gpu/drm/ast/ast_sil164.c index 496c7120e515..6a72268d2314 100644 --- a/drivers/gpu/drm/ast/ast_sil164.c +++ b/drivers/gpu/drm/ast/ast_sil164.c @@ -71,52 +71,49 @@ static const struct drm_connector_funcs ast_sil164_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_sil164_connector_init(struct drm_device *dev, struct drm_connector *connector) +/* + * Output + */ + +int ast_sil164_output_init(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; + struct drm_crtc *crtc = &ast->crtc; struct i2c_adapter *ddc; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* DDC */ + ddc = ast_ddc_create(ast); - if (IS_ERR(ddc)) { - ret = PTR_ERR(ddc); - drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret); + if (IS_ERR(ddc)) + return PTR_ERR(ddc); + + /* encoder */ + + encoder = &ast->output.sil164.encoder; + ret = drm_encoder_init(dev, encoder, &ast_sil164_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + if (ret) return ret; - } + encoder->possible_crtcs = drm_crtc_mask(crtc); + + /* connector */ + ast_connector = &ast->output.sil164.connector; + connector = &ast_connector->base; ret = drm_connector_init_with_ddc(dev, connector, &ast_sil164_connector_funcs, DRM_MODE_CONNECTOR_DVII, ddc); if (ret) return ret; - drm_connector_helper_add(connector, &ast_sil164_connector_helper_funcs); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - return 0; -} - -int ast_sil164_output_init(struct ast_device *ast) -{ - struct drm_device *dev = &ast->base; - struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.sil164.encoder; - struct ast_connector *ast_connector = &ast->output.sil164.connector; - struct drm_connector *connector = &ast_connector->base; - int ret; - - ret = drm_encoder_init(dev, encoder, &ast_sil164_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); - if (ret) - return ret; - encoder->possible_crtcs = drm_crtc_mask(crtc); - - ret = ast_sil164_connector_init(dev, connector); - if (ret) - return ret; ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); -- GitLab From 197c441bfd267f9fe988934f69e2c529cd0f0a63 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:26 +0200 Subject: [PATCH 207/970] drm/ast: vga: Inline ast_vga_connector_init() Inline ast_vga_connector_init() into its only caller. The helper currently only does half of the connector-init work and is trivial enough to be inlined. While at it, remove the error message from the call to ast_ddc_create(). The function already warns on errors. Also set the local variables for encoder and connector as late as possible, so that the compiler warns if we use them before having initialized the instance. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-9-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_vga.c | 55 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_vga.c b/drivers/gpu/drm/ast/ast_vga.c index 3e815da43fbd..5c79b773af57 100644 --- a/drivers/gpu/drm/ast/ast_vga.c +++ b/drivers/gpu/drm/ast/ast_vga.c @@ -71,52 +71,49 @@ static const struct drm_connector_funcs ast_vga_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static int ast_vga_connector_init(struct drm_device *dev, struct drm_connector *connector) +/* + * Output + */ + +int ast_vga_output_init(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; + struct drm_crtc *crtc = &ast->crtc; struct i2c_adapter *ddc; + struct drm_encoder *encoder; + struct ast_connector *ast_connector; + struct drm_connector *connector; int ret; + /* DDC */ + ddc = ast_ddc_create(ast); - if (IS_ERR(ddc)) { - ret = PTR_ERR(ddc); - drm_err(dev, "failed to add DDC bus for connector; ret=%d\n", ret); + if (IS_ERR(ddc)) + return PTR_ERR(ddc); + + /* encoder */ + + encoder = &ast->output.vga.encoder; + ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs, + DRM_MODE_ENCODER_DAC, NULL); + if (ret) return ret; - } + encoder->possible_crtcs = drm_crtc_mask(crtc); + + /* connector */ + ast_connector = &ast->output.vga.connector; + connector = &ast_connector->base; ret = drm_connector_init_with_ddc(dev, connector, &ast_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA, ddc); if (ret) return ret; - drm_connector_helper_add(connector, &ast_vga_connector_helper_funcs); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - return 0; -} - -int ast_vga_output_init(struct ast_device *ast) -{ - struct drm_device *dev = &ast->base; - struct drm_crtc *crtc = &ast->crtc; - struct drm_encoder *encoder = &ast->output.vga.encoder; - struct ast_connector *ast_connector = &ast->output.vga.connector; - struct drm_connector *connector = &ast_connector->base; - int ret; - - ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs, - DRM_MODE_ENCODER_DAC, NULL); - if (ret) - return ret; - encoder->possible_crtcs = drm_crtc_mask(crtc); - - ret = ast_vga_connector_init(dev, connector); - if (ret) - return ret; ast_connector->physical_status = connector->status; ret = drm_connector_attach_encoder(connector, encoder); -- GitLab From 0994ea1b279eea7fc441e3fe17739aab9db919ef Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:27 +0200 Subject: [PATCH 208/970] drm/ast: Respect return value from CRTC init Return an error if CRTC initialization fails. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-10-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_mode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 784e8ac0e668..f90fade5d681 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1396,7 +1396,9 @@ int ast_mode_config_init(struct ast_device *ast) if (ret) return ret; - ast_crtc_init(dev); + ret = ast_crtc_init(dev); + if (ret) + return ret; switch (ast->tx_chip) { case AST_TX_NONE: -- GitLab From c1779a2346fe7d7ea8628e4062afbe6f0db113ed Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 11 Sep 2024 13:51:28 +0200 Subject: [PATCH 209/970] drm/ast: Avoid upcasting to struct ast_device Several functions receive an instance of struct drm_device only to upcast it to struct ast_device. Improve type safety by passing the AST device directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911115347.899148-11-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.c | 2 +- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_main.c | 8 ++++---- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- drivers/gpu/drm/ast/ast_post.c | 30 ++++++++++++------------------ 5 files changed, 21 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 225817087b4d..63b7ef02513d 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -396,7 +396,7 @@ static int ast_drm_thaw(struct drm_device *dev) ast_enable_vga(ast->ioregs); ast_open_key(ast->ioregs); ast_enable_mmio(dev->dev, ast->ioregs); - ast_post_gpu(dev); + ast_post_gpu(ast); return drm_mode_config_helper_resume(dev); } diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index e29db59bb7d8..21ce3769bf0d 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -446,7 +446,7 @@ int ast_mode_config_init(struct ast_device *ast); int ast_mm_init(struct ast_device *ast); /* ast post */ -void ast_post_gpu(struct drm_device *dev); +void ast_post_gpu(struct ast_device *ast); u32 ast_mindwm(struct ast_device *ast, u32 r); void ast_moutdwm(struct ast_device *ast, u32 r, u32 v); void ast_patch_ahb_2500(void __iomem *regs); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 3aeb0f4b19d5..3d92d9e5208f 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -132,10 +132,10 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) drm_info(dev, "Using %s\n", info_str[ast->tx_chip]); } -static int ast_get_dram_info(struct drm_device *dev) +static int ast_get_dram_info(struct ast_device *ast) { + struct drm_device *dev = &ast->base; struct device_node *np = dev->dev->of_node; - struct ast_device *ast = to_ast_device(dev); uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; uint32_t denum, num, div, ref_pll, dsel; @@ -277,7 +277,7 @@ struct drm_device *ast_device_create(struct pci_dev *pdev, ast_detect_widescreen(ast); ast_detect_tx_chip(ast, need_post); - ret = ast_get_dram_info(dev); + ret = ast_get_dram_info(ast); if (ret) return ERR_PTR(ret); @@ -285,7 +285,7 @@ struct drm_device *ast_device_create(struct pci_dev *pdev, ast->mclk, ast->dram_type, ast->dram_bus_width); if (need_post) - ast_post_gpu(dev); + ast_post_gpu(ast); ret = ast_mm_init(ast); if (ret) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index f90fade5d681..9d5321c81e68 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1287,9 +1287,9 @@ static const struct drm_crtc_funcs ast_crtc_funcs = { .atomic_destroy_state = ast_crtc_atomic_destroy_state, }; -static int ast_crtc_init(struct drm_device *dev) +static int ast_crtc_init(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; struct drm_crtc *crtc = &ast->crtc; int ret; @@ -1396,7 +1396,7 @@ int ast_mode_config_init(struct ast_device *ast) if (ret) return ret; - ret = ast_crtc_init(dev); + ret = ast_crtc_init(ast); if (ret) return ret; diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 324778c72d23..364030f97571 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -34,16 +34,14 @@ #include "ast_dram_tables.h" #include "ast_drv.h" -static void ast_post_chip_2300(struct drm_device *dev); -static void ast_post_chip_2500(struct drm_device *dev); +static void ast_post_chip_2300(struct ast_device *ast); +static void ast_post_chip_2500(struct ast_device *ast); static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff }; -static void -ast_set_def_ext_reg(struct drm_device *dev) +static void ast_set_def_ext_reg(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 i, index, reg; const u8 *ext_reg_info; @@ -252,9 +250,8 @@ static void cbrdlli_ast2150(struct ast_device *ast, int busw) -static void ast_init_dram_reg(struct drm_device *dev) +static void ast_init_dram_reg(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); u8 j; u32 data, temp, i; const struct ast_dramstruct *dram_reg_info; @@ -343,22 +340,20 @@ static void ast_init_dram_reg(struct drm_device *dev) } while ((j & 0x40) == 0); } -void ast_post_gpu(struct drm_device *dev) +void ast_post_gpu(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); - - ast_set_def_ext_reg(dev); + ast_set_def_ext_reg(ast); if (IS_AST_GEN7(ast)) { if (ast->tx_chip == AST_TX_ASTDP) ast_dp_launch(ast); } else if (ast->config_mode == ast_use_p2a) { if (IS_AST_GEN6(ast)) - ast_post_chip_2500(dev); + ast_post_chip_2500(ast); else if (IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) - ast_post_chip_2300(dev); + ast_post_chip_2300(ast); else - ast_init_dram_reg(dev); + ast_init_dram_reg(ast); ast_init_3rdtx(ast); } else { @@ -1569,9 +1564,8 @@ static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param) } -static void ast_post_chip_2300(struct drm_device *dev) +static void ast_post_chip_2300(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); struct ast2300_dram_param param; u32 temp; u8 reg; @@ -2038,9 +2032,9 @@ void ast_patch_ahb_2500(void __iomem *regs) __ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */ } -void ast_post_chip_2500(struct drm_device *dev) +void ast_post_chip_2500(struct ast_device *ast) { - struct ast_device *ast = to_ast_device(dev); + struct drm_device *dev = &ast->base; u32 temp; u8 reg; -- GitLab From 9ba0e0f30ca42a98af3689460063edfb6315718a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= <jose.souza@intel.com> Date: Thu, 12 Sep 2024 08:38:42 -0700 Subject: [PATCH 210/970] drm/xe/oa: Fix overflow in oa batch buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default xe_bb_create_job() appends a MI_BATCH_BUFFER_END to batch buffer, this is not a problem if batch buffer is only used once but oa reuses the batch buffer for the same metric and at each call it appends a MI_BATCH_BUFFER_END, printing the warning below and then overflowing. [ 381.072016] ------------[ cut here ]------------ [ 381.072019] xe 0000:00:02.0: [drm] Assertion `bb->len * 4 + bb_prefetch(q->gt) <= size` failed! platform: LUNARLAKE subplatform: 1 graphics: Xe2_LPG / Xe2_HPG 20.04 step B0 media: Xe2_LPM / Xe2_HPM 20.00 step B0 tile: 0 VRAM 0 B GT: 0 type 1 So here checking if batch buffer already have MI_BATCH_BUFFER_END if not append it. v2: - simply fix, suggestion from Ashutosh Cc: Ashutosh Dixit <ashutosh.dixit@intel.com> Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912153842.35813-1-jose.souza@intel.com --- drivers/gpu/drm/xe/xe_bb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_bb.c b/drivers/gpu/drm/xe/xe_bb.c index a13e0b3a169e..ef777dbdf4ec 100644 --- a/drivers/gpu/drm/xe/xe_bb.c +++ b/drivers/gpu/drm/xe/xe_bb.c @@ -65,7 +65,8 @@ __xe_bb_create_job(struct xe_exec_queue *q, struct xe_bb *bb, u64 *addr) { u32 size = drm_suballoc_size(bb->bo); - bb->cs[bb->len++] = MI_BATCH_BUFFER_END; + if (bb->len == 0 || bb->cs[bb->len - 1] != MI_BATCH_BUFFER_END) + bb->cs[bb->len++] = MI_BATCH_BUFFER_END; xe_gt_assert(q->gt, bb->len * 4 + bb_prefetch(q->gt) <= size); -- GitLab From ef77507bc849dea5cd6d216614f58763bd19ff4c Mon Sep 17 00:00:00 2001 From: Longlong Xia <xialonglong@kylinos.cn> Date: Mon, 19 Aug 2024 17:58:16 +0800 Subject: [PATCH 211/970] accel/qaic: Change to use DEFINE_SHOW_ATTRIBUTE macro Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code. No functional change. Signed-off-by: Longlong Xia <xialonglong@kylinos.cn> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240819095816.447096-1-xialonglong@kylinos.cn --- drivers/accel/qaic/qaic_debugfs.c | 43 ++++--------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) diff --git a/drivers/accel/qaic/qaic_debugfs.c b/drivers/accel/qaic/qaic_debugfs.c index 20b653d99e52..ba0cf2f94732 100644 --- a/drivers/accel/qaic/qaic_debugfs.c +++ b/drivers/accel/qaic/qaic_debugfs.c @@ -64,20 +64,9 @@ static int bootlog_show(struct seq_file *s, void *unused) return 0; } -static int bootlog_fops_open(struct inode *inode, struct file *file) -{ - return single_open(file, bootlog_show, inode->i_private); -} - -static const struct file_operations bootlog_fops = { - .owner = THIS_MODULE, - .open = bootlog_fops_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(bootlog); -static int read_dbc_fifo_size(struct seq_file *s, void *unused) +static int fifo_size_show(struct seq_file *s, void *unused) { struct dma_bridge_chan *dbc = s->private; @@ -85,20 +74,9 @@ static int read_dbc_fifo_size(struct seq_file *s, void *unused) return 0; } -static int fifo_size_open(struct inode *inode, struct file *file) -{ - return single_open(file, read_dbc_fifo_size, inode->i_private); -} - -static const struct file_operations fifo_size_fops = { - .owner = THIS_MODULE, - .open = fifo_size_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(fifo_size); -static int read_dbc_queued(struct seq_file *s, void *unused) +static int queued_show(struct seq_file *s, void *unused) { struct dma_bridge_chan *dbc = s->private; u32 tail = 0, head = 0; @@ -115,18 +93,7 @@ static int read_dbc_queued(struct seq_file *s, void *unused) return 0; } -static int queued_open(struct inode *inode, struct file *file) -{ - return single_open(file, read_dbc_queued, inode->i_private); -} - -static const struct file_operations queued_fops = { - .owner = THIS_MODULE, - .open = queued_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(queued); void qaic_debugfs_init(struct qaic_drm_device *qddev) { -- GitLab From cdb389a4c9bc2faea866b517afc3aa3faef46022 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com> Date: Fri, 13 Sep 2024 14:02:54 +0800 Subject: [PATCH 212/970] drm/xe/irq: Remove unneeded semicolon Remove unnecessary semicolon in pick_engine_gt(). Reported-by: Abaci Robot <abaci@linux.alibaba.com> Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=8757 Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240913060254.26678-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 07577b418205..e501002e8a04 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -280,7 +280,7 @@ static struct xe_gt *pick_engine_gt(struct xe_tile *tile, return tile->media_gt; default: break; - }; + } fallthrough; default: return tile->primary_gt; -- GitLab From d92b90f9a54d9300a6e883258e79f36dab53bfae Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Tue, 27 Aug 2024 12:45:23 +0200 Subject: [PATCH 213/970] drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real VLA Replace the fake VLA at end of the vbva_mouse_pointer_shape shape with a real VLA to fix a "memcpy: detected field-spanning write error" warning: [ 13.319813] memcpy: detected field-spanning write (size 16896) of single field "p->data" at drivers/gpu/drm/vboxvideo/hgsmi_base.c:154 (size 4) [ 13.319841] WARNING: CPU: 0 PID: 1105 at drivers/gpu/drm/vboxvideo/hgsmi_base.c:154 hgsmi_update_pointer_shape+0x192/0x1c0 [vboxvideo] [ 13.320038] Call Trace: [ 13.320173] hgsmi_update_pointer_shape [vboxvideo] [ 13.320184] vbox_cursor_atomic_update [vboxvideo] Note as mentioned in the added comment it seems the original length calculation for the allocated and send hgsmi buffer is 4 bytes too large. Changing this is not the goal of this patch, so this behavior is kept. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240827104523.17442-1-hdegoede@redhat.com --- drivers/gpu/drm/vboxvideo/hgsmi_base.c | 10 +++++++++- drivers/gpu/drm/vboxvideo/vboxvideo.h | 4 +--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/hgsmi_base.c b/drivers/gpu/drm/vboxvideo/hgsmi_base.c index 8c041d7ce4f1..87dccaecc3e5 100644 --- a/drivers/gpu/drm/vboxvideo/hgsmi_base.c +++ b/drivers/gpu/drm/vboxvideo/hgsmi_base.c @@ -139,7 +139,15 @@ int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags, flags |= VBOX_MOUSE_POINTER_VISIBLE; } - p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA, + /* + * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape + * from having a 4 bytes fixed array at the end to using a proper VLA + * at the end. These 4 extra bytes were not subtracted from sizeof(*p) + * before the switch to the VLA, so this way the behavior is unchanged. + * Chances are these 4 extra bytes are not necessary but they are kept + * to avoid regressions. + */ + p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA, VBVA_MOUSE_POINTER_SHAPE); if (!p) return -ENOMEM; diff --git a/drivers/gpu/drm/vboxvideo/vboxvideo.h b/drivers/gpu/drm/vboxvideo/vboxvideo.h index f60d82504da0..79ec8481de0e 100644 --- a/drivers/gpu/drm/vboxvideo/vboxvideo.h +++ b/drivers/gpu/drm/vboxvideo/vboxvideo.h @@ -351,10 +351,8 @@ struct vbva_mouse_pointer_shape { * Bytes in the gap between the AND and the XOR mask are undefined. * XOR mask scanlines have no gap between them and size of XOR mask is: * xor_len = width * 4 * height. - * - * Preallocate 4 bytes for accessing actual data as p->data. */ - u8 data[4]; + u8 data[]; } __packed; /* pointer is visible */ -- GitLab From a88fee2d67d9b78c24630a987a88ccf886b2498b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Date: Tue, 6 Aug 2024 16:50:27 +0300 Subject: [PATCH 214/970] drm/omap: Fix possible NULL dereference smatch reports: drivers/gpu/drm/omapdrm/dss/base.c:176 omapdss_device_disconnect() error: we previously assumed 'src' could be null (see line 169) This code is mostly from a time when omapdrm had its own display device model. I can't honestly remember the details, and I don't think it's worth digging in deeply into that for a legacy driver. However, it looks like we only call omapdss_device_disconnect() and omapdss_device_connect() with NULL as the src parameter. We can thus drop the src parameter from both functions, and fix the smatch warning. I don't think omapdss_device_disconnect() ever gets NULL for the dst parameter (if it did, we'd crash soon after returning from the function), but I have kept the !dst check, just in case, but I added a WARN_ON() there. Also, if the dst parameter can be NULL, we can't always get the struct dss_device pointer from dst->dss (which is only used for a debug print). To make sure we can't hit that issue, do it similarly to the omapdss_device_connect() function: add 'struct dss_device *dss' as the first parameter, so that we always have it regardless of the dst. Fixes: 79107f274b2f ("drm/omap: Add support for drm_bridge") Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240806-omapdrm-misc-fixes-v1-1-15d31aea0831@ideasonboard.com --- drivers/gpu/drm/omapdrm/dss/base.c | 25 ++++++------------------- drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 +-- drivers/gpu/drm/omapdrm/omap_drv.c | 4 ++-- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 5f8002f6bb7a..a4ac113e1690 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -139,21 +139,13 @@ static bool omapdss_device_is_connected(struct omap_dss_device *dssdev) } int omapdss_device_connect(struct dss_device *dss, - struct omap_dss_device *src, struct omap_dss_device *dst) { - dev_dbg(&dss->pdev->dev, "connect(%s, %s)\n", - src ? dev_name(src->dev) : "NULL", + dev_dbg(&dss->pdev->dev, "connect(%s)\n", dst ? dev_name(dst->dev) : "NULL"); - if (!dst) { - /* - * The destination is NULL when the source is connected to a - * bridge instead of a DSS device. Stop here, we will attach - * the bridge later when we will have a DRM encoder. - */ - return src && src->bridge ? 0 : -EINVAL; - } + if (!dst) + return -EINVAL; if (omapdss_device_is_connected(dst)) return -EBUSY; @@ -163,19 +155,14 @@ int omapdss_device_connect(struct dss_device *dss, return 0; } -void omapdss_device_disconnect(struct omap_dss_device *src, +void omapdss_device_disconnect(struct dss_device *dss, struct omap_dss_device *dst) { - struct dss_device *dss = src ? src->dss : dst->dss; - - dev_dbg(&dss->pdev->dev, "disconnect(%s, %s)\n", - src ? dev_name(src->dev) : "NULL", + dev_dbg(&dss->pdev->dev, "disconnect(%s)\n", dst ? dev_name(dst->dev) : "NULL"); - if (!dst) { - WARN_ON(!src->bridge); + if (WARN_ON(!dst)) return; - } if (!dst->id && !omapdss_device_is_connected(dst)) { WARN_ON(1); diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 040d5a3e33d6..4c22c09c93d5 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -242,9 +242,8 @@ struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev); void omapdss_device_put(struct omap_dss_device *dssdev); struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node); int omapdss_device_connect(struct dss_device *dss, - struct omap_dss_device *src, struct omap_dss_device *dst); -void omapdss_device_disconnect(struct omap_dss_device *src, +void omapdss_device_disconnect(struct dss_device *dss, struct omap_dss_device *dst); int omap_dss_get_num_overlay_managers(void); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index d3eac4817d76..a982378aa141 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -307,7 +307,7 @@ static void omap_disconnect_pipelines(struct drm_device *ddev) for (i = 0; i < priv->num_pipes; i++) { struct omap_drm_pipeline *pipe = &priv->pipes[i]; - omapdss_device_disconnect(NULL, pipe->output); + omapdss_device_disconnect(priv->dss, pipe->output); omapdss_device_put(pipe->output); pipe->output = NULL; @@ -325,7 +325,7 @@ static int omap_connect_pipelines(struct drm_device *ddev) int r; for_each_dss_output(output) { - r = omapdss_device_connect(priv->dss, NULL, output); + r = omapdss_device_connect(priv->dss, output); if (r == -EPROBE_DEFER) { omapdss_device_put(output); return r; -- GitLab From 0d76cb1148f3a65f62a18c3fe632f6cd3c2c5871 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Date: Tue, 6 Aug 2024 16:50:28 +0300 Subject: [PATCH 215/970] drm/omap: Hide sparse warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sparse reports: drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:122:16: warning: incorrect type in argument 1 (different address spaces) drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:122:16: expected void const volatile [noderef] __iomem *addr drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:122:16: got unsigned int [usertype] *wa_dma_data drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:130:9: warning: incorrect type in argument 2 (different address spaces) drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:130:9: expected void volatile [noderef] __iomem *addr drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:130:9: got unsigned int [usertype] *wa_dma_data drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:414:9: warning: incorrect type in argument 1 (different address spaces) drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:414:9: expected void const volatile [noderef] __iomem *addr drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:414:9: got unsigned int * These come from pieces of code which do essentially: p = dma_alloc_coherent() dma_transfer_to_p() readl(p) writel(x, p) dma_transfer_from_p() I think we would do just fine without readl() and writel(), accessing the memory without any extras, but ensuring that the necessary barriers are in place. But this code is for a legacy platform, has been working for ages, and it's doing work-arounds for hardware issues, and those hardware issues are very difficult to trigger... So I would just rather leave the code be as it is now. However, the warnings are not nice. Hide the warnings by a (__iomem void *) typecast. Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202407311737.VsJ0Sr1w-lkp@intel.com/ Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240806-omapdrm-misc-fixes-v1-2-15d31aea0831@ideasonboard.com --- drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index 1aca3060333e..fcd600024136 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c @@ -119,7 +119,7 @@ static u32 dmm_read_wa(struct dmm *dmm, u32 reg) * earlier than the DMA finished writing the value to memory. */ rmb(); - return readl(dmm->wa_dma_data); + return readl((__iomem void *)dmm->wa_dma_data); } static void dmm_write_wa(struct dmm *dmm, u32 val, u32 reg) @@ -127,7 +127,7 @@ static void dmm_write_wa(struct dmm *dmm, u32 val, u32 reg) dma_addr_t src, dst; int r; - writel(val, dmm->wa_dma_data); + writel(val, (__iomem void *)dmm->wa_dma_data); /* * As per i878 workaround, the DMA is used to access the DMM registers. * Make sure that the writel is not moved by the compiler or the CPU, so @@ -411,7 +411,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) */ /* read back to ensure the data is in RAM */ - readl(&txn->last_pat->next_pa); + readl((__iomem void *)&txn->last_pat->next_pa); /* write to PAT_DESCR to clear out any pending transaction */ dmm_write(dmm, 0x0, reg[PAT_DESCR][engine->id]); -- GitLab From e6a1c4037227539373c8cf484ace83833e2ad6a2 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Date: Tue, 6 Aug 2024 16:50:29 +0300 Subject: [PATCH 216/970] drm/omap: Fix locking in omap_gem_new_dmabuf() omap_gem_new_dmabuf() creates the new gem object, and then takes and holds the omap_obj->lock for the rest of the function. This has two issues: - omap_gem_free_object(), which is called in the error paths, also takes the same lock, leading to deadlock - Even if the above wouldn't happen, in the error cases omap_gem_new_dmabuf() still unlocks omap_obj->lock, even after the omap_obj has already been freed. Furthermore, I don't think there's any reason to take the lock at all, as the object was just created and not yet shared with anyone else. To fix all this, drop taking the lock. Fixes: 3cbd0c587b12 ("drm/omap: gem: Replace struct_mutex usage with omap_obj private lock") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/all/511b99d7-aade-4f92-bd3e-63163a13d617@stanley.mountain/ Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240806-omapdrm-misc-fixes-v1-3-15d31aea0831@ideasonboard.com --- drivers/gpu/drm/omapdrm/omap_gem.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index fdae677558f3..b9c67e4ca360 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1402,8 +1402,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, omap_obj = to_omap_bo(obj); - mutex_lock(&omap_obj->lock); - omap_obj->sgt = sgt; if (omap_gem_sgt_is_contiguous(sgt, size)) { @@ -1418,21 +1416,17 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); if (!pages) { omap_gem_free_object(obj); - obj = ERR_PTR(-ENOMEM); - goto done; + return ERR_PTR(-ENOMEM); } omap_obj->pages = pages; ret = drm_prime_sg_to_page_array(sgt, pages, npages); if (ret) { omap_gem_free_object(obj); - obj = ERR_PTR(-ENOMEM); - goto done; + return ERR_PTR(-ENOMEM); } } -done: - mutex_unlock(&omap_obj->lock); return obj; } -- GitLab From f70181b3bdec6b8a166c6295937c4a8a5322515c Mon Sep 17 00:00:00 2001 From: Tejas Vipin <tejasvipin76@gmail.com> Date: Sat, 14 Sep 2024 09:13:41 +0530 Subject: [PATCH 217/970] drm/panel: raydium-rm69380: transition to mipi_dsi wrapped functions Changes the raydium-rm69380 panel to use multi style functions for improved error handling. Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Tejas Vipin <tejasvipin76@gmail.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240914034341.897197-1-tejasvipin76@gmail.com --- drivers/gpu/drm/panel/panel-raydium-rm69380.c | 93 ++++++------------- 1 file changed, 29 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-raydium-rm69380.c b/drivers/gpu/drm/panel/panel-raydium-rm69380.c index 4dca6802faef..d3071c01aaea 100644 --- a/drivers/gpu/drm/panel/panel-raydium-rm69380.c +++ b/drivers/gpu/drm/panel/panel-raydium-rm69380.c @@ -46,108 +46,73 @@ static void rm69380_reset(struct rm69380_panel *ctx) static int rm69380_on(struct rm69380_panel *ctx) { struct mipi_dsi_device *dsi = ctx->dsi[0]; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags |= MIPI_DSI_MODE_LPM; if (ctx->dsi[1]) ctx->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM; - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd4); - mipi_dsi_dcs_write_seq(dsi, 0x00, 0x80); - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0xd0); - mipi_dsi_dcs_write_seq(dsi, 0x48, 0x00); - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x26); - mipi_dsi_dcs_write_seq(dsi, 0x75, 0x3f); - mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1a); - mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00); - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x28); - mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x08); - - ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - if (ret < 0) { - dev_err(dev, "Failed to set tear on: %d\n", ret); - return ret; - } - - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to exit sleep mode: %d\n", ret); - return ret; - } - msleep(20); - - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display on: %d\n", ret); - return ret; - } - msleep(36); - - return 0; + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd4); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x80); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0xd0); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x26); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x3f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x1a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x28); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc2, 0x08); + + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 36); + + return dsi_ctx.accum_err; } -static int rm69380_off(struct rm69380_panel *ctx) +static void rm69380_off(struct rm69380_panel *ctx) { struct mipi_dsi_device *dsi = ctx->dsi[0]; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; if (ctx->dsi[1]) ctx->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM; - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); - return ret; - } - msleep(35); - - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); - return ret; - } - msleep(20); - - return 0; + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 35); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); } static int rm69380_prepare(struct drm_panel *panel) { struct rm69380_panel *ctx = to_rm69380_panel(panel); - struct device *dev = &ctx->dsi[0]->dev; int ret; ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators: %d\n", ret); + if (ret < 0) return ret; - } rm69380_reset(ctx); ret = rm69380_on(ctx); if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); gpiod_set_value_cansleep(ctx->reset_gpio, 1); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - return ret; } - return 0; + return ret; } static int rm69380_unprepare(struct drm_panel *panel) { struct rm69380_panel *ctx = to_rm69380_panel(panel); - struct device *dev = &ctx->dsi[0]->dev; - int ret; - ret = rm69380_off(ctx); - if (ret < 0) - dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + rm69380_off(ctx); gpiod_set_value_cansleep(ctx->reset_gpio, 1); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); -- GitLab From 02fdf821ed79f59c40d766a85947aa7cc25d4364 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 12 Sep 2024 22:38:12 +0200 Subject: [PATCH 218/970] drm/xe/guc: Fix GUC_{SUBMIT,FIRMWARE}_VER helper macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those macros rely on non-existing MAKE_VER_STRUCT macro, while the correct one that should be used is named MAKE_GUC_VER_STRUCT. Fixes: 4eb0aab6e443 ("drm/xe/guc: Bump minimum required GuC version to v70.29.2") Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Julia Filipchuk <julia.filipchuk@intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912203817.1880-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_guc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc.h b/drivers/gpu/drm/xe/xe_guc.h index c3e6b51f7a09..42116b167c98 100644 --- a/drivers/gpu/drm/xe/xe_guc.h +++ b/drivers/gpu/drm/xe/xe_guc.h @@ -18,8 +18,10 @@ */ #define MAKE_GUC_VER(maj, min, pat) (((maj) << 16) | ((min) << 8) | (pat)) #define MAKE_GUC_VER_STRUCT(ver) MAKE_GUC_VER((ver).major, (ver).minor, (ver).patch) -#define GUC_SUBMIT_VER(guc) MAKE_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_COMPATIBILITY]) -#define GUC_FIRMWARE_VER(guc) MAKE_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_RELEASE]) +#define GUC_SUBMIT_VER(guc) \ + MAKE_GUC_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_COMPATIBILITY]) +#define GUC_FIRMWARE_VER(guc) \ + MAKE_GUC_VER_STRUCT((guc)->fw.versions.found[XE_UC_FW_VER_RELEASE]) struct drm_printer; -- GitLab From 804ce41f66e22d20751dd98e696ae3e0a958e4ac Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 12 Sep 2024 22:38:13 +0200 Subject: [PATCH 219/970] drm/xe/guc: Add PF2GUC_SAVE_RESTORE_VF to ABI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In upcoming patches we will add support to the PF driver to save and restore a VF state maintained by the GuC to allow VF migration. Add necessary H2G definitions to our GuC firmware ABI header. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Cc: Tomasz Lis <tomasz.lis@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912203817.1880-3-michal.wajdeczko@intel.com --- .../gpu/drm/xe/abi/guc_actions_sriov_abi.h | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/gpu/drm/xe/abi/guc_actions_sriov_abi.h b/drivers/gpu/drm/xe/abi/guc_actions_sriov_abi.h index 181180f5945c..b6a1852749dd 100644 --- a/drivers/gpu/drm/xe/abi/guc_actions_sriov_abi.h +++ b/drivers/gpu/drm/xe/abi/guc_actions_sriov_abi.h @@ -557,4 +557,65 @@ #define VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_2_VALUE64 GUC_HXG_REQUEST_MSG_n_DATAn #define VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_3_VALUE96 GUC_HXG_REQUEST_MSG_n_DATAn +/** + * DOC: PF2GUC_SAVE_RESTORE_VF + * + * This message is used by the PF to migrate VF info state maintained by the GuC. + * + * This message must be sent as `CTB HXG Message`_. + * + * Available since GuC version 70.25.0 + * + * +---+-------+--------------------------------------------------------------+ + * | | Bits | Description | + * +===+=======+==============================================================+ + * | 0 | 31 | ORIGIN = GUC_HXG_ORIGIN_HOST_ | + * | +-------+--------------------------------------------------------------+ + * | | 30:28 | TYPE = GUC_HXG_TYPE_REQUEST_ | + * | +-------+--------------------------------------------------------------+ + * | | 27:16 | DATA0 = **OPCODE** - operation to take: | + * | | | | + * | | | - _`GUC_PF_OPCODE_VF_SAVE` = 0 | + * | | | - _`GUC_PF_OPCODE_VF_RESTORE` = 1 | + * | +-------+--------------------------------------------------------------+ + * | | 15:0 | ACTION = _`GUC_ACTION_PF2GUC_SAVE_RESTORE_VF` = 0x550B | + * +---+-------+--------------------------------------------------------------+ + * | 1 | 31:0 | **VFID** - VF identifier | + * +---+-------+--------------------------------------------------------------+ + * | 2 | 31:0 | **ADDR_LO** - lower 32-bits of GGTT offset to the buffer | + * | | | where the VF info will be save to or restored from. | + * +---+-------+--------------------------------------------------------------+ + * | 3 | 31:0 | **ADDR_HI** - upper 32-bits of GGTT offset to the buffer | + * | | | where the VF info will be save to or restored from. | + * +---+-------+--------------------------------------------------------------+ + * | 4 | 27:0 | **SIZE** - size of the buffer (in dwords) | + * | +-------+--------------------------------------------------------------+ + * | | 31:28 | MBZ | + * +---+-------+--------------------------------------------------------------+ + * + * +---+-------+--------------------------------------------------------------+ + * | | Bits | Description | + * +===+=======+==============================================================+ + * | 0 | 31 | ORIGIN = GUC_HXG_ORIGIN_GUC_ | + * | +-------+--------------------------------------------------------------+ + * | | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_ | + * | +-------+--------------------------------------------------------------+ + * | | 27:0 | DATA0 = **USED** - size of used buffer space (in dwords) | + * +---+-------+--------------------------------------------------------------+ + */ +#define GUC_ACTION_PF2GUC_SAVE_RESTORE_VF 0x550Bu + +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_LEN (GUC_HXG_EVENT_MSG_MIN_LEN + 4u) +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_0_OPCODE GUC_HXG_EVENT_MSG_0_DATA0 +#define GUC_PF_OPCODE_VF_SAVE 0u +#define GUC_PF_OPCODE_VF_RESTORE 1u +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_1_VFID GUC_HXG_EVENT_MSG_n_DATAn +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_2_ADDR_LO GUC_HXG_EVENT_MSG_n_DATAn +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_3_ADDR_HI GUC_HXG_EVENT_MSG_n_DATAn +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_4_SIZE (0xfffffffu << 0) +#define PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_4_MBZ (0xfu << 28) + +#define PF2GUC_SAVE_RESTORE_VF_RESPONSE_MSG_LEN GUC_HXG_RESPONSE_MSG_MIN_LEN +#define PF2GUC_SAVE_RESTORE_VF_RESPONSE_MSG_0_USED GUC_HXG_RESPONSE_MSG_0_DATA0 + #endif -- GitLab From d86e3737c7ab907690c20bcde7c1f78f42fce6c2 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Fri, 13 Sep 2024 14:00:13 +0200 Subject: [PATCH 220/970] drm/xe/pf: Add functions to save and restore VF GuC state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To successfully migrate a VM with attached GPU VF we also need to migrate VF's GuC state. Add necessary functions that interacts with GuC to save and restore a VF GuC state. We will start using them in upcoming patches. Since VF migration requires many more changes in the driver, enable those functions only under debug config. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Cc: Tomasz Lis <tomasz.lis@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240913120013.1924-1-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 2 + drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c | 334 ++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h | 17 + .../drm/xe/xe_gt_sriov_pf_migration_types.h | 40 +++ drivers/gpu/drm/xe/xe_gt_sriov_pf_types.h | 6 + 6 files changed, 400 insertions(+) create mode 100644 drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c create mode 100644 drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h create mode 100644 drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index edfd812e0f41..8f1c5c329f79 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -129,6 +129,7 @@ xe-$(CONFIG_PCI_IOV) += \ xe_gt_sriov_pf.o \ xe_gt_sriov_pf_config.o \ xe_gt_sriov_pf_control.o \ + xe_gt_sriov_pf_migration.o \ xe_gt_sriov_pf_monitor.o \ xe_gt_sriov_pf_policy.o \ xe_gt_sriov_pf_service.o \ diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c index 065a9878f8e9..e71fc3d2bda2 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c @@ -13,6 +13,7 @@ #include "xe_gt_sriov_pf_config.h" #include "xe_gt_sriov_pf_control.h" #include "xe_gt_sriov_pf_helpers.h" +#include "xe_gt_sriov_pf_migration.h" #include "xe_gt_sriov_pf_service.h" #include "xe_mmio.h" @@ -89,6 +90,7 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt) pf_enable_ggtt_guest_update(gt); xe_gt_sriov_pf_service_update(gt); + xe_gt_sriov_pf_migration_init(gt); } static u32 pf_get_vf_regs_stride(struct xe_device *xe) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c new file mode 100644 index 000000000000..b7188fa6ac07 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2024 Intel Corporation + */ + +#include <drm/drm_managed.h> + +#include "abi/guc_actions_sriov_abi.h" +#include "xe_bo.h" +#include "xe_gt_sriov_pf_helpers.h" +#include "xe_gt_sriov_pf_migration.h" +#include "xe_gt_sriov_printk.h" +#include "xe_guc.h" +#include "xe_guc_ct.h" +#include "xe_sriov.h" + +/* Return: number of dwords saved/restored/required or a negative error code on failure */ +static int guc_action_vf_save_restore(struct xe_guc *guc, u32 vfid, u32 opcode, + u64 addr, u32 ndwords) +{ + u32 request[PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_LEN] = { + FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | + FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) | + FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_PF2GUC_SAVE_RESTORE_VF) | + FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_0_OPCODE, opcode), + FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_1_VFID, vfid), + FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_2_ADDR_LO, lower_32_bits(addr)), + FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_3_ADDR_HI, upper_32_bits(addr)), + FIELD_PREP(PF2GUC_SAVE_RESTORE_VF_REQUEST_MSG_4_SIZE, ndwords), + }; + + return xe_guc_ct_send_block(&guc->ct, request, ARRAY_SIZE(request)); +} + +/* Return: size of the state in dwords or a negative error code on failure */ +static int pf_send_guc_query_vf_state_size(struct xe_gt *gt, unsigned int vfid) +{ + int ret; + + ret = guc_action_vf_save_restore(>->uc.guc, vfid, GUC_PF_OPCODE_VF_SAVE, 0, 0); + return ret ?: -ENODATA; +} + +/* Return: number of state dwords saved or a negative error code on failure */ +static int pf_send_guc_save_vf_state(struct xe_gt *gt, unsigned int vfid, + void *buff, size_t size) +{ + const int ndwords = size / sizeof(u32); + struct xe_tile *tile = gt_to_tile(gt); + struct xe_device *xe = tile_to_xe(tile); + struct xe_guc *guc = >->uc.guc; + struct xe_bo *bo; + int ret; + + xe_gt_assert(gt, size % sizeof(u32) == 0); + xe_gt_assert(gt, size == ndwords * sizeof(u32)); + + bo = xe_bo_create_pin_map(xe, tile, NULL, + ALIGN(size, PAGE_SIZE), + ttm_bo_type_kernel, + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_GGTT | + XE_BO_FLAG_GGTT_INVALIDATE); + if (IS_ERR(bo)) + return PTR_ERR(bo); + + ret = guc_action_vf_save_restore(guc, vfid, GUC_PF_OPCODE_VF_SAVE, + xe_bo_ggtt_addr(bo), ndwords); + if (!ret) + ret = -ENODATA; + else if (ret > ndwords) + ret = -EPROTO; + else if (ret > 0) + xe_map_memcpy_from(xe, buff, &bo->vmap, 0, ret * sizeof(u32)); + + xe_bo_unpin_map_no_vm(bo); + return ret; +} + +/* Return: number of state dwords restored or a negative error code on failure */ +static int pf_send_guc_restore_vf_state(struct xe_gt *gt, unsigned int vfid, + const void *buff, size_t size) +{ + const int ndwords = size / sizeof(u32); + struct xe_tile *tile = gt_to_tile(gt); + struct xe_device *xe = tile_to_xe(tile); + struct xe_guc *guc = >->uc.guc; + struct xe_bo *bo; + int ret; + + xe_gt_assert(gt, size % sizeof(u32) == 0); + xe_gt_assert(gt, size == ndwords * sizeof(u32)); + + bo = xe_bo_create_pin_map(xe, tile, NULL, + ALIGN(size, PAGE_SIZE), + ttm_bo_type_kernel, + XE_BO_FLAG_SYSTEM | + XE_BO_FLAG_GGTT | + XE_BO_FLAG_GGTT_INVALIDATE); + if (IS_ERR(bo)) + return PTR_ERR(bo); + + xe_map_memcpy_to(xe, &bo->vmap, 0, buff, size); + + ret = guc_action_vf_save_restore(guc, vfid, GUC_PF_OPCODE_VF_RESTORE, + xe_bo_ggtt_addr(bo), ndwords); + if (!ret) + ret = -ENODATA; + else if (ret > ndwords) + ret = -EPROTO; + + xe_bo_unpin_map_no_vm(bo); + return ret; +} + +static bool pf_migration_supported(struct xe_gt *gt) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + return gt->sriov.pf.migration.supported; +} + +static struct mutex *pf_migration_mutex(struct xe_gt *gt) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + return >->sriov.pf.migration.snapshot_lock; +} + +static struct xe_gt_sriov_state_snapshot *pf_pick_vf_snapshot(struct xe_gt *gt, + unsigned int vfid) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + lockdep_assert_held(pf_migration_mutex(gt)); + + return >->sriov.pf.vfs[vfid].snapshot; +} + +static unsigned int pf_snapshot_index(struct xe_gt *gt, struct xe_gt_sriov_state_snapshot *snapshot) +{ + return container_of(snapshot, struct xe_gt_sriov_metadata, snapshot) - gt->sriov.pf.vfs; +} + +static void pf_free_guc_state(struct xe_gt *gt, struct xe_gt_sriov_state_snapshot *snapshot) +{ + struct xe_device *xe = gt_to_xe(gt); + + drmm_kfree(&xe->drm, snapshot->guc.buff); + snapshot->guc.buff = NULL; + snapshot->guc.size = 0; +} + +static int pf_alloc_guc_state(struct xe_gt *gt, + struct xe_gt_sriov_state_snapshot *snapshot, + size_t size) +{ + struct xe_device *xe = gt_to_xe(gt); + void *p; + + pf_free_guc_state(gt, snapshot); + + if (!size) + return -ENODATA; + + if (size % sizeof(u32)) + return -EINVAL; + + if (size > SZ_2M) + return -EFBIG; + + p = drmm_kzalloc(&xe->drm, size, GFP_KERNEL); + if (!p) + return -ENOMEM; + + snapshot->guc.buff = p; + snapshot->guc.size = size; + return 0; +} + +static void pf_dump_guc_state(struct xe_gt *gt, struct xe_gt_sriov_state_snapshot *snapshot) +{ + if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) { + unsigned int vfid __maybe_unused = pf_snapshot_index(gt, snapshot); + + xe_gt_sriov_dbg_verbose(gt, "VF%u GuC state is %zu dwords:\n", + vfid, snapshot->guc.size / sizeof(u32)); + print_hex_dump_bytes("state: ", DUMP_PREFIX_OFFSET, + snapshot->guc.buff, min(SZ_64, snapshot->guc.size)); + } +} + +static int pf_save_vf_guc_state(struct xe_gt *gt, unsigned int vfid) +{ + struct xe_gt_sriov_state_snapshot *snapshot = pf_pick_vf_snapshot(gt, vfid); + size_t size; + int ret; + + ret = pf_send_guc_query_vf_state_size(gt, vfid); + if (ret < 0) + goto fail; + size = ret * sizeof(u32); + xe_gt_sriov_dbg_verbose(gt, "VF%u state size is %d dwords (%zu bytes)\n", vfid, ret, size); + + ret = pf_alloc_guc_state(gt, snapshot, size); + if (ret < 0) + goto fail; + + ret = pf_send_guc_save_vf_state(gt, vfid, snapshot->guc.buff, size); + if (ret < 0) + goto fail; + size = ret * sizeof(u32); + xe_gt_assert(gt, size); + xe_gt_assert(gt, size <= snapshot->guc.size); + snapshot->guc.size = size; + + pf_dump_guc_state(gt, snapshot); + return 0; + +fail: + xe_gt_sriov_dbg(gt, "Unable to save VF%u state (%pe)\n", vfid, ERR_PTR(ret)); + pf_free_guc_state(gt, snapshot); + return ret; +} + +/** + * xe_gt_sriov_pf_migration_save_guc_state() - Take a GuC VF state snapshot. + * @gt: the &xe_gt + * @vfid: the VF identifier + * + * This function is for PF only. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid) +{ + int err; + + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid != PFID); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + + if (!pf_migration_supported(gt)) + return -ENOPKG; + + mutex_lock(pf_migration_mutex(gt)); + err = pf_save_vf_guc_state(gt, vfid); + mutex_unlock(pf_migration_mutex(gt)); + + return err; +} + +static int pf_restore_vf_guc_state(struct xe_gt *gt, unsigned int vfid) +{ + struct xe_gt_sriov_state_snapshot *snapshot = pf_pick_vf_snapshot(gt, vfid); + int ret; + + if (!snapshot->guc.size) + return -ENODATA; + + xe_gt_sriov_dbg_verbose(gt, "restoring %zu dwords of VF%u GuC state\n", + snapshot->guc.size / sizeof(u32), vfid); + ret = pf_send_guc_restore_vf_state(gt, vfid, snapshot->guc.buff, snapshot->guc.size); + if (ret < 0) + goto fail; + + xe_gt_sriov_dbg_verbose(gt, "restored %d dwords of VF%u GuC state\n", ret, vfid); + return 0; + +fail: + xe_gt_sriov_dbg(gt, "Failed to restore VF%u GuC state (%pe)\n", vfid, ERR_PTR(ret)); + return ret; +} + +/** + * xe_gt_sriov_pf_migration_restore_guc_state() - Restore a GuC VF state. + * @gt: the &xe_gt + * @vfid: the VF identifier + * + * This function is for PF only. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vfid) +{ + int ret; + + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid != PFID); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + + if (!pf_migration_supported(gt)) + return -ENOPKG; + + mutex_lock(pf_migration_mutex(gt)); + ret = pf_restore_vf_guc_state(gt, vfid); + mutex_unlock(pf_migration_mutex(gt)); + + return ret; +} + +static bool pf_check_migration_support(struct xe_gt *gt) +{ + /* GuC 70.25 with save/restore v2 is required */ + xe_gt_assert(gt, GUC_FIRMWARE_VER(>->uc.guc) >= MAKE_GUC_VER(70, 25, 0)); + + /* XXX: for now this is for feature enabling only */ + return IS_ENABLED(CONFIG_DRM_XE_DEBUG); +} + +/** + * xe_gt_sriov_pf_migration_init() - Initialize support for VF migration. + * @gt: the &xe_gt + * + * This function is for PF only. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_migration_init(struct xe_gt *gt) +{ + struct xe_device *xe = gt_to_xe(gt); + int err; + + xe_gt_assert(gt, IS_SRIOV_PF(xe)); + + gt->sriov.pf.migration.supported = pf_check_migration_support(gt); + + if (!pf_migration_supported(gt)) + return 0; + + err = drmm_mutex_init(&xe->drm, >->sriov.pf.migration.snapshot_lock); + if (err) + return err; + + return 0; +} diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h new file mode 100644 index 000000000000..6643d730a9ab --- /dev/null +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef _XE_GT_SRIOV_PF_MIGRATION_H_ +#define _XE_GT_SRIOV_PF_MIGRATION_H_ + +#include <linux/types.h> + +struct xe_gt; + +int xe_gt_sriov_pf_migration_init(struct xe_gt *gt); +int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid); +int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vfid); + +#endif diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h new file mode 100644 index 000000000000..1f3110b6d44f --- /dev/null +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration_types.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef _XE_GT_SRIOV_PF_MIGRATION_TYPES_H_ +#define _XE_GT_SRIOV_PF_MIGRATION_TYPES_H_ + +#include <linux/mutex.h> +#include <linux/types.h> + +/** + * struct xe_gt_sriov_state_snapshot - GT-level per-VF state snapshot data. + * + * Used by the PF driver to maintain per-VF migration data. + */ +struct xe_gt_sriov_state_snapshot { + /** @guc: GuC VF state snapshot */ + struct { + /** @guc.buff: buffer with the VF state */ + u32 *buff; + /** @guc.size: size of the buffer (must be dwords aligned) */ + u32 size; + } guc; +}; + +/** + * struct xe_gt_sriov_pf_migration - GT-level data. + * + * Used by the PF driver to maintain non-VF specific per-GT data. + */ +struct xe_gt_sriov_pf_migration { + /** @supported: indicates whether the feature is supported */ + bool supported; + + /** @snapshot_lock: protects all VFs snapshots */ + struct mutex snapshot_lock; +}; + +#endif diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_types.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_types.h index 28e1b130bf87..0426b1a77069 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_types.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_types.h @@ -10,6 +10,7 @@ #include "xe_gt_sriov_pf_config_types.h" #include "xe_gt_sriov_pf_control_types.h" +#include "xe_gt_sriov_pf_migration_types.h" #include "xe_gt_sriov_pf_monitor_types.h" #include "xe_gt_sriov_pf_policy_types.h" #include "xe_gt_sriov_pf_service_types.h" @@ -29,6 +30,9 @@ struct xe_gt_sriov_metadata { /** @version: negotiated VF/PF ABI version */ struct xe_gt_sriov_pf_service_version version; + + /** @snapshot: snapshot of the VF state data */ + struct xe_gt_sriov_state_snapshot snapshot; }; /** @@ -36,6 +40,7 @@ struct xe_gt_sriov_metadata { * @service: service data. * @control: control data. * @policy: policy data. + * @migration: migration data. * @spare: PF-only provisioning configuration. * @vfs: metadata for all VFs. */ @@ -43,6 +48,7 @@ struct xe_gt_sriov_pf { struct xe_gt_sriov_pf_service service; struct xe_gt_sriov_pf_control control; struct xe_gt_sriov_pf_policy policy; + struct xe_gt_sriov_pf_migration migration; struct xe_gt_sriov_spare_config spare; struct xe_gt_sriov_metadata *vfs; }; -- GitLab From 14423f08c3eaad3ad198e308865d984692d6c5f7 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 12 Sep 2024 22:38:15 +0200 Subject: [PATCH 221/970] drm/xe/pf: Save VF GuC state when pausing VF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since usually pausing the VF is done as a first step to migrate that VF, immediately save VF GuC state as a final step of the VF pausing to have that data ready to export when needed. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Cc: Tomasz Lis <tomasz.lis@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912203817.1880-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c | 41 ++++++++++++++++++- .../gpu/drm/xe/xe_gt_sriov_pf_control_types.h | 2 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c index b4fd5a81aff1..1f50aec3a059 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c @@ -13,6 +13,7 @@ #include "xe_gt_sriov_pf_config.h" #include "xe_gt_sriov_pf_control.h" #include "xe_gt_sriov_pf_helpers.h" +#include "xe_gt_sriov_pf_migration.h" #include "xe_gt_sriov_pf_monitor.h" #include "xe_gt_sriov_pf_service.h" #include "xe_gt_sriov_printk.h" @@ -177,6 +178,7 @@ static const char *control_bit_to_string(enum xe_gt_sriov_control_bits bit) CASE2STR(PAUSE_SEND_PAUSE); CASE2STR(PAUSE_WAIT_GUC); CASE2STR(PAUSE_GUC_DONE); + CASE2STR(PAUSE_SAVE_GUC); CASE2STR(PAUSE_FAILED); CASE2STR(PAUSED); CASE2STR(RESUME_WIP); @@ -416,6 +418,10 @@ static void pf_enter_vf_ready(struct xe_gt *gt, unsigned int vfid) * : | : / * : v : / * : PAUSE_GUC_DONE o-----restart + * : | : + * : | o---<--busy : + * : v / / : + * : PAUSE_SAVE_GUC : * : / : * : / : * :....o..............o...............o...........: @@ -435,6 +441,7 @@ static void pf_exit_vf_pause_wip(struct xe_gt *gt, unsigned int vfid) pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE); pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC); pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_GUC_DONE); + pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC); } } @@ -465,12 +472,41 @@ static void pf_enter_vf_pause_rejected(struct xe_gt *gt, unsigned int vfid) pf_enter_vf_pause_failed(gt, vfid); } +static void pf_enter_vf_pause_save_guc(struct xe_gt *gt, unsigned int vfid) +{ + if (!pf_enter_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC)) + pf_enter_vf_state_machine_bug(gt, vfid); +} + +static bool pf_exit_vf_pause_save_guc(struct xe_gt *gt, unsigned int vfid) +{ + int err; + + if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC)) + return false; + + err = xe_gt_sriov_pf_migration_save_guc_state(gt, vfid); + if (err) { + /* retry if busy */ + if (err == -EBUSY) { + pf_enter_vf_pause_save_guc(gt, vfid); + return true; + } + /* give up on error */ + if (err == -EIO) + pf_enter_vf_mismatch(gt, vfid); + } + + pf_enter_vf_pause_completed(gt, vfid); + return true; +} + static bool pf_exit_vf_pause_guc_done(struct xe_gt *gt, unsigned int vfid) { if (!pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_PAUSE_GUC_DONE)) return false; - pf_enter_vf_pause_completed(gt, vfid); + pf_enter_vf_pause_save_guc(gt, vfid); return true; } @@ -1339,6 +1375,9 @@ static bool pf_process_vf_state_machine(struct xe_gt *gt, unsigned int vfid) if (pf_exit_vf_pause_guc_done(gt, vfid)) return true; + if (pf_exit_vf_pause_save_guc(gt, vfid)) + return true; + if (pf_exit_vf_resume_send_resume(gt, vfid)) return true; diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h index 11830aafea45..f02f941b4ad2 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_control_types.h @@ -27,6 +27,7 @@ * @XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE: indicates that the PF is about to send a PAUSE command. * @XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC: indicates that the PF awaits for a response from the GuC. * @XE_GT_SRIOV_STATE_PAUSE_GUC_DONE: indicates that the PF has received a response from the GuC. + * @XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC: indicates that the PF needs to save the VF GuC state. * @XE_GT_SRIOV_STATE_PAUSE_FAILED: indicates that a VF pause operation has failed. * @XE_GT_SRIOV_STATE_PAUSED: indicates that the VF is paused. * @XE_GT_SRIOV_STATE_RESUME_WIP: indicates the a VF resume operation is in progress. @@ -56,6 +57,7 @@ enum xe_gt_sriov_control_bits { XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE, XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC, XE_GT_SRIOV_STATE_PAUSE_GUC_DONE, + XE_GT_SRIOV_STATE_PAUSE_SAVE_GUC, XE_GT_SRIOV_STATE_PAUSE_FAILED, XE_GT_SRIOV_STATE_PAUSED, -- GitLab From d620448fb5673d0705e50e3f73b890a10cfe7c80 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 12 Sep 2024 22:38:16 +0200 Subject: [PATCH 222/970] drm/xe/pf: Allow to view and replace VF GuC state over debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For feature enabling and testing purposes, allow to view saved VF GuC state and to replace it, but only under strict debug config. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Cc: Tomasz Lis <tomasz.lis@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912203817.1880-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c | 46 ++++++++++ drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c | 85 +++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h | 7 ++ 3 files changed, 138 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c index 2290ddaf9594..e990a63ec998 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c @@ -17,6 +17,7 @@ #include "xe_gt_sriov_pf_control.h" #include "xe_gt_sriov_pf_debugfs.h" #include "xe_gt_sriov_pf_helpers.h" +#include "xe_gt_sriov_pf_migration.h" #include "xe_gt_sriov_pf_monitor.h" #include "xe_gt_sriov_pf_policy.h" #include "xe_gt_sriov_pf_service.h" @@ -375,6 +376,44 @@ static const struct file_operations control_ops = { .llseek = default_llseek, }; +/* + * /sys/kernel/debug/dri/0/ + * ├── gt0 + * │  ├── vf1 + * │  │  ├── guc_state + */ +static ssize_t guc_state_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + struct dentry *dent = file_dentry(file); + struct dentry *parent = dent->d_parent; + struct xe_gt *gt = extract_gt(parent); + unsigned int vfid = extract_vfid(parent); + + return xe_gt_sriov_pf_migration_read_guc_state(gt, vfid, buf, count, pos); +} + +static ssize_t guc_state_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct dentry *dent = file_dentry(file); + struct dentry *parent = dent->d_parent; + struct xe_gt *gt = extract_gt(parent); + unsigned int vfid = extract_vfid(parent); + + if (*pos) + return -EINVAL; + + return xe_gt_sriov_pf_migration_write_guc_state(gt, vfid, buf, count); +} + +static const struct file_operations guc_state_ops = { + .owner = THIS_MODULE, + .read = guc_state_read, + .write = guc_state_write, + .llseek = default_llseek, +}; + /** * xe_gt_sriov_pf_debugfs_register - Register SR-IOV PF specific entries in GT debugfs. * @gt: the &xe_gt to register @@ -423,5 +462,12 @@ void xe_gt_sriov_pf_debugfs_register(struct xe_gt *gt, struct dentry *root) pf_add_config_attrs(gt, vfdentry, VFID(n)); debugfs_create_file("control", 0600, vfdentry, NULL, &control_ops); + + /* for testing/debugging purposes only! */ + if (IS_ENABLED(CONFIG_DRM_XE_DEBUG)) { + debugfs_create_file("guc_state", + IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 0600 : 0400, + vfdentry, NULL, &guc_state_ops); + } } } diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c index b7188fa6ac07..c712111aa30d 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c @@ -297,6 +297,91 @@ int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vf return ret; } +#ifdef CONFIG_DEBUG_FS +/** + * xe_gt_sriov_pf_migration_read_guc_state() - Read a GuC VF state. + * @gt: the &xe_gt + * @vfid: the VF identifier + * @buf: the user space buffer to read to + * @count: the maximum number of bytes to read + * @pos: the current position in the buffer + * + * This function is for PF only. + * + * This function reads up to @count bytes from the saved VF GuC state buffer + * at offset @pos into the user space address starting at @buf. + * + * Return: the number of bytes read or a negative error code on failure. + */ +ssize_t xe_gt_sriov_pf_migration_read_guc_state(struct xe_gt *gt, unsigned int vfid, + char __user *buf, size_t count, loff_t *pos) +{ + struct xe_gt_sriov_state_snapshot *snapshot; + ssize_t ret; + + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid != PFID); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + + if (!pf_migration_supported(gt)) + return -ENOPKG; + + mutex_lock(pf_migration_mutex(gt)); + snapshot = pf_pick_vf_snapshot(gt, vfid); + if (snapshot->guc.size) + ret = simple_read_from_buffer(buf, count, pos, snapshot->guc.buff, + snapshot->guc.size); + else + ret = -ENODATA; + mutex_unlock(pf_migration_mutex(gt)); + + return ret; +} + +/** + * xe_gt_sriov_pf_migration_write_guc_state() - Write a GuC VF state. + * @gt: the &xe_gt + * @vfid: the VF identifier + * @buf: the user space buffer with GuC VF state + * @size: the size of GuC VF state (in bytes) + * + * This function is for PF only. + * + * This function reads @size bytes of the VF GuC state stored at user space + * address @buf and writes it into a internal VF state buffer. + * + * Return: the number of bytes used or a negative error code on failure. + */ +ssize_t xe_gt_sriov_pf_migration_write_guc_state(struct xe_gt *gt, unsigned int vfid, + const char __user *buf, size_t size) +{ + struct xe_gt_sriov_state_snapshot *snapshot; + loff_t pos = 0; + ssize_t ret; + + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid != PFID); + xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt))); + + if (!pf_migration_supported(gt)) + return -ENOPKG; + + mutex_lock(pf_migration_mutex(gt)); + snapshot = pf_pick_vf_snapshot(gt, vfid); + ret = pf_alloc_guc_state(gt, snapshot, size); + if (!ret) { + ret = simple_write_to_buffer(snapshot->guc.buff, size, &pos, buf, size); + if (ret < 0) + pf_free_guc_state(gt, snapshot); + else + pf_dump_guc_state(gt, snapshot); + } + mutex_unlock(pf_migration_mutex(gt)); + + return ret; +} +#endif /* CONFIG_DEBUG_FS */ + static bool pf_check_migration_support(struct xe_gt *gt) { /* GuC 70.25 with save/restore v2 is required */ diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h index 6643d730a9ab..09faeae00ddb 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h @@ -14,4 +14,11 @@ int xe_gt_sriov_pf_migration_init(struct xe_gt *gt); int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid); int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vfid); +#ifdef CONFIG_DEBUG_FS +ssize_t xe_gt_sriov_pf_migration_read_guc_state(struct xe_gt *gt, unsigned int vfid, + char __user *buf, size_t count, loff_t *pos); +ssize_t xe_gt_sriov_pf_migration_write_guc_state(struct xe_gt *gt, unsigned int vfid, + const char __user *buf, size_t count); +#endif + #endif -- GitLab From 20e3aa503feb2deafd4185f50cee0da047f62e21 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 12 Sep 2024 22:38:17 +0200 Subject: [PATCH 223/970] drm/xe/pf: Allow to trigger VF GuC state restore from debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For feature enabling and testing purposes, allow to restore saved or replaced VF GuC state from debugfs, bypassing normal migration flow. This is available only under strict debug config. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Cc: Tomasz Lis <tomasz.lis@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912203817.1880-7-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c index e990a63ec998..ccbcf6e572d0 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c @@ -313,6 +313,9 @@ static const struct { { "stop", xe_gt_sriov_pf_control_stop_vf }, { "pause", xe_gt_sriov_pf_control_pause_vf }, { "resume", xe_gt_sriov_pf_control_resume_vf }, +#ifdef CONFIG_DRM_XE_DEBUG_SRIOV + { "restore!", xe_gt_sriov_pf_migration_restore_guc_state }, +#endif }; static ssize_t control_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) -- GitLab From 06c3c406850e5495bb56ccf624d0c9477e1ba901 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Tue, 13 Aug 2024 11:25:05 +0100 Subject: [PATCH 224/970] drm/v3d: Appease lockdep while updating GPU stats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lockdep thinks our seqcount_t usage is unsafe because the update path can be both from irq and worker context: [ ] ================================ [ ] WARNING: inconsistent lock state [ ] 6.10.3-v8-16k-numa #159 Tainted: G WC [ ] -------------------------------- [ ] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. [ ] swapper/0/0 [HC1[1]:SC0[0]:HE0:SE1] takes: [ ] ffff80003d7c08d0 (&v3d_priv->stats[i].lock){?.+.}-{0:0}, at: v3d_irq+0xc8/0x660 [v3d] [ ] {HARDIRQ-ON-W} state was registered at: [ ] lock_acquire+0x1f8/0x328 [ ] v3d_job_start_stats.isra.0+0xd8/0x218 [v3d] [ ] v3d_bin_job_run+0x23c/0x388 [v3d] [ ] drm_sched_run_job_work+0x520/0x6d0 [gpu_sched] [ ] process_one_work+0x62c/0xb48 [ ] worker_thread+0x468/0x5b0 [ ] kthread+0x1c4/0x1e0 [ ] ret_from_fork+0x10/0x20 [ ] irq event stamp: 337094 [ ] hardirqs last enabled at (337093): [<ffffc0008144ce7c>] default_idle_call+0x11c/0x140 [ ] hardirqs last disabled at (337094): [<ffffc0008144a354>] el1_interrupt+0x24/0x58 [ ] softirqs last enabled at (337082): [<ffffc00080061d90>] handle_softirqs+0x4e0/0x538 [ ] softirqs last disabled at (337073): [<ffffc00080010364>] __do_softirq+0x1c/0x28 [ ] other info that might help us debug this: [ ] Possible unsafe locking scenario: [ ] CPU0 [ ] ---- [ ] lock(&v3d_priv->stats[i].lock); [ ] <Interrupt> [ ] lock(&v3d_priv->stats[i].lock); [ ] *** DEADLOCK *** [ ] no locks held by swapper/0/0. [ ] stack backtrace: [ ] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G WC 6.10.3-v8-16k-numa #159 [ ] Hardware name: Raspberry Pi 5 Model B Rev 1.0 (DT) [ ] Call trace: [ ] dump_backtrace+0x170/0x1b8 [ ] show_stack+0x20/0x38 [ ] dump_stack_lvl+0xb4/0xd0 [ ] dump_stack+0x18/0x28 [ ] print_usage_bug+0x3cc/0x3f0 [ ] mark_lock+0x4d0/0x968 [ ] __lock_acquire+0x784/0x18c8 [ ] lock_acquire+0x1f8/0x328 [ ] v3d_job_update_stats+0xec/0x2e0 [v3d] [ ] v3d_irq+0xc8/0x660 [v3d] [ ] __handle_irq_event_percpu+0x1f8/0x488 [ ] handle_irq_event+0x88/0x128 [ ] handle_fasteoi_irq+0x298/0x408 [ ] generic_handle_domain_irq+0x50/0x78 But it is a false positive because all the queue-stats pairs have their own lock and jobs are also one at a time. Nevertheless we can appease lockdep by disabling local interrupts to make it see lock usage is consistent. Cc: MaÃra Canal <mcanal@igalia.com> Fixes: 6abe93b621ab ("drm/v3d: Fix race-condition between sysfs/fdinfo and interrupt handler") Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240813102505.80512-2-tursulin@igalia.com --- drivers/gpu/drm/v3d/v3d_sched.c | 46 +++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index f58c38d7de29..99ac4995b5a1 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -135,8 +135,31 @@ v3d_job_start_stats(struct v3d_job *job, enum v3d_queue queue) struct v3d_stats *global_stats = &v3d->queue[queue].stats; struct v3d_stats *local_stats = &file->stats[queue]; u64 now = local_clock(); - - preempt_disable(); + unsigned long flags; + + /* + * We only need to disable local interrupts to appease lockdep who + * otherwise would think v3d_job_start_stats vs v3d_stats_update has an + * unsafe in-irq vs no-irq-off usage problem. This is a false positive + * because all the locks are per queue and stats type, and all jobs are + * completely one at a time serialised. More specifically: + * + * 1. Locks for GPU queues are updated from interrupt handlers under a + * spin lock and started here with preemption disabled. + * + * 2. Locks for CPU queues are updated from the worker with preemption + * disabled and equally started here with preemption disabled. + * + * Therefore both are consistent. + * + * 3. Because next job can only be queued after the previous one has + * been signaled, and locks are per queue, there is also no scope for + * the start part to race with the update part. + */ + if (IS_ENABLED(CONFIG_LOCKDEP)) + local_irq_save(flags); + else + preempt_disable(); write_seqcount_begin(&local_stats->lock); local_stats->start_ns = now; @@ -146,7 +169,10 @@ v3d_job_start_stats(struct v3d_job *job, enum v3d_queue queue) global_stats->start_ns = now; write_seqcount_end(&global_stats->lock); - preempt_enable(); + if (IS_ENABLED(CONFIG_LOCKDEP)) + local_irq_restore(flags); + else + preempt_enable(); } static void @@ -167,11 +193,21 @@ v3d_job_update_stats(struct v3d_job *job, enum v3d_queue queue) struct v3d_stats *global_stats = &v3d->queue[queue].stats; struct v3d_stats *local_stats = &file->stats[queue]; u64 now = local_clock(); + unsigned long flags; + + /* See comment in v3d_job_start_stats() */ + if (IS_ENABLED(CONFIG_LOCKDEP)) + local_irq_save(flags); + else + preempt_disable(); - preempt_disable(); v3d_stats_update(local_stats, now); v3d_stats_update(global_stats, now); - preempt_enable(); + + if (IS_ENABLED(CONFIG_LOCKDEP)) + local_irq_restore(flags); + else + preempt_enable(); } static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job) -- GitLab From fdc81c43f0c14ace6383024a02585e3fcbd1ceba Mon Sep 17 00:00:00 2001 From: He Lugang <helugang@uniontech.com> Date: Wed, 11 Sep 2024 18:22:15 +0800 Subject: [PATCH 225/970] drm/xe: use devm_add_action_or_reset() helper Use devm_add_action_or_reset() to release resources in case of failure, because the cleanup function will be automatically called. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: He Lugang <helugang@uniontech.com> Link: https://patchwork.freedesktop.org/patch/msgid/9631BC17D1E028A2+20240911102215.84865-1-helugang@uniontech.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_gt_freq.c | 4 ++-- drivers/gpu/drm/xe/xe_gt_sysfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c index 552435951f11..6bd39b2c5003 100644 --- a/drivers/gpu/drm/xe/xe_gt_freq.c +++ b/drivers/gpu/drm/xe/xe_gt_freq.c @@ -237,11 +237,11 @@ int xe_gt_freq_init(struct xe_gt *gt) if (!gt->freq) return -ENOMEM; - err = devm_add_action(xe->drm.dev, freq_fini, gt->freq); + err = sysfs_create_files(gt->freq, freq_attrs); if (err) return err; - err = sysfs_create_files(gt->freq, freq_attrs); + err = devm_add_action_or_reset(xe->drm.dev, freq_fini, gt->freq); if (err) return err; diff --git a/drivers/gpu/drm/xe/xe_gt_sysfs.c b/drivers/gpu/drm/xe/xe_gt_sysfs.c index a05c3699e8b9..ec2b8246204b 100644 --- a/drivers/gpu/drm/xe/xe_gt_sysfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sysfs.c @@ -51,5 +51,5 @@ int xe_gt_sysfs_init(struct xe_gt *gt) gt->sysfs = &kg->base; - return devm_add_action(xe->drm.dev, gt_sysfs_fini, gt); + return devm_add_action_or_reset(xe->drm.dev, gt_sysfs_fini, gt); } -- GitLab From 37173392741c425191b959acb3adf70c9a4610c0 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Mon, 16 Sep 2024 09:49:12 +0100 Subject: [PATCH 226/970] drm/xe/vram: fix ccs offset calculation Spec says SW is expected to round up to the nearest 128K, if not already aligned for the CC unit view of CCS. We are seeing the assert sometimes pop on BMG to tell us that there is a hole between GSM and CCS, as well as popping other asserts with having a vram size with strange alignment, which is likely caused by misaligned offset here. v2 (Shuicheng): - Do the round_up() on final SW address. BSpec: 68023 Fixes: b5c2ca0372dc ("drm/xe/xe2hpg: Determine flat ccs offset for vram") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Cc: Akshata Jahagirdar <akshata.jahagirdar@intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Cc: Shuicheng Lin <shuicheng.lin@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Cc: stable@vger.kernel.org # v6.10+ Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Tested-by: Shuicheng Lin <shuicheng.lin@intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916084911.13119-2-matthew.auld@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_vram.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c index 7e765b1499b1..2a623bfcda7e 100644 --- a/drivers/gpu/drm/xe/xe_vram.c +++ b/drivers/gpu/drm/xe/xe_vram.c @@ -182,6 +182,7 @@ static inline u64 get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size) offset = offset_hi << 32; /* HW view bits 39:32 */ offset |= offset_lo << 6; /* HW view bits 31:6 */ offset *= num_enabled; /* convert to SW view */ + offset = round_up(offset, SZ_128K); /* SW must round up to nearest 128K */ /* We don't expect any holes */ xe_assert_msg(xe, offset == (xe_mmio_read64_2x32(>_to_tile(gt)->mmio, GSMBASE) - -- GitLab From bc6763187270154ab48715d26bc129eba34e471a Mon Sep 17 00:00:00 2001 From: Lucas De Marchi <lucas.demarchi@intel.com> Date: Mon, 16 Sep 2024 12:21:49 -0700 Subject: [PATCH 227/970] drm/xe/rtp: Remove unneeded semicolon Fix coccicheck report with regard to unneeded semicolon. This is currently the only case according to make coccicheck \ MODE=report \ COCCI=scripts/coccinelle/misc/semicolon.cocci \ M=drivers/gpu/drm/xe Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409151152.pJ4ukp5k-lkp@intel.com/ Reviewed-by: Jagmeet Randhawa <jagmeet.randhawa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916192149.855996-1-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_rtp.c b/drivers/gpu/drm/xe/xe_rtp.c index 86c705d18c0d..b13d4d62f0b1 100644 --- a/drivers/gpu/drm/xe/xe_rtp.c +++ b/drivers/gpu/drm/xe/xe_rtp.c @@ -196,7 +196,7 @@ static void rtp_get_context(struct xe_rtp_process_ctx *ctx, *gt = (*hwe)->gt; *xe = gt_to_xe(*gt); break; - }; + } } /** -- GitLab From 319e53f155907cf2c6dabc16ec9dce0179bc04d1 Mon Sep 17 00:00:00 2001 From: Lyude Paul <lyude@redhat.com> Date: Mon, 16 Sep 2024 19:00:08 -0400 Subject: [PATCH 228/970] drm/panic: Fix uninitialized spinlock acquisition with CONFIG_DRM_PANIC=n It turns out that if you happen to have a kernel config where CONFIG_DRM_PANIC is disabled and spinlock debugging is enabled, along with KMS being enabled - we'll end up trying to acquire an uninitialized spin_lock with drm_panic_lock() when we try to do a commit: rvkms rvkms.0: [drm:drm_atomic_commit] committing 0000000068d2ade1 INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator. CPU: 4 PID: 1347 Comm: modprobe Not tainted 6.10.0-rc1Lyude-Test+ #272 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20240524-3.fc40 05/24/2024 Call Trace: <TASK> dump_stack_lvl+0x77/0xa0 assign_lock_key+0x114/0x120 register_lock_class+0xa8/0x2c0 __lock_acquire+0x7d/0x2bd0 ? __vmap_pages_range_noflush+0x3a8/0x550 ? drm_atomic_helper_swap_state+0x2ad/0x3a0 lock_acquire+0xec/0x290 ? drm_atomic_helper_swap_state+0x2ad/0x3a0 ? lock_release+0xee/0x310 _raw_spin_lock_irqsave+0x4e/0x70 ? drm_atomic_helper_swap_state+0x2ad/0x3a0 drm_atomic_helper_swap_state+0x2ad/0x3a0 drm_atomic_helper_commit+0xb1/0x270 drm_atomic_commit+0xaf/0xe0 ? __pfx___drm_printfn_info+0x10/0x10 drm_client_modeset_commit_atomic+0x1a1/0x250 drm_client_modeset_commit_locked+0x4b/0x180 drm_client_modeset_commit+0x27/0x50 __drm_fb_helper_restore_fbdev_mode_unlocked+0x76/0x90 drm_fb_helper_set_par+0x38/0x40 fbcon_init+0x3c4/0x690 visual_init+0xc0/0x120 do_bind_con_driver+0x409/0x4c0 do_take_over_console+0x233/0x280 do_fb_registered+0x11f/0x210 fbcon_fb_registered+0x2c/0x60 register_framebuffer+0x248/0x2a0 __drm_fb_helper_initial_config_and_unlock+0x58a/0x720 drm_fbdev_generic_client_hotplug+0x6e/0xb0 drm_client_register+0x76/0xc0 _RNvXs_CsHeezP08sTT_5rvkmsNtB4_5RvkmsNtNtCs1cdwasc6FUb_6kernel8platform6Driver5probe+0xed2/0x1060 [rvkms] ? _RNvMs_NtCs1cdwasc6FUb_6kernel8platformINtB4_7AdapterNtCsHeezP08sTT_5rvkms5RvkmsE14probe_callbackBQ_+0x2b/0x70 [rvkms] ? acpi_dev_pm_attach+0x25/0x110 ? platform_probe+0x6a/0xa0 ? really_probe+0x10b/0x400 ? __driver_probe_device+0x7c/0x140 ? driver_probe_device+0x22/0x1b0 ? __device_attach_driver+0x13a/0x1c0 ? __pfx___device_attach_driver+0x10/0x10 ? bus_for_each_drv+0x114/0x170 ? __device_attach+0xd6/0x1b0 ? bus_probe_device+0x9e/0x120 ? device_add+0x288/0x4b0 ? platform_device_add+0x75/0x230 ? platform_device_register_full+0x141/0x180 ? rust_helper_platform_device_register_simple+0x85/0xb0 ? _RNvMs2_NtCs1cdwasc6FUb_6kernel8platformNtB5_6Device13create_simple+0x1d/0x60 ? _RNvXs0_CsHeezP08sTT_5rvkmsNtB5_5RvkmsNtCs1cdwasc6FUb_6kernel6Module4init+0x11e/0x160 [rvkms] ? 0xffffffffc083f000 ? init_module+0x20/0x1000 [rvkms] ? kernfs_xattr_get+0x3e/0x80 ? do_one_initcall+0x148/0x3f0 ? __lock_acquire+0x5ef/0x2bd0 ? __lock_acquire+0x5ef/0x2bd0 ? __lock_acquire+0x5ef/0x2bd0 ? put_cpu_partial+0x51/0x1d0 ? lock_acquire+0xec/0x290 ? put_cpu_partial+0x51/0x1d0 ? lock_release+0xee/0x310 ? put_cpu_partial+0x51/0x1d0 ? fs_reclaim_acquire+0x69/0xf0 ? lock_acquire+0xec/0x290 ? fs_reclaim_acquire+0x69/0xf0 ? kfree+0x22f/0x340 ? lock_release+0xee/0x310 ? kmalloc_trace_noprof+0x48/0x340 ? do_init_module+0x22/0x240 ? kmalloc_trace_noprof+0x155/0x340 ? do_init_module+0x60/0x240 ? __se_sys_finit_module+0x2e0/0x3f0 ? do_syscall_64+0xa4/0x180 ? syscall_exit_to_user_mode+0x108/0x140 ? do_syscall_64+0xb0/0x180 ? vma_end_read+0xd0/0xe0 ? do_user_addr_fault+0x309/0x640 ? clear_bhb_loop+0x45/0xa0 ? clear_bhb_loop+0x45/0xa0 ? clear_bhb_loop+0x45/0xa0 ? entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK> Fix this by stubbing these macros out when this config option isn't enabled, along with fixing the unused variable warning that introduces. Signed-off-by: Lyude Paul <lyude@redhat.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Fixes: e2a1cda3e0c7 ("drm/panic: Add drm panic locking") Cc: <stable@vger.kernel.org> # v6.10+ Link: https://patchwork.freedesktop.org/patch/msgid/20240916230103.611490-1-lyude@redhat.com --- drivers/gpu/drm/drm_atomic_helper.c | 2 +- include/drm/drm_panic.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 43cdf39019a4..5186d2114a50 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3015,7 +3015,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state, bool stall) { int i, ret; - unsigned long flags; + unsigned long flags = 0; struct drm_connector *connector; struct drm_connector_state *old_conn_state, *new_conn_state; struct drm_crtc *crtc; diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h index 54085d5d05c3..f4e1fa9ae607 100644 --- a/include/drm/drm_panic.h +++ b/include/drm/drm_panic.h @@ -64,6 +64,8 @@ struct drm_scanout_buffer { }; +#ifdef CONFIG_DRM_PANIC + /** * drm_panic_trylock - try to enter the panic printing critical section * @dev: struct drm_device @@ -149,4 +151,16 @@ struct drm_scanout_buffer { #define drm_panic_unlock(dev, flags) \ raw_spin_unlock_irqrestore(&(dev)->mode_config.panic_lock, flags) +#else + +static inline bool drm_panic_trylock(struct drm_device *dev, unsigned long flags) +{ + return true; +} + +static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {} +static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {} + +#endif + #endif /* __DRM_PANIC_H__ */ -- GitLab From 8a677d5b0a20ed4715cb4a8b0f8a08712ec0997c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi <rodrigo.vivi@intel.com> Date: Tue, 17 Sep 2024 16:32:43 -0400 Subject: [PATCH 229/970] drm/xe/display: Remove i915_drv.h include Change HAS_DISPLAY towards intel_display and remove one of the last includes of i915_drv.h in Xe. Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240917203243.659393-1-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/display/xe_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 86009a17e4c2..94ac537f2514 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -13,7 +13,6 @@ #include <uapi/drm/xe_drm.h> #include "soc/intel_dram.h" -#include "i915_drv.h" /* FIXME: HAS_DISPLAY() depends on this */ #include "intel_acpi.h" #include "intel_audio.h" #include "intel_bw.h" @@ -34,7 +33,7 @@ static bool has_display(struct xe_device *xe) { - return HAS_DISPLAY(xe); + return HAS_DISPLAY(&xe->display); } /** -- GitLab From cb2deca056d579fe008c8d0a4ceb04d2b368fe42 Mon Sep 17 00:00:00 2001 From: Nikolai Afanasenkov <nikolai.afanasenkov@hp.com> Date: Mon, 16 Sep 2024 13:50:42 -0600 Subject: [PATCH 230/970] ALSA: hda/realtek: fix mute/micmute LED for HP mt645 G8 The HP Elite mt645 G8 Mobile Thin Client uses an ALC236 codec and needs the ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF quirk to enable the mute and micmute LED functionality. This patch adds the system ID of the HP Elite mt645 G8 to the `alc269_fixup_tbl` in `patch_realtek.c` to enable the required quirk. Cc: stable@vger.kernel.org Signed-off-by: Nikolai Afanasenkov <nikolai.afanasenkov@hp.com> Link: https://patch.msgid.link/20240916195042.4050-1-nikolai.afanasenkov@hp.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4ca66234e561..9471396bbca6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10490,6 +10490,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8ca2, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8caf, "HP Elite mt645 G8 Mobile Thin Client", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8cbd, "HP Pavilion Aero Laptop 13-bg0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8cde, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2), -- GitLab From 8451a3c7879d8883fd3fbd9dd7cbe7ecc31e89ce Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda <Vijendar.Mukunda@amd.com> Date: Mon, 16 Sep 2024 11:43:18 +0530 Subject: [PATCH 231/970] ASoC: amd: acp: don't set card long_name UCM can load a board-specific file based on the card long_name. Remove the constant "AMD Soundwire SOF" long_name so that the ASoC core can set the long_name based on DMI information. Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> Link: https://patch.msgid.link/20240916061318.3147988-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/amd/acp/acp-sdw-sof-mach.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c index 6c50c8276538..306854fb08e3 100644 --- a/sound/soc/amd/acp/acp-sdw-sof-mach.c +++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c @@ -400,9 +400,6 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) return ret; } -/* SoC card */ -static const char sdw_card_long_name[] = "AMD Soundwire SOF"; - static int mc_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); @@ -463,8 +460,6 @@ static int mc_probe(struct platform_device *pdev) if (!card->components) return -ENOMEM; - card->long_name = sdw_card_long_name; - /* Register the card */ ret = devm_snd_soc_register_card(card->dev, card); if (ret) { -- GitLab From 6e4f0d39fd52648a1ce580fc040fb2f008ec2ad9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 16 Sep 2024 10:25:13 +0200 Subject: [PATCH 232/970] drm/ast: Rename register constants for TX-chip types The type of the TX chip is provided in VGACRD1. Rename the constants accordingly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916082920.56234-2-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_main.c | 4 ++-- drivers/gpu/drm/ast/ast_reg.h | 26 ++++++++++++-------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 3d92d9e5208f..d0e4f0dc9234 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -120,8 +120,8 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) ast->tx_chip = AST_TX_DP501; } } else if (IS_AST_GEN7(ast)) { - if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) == - ASTDP_DPMCU_TX) { + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, AST_IO_VGACRD1_TX_TYPE_MASK) == + AST_IO_VGACRD1_TX_ASTDP) { int ret = ast_dp_launch(ast); if (!ret) diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index 6a1f756650ab..daa5d3a9e6a1 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -37,7 +37,18 @@ #define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ #define AST_IO_VGACRCB_HWC_ENABLED BIT(1) -#define AST_IO_VGACRD1_MCU_FW_EXECUTING BIT(5) +#define AST_IO_VGACRD1_MCU_FW_EXECUTING BIT(5) +/* Display Transmitter Type */ +#define AST_IO_VGACRD1_TX_TYPE_MASK GENMASK(3, 1) +#define AST_IO_VGACRD1_NO_TX 0x00 +#define AST_IO_VGACRD1_TX_ITE66121_VBIOS 0x02 +#define AST_IO_VGACRD1_TX_SIL164_VBIOS 0x04 +#define AST_IO_VGACRD1_TX_CH7003_VBIOS 0x06 +#define AST_IO_VGACRD1_TX_DP501_VBIOS 0x08 +#define AST_IO_VGACRD1_TX_ANX9807_VBIOS 0x0a +#define AST_IO_VGACRD1_TX_FW_EMBEDDED_FW 0x0c +#define AST_IO_VGACRD1_TX_ASTDP 0x0e + #define AST_IO_VGACRD7_EDID_VALID_FLAG BIT(0) #define AST_IO_VGACRDC_LINK_SUCCESS BIT(0) #define AST_IO_VGACRDF_HPD BIT(0) @@ -49,19 +60,6 @@ #define AST_IO_VGAIR1_R (0x5A) #define AST_IO_VGAIR1_VREFRESH BIT(3) -/* - * Display Transmitter Type - */ - -#define TX_TYPE_MASK GENMASK(3, 1) -#define NO_TX (0 << 1) -#define ITE66121_VBIOS_TX (1 << 1) -#define SI164_VBIOS_TX (2 << 1) -#define CH7003_VBIOS_TX (3 << 1) -#define DP501_VBIOS_TX (4 << 1) -#define ANX9807_VBIOS_TX (5 << 1) -#define TX_FW_EMBEDDED_FW_TX (6 << 1) -#define ASTDP_DPMCU_TX (7 << 1) #define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) //#define AST_VRAM_INIT_BY_BMC BIT(7) -- GitLab From f93d66635fb3d4e3995dcc20acfa0498a2fa609d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 16 Sep 2024 10:25:14 +0200 Subject: [PATCH 233/970] drm/ast: Use TX-chip register constants Replace magic values with named constants when reading the TX chip from VGACRD1. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916082920.56234-3-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp501.c | 13 +++++++------ drivers/gpu/drm/ast/ast_main.c | 9 +++++---- drivers/gpu/drm/ast/ast_reg.h | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index e5553334bfde..9e19d8c17730 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -444,18 +444,19 @@ static void ast_init_analog(struct ast_device *ast) void ast_init_3rdtx(struct ast_device *ast) { - u8 jreg; + u8 vgacrd1; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { - jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); - switch (jreg & 0x0e) { - case 0x04: + vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, + AST_IO_VGACRD1_TX_TYPE_MASK); + switch (vgacrd1) { + case AST_IO_VGACRD1_TX_SIL164_VBIOS: ast_init_dvo(ast); break; - case 0x08: + case AST_IO_VGACRD1_TX_DP501_VBIOS: ast_launch_m68k(ast); break; - case 0x0c: + case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW: ast_init_dvo(ast); break; default: diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index d0e4f0dc9234..7289bdc6066e 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -101,12 +101,13 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * the SOC scratch register #1 bits 11:8 (interestingly marked * as "reserved" in the spec) */ - jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, + AST_IO_VGACRD1_TX_TYPE_MASK); switch (jreg) { - case 0x04: + case AST_IO_VGACRD1_TX_SIL164_VBIOS: ast->tx_chip = AST_TX_SIL164; break; - case 0x08: + case AST_IO_VGACRD1_TX_DP501_VBIOS: ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL); if (ast->dp501_fw_addr) { /* backup firmware */ @@ -116,7 +117,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) } } fallthrough; - case 0x0c: + case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW: ast->tx_chip = AST_TX_DP501; } } else if (IS_AST_GEN7(ast)) { diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h index daa5d3a9e6a1..2aadf07d135a 100644 --- a/drivers/gpu/drm/ast/ast_reg.h +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -46,7 +46,7 @@ #define AST_IO_VGACRD1_TX_CH7003_VBIOS 0x06 #define AST_IO_VGACRD1_TX_DP501_VBIOS 0x08 #define AST_IO_VGACRD1_TX_ANX9807_VBIOS 0x0a -#define AST_IO_VGACRD1_TX_FW_EMBEDDED_FW 0x0c +#define AST_IO_VGACRD1_TX_FW_EMBEDDED_FW 0x0c /* special case of DP501 */ #define AST_IO_VGACRD1_TX_ASTDP 0x0e #define AST_IO_VGACRD7_EDID_VALID_FLAG BIT(0) -- GitLab From a5c2320151ff7cdf9ec50630d638a417ff927e31 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 16 Sep 2024 10:25:15 +0200 Subject: [PATCH 234/970] drm/ast: Warn about unsupported TX chips A number of TX chips are listed in VGACRD1, but not supported by the ast driver. Whether any existing product uses such a chip is unknown. Warn if the driver encounters any. We can then add support as necessary. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Suggested-by: Jocelyn Falempe <jfalempe@redhat.com> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916082920.56234-4-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_main.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 7289bdc6066e..bc37c65305d4 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -76,7 +76,22 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) }; struct drm_device *dev = &ast->base; - u8 jreg; + u8 jreg, vgacrd1; + + /* + * Several of the listed TX chips are not explicitly supported + * by the ast driver. If these exist in real-world devices, they + * are most likely reported as VGA or SIL164 outputs. We warn here + * to get bug reports for these devices. If none come in for some + * time, we can begin to fail device probing on these values. + */ + vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, AST_IO_VGACRD1_TX_TYPE_MASK); + drm_WARN(dev, vgacrd1 == AST_IO_VGACRD1_TX_ITE66121_VBIOS, + "ITE IT66121 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); + drm_WARN(dev, vgacrd1 == AST_IO_VGACRD1_TX_CH7003_VBIOS, + "Chrontel CH7003 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); + drm_WARN(dev, vgacrd1 == AST_IO_VGACRD1_TX_ANX9807_VBIOS, + "Analogix ANX9807 detected, 0x%x, Gen%lu\n", vgacrd1, AST_GEN(ast)); /* Check 3rd Tx option (digital output afaik) */ ast->tx_chip = AST_TX_NONE; -- GitLab From ec2d1539e159f53eae708e194c449cfefa004994 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi <rodrigo.vivi@intel.com> Date: Thu, 12 Sep 2024 17:45:07 -0400 Subject: [PATCH 235/970] drm/xe: Restore pci state upon resume The pci state was saved, but not restored. Restore right after the power state transition request like every other driver. v2: Use right fixes tag, since this was there initialy, but accidentally removed. Fixes: f6761c68c0ac ("drm/xe/display: Improve s2idle handling.") Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912214507.456897-1-rodrigo.vivi@intel.com Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> --- drivers/gpu/drm/xe/xe_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index a1d08e20cd34..2c2d269ebe8e 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -944,6 +944,8 @@ static int xe_pci_resume(struct device *dev) if (err) return err; + pci_restore_state(pdev); + err = pci_enable_device(pdev); if (err) return err; -- GitLab From 71a3161e9d7d2229cb4eefd4c49effb97caf3db3 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Date: Fri, 13 Sep 2024 13:47:53 +0200 Subject: [PATCH 236/970] drm/xe: Fix DSB buffer coherency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the scanout flag to force WC caching, and add the memory barrier where needed. Reviewed-by: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240913114754.7956-2-maarten.lankhorst@linux.intel.com Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> --- drivers/gpu/drm/xe/display/xe_dsb_buffer.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c index f99d901a3214..f95375451e2f 100644 --- a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c +++ b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c @@ -48,11 +48,12 @@ bool intel_dsb_buffer_create(struct intel_crtc *crtc, struct intel_dsb_buffer *d if (!vma) return false; + /* Set scanout flag for WC mapping */ obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, PAGE_ALIGN(size), ttm_bo_type_kernel, XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) | - XE_BO_FLAG_GGTT); + XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT); if (IS_ERR(obj)) { kfree(vma); return false; @@ -73,5 +74,9 @@ void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf) void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf) { - /* TODO: add xe specific flush_map() for dsb buffer object. */ + /* + * The memory barrier here is to ensure coherency of DSB vs MMIO, + * both for weak ordering archs and discrete cards. + */ + xe_device_wmb(dsb_buf->vma->bo->tile->xe); } -- GitLab From 17d32430361898932678fc6d77e448f260c8a3a8 Mon Sep 17 00:00:00 2001 From: Animesh Manna <animesh.manna@intel.com> Date: Fri, 13 Sep 2024 13:47:54 +0200 Subject: [PATCH 237/970] drm/xe: Revert "drm/i915: Disable DSB in Xe KMD" This reverts commit c27f010aa1884276ee5dae72034d84987060c769. After fix from [1] dsb timeout issue is not reproducible on local testing with xe driver. Checking CI result to confirm and not for review. [1] https://patchwork.freedesktop.org/series/130783/ Signed-off-by: Animesh Manna <animesh.manna@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240913114754.7956-3-maarten.lankhorst@linux.intel.com Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/i915/display/intel_dsb.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index da24e041d269..e0c628d1fe7d 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -706,10 +706,6 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, if (!i915->display.params.enable_dsb) return NULL; - /* TODO: DSB is broken in Xe KMD, so disabling it until fixed */ - if (!IS_ENABLED(I915)) - return NULL; - dsb = kzalloc(sizeof(*dsb), GFP_KERNEL); if (!dsb) goto out; -- GitLab From 1378c633a3fbfeb344c486ffda0e920a21e62712 Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Tue, 17 Sep 2024 22:44:36 -0700 Subject: [PATCH 238/970] drm/xe: Convert to USM lock to rwsem Remove contention from GPU fault path for ASID->VM lookup. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918054436.1971839-1-matthew.brost@intel.com --- drivers/gpu/drm/xe/xe_device.c | 4 +--- drivers/gpu/drm/xe/xe_device_types.h | 2 +- drivers/gpu/drm/xe/xe_gt_pagefault.c | 8 ++++---- drivers/gpu/drm/xe/xe_vm.c | 8 ++++---- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 4d3c794f134c..38eade07a004 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -335,9 +335,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, init_waitqueue_head(&xe->ufence_wq); - err = drmm_mutex_init(&xe->drm, &xe->usm.lock); - if (err) - goto err; + init_rwsem(&xe->usm.lock); xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC); diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index c92df0a2423f..4507a5756a05 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -395,7 +395,7 @@ struct xe_device { /** @usm.next_asid: next ASID, used to cyclical alloc asids */ u32 next_asid; /** @usm.lock: protects UM state */ - struct mutex lock; + struct rw_semaphore lock; } usm; /** @pinned: pinned BO state */ diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c index 00af059a8971..5c3af2bb5402 100644 --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c @@ -198,13 +198,13 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) return -EFAULT; /* ASID to VM */ - mutex_lock(&xe->usm.lock); + down_read(&xe->usm.lock); vm = xa_load(&xe->usm.asid_to_vm, pf->asid); if (vm && xe_vm_in_fault_mode(vm)) xe_vm_get(vm); else vm = NULL; - mutex_unlock(&xe->usm.lock); + up_read(&xe->usm.lock); if (!vm) return -EINVAL; @@ -549,11 +549,11 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc) return -EINVAL; /* ASID to VM */ - mutex_lock(&xe->usm.lock); + down_read(&xe->usm.lock); vm = xa_load(&xe->usm.asid_to_vm, acc->asid); if (vm) xe_vm_get(vm); - mutex_unlock(&xe->usm.lock); + up_read(&xe->usm.lock); if (!vm || !xe_vm_in_fault_mode(vm)) return -EINVAL; diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 7acd5fc9d032..a3d7cb7cfd22 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1613,7 +1613,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) up_write(&vm->lock); - mutex_lock(&xe->usm.lock); + down_write(&xe->usm.lock); if (vm->usm.asid) { void *lookup; @@ -1623,7 +1623,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); xe_assert(xe, lookup == vm); } - mutex_unlock(&xe->usm.lock); + up_write(&xe->usm.lock); for_each_tile(tile, xe, id) xe_range_fence_tree_fini(&vm->rftree[id]); @@ -1772,11 +1772,11 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, goto err_close_and_put; if (xe->info.has_asid) { - mutex_lock(&xe->usm.lock); + down_write(&xe->usm.lock); err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, XA_LIMIT(1, XE_MAX_ASID - 1), &xe->usm.next_asid, GFP_KERNEL); - mutex_unlock(&xe->usm.lock); + up_write(&xe->usm.lock); if (err < 0) goto err_free_id; -- GitLab From 58548b91101f0a8772d1fe992cac7cd3226a471e Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Tue, 17 Sep 2024 15:16:16 -0700 Subject: [PATCH 239/970] drm/xe: Defer gt->mmio initialization until after multi-tile setup With the recent xe_mmio redesign, tiles and GTs each have their own MMIO accessor, with the GT inheriting some of the information (such as the iomap pointer) from their containing tile. Given that non-root tiles get initialized later than the root tile (and currently after the point at which GT MMIO is initialized for _all_ GTs), we wind up incorrectly inheriting uninitialized pointers for the initialization of GT MMIO for GTs that reside on non-root tiles. This causes a driver crash on multi-tile PVC platforms. With the general xe_mmio redesign, it's now only necessary to do the GT-level MMIO setup before the point we start reading/writing GT registers. Move initialization of gt->mmio out of xe_info_init (which runs before non-root tiles are initialized) and to the beginning of where we start actually accessing the GTs themselves. The high-level initialization flow now boils down to: - General device init, software-only setup - (no register access possible yet) - Root tile initialization - (access to device/tile0 registers possible via xe_root_tile_mmio()) - Initialization of non-root tiles - (access to any tile's registers possible via tile->mmio) - GT MMIO initialization, inheriting iomap from each GT's tile - (access to any GT's registers possible via gt->mmio) Fixes: fa599b8c95a7 ("drm/xe: Populate GT's mmio iomap from tile during init") Reported-by: John Harrison <John.C.Harrison@Intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240917221615.875962-2-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_device.c | 7 +++++++ drivers/gpu/drm/xe/xe_gt.c | 24 ++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_gt.h | 1 + drivers/gpu/drm/xe/xe_pci.c | 12 ------------ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 38eade07a004..709acea5c388 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -654,6 +654,13 @@ int xe_device_probe(struct xe_device *xe) err = xe_gt_init_early(gt); if (err) return err; + + /* + * Only after this point can GT-specific MMIO operations + * (including things like communication with the GuC) + * be performed. + */ + xe_gt_mmio_init(gt); } for_each_tile(tile, xe, id) { diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 935d1dfd9459..274737417b0f 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -625,6 +625,30 @@ int xe_gt_init(struct xe_gt *gt) return 0; } +/** + * xe_gt_mmio_init() - Initialize GT's MMIO access + * @gt: the GT object + * + * Initialize GT's MMIO accessor, which will be used to access registers inside + * this GT. + */ +void xe_gt_mmio_init(struct xe_gt *gt) +{ + struct xe_tile *tile = gt_to_tile(gt); + + gt->mmio.regs = tile->mmio.regs; + gt->mmio.regs_size = tile->mmio.regs_size; + gt->mmio.tile = tile; + + if (gt->info.type == XE_GT_TYPE_MEDIA) { + gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; + gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; + } + + if (IS_SRIOV_VF(gt_to_xe(gt))) + gt->mmio.sriov_vf_gt = gt; +} + void xe_gt_record_user_engines(struct xe_gt *gt) { struct xe_hw_engine *hwe; diff --git a/drivers/gpu/drm/xe/xe_gt.h b/drivers/gpu/drm/xe/xe_gt.h index 97def44afa4c..05c8351d0f39 100644 --- a/drivers/gpu/drm/xe/xe_gt.h +++ b/drivers/gpu/drm/xe/xe_gt.h @@ -37,6 +37,7 @@ struct xe_gt *xe_gt_alloc(struct xe_tile *tile); int xe_gt_init_hwconfig(struct xe_gt *gt); int xe_gt_init_early(struct xe_gt *gt); int xe_gt_init(struct xe_gt *gt); +void xe_gt_mmio_init(struct xe_gt *gt); void xe_gt_declare_wedged(struct xe_gt *gt); int xe_gt_record_default_lrcs(struct xe_gt *gt); diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 2c2d269ebe8e..edaeefd2d648 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -716,11 +716,6 @@ static int xe_info_init(struct xe_device *xe, gt->info.type = XE_GT_TYPE_MAIN; gt->info.has_indirect_ring_state = graphics_desc->has_indirect_ring_state; gt->info.engine_mask = graphics_desc->hw_engine_mask; - gt->mmio.regs = tile->mmio.regs; - gt->mmio.regs_size = tile->mmio.regs_size; - gt->mmio.tile = tile; - if (IS_SRIOV_VF(xe)) - gt->mmio.sriov_vf_gt = gt; if (MEDIA_VER(xe) < 13 && media_desc) gt->info.engine_mask |= media_desc->hw_engine_mask; @@ -740,13 +735,6 @@ static int xe_info_init(struct xe_device *xe, gt->info.type = XE_GT_TYPE_MEDIA; gt->info.has_indirect_ring_state = media_desc->has_indirect_ring_state; gt->info.engine_mask = media_desc->hw_engine_mask; - gt->mmio.regs = tile->mmio.regs; - gt->mmio.regs_size = tile->mmio.regs_size; - gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET; - gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH; - gt->mmio.tile = tile; - if (IS_SRIOV_VF(xe)) - gt->mmio.sriov_vf_gt = gt; /* * FIXME: At the moment multi-tile and standalone media are -- GitLab From b46afdac45a251d76a4575be78beba343f08b52f Mon Sep 17 00:00:00 2001 From: Ilia Levi <ilia.levi@intel.com> Date: Wed, 18 Sep 2024 08:39:38 +0300 Subject: [PATCH 240/970] drm/xe: Introduce dedicated config for memirq debug Separate config for debugging memory based interrupts (memirq) infrastructure. Signed-off-by: Ilia Levi <ilia.levi@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918053942.1331811-2-illevi@habana.ai --- drivers/gpu/drm/xe/Kconfig.debug | 12 ++++++++++++ drivers/gpu/drm/xe/xe_memirq.c | 29 +++++++++++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/xe/Kconfig.debug b/drivers/gpu/drm/xe/Kconfig.debug index bc177368af6c..2de0de41b8dd 100644 --- a/drivers/gpu/drm/xe/Kconfig.debug +++ b/drivers/gpu/drm/xe/Kconfig.debug @@ -40,9 +40,21 @@ config DRM_XE_DEBUG_VM If in doubt, say "N". +config DRM_XE_DEBUG_MEMIRQ + bool "Enable extra memirq debugging" + default n + help + Choose this option to enable additional debugging info for + memory based interrupts. + + Recommended for driver developers only. + + If in doubt, say "N". + config DRM_XE_DEBUG_SRIOV bool "Enable extra SR-IOV debugging" default n + select DRM_XE_DEBUG_MEMIRQ help Enable extra SR-IOV debugging info. diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index 95b6e9d7b7db..ecb4870c3356 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -20,10 +20,21 @@ #include "xe_map.h" #include "xe_memirq.h" #include "xe_sriov.h" -#include "xe_sriov_printk.h" #define memirq_assert(m, condition) xe_tile_assert(memirq_to_tile(m), condition) -#define memirq_debug(m, msg...) xe_sriov_dbg_verbose(memirq_to_xe(m), "MEMIRQ: " msg) +#define memirq_printk(m, _level, _fmt, ...) \ + drm_##_level(&memirq_to_xe(m)->drm, "MEMIRQ%u: " _fmt, \ + memirq_to_tile(m)->id, ##__VA_ARGS__) + +#ifdef CONFIG_DRM_XE_DEBUG_MEMIRQ +#define memirq_debug(m, _fmt, ...) memirq_printk(m, dbg, _fmt, ##__VA_ARGS__) +#else +#define memirq_debug(...) +#endif + +#define memirq_err(m, _fmt, ...) memirq_printk(m, err, _fmt, ##__VA_ARGS__) +#define memirq_err_ratelimited(m, _fmt, ...) \ + memirq_printk(m, err_ratelimited, _fmt, ##__VA_ARGS__) static struct xe_tile *memirq_to_tile(struct xe_memirq *memirq) { @@ -157,8 +168,7 @@ static int memirq_alloc_pages(struct xe_memirq *memirq) return drmm_add_action_or_reset(&xe->drm, __release_xe_bo, memirq->bo); out: - xe_sriov_err(memirq_to_xe(memirq), - "Failed to allocate memirq page (%pe)\n", ERR_PTR(err)); + memirq_err(memirq, "Failed to allocate memirq page (%pe)\n", ERR_PTR(err)); return err; } @@ -299,9 +309,8 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) return 0; failed: - xe_sriov_err(memirq_to_xe(memirq), - "Failed to setup report pages in %s (%pe)\n", - guc_name(guc), ERR_PTR(err)); + memirq_err(memirq, "Failed to setup report pages in %s (%pe)\n", + guc_name(guc), ERR_PTR(err)); return err; } @@ -349,9 +358,9 @@ static bool memirq_received(struct xe_memirq *memirq, struct iosys_map *vector, value = iosys_map_rd(vector, offset, u8); if (value) { if (value != 0xff) - xe_sriov_err_ratelimited(memirq_to_xe(memirq), - "Unexpected memirq value %#x from %s at %u\n", - value, name, offset); + memirq_err_ratelimited(memirq, + "Unexpected memirq value %#x from %s at %u\n", + value, name, offset); iosys_map_wr(vector, offset, u8, 0x00); } -- GitLab From 6fa86e7ad46e3a779e41868e1f082152cc24a6ca Mon Sep 17 00:00:00 2001 From: Ilia Levi <ilia.levi@intel.com> Date: Wed, 18 Sep 2024 08:39:39 +0300 Subject: [PATCH 241/970] drm/xe: Introduce xe_device_uses_memirq() Simplify some memirq usage scenarios and asserts in memirq infrastructure. Signed-off-by: Ilia Levi <ilia.levi@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918053942.1331811-3-illevi@habana.ai --- drivers/gpu/drm/xe/xe_device.c | 8 +++----- drivers/gpu/drm/xe/xe_device.h | 6 ++++++ drivers/gpu/drm/xe/xe_irq.c | 2 +- drivers/gpu/drm/xe/xe_lrc.c | 2 +- drivers/gpu/drm/xe/xe_memirq.c | 22 +++++++--------------- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 709acea5c388..dee25309f239 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -676,11 +676,9 @@ int xe_device_probe(struct xe_device *xe) err = xe_ggtt_init_early(tile->mem.ggtt); if (err) return err; - if (IS_SRIOV_VF(xe)) { - err = xe_memirq_init(&tile->sriov.vf.memirq); - if (err) - return err; - } + err = xe_memirq_init(&tile->sriov.vf.memirq); + if (err) + return err; } for_each_gt(gt, xe, id) { diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h index ca8d8ef6342b..11a63384d3a8 100644 --- a/drivers/gpu/drm/xe/xe_device.h +++ b/drivers/gpu/drm/xe/xe_device.h @@ -10,6 +10,7 @@ #include "xe_device_types.h" #include "xe_gt_types.h" +#include "xe_sriov.h" static inline struct xe_device *to_xe_device(const struct drm_device *dev) { @@ -159,6 +160,11 @@ static inline bool xe_device_has_memirq(struct xe_device *xe) return GRAPHICS_VERx100(xe) >= 1250; } +static inline bool xe_device_uses_memirq(struct xe_device *xe) +{ + return xe_device_has_memirq(xe) && IS_SRIOV_VF(xe); +} + u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size); void xe_device_snapshot_print(struct xe_device *xe, struct drm_printer *p); diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index e501002e8a04..250036abec52 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -135,7 +135,7 @@ void xe_irq_enable_hwe(struct xe_gt *gt) u32 gsc_mask = 0; u32 heci_mask = 0; - if (IS_SRIOV_VF(xe) && xe_device_has_memirq(xe)) + if (xe_device_uses_memirq(xe)) return; if (xe_device_uc_enabled(xe)) { diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index aec7db39c061..50d9521ba9f5 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -602,7 +602,7 @@ static void set_memory_based_intr(u32 *regs, struct xe_hw_engine *hwe) struct xe_memirq *memirq = >_to_tile(hwe->gt)->sriov.vf.memirq; struct xe_device *xe = gt_to_xe(hwe->gt); - if (!IS_SRIOV_VF(xe) || !xe_device_has_memirq(xe)) + if (!xe_device_uses_memirq(xe)) return; regs[CTX_LRM_INT_MASK_ENABLE] = MI_LOAD_REGISTER_MEM | diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index ecb4870c3356..b48be52bf684 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -200,9 +200,7 @@ int xe_memirq_init(struct xe_memirq *memirq) struct xe_device *xe = memirq_to_xe(memirq); int err; - memirq_assert(memirq, IS_SRIOV_VF(xe)); - - if (!xe_device_has_memirq(xe)) + if (!xe_device_uses_memirq(xe)) return 0; err = memirq_alloc_pages(memirq); @@ -226,8 +224,7 @@ int xe_memirq_init(struct xe_memirq *memirq) */ u32 xe_memirq_source_ptr(struct xe_memirq *memirq) { - memirq_assert(memirq, IS_SRIOV_VF(memirq_to_xe(memirq))); - memirq_assert(memirq, xe_device_has_memirq(memirq_to_xe(memirq))); + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET; @@ -244,8 +241,7 @@ u32 xe_memirq_source_ptr(struct xe_memirq *memirq) */ u32 xe_memirq_status_ptr(struct xe_memirq *memirq) { - memirq_assert(memirq, IS_SRIOV_VF(memirq_to_xe(memirq))); - memirq_assert(memirq, xe_device_has_memirq(memirq_to_xe(memirq))); + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET; @@ -262,8 +258,7 @@ u32 xe_memirq_status_ptr(struct xe_memirq *memirq) */ u32 xe_memirq_enable_ptr(struct xe_memirq *memirq) { - memirq_assert(memirq, IS_SRIOV_VF(memirq_to_xe(memirq))); - memirq_assert(memirq, xe_device_has_memirq(memirq_to_xe(memirq))); + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_ENABLE_OFFSET; @@ -289,8 +284,7 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) u32 source, status; int err; - memirq_assert(memirq, IS_SRIOV_VF(memirq_to_xe(memirq))); - memirq_assert(memirq, xe_device_has_memirq(memirq_to_xe(memirq))); + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); source = xe_memirq_source_ptr(memirq) + offset; @@ -325,8 +319,7 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) */ void xe_memirq_reset(struct xe_memirq *memirq) { - memirq_assert(memirq, IS_SRIOV_VF(memirq_to_xe(memirq))); - memirq_assert(memirq, xe_device_has_memirq(memirq_to_xe(memirq))); + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); if (memirq->bo) memirq_set_enable(memirq, false); @@ -343,8 +336,7 @@ void xe_memirq_reset(struct xe_memirq *memirq) */ void xe_memirq_postinstall(struct xe_memirq *memirq) { - memirq_assert(memirq, IS_SRIOV_VF(memirq_to_xe(memirq))); - memirq_assert(memirq, xe_device_has_memirq(memirq_to_xe(memirq))); + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); if (memirq->bo) memirq_set_enable(memirq, true); -- GitLab From 4157849ca3cae488bf0c06184fd3d7c2a5b29dad Mon Sep 17 00:00:00 2001 From: Ilia Levi <ilia.levi@intel.com> Date: Wed, 18 Sep 2024 08:39:40 +0300 Subject: [PATCH 242/970] drm/xe: move memirq out of VF Up until now only VF used Memory Based Interrupts (memirq). Moving it out of VF to cater for other usages, specifically MSI-X. Signed-off-by: Ilia Levi <ilia.levi@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918053942.1331811-4-illevi@habana.ai --- drivers/gpu/drm/xe/xe_device.c | 2 +- drivers/gpu/drm/xe/xe_device_types.h | 6 +++--- drivers/gpu/drm/xe/xe_guc.c | 2 +- drivers/gpu/drm/xe/xe_irq.c | 6 +++--- drivers/gpu/drm/xe/xe_lrc.c | 2 +- drivers/gpu/drm/xe/xe_memirq.c | 19 ++++++++----------- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index dee25309f239..cb5a9fd820cf 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -676,7 +676,7 @@ int xe_device_probe(struct xe_device *xe) err = xe_ggtt_init_early(tile->mem.ggtt); if (err) return err; - err = xe_memirq_init(&tile->sriov.vf.memirq); + err = xe_memirq_init(&tile->memirq); if (err) return err; } diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 4507a5756a05..5ad96d283a71 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -226,14 +226,14 @@ struct xe_tile { struct xe_lmtt lmtt; } pf; struct { - /** @sriov.vf.memirq: Memory Based Interrupts. */ - struct xe_memirq memirq; - /** @sriov.vf.ggtt_balloon: GGTT regions excluded from use. */ struct xe_ggtt_node *ggtt_balloon[2]; } vf; } sriov; + /** @memirq: Memory Based Interrupts. */ + struct xe_memirq memirq; + /** @pcode: tile's PCODE */ struct { /** @pcode.lock: protecting tile's PCODE mailbox data */ diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index 1eb5bb7e8771..b6cd5e941f19 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -866,7 +866,7 @@ int xe_guc_enable_communication(struct xe_guc *guc) struct xe_gt *gt = guc_to_gt(guc); struct xe_tile *tile = gt_to_tile(gt); - err = xe_memirq_init_guc(&tile->sriov.vf.memirq, guc); + err = xe_memirq_init_guc(&tile->memirq, guc); if (err) return err; } else { diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 250036abec52..5eb7775c0fd2 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -567,7 +567,7 @@ static void vf_irq_reset(struct xe_device *xe) for_each_tile(tile, xe, id) { if (xe_device_has_memirq(xe)) - xe_memirq_reset(&tile->sriov.vf.memirq); + xe_memirq_reset(&tile->memirq); else gt_irq_reset(tile); } @@ -610,7 +610,7 @@ static void vf_irq_postinstall(struct xe_device *xe) for_each_tile(tile, xe, id) if (xe_device_has_memirq(xe)) - xe_memirq_postinstall(&tile->sriov.vf.memirq); + xe_memirq_postinstall(&tile->memirq); if (GRAPHICS_VERx100(xe) < 1210) xelp_intr_enable(xe, true); @@ -653,7 +653,7 @@ static irqreturn_t vf_mem_irq_handler(int irq, void *arg) spin_unlock(&xe->irq.lock); for_each_tile(tile, xe, id) - xe_memirq_handler(&tile->sriov.vf.memirq); + xe_memirq_handler(&tile->memirq); return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index 50d9521ba9f5..e40f48f4240f 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -599,7 +599,7 @@ static void set_context_control(u32 *regs, struct xe_hw_engine *hwe) static void set_memory_based_intr(u32 *regs, struct xe_hw_engine *hwe) { - struct xe_memirq *memirq = >_to_tile(hwe->gt)->sriov.vf.memirq; + struct xe_memirq *memirq = >_to_tile(hwe->gt)->memirq; struct xe_device *xe = gt_to_xe(hwe->gt); if (!xe_device_uses_memirq(xe)) diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index b48be52bf684..8b12209d995a 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -19,7 +19,6 @@ #include "xe_hw_engine.h" #include "xe_map.h" #include "xe_memirq.h" -#include "xe_sriov.h" #define memirq_assert(m, condition) xe_tile_assert(memirq_to_tile(m), condition) #define memirq_printk(m, _level, _fmt, ...) \ @@ -38,7 +37,7 @@ static struct xe_tile *memirq_to_tile(struct xe_memirq *memirq) { - return container_of(memirq, struct xe_tile, sriov.vf.memirq); + return container_of(memirq, struct xe_tile, memirq); } static struct xe_device *memirq_to_xe(struct xe_memirq *memirq) @@ -188,9 +187,7 @@ static void memirq_set_enable(struct xe_memirq *memirq, bool enable) * * These allocations are managed and will be implicitly released on unload. * - * Note: This function shall be called only by the VF driver. - * - * If this function fails then VF driver won't be able to operate correctly. + * If this function fails then the driver won't be able to operate correctly. * If `Memory Based Interrupts`_ are not used this function will return 0. * * Return: 0 on success or a negative error code on failure. @@ -217,7 +214,7 @@ int xe_memirq_init(struct xe_memirq *memirq) * xe_memirq_source_ptr - Get GGTT's offset of the `Interrupt Source Report Page`_. * @memirq: the &xe_memirq to query * - * Shall be called only on VF driver when `Memory Based Interrupts`_ are used + * Shall be called when `Memory Based Interrupts`_ are used * and xe_memirq_init() didn't fail. * * Return: GGTT's offset of the `Interrupt Source Report Page`_. @@ -234,7 +231,7 @@ u32 xe_memirq_source_ptr(struct xe_memirq *memirq) * xe_memirq_status_ptr - Get GGTT's offset of the `Interrupt Status Report Page`_. * @memirq: the &xe_memirq to query * - * Shall be called only on VF driver when `Memory Based Interrupts`_ are used + * Shall be called when `Memory Based Interrupts`_ are used * and xe_memirq_init() didn't fail. * * Return: GGTT's offset of the `Interrupt Status Report Page`_. @@ -251,7 +248,7 @@ u32 xe_memirq_status_ptr(struct xe_memirq *memirq) * xe_memirq_enable_ptr - Get GGTT's offset of the Interrupt Enable Mask. * @memirq: the &xe_memirq to query * - * Shall be called only on VF driver when `Memory Based Interrupts`_ are used + * Shall be called when `Memory Based Interrupts`_ are used * and xe_memirq_init() didn't fail. * * Return: GGTT's offset of the Interrupt Enable Mask. @@ -272,7 +269,7 @@ u32 xe_memirq_enable_ptr(struct xe_memirq *memirq) * Register `Interrupt Source Report Page`_ and `Interrupt Status Report Page`_ * to be used by the GuC when `Memory Based Interrupts`_ are required. * - * Shall be called only on VF driver when `Memory Based Interrupts`_ are used + * Shall be called when `Memory Based Interrupts`_ are used * and xe_memirq_init() didn't fail. * * Return: 0 on success or a negative error code on failure. @@ -314,7 +311,7 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) * * This is part of the driver IRQ setup flow. * - * This function shall only be used by the VF driver on platforms that use + * This function shall only be used on platforms that use * `Memory Based Interrupts`_. */ void xe_memirq_reset(struct xe_memirq *memirq) @@ -331,7 +328,7 @@ void xe_memirq_reset(struct xe_memirq *memirq) * * This is part of the driver IRQ setup flow. * - * This function shall only be used by the VF driver on platforms that use + * This function shall only be used on platforms that use * `Memory Based Interrupts`_. */ void xe_memirq_postinstall(struct xe_memirq *memirq) -- GitLab From ef6103d20f97f201d2483f16fea363f87d7caba8 Mon Sep 17 00:00:00 2001 From: Ilia Levi <ilia.levi@intel.com> Date: Wed, 18 Sep 2024 08:39:41 +0300 Subject: [PATCH 243/970] drm/xe: memirq infra changes for MSI-X When using MSI-X, hw engines report interrupt status and source to engine instance 0. For this scenario, in order to differentiate between the engines, we need to pass different status/source pointers in the LRC. The requirements on those pointers are: - Interrupt status should be 4KiB aligned - Interrupt source should be 64 bytes aligned To accommodate this, we duplicate the current memirq page layout - allocating a page for each engine instance and pass this page in the LRC. Note that the same page can be reused for different engine types. For example, an LRC executing on CCS #x will have pointers to page #x, and an LRC executing on BCS #x will have the same pointers. Thus, to locate the proper page, the pointer accessors were modified to receive the hw engine. Signed-off-by: Ilia Levi <ilia.levi@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918053942.1331811-5-illevi@habana.ai --- drivers/gpu/drm/xe/xe_device.h | 8 ++- drivers/gpu/drm/xe/xe_lrc.c | 4 +- drivers/gpu/drm/xe/xe_memirq.c | 89 +++++++++++++++++++++++----- drivers/gpu/drm/xe/xe_memirq.h | 5 +- drivers/gpu/drm/xe/xe_memirq_types.h | 4 +- 5 files changed, 89 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h index 11a63384d3a8..4c3f0ebe78a9 100644 --- a/drivers/gpu/drm/xe/xe_device.h +++ b/drivers/gpu/drm/xe/xe_device.h @@ -155,6 +155,12 @@ static inline bool xe_device_has_sriov(struct xe_device *xe) return xe->info.has_sriov; } +static inline bool xe_device_has_msix(struct xe_device *xe) +{ + /* TODO: change this when MSI-X support is fully integrated */ + return false; +} + static inline bool xe_device_has_memirq(struct xe_device *xe) { return GRAPHICS_VERx100(xe) >= 1250; @@ -162,7 +168,7 @@ static inline bool xe_device_has_memirq(struct xe_device *xe) static inline bool xe_device_uses_memirq(struct xe_device *xe) { - return xe_device_has_memirq(xe) && IS_SRIOV_VF(xe); + return xe_device_has_memirq(xe) && (IS_SRIOV_VF(xe) || xe_device_has_msix(xe)); } u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size); diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index e40f48f4240f..f0976230012a 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -613,9 +613,9 @@ static void set_memory_based_intr(u32 *regs, struct xe_hw_engine *hwe) regs[CTX_LRI_INT_REPORT_PTR] = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(2) | MI_LRI_LRM_CS_MMIO | MI_LRI_FORCE_POSTED; regs[CTX_INT_STATUS_REPORT_REG] = RING_INT_STATUS_RPT_PTR(0).addr; - regs[CTX_INT_STATUS_REPORT_PTR] = xe_memirq_status_ptr(memirq); + regs[CTX_INT_STATUS_REPORT_PTR] = xe_memirq_status_ptr(memirq, hwe); regs[CTX_INT_SRC_REPORT_REG] = RING_INT_SRC_RPT_PTR(0).addr; - regs[CTX_INT_SRC_REPORT_PTR] = xe_memirq_source_ptr(memirq); + regs[CTX_INT_SRC_REPORT_PTR] = xe_memirq_source_ptr(memirq, hwe); } static int lrc_ring_mi_mode(struct xe_hw_engine *hwe) diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index 8b12209d995a..ae4279a7f947 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -115,6 +115,44 @@ static const char *guc_name(struct xe_guc *guc) * | | * | | * +-----------+ + * + * + * MSI-X use case + * + * When using MSI-X, hw engines report interrupt status and source to engine + * instance 0. For this scenario, in order to differentiate between the + * engines, we need to pass different status/source pointers in the LRC. + * + * The requirements on those pointers are: + * - Interrupt status should be 4KiB aligned + * - Interrupt source should be 64 bytes aligned + * + * To accommodate this, we duplicate the memirq page layout above - + * allocating a page for each engine instance and pass this page in the LRC. + * Note that the same page can be reused for different engine types. + * For example, an LRC executing on CCS #x will have pointers to page #x, + * and an LRC executing on BCS #x will have the same pointers. + * + * :: + * + * 0x0000 +==============================+ <== page for instance 0 (BCS0, CCS0, etc.) + * | Interrupt Status Report Page | + * 0x0400 +==============================+ + * | Interrupt Source Report Page | + * 0x0440 +==============================+ + * | Interrupt Enable Mask | + * +==============================+ + * | Not used | + * 0x1000 +==============================+ <== page for instance 1 (BCS1, CCS1, etc.) + * | Interrupt Status Report Page | + * 0x1400 +==============================+ + * | Interrupt Source Report Page | + * 0x1440 +==============================+ + * | Not used | + * 0x2000 +==============================+ <== page for instance 2 (BCS2, CCS2, etc.) + * | ... | + * +==============================+ + * */ static void __release_xe_bo(struct drm_device *drm, void *arg) @@ -124,18 +162,30 @@ static void __release_xe_bo(struct drm_device *drm, void *arg) xe_bo_unpin_map_no_vm(bo); } +static inline bool hw_reports_to_instance_zero(struct xe_memirq *memirq) +{ + /* + * When the HW engines are configured to use MSI-X, + * they report interrupt status and source to the offset of + * engine instance 0. + */ + return xe_device_has_msix(memirq_to_xe(memirq)); +} + static int memirq_alloc_pages(struct xe_memirq *memirq) { struct xe_device *xe = memirq_to_xe(memirq); struct xe_tile *tile = memirq_to_tile(memirq); + size_t bo_size = hw_reports_to_instance_zero(memirq) ? + XE_HW_ENGINE_MAX_INSTANCE * SZ_4K : SZ_4K; struct xe_bo *bo; int err; - BUILD_BUG_ON(!IS_ALIGNED(XE_MEMIRQ_SOURCE_OFFSET, SZ_64)); - BUILD_BUG_ON(!IS_ALIGNED(XE_MEMIRQ_STATUS_OFFSET, SZ_4K)); + BUILD_BUG_ON(!IS_ALIGNED(XE_MEMIRQ_SOURCE_OFFSET(0), SZ_64)); + BUILD_BUG_ON(!IS_ALIGNED(XE_MEMIRQ_STATUS_OFFSET(0), SZ_4K)); /* XXX: convert to managed bo */ - bo = xe_bo_create_pin_map(xe, tile, NULL, SZ_4K, + bo = xe_bo_create_pin_map(xe, tile, NULL, bo_size, ttm_bo_type_kernel, XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT | @@ -150,19 +200,20 @@ static int memirq_alloc_pages(struct xe_memirq *memirq) memirq_assert(memirq, !xe_bo_is_vram(bo)); memirq_assert(memirq, !memirq->bo); - iosys_map_memset(&bo->vmap, 0, 0, SZ_4K); + iosys_map_memset(&bo->vmap, 0, 0, bo_size); memirq->bo = bo; - memirq->source = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_SOURCE_OFFSET); - memirq->status = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_STATUS_OFFSET); + memirq->source = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_SOURCE_OFFSET(0)); + memirq->status = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_STATUS_OFFSET(0)); memirq->mask = IOSYS_MAP_INIT_OFFSET(&bo->vmap, XE_MEMIRQ_ENABLE_OFFSET); memirq_assert(memirq, !memirq->source.is_iomem); memirq_assert(memirq, !memirq->status.is_iomem); memirq_assert(memirq, !memirq->mask.is_iomem); - memirq_debug(memirq, "page offsets: source %#x status %#x\n", - xe_memirq_source_ptr(memirq), xe_memirq_status_ptr(memirq)); + memirq_debug(memirq, "page offsets: bo %#x bo_size %zu source %#x status %#x\n", + xe_bo_ggtt_addr(bo), bo_size, XE_MEMIRQ_SOURCE_OFFSET(0), + XE_MEMIRQ_STATUS_OFFSET(0)); return drmm_add_action_or_reset(&xe->drm, __release_xe_bo, memirq->bo); @@ -213,35 +264,45 @@ int xe_memirq_init(struct xe_memirq *memirq) /** * xe_memirq_source_ptr - Get GGTT's offset of the `Interrupt Source Report Page`_. * @memirq: the &xe_memirq to query + * @hwe: the hw engine for which we want the report page * * Shall be called when `Memory Based Interrupts`_ are used * and xe_memirq_init() didn't fail. * * Return: GGTT's offset of the `Interrupt Source Report Page`_. */ -u32 xe_memirq_source_ptr(struct xe_memirq *memirq) +u32 xe_memirq_source_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { + u16 instance; + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); - return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET; + instance = hw_reports_to_instance_zero(memirq) ? hwe->instance : 0; + + return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET(instance); } /** * xe_memirq_status_ptr - Get GGTT's offset of the `Interrupt Status Report Page`_. * @memirq: the &xe_memirq to query + * @hwe: the hw engine for which we want the report page * * Shall be called when `Memory Based Interrupts`_ are used * and xe_memirq_init() didn't fail. * * Return: GGTT's offset of the `Interrupt Status Report Page`_. */ -u32 xe_memirq_status_ptr(struct xe_memirq *memirq) +u32 xe_memirq_status_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { + u16 instance; + memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); - return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET; + instance = hw_reports_to_instance_zero(memirq) ? hwe->instance : 0; + + return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET(instance); } /** @@ -284,8 +345,8 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); memirq_assert(memirq, memirq->bo); - source = xe_memirq_source_ptr(memirq) + offset; - status = xe_memirq_status_ptr(memirq) + offset * SZ_16; + source = xe_memirq_source_ptr(memirq, NULL) + offset; + status = xe_memirq_status_ptr(memirq, NULL) + offset * SZ_16; err = xe_guc_self_cfg64(guc, GUC_KLV_SELF_CFG_MEMIRQ_SOURCE_ADDR_KEY, source); diff --git a/drivers/gpu/drm/xe/xe_memirq.h b/drivers/gpu/drm/xe/xe_memirq.h index 2d40d03c3095..15efae2a7a55 100644 --- a/drivers/gpu/drm/xe/xe_memirq.h +++ b/drivers/gpu/drm/xe/xe_memirq.h @@ -9,12 +9,13 @@ #include <linux/types.h> struct xe_guc; +struct xe_hw_engine; struct xe_memirq; int xe_memirq_init(struct xe_memirq *memirq); -u32 xe_memirq_source_ptr(struct xe_memirq *memirq); -u32 xe_memirq_status_ptr(struct xe_memirq *memirq); +u32 xe_memirq_source_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe); +u32 xe_memirq_status_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe); u32 xe_memirq_enable_ptr(struct xe_memirq *memirq); void xe_memirq_reset(struct xe_memirq *memirq); diff --git a/drivers/gpu/drm/xe/xe_memirq_types.h b/drivers/gpu/drm/xe/xe_memirq_types.h index 625b6b8736cc..9d0f6c1cdb9d 100644 --- a/drivers/gpu/drm/xe/xe_memirq_types.h +++ b/drivers/gpu/drm/xe/xe_memirq_types.h @@ -11,9 +11,9 @@ struct xe_bo; /* ISR */ -#define XE_MEMIRQ_STATUS_OFFSET 0x0 +#define XE_MEMIRQ_STATUS_OFFSET(inst) ((inst) * SZ_4K + 0x0) /* IIR */ -#define XE_MEMIRQ_SOURCE_OFFSET 0x400 +#define XE_MEMIRQ_SOURCE_OFFSET(inst) ((inst) * SZ_4K + 0x400) /* IMR */ #define XE_MEMIRQ_ENABLE_OFFSET 0x440 -- GitLab From aa4e216827553f487c121264579807c35b5571c8 Mon Sep 17 00:00:00 2001 From: Ilia Levi <ilia.levi@intel.com> Date: Wed, 18 Sep 2024 08:39:42 +0300 Subject: [PATCH 244/970] drm/xe: memirq handler changes Expose an interrupt processing handler for a single hw engine. Refactor code to use this handler from the VF. This handler also caters for the MSI-X mode, where the hardware engines report interrupt source and status to the offset of engine instance zero (this usage will be introduced in upcoming MSI-X enabling series). Signed-off-by: Ilia Levi <ilia.levi@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918053942.1331811-6-illevi@habana.ai --- drivers/gpu/drm/xe/xe_hw_engine.c | 28 +++++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_memirq.c | 31 ++++++++++++++++++++++++------- drivers/gpu/drm/xe/xe_memirq.h | 1 + 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index a7abc4b67e67..d7408d06ee20 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -460,6 +460,30 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe) xe_rtp_process_to_sr(&ctx, engine_entries, &hwe->reg_sr); } +static const struct engine_info *find_engine_info(enum xe_engine_class class, int instance) +{ + const struct engine_info *info; + enum xe_hw_engine_id id; + + for (id = 0; id < XE_NUM_HW_ENGINES; ++id) { + info = &engine_infos[id]; + if (info->class == class && info->instance == instance) + return info; + } + + return NULL; +} + +static u16 get_msix_irq_offset(struct xe_gt *gt, enum xe_engine_class class) +{ + /* For MSI-X, hw engines report to offset of engine instance zero */ + const struct engine_info *info = find_engine_info(class, 0); + + xe_gt_assert(gt, info); + + return info ? info->irq_offset : 0; +} + static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe, enum xe_hw_engine_id id) { @@ -479,7 +503,9 @@ static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe, hwe->class = info->class; hwe->instance = info->instance; hwe->mmio_base = info->mmio_base; - hwe->irq_offset = info->irq_offset; + hwe->irq_offset = xe_device_has_msix(gt_to_xe(gt)) ? + get_msix_irq_offset(gt, info->class) : + info->irq_offset; hwe->domain = info->domain; hwe->name = info->name; hwe->fence_irq = >->fence_irq[info->class]; diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index ae4279a7f947..3f8d4ca64302 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -437,6 +437,28 @@ static void memirq_dispatch_guc(struct xe_memirq *memirq, struct iosys_map *stat xe_guc_irq_handler(guc, GUC_INTR_GUC2HOST); } +/** + * xe_memirq_hwe_handler - Check and process interrupts for a specific HW engine. + * @memirq: the &xe_memirq + * @hwe: the hw engine to process + * + * This function reads and dispatches `Memory Based Interrupts` for the provided HW engine. + */ +void xe_memirq_hwe_handler(struct xe_memirq *memirq, struct xe_hw_engine *hwe) +{ + u16 offset = hwe->irq_offset; + u16 instance = hw_reports_to_instance_zero(memirq) ? hwe->instance : 0; + struct iosys_map src_offset = IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, + XE_MEMIRQ_SOURCE_OFFSET(instance)); + + if (memirq_received(memirq, &src_offset, offset, "SRC")) { + struct iosys_map status_offset = + IOSYS_MAP_INIT_OFFSET(&memirq->bo->vmap, + XE_MEMIRQ_STATUS_OFFSET(instance) + offset * SZ_16); + memirq_dispatch_engine(memirq, &status_offset, hwe); + } +} + /** * xe_memirq_handler - The `Memory Based Interrupts`_ Handler. * @memirq: the &xe_memirq @@ -464,13 +486,8 @@ void xe_memirq_handler(struct xe_memirq *memirq) if (gt->tile != tile) continue; - for_each_hw_engine(hwe, gt, id) { - if (memirq_received(memirq, &memirq->source, hwe->irq_offset, "SRC")) { - map = IOSYS_MAP_INIT_OFFSET(&memirq->status, - hwe->irq_offset * SZ_16); - memirq_dispatch_engine(memirq, &map, hwe); - } - } + for_each_hw_engine(hwe, gt, id) + xe_memirq_hwe_handler(memirq, hwe); } /* GuC and media GuC (if present) must be checked separately */ diff --git a/drivers/gpu/drm/xe/xe_memirq.h b/drivers/gpu/drm/xe/xe_memirq.h index 15efae2a7a55..06130650e9d6 100644 --- a/drivers/gpu/drm/xe/xe_memirq.h +++ b/drivers/gpu/drm/xe/xe_memirq.h @@ -20,6 +20,7 @@ u32 xe_memirq_enable_ptr(struct xe_memirq *memirq); void xe_memirq_reset(struct xe_memirq *memirq); void xe_memirq_postinstall(struct xe_memirq *memirq); +void xe_memirq_hwe_handler(struct xe_memirq *memirq, struct xe_hw_engine *hwe); void xe_memirq_handler(struct xe_memirq *memirq); int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc); -- GitLab From 84e8d59651879b2ff8499bddbbc9549b7f1a646b Mon Sep 17 00:00:00 2001 From: David Lawrence Glanzman <davidglanzman@yahoo.com> Date: Tue, 17 Sep 2024 00:44:08 -0400 Subject: [PATCH 245/970] ASoC: amd: yc: Add quirk for HP Dragonfly pro one Adds a quirk entry to enable the mic on HP Dragonfly pro one laptop Signed-off-by: David Lawrence Glanzman <davidglanzman@yahoo.com> Link: https://patch.msgid.link/1249c09bd6bf696b59d087a4f546ae397828656c.camel@yahoo.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 0523c16305db..1846c0008a14 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -437,6 +437,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "8A3E"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), + DMI_MATCH(DMI_BOARD_NAME, "8A7F"), + } + }, { .driver_data = &acp6x_card, .matches = { -- GitLab From 85109780543b5100aba1d0842b6a7c3142be74d2 Mon Sep 17 00:00:00 2001 From: Tang Bin <tangbin@cmss.chinamobile.com> Date: Sat, 14 Sep 2024 16:16:08 +0800 Subject: [PATCH 246/970] ASoC: topology: Fix incorrect addressing assignments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variable 'kc' is handled in the function soc_tplg_control_dbytes_create(), and 'kc->private_value' is assigned to 'sbe', so In the function soc_tplg_dbytes_create(), the right 'sbe' should be 'kc.private_value', the same logical error in the function soc_tplg_dmixer_create(), thus fix them. Fixes: 0867278200f7 ("ASoC: topology: Unify code for creating standalone and widget bytes control") Fixes: 4654ca7cc8d6 ("ASoC: topology: Unify code for creating standalone and widget mixer control") Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com> Reviewed-by: Amadeusz SÅ‚awiÅ„ski <amadeuszx.slawinski@linux.intel.com> Link: https://patch.msgid.link/20240914081608.3514-1-tangbin@cmss.chinamobile.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/soc-topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index af3158cdc8d5..97517423d1f0 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -889,7 +889,7 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, size_t size) return ret; /* register dynamic object */ - sbe = (struct soc_bytes_ext *)&kc.private_value; + sbe = (struct soc_bytes_ext *)kc.private_value; INIT_LIST_HEAD(&sbe->dobj.list); sbe->dobj.type = SND_SOC_DOBJ_BYTES; @@ -923,7 +923,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, size_t size) return ret; /* register dynamic object */ - sm = (struct soc_mixer_control *)&kc.private_value; + sm = (struct soc_mixer_control *)kc.private_value; INIT_LIST_HEAD(&sm->dobj.list); sm->dobj.type = SND_SOC_DOBJ_MIXER; -- GitLab From 5b40191152282e1f25d7b9826bcda41be927b39f Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi <rodrigo.vivi@intel.com> Date: Fri, 6 Sep 2024 15:06:03 +0300 Subject: [PATCH 247/970] drm/xe/pciids: Add PVC's PCI device ID macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PVC PCI IDs to the xe_pciids.h header. They're not yet used in the driver. Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> Acked-by: Simona Vetter <simona.vetter@ffwll.ch> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/6ac1829493a53a3fec889c746648d627a0296892.1725624296.git.jani.nikula@intel.com --- include/drm/intel/xe_pciids.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h index 79001afa7d27..67baa7c2246a 100644 --- a/include/drm/intel/xe_pciids.h +++ b/include/drm/intel/xe_pciids.h @@ -191,6 +191,22 @@ MACRO__(0x7D60, ## __VA_ARGS__), \ MACRO__(0x7DD5, ## __VA_ARGS__) +/* PVC */ +#define XE_PVC_IDS(MACRO__, ...) \ + MACRO__(0x0B69, ## __VA_ARGS__), \ + MACRO__(0x0B6E, ## __VA_ARGS__), \ + MACRO__(0x0BD4, ## __VA_ARGS__), \ + MACRO__(0x0BD5, ## __VA_ARGS__), \ + MACRO__(0x0BD6, ## __VA_ARGS__), \ + MACRO__(0x0BD7, ## __VA_ARGS__), \ + MACRO__(0x0BD8, ## __VA_ARGS__), \ + MACRO__(0x0BD9, ## __VA_ARGS__), \ + MACRO__(0x0BDA, ## __VA_ARGS__), \ + MACRO__(0x0BDB, ## __VA_ARGS__), \ + MACRO__(0x0BE0, ## __VA_ARGS__), \ + MACRO__(0x0BE1, ## __VA_ARGS__), \ + MACRO__(0x0BE5, ## __VA_ARGS__) + #define XE_LNL_IDS(MACRO__, ...) \ MACRO__(0x6420, ## __VA_ARGS__), \ MACRO__(0x64A0, ## __VA_ARGS__), \ -- GitLab From 49f5ee951f11f4d6a124f00f71b2590507811a55 Mon Sep 17 00:00:00 2001 From: Baojun Xu <baojun.xu@ti.com> Date: Thu, 19 Sep 2024 15:57:43 +0800 Subject: [PATCH 248/970] ALSA: hda/tas2781: Add new quirk for Lenovo Y990 Laptop Add new vendor_id and subsystem_id in quirk for Lenovo Y990 Laptop. Signed-off-by: Baojun Xu <baojun.xu@ti.com> Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20240919075743.259-1-baojun.xu@ti.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9471396bbca6..f787ff4182d4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10843,6 +10843,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38d2, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x38d7, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x38df, "Y990 YG DUAL", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x17aa, 0x38f9, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x17aa, 0x38fa, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), -- GitLab From 87d45979140e49611696e97e2b33df572bf4fa24 Mon Sep 17 00:00:00 2001 From: Andrew Kreimer <algonell@gmail.com> Date: Sun, 15 Sep 2024 15:39:43 +0300 Subject: [PATCH 249/970] drm/rockchip: Fix a typo Fix a typo in comments. Reported-by: Matthew Wilcox <willy@infradead.org> Signed-off-by: Andrew Kreimer <algonell@gmail.com> Acked-by: Andy Yan<andyshrk@163.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240915123943.105118-1-algonell@gmail.com --- drivers/gpu/drm/rockchip/cdn-dp-reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h index 441248b7a79e..c7780ae3272a 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h @@ -77,7 +77,7 @@ #define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830 #define SOURCE_PIF_SW_RESET 0x30834 -/* bellow registers need access by mailbox */ +/* below registers need access by mailbox */ /* source car addr */ #define SOURCE_HDTX_CAR 0x0900 #define SOURCE_DPTX_CAR 0x0904 -- GitLab From 3303a206ae7474b2f8a5d17d8df9de08bac16ca5 Mon Sep 17 00:00:00 2001 From: Jonas Karlman <jonas@kwiboo.se> Date: Sun, 8 Sep 2024 14:54:58 +0000 Subject: [PATCH 250/970] drm/rockchip: dw_hdmi: Filter modes based on hdmiphy_clk RK3228 and RK3328 clock rate is being validated against a mpll config table intended for a Synopsys phy, and not the used inno-hdmi-phy. Instead get a reference to the hdmiphy clk and validate rates against it to enable use of HDMI2.0 modes, e.g. 4K@60Hz, on RK3228 and RK3328. For Synopsis phy the max_tmds_clock validation is sufficient. Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Tested-by: Diederik de Haas <didi.debian@cknow.org> # Rock64 Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-2-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 35 ++++++++++----------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 240552eb517f..36cc700766fd 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -76,6 +76,7 @@ struct rockchip_hdmi { struct rockchip_encoder encoder; const struct rockchip_hdmi_chip_data *chip_data; const struct dw_hdmi_plat_data *plat_data; + struct clk *hdmiphy_clk; struct clk *ref_clk; struct clk *grf_clk; struct dw_hdmi *hdmi; @@ -251,10 +252,7 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, const struct drm_display_mode *mode) { struct rockchip_hdmi *hdmi = data; - const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; int pclk = mode->clock * 1000; - bool exact_match = hdmi->plat_data->phy_force_vendor; - int i; if (hdmi->chip_data->max_tmds_clock && mode->clock > hdmi->chip_data->max_tmds_clock) @@ -263,26 +261,18 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data, if (hdmi->ref_clk) { int rpclk = clk_round_rate(hdmi->ref_clk, pclk); - if (abs(rpclk - pclk) > pclk / 1000) + if (rpclk < 0 || abs(rpclk - pclk) > pclk / 1000) return MODE_NOCLOCK; } - for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) { - /* - * For vendor specific phys force an exact match of the pixelclock - * to preserve the original behaviour of the driver. - */ - if (exact_match && pclk == mpll_cfg[i].mpixelclock) - return MODE_OK; - /* - * The Synopsys phy can work with pixelclocks up to the value given - * in the corresponding mpll_cfg entry. - */ - if (!exact_match && pclk <= mpll_cfg[i].mpixelclock) - return MODE_OK; + if (hdmi->hdmiphy_clk) { + int rpclk = clk_round_rate(hdmi->hdmiphy_clk, pclk); + + if (rpclk < 0 || abs(rpclk - pclk) > pclk / 1000) + return MODE_NOCLOCK; } - return MODE_BAD; + return MODE_OK; } static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) @@ -607,6 +597,15 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, return ret; } + if (hdmi->phy) { + struct of_phandle_args clkspec; + + clkspec.np = hdmi->phy->dev.of_node; + hdmi->hdmiphy_clk = of_clk_get_from_provider(&clkspec); + if (IS_ERR(hdmi->hdmiphy_clk)) + hdmi->hdmiphy_clk = NULL; + } + if (hdmi->chip_data == &rk3568_chip_data) { regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1, HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK | -- GitLab From 6e94e2871eb706a17692acf7ef85ecf2789f6433 Mon Sep 17 00:00:00 2001 From: Yakir Yang <ykk@rock-chips.com> Date: Sun, 8 Sep 2024 14:54:59 +0000 Subject: [PATCH 251/970] drm/rockchip: dw_hdmi: Adjust cklvl & txlvl for RF/EMI Dut to the high HDMI signal voltage driver, Mickey have meet a serious RF/EMI problem, so we decided to reduce HDMI signal voltage to a proper value. The default params for phy is cklvl = 20 & txlvl = 13 (RF/EMI failed) ck: lvl = 13, term=100, vlo = 2.71, vhi=3.14, vswing = 0.43 tx: lvl = 20, term=100, vlo = 2.81, vhi=3.16, vswing = 0.35 1. We decided to reduce voltage value to lower, but VSwing still keep high, RF/EMI have been improved but still failed. ck: lvl = 6, term=100, vlo = 2.61, vhi=3.11, vswing = 0.50 tx: lvl = 6, term=100, vlo = 2.61, vhi=3.11, vswing = 0.50 2. We try to keep voltage value and vswing both lower, then RF/EMI test all passed ;) ck: lvl = 11, term= 66, vlo = 2.68, vhi=3.09, vswing = 0.40 tx: lvl = 11, term= 66, vlo = 2.68, vhi=3.09, vswing = 0.40 When we back to run HDMI different test and single-end test, we see different test passed, but signle-end test failed. The oscilloscope show that simgle-end clock's VL value is 1.78v (which remind LowLimit should not lower then 2.6v). 3. That's to say there are some different between PHY document and measure value. And according to experiment 2 results, we need to higher clock voltage and lower data voltage, then we can keep RF/EMI satisfied and single-end & differen test passed. ck: lvl = 9, term=100, vlo = 2.65, vhi=3.12, vswing = 0.47 tx: lvl = 16, term=100, vlo = 2.75, vhi=3.15, vswing = 0.39 Signed-off-by: Yakir Yang <ykk@rock-chips.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-3-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 36cc700766fd..fc5e87285a91 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -202,7 +202,7 @@ static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { static const struct dw_hdmi_phy_config rockchip_phy_config[] = { /*pixelclk symbol term vlev*/ { 74250000, 0x8009, 0x0004, 0x0272}, - { 148500000, 0x802b, 0x0004, 0x028d}, + { 165000000, 0x802b, 0x0004, 0x0209}, { 297000000, 0x8039, 0x0005, 0x028d}, { ~0UL, 0x0000, 0x0000, 0x0000} }; -- GitLab From b60c86d305f46483d3ed0743e9ec97a76addcabc Mon Sep 17 00:00:00 2001 From: Nickey Yang <nickey.yang@rock-chips.com> Date: Sun, 8 Sep 2024 14:55:00 +0000 Subject: [PATCH 252/970] drm/rockchip: dw_hdmi: Add phy_config for 594Mhz pixel clock Add phy_config for 594Mhz pixel clock used for HDMI2.0 display modes. Signed-off-by: Nickey Yang <nickey.yang@rock-chips.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-4-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index fc5e87285a91..dffbae005a96 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -204,6 +204,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = { { 74250000, 0x8009, 0x0004, 0x0272}, { 165000000, 0x802b, 0x0004, 0x0209}, { 297000000, 0x8039, 0x0005, 0x028d}, + { 594000000, 0x8039, 0x0000, 0x019d}, { ~0UL, 0x0000, 0x0000, 0x0000} }; -- GitLab From 7d324630f3515bd6e11cadeb1d748bd74ecc9664 Mon Sep 17 00:00:00 2001 From: Douglas Anderson <dianders@chromium.org> Date: Sun, 8 Sep 2024 14:55:01 +0000 Subject: [PATCH 253/970] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always Jitter was improved by lowering the MPLL bandwidth to account for high frequency noise in the rk3288 PLL. In each case MPLL bandwidth was lowered only enough to get us a comfortable margin. We believe that lowering the bandwidth like this is safe given sufficient testing. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Yakir Yang <ykk@rock-chips.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-5-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index dffbae005a96..a050a65af8f2 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -179,23 +179,9 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { /* pixelclk bpp8 bpp10 bpp12 */ { - 40000000, { 0x0018, 0x0018, 0x0018 }, - }, { - 65000000, { 0x0028, 0x0028, 0x0028 }, - }, { - 66000000, { 0x0038, 0x0038, 0x0038 }, - }, { - 74250000, { 0x0028, 0x0038, 0x0038 }, - }, { - 83500000, { 0x0028, 0x0038, 0x0038 }, - }, { - 146250000, { 0x0038, 0x0038, 0x0038 }, - }, { - 148500000, { 0x0000, 0x0038, 0x0038 }, - }, { 600000000, { 0x0000, 0x0000, 0x0000 }, }, { - ~0UL, { 0x0000, 0x0000, 0x0000}, + ~0UL, { 0x0000, 0x0000, 0x0000 }, } }; -- GitLab From 7595c7ef17ffe70d0f4fdda01f87f105a12de66b Mon Sep 17 00:00:00 2001 From: Douglas Anderson <dianders@chromium.org> Date: Sun, 8 Sep 2024 14:55:02 +0000 Subject: [PATCH 254/970] drm/rockchip: dw_hdmi: Use auto-generated tables The previous tables for mpll_cfg and curr_ctrl were created using the 20-pages of example settings provided by the PHY vendor. Those example settings weren't particularly dense, so there were places where we were guessing what the settings would be for 10-bit and 12-bit (not that we use those anyway). It was also always a lot of extra work every time we wanted to add a new clock rate since we had to cross-reference several tables. In <https://crrev.com/c/285855> I've gone through the work to figure out how to generate this table automatically. Let's now use the automatically generated table and then we'll never need to look at it again. We only support 8-bit mode right now and only support a small number of clock rates and I've verified that the only 8-bit rate that was affected was 148.5. That mode appears to have been wrong in the old table. Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Yakir Yang <ykk@rock-chips.com> Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-6-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 104 ++++++++++---------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index a050a65af8f2..090d8c0f306f 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -92,74 +92,70 @@ static struct rockchip_hdmi *to_rockchip_hdmi(struct drm_encoder *encoder) static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { - 27000000, { - { 0x00b3, 0x0000}, - { 0x2153, 0x0000}, - { 0x40f3, 0x0000} + 30666000, { + { 0x00b3, 0x0000 }, + { 0x2153, 0x0000 }, + { 0x40f3, 0x0000 }, }, }, { - 36000000, { - { 0x00b3, 0x0000}, - { 0x2153, 0x0000}, - { 0x40f3, 0x0000} + 36800000, { + { 0x00b3, 0x0000 }, + { 0x2153, 0x0000 }, + { 0x40a2, 0x0001 }, }, }, { - 40000000, { - { 0x00b3, 0x0000}, - { 0x2153, 0x0000}, - { 0x40f3, 0x0000} + 46000000, { + { 0x00b3, 0x0000 }, + { 0x2142, 0x0001 }, + { 0x40a2, 0x0001 }, }, }, { - 54000000, { - { 0x0072, 0x0001}, - { 0x2142, 0x0001}, - { 0x40a2, 0x0001}, + 61333000, { + { 0x0072, 0x0001 }, + { 0x2142, 0x0001 }, + { 0x40a2, 0x0001 }, }, }, { - 65000000, { - { 0x0072, 0x0001}, - { 0x2142, 0x0001}, - { 0x40a2, 0x0001}, + 73600000, { + { 0x0072, 0x0001 }, + { 0x2142, 0x0001 }, + { 0x4061, 0x0002 }, }, }, { - 66000000, { - { 0x013e, 0x0003}, - { 0x217e, 0x0002}, - { 0x4061, 0x0002} + 92000000, { + { 0x0072, 0x0001 }, + { 0x2145, 0x0002 }, + { 0x4061, 0x0002 }, }, }, { - 74250000, { - { 0x0072, 0x0001}, - { 0x2145, 0x0002}, - { 0x4061, 0x0002} + 122666000, { + { 0x0051, 0x0002 }, + { 0x2145, 0x0002 }, + { 0x4061, 0x0002 }, }, }, { - 83500000, { - { 0x0072, 0x0001}, + 147200000, { + { 0x0051, 0x0002 }, + { 0x2145, 0x0002 }, + { 0x4064, 0x0003 }, }, }, { - 108000000, { - { 0x0051, 0x0002}, - { 0x2145, 0x0002}, - { 0x4061, 0x0002} + 184000000, { + { 0x0051, 0x0002 }, + { 0x214c, 0x0003 }, + { 0x4064, 0x0003 }, }, }, { - 106500000, { - { 0x0051, 0x0002}, - { 0x2145, 0x0002}, - { 0x4061, 0x0002} - }, - }, { - 146250000, { - { 0x0051, 0x0002}, - { 0x2145, 0x0002}, - { 0x4061, 0x0002} + 226666000, { + { 0x0040, 0x0003 }, + { 0x214c, 0x0003 }, + { 0x4064, 0x0003 }, }, }, { - 148500000, { - { 0x0051, 0x0003}, - { 0x214c, 0x0003}, - { 0x4064, 0x0003} + 272000000, { + { 0x0040, 0x0003 }, + { 0x214c, 0x0003 }, + { 0x5a64, 0x0003 }, }, }, { 340000000, { @@ -167,11 +163,17 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { 0x3b4c, 0x0003 }, { 0x5a64, 0x0003 }, }, + }, { + 600000000, { + { 0x1a40, 0x0003 }, + { 0x3b4c, 0x0003 }, + { 0x5a64, 0x0003 }, + }, }, { ~0UL, { - { 0x00a0, 0x000a }, - { 0x2001, 0x000f }, - { 0x4002, 0x000f }, + { 0x0000, 0x0000 }, + { 0x0000, 0x0000 }, + { 0x0000, 0x0000 }, }, } }; -- GitLab From 28f0ae48e7fdbd6cdcf3972c8d8686a529ae1ede Mon Sep 17 00:00:00 2001 From: Jonas Karlman <jonas@kwiboo.se> Date: Sun, 8 Sep 2024 14:55:03 +0000 Subject: [PATCH 255/970] drm/rockchip: dw_hdmi: Enable 4K@60Hz mode on RK3399 and RK356x Use a maximum TMDS clock rate limit of 594MHz to enable use of HDMI2.0 modes, e.g. 4K@60Hz, on RK3399 and RK3568. Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Tested-by: Diederik de Haas <didi.debian@cknow.org> # Quartz64 Model B Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-7-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 090d8c0f306f..96e1097f993d 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -481,7 +481,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL), .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL), - .max_tmds_clock = 340000, + .max_tmds_clock = 594000, }; static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { @@ -495,7 +495,7 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { static struct rockchip_hdmi_chip_data rk3568_chip_data = { .lcdsel_grf_reg = -1, - .max_tmds_clock = 340000, + .max_tmds_clock = 594000, }; static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = { -- GitLab From 0c4558a1bc2df9b6e6fb311de9cab192b0943426 Mon Sep 17 00:00:00 2001 From: Jonas Karlman <jonas@kwiboo.se> Date: Sun, 8 Sep 2024 14:55:04 +0000 Subject: [PATCH 256/970] drm/rockchip: Load crtc devices in preferred order On RK3399 the VOPL is loaded before VOPB and get registered as crtc-0. However, on RK3288 and PX30 VOPB is gets registered as crtc-0 instead of VOPL. With VOPL registered as crtc-0 the kernel kms client is not able to enable 4K display modes for console use on RK3399. Load VOPB before VOPL to help kernel kms client make use of 4K display modes for console use on RK3399. Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240908145511.3331451-8-jonas@kwiboo.se --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 44d769d9234d..b84451d59187 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -354,11 +354,34 @@ static void rockchip_drm_match_remove(struct device *dev) device_link_del(link); } +/* list of preferred vop devices */ +static const char *const rockchip_drm_match_preferred[] = { + "rockchip,rk3399-vop-big", + NULL, +}; + static struct component_match *rockchip_drm_match_add(struct device *dev) { struct component_match *match = NULL; + struct device_node *port; int i; + /* add preferred vop device match before adding driver device matches */ + for (i = 0; ; i++) { + port = of_parse_phandle(dev->of_node, "ports", i); + if (!port) + break; + + if (of_device_is_available(port->parent) && + of_device_compatible_match(port->parent, + rockchip_drm_match_preferred)) + drm_of_component_match_add(dev, &match, + component_compare_of, + port->parent); + + of_node_put(port); + } + for (i = 0; i < num_rockchip_sub_drivers; i++) { struct platform_driver *drv = rockchip_sub_drivers[i]; struct device *p = NULL, *d; -- GitLab From 01e709aeaf913a4d0e04f9957d399cf6fc3b5455 Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com> Date: Thu, 19 Sep 2024 15:16:52 +0000 Subject: [PATCH 257/970] ASoC: cs35l45: Corrects cs35l45_get_clk_freq_id function data type Changes cs35l45_get_clk_freq_id() function data type from unsigned int to int. This function is returns a positive index value if successful or a negative error code if unsuccessful. Functionally there should be no difference as long as the unsigned int return is interpreted as an int, however it should be corrected for readability. Signed-off-by: Ricardo Rivera-Matos <rriveram@opensource.cirrus.com> Link: https://patch.msgid.link/20240919151654.197337-1-rriveram@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/codecs/cs35l45-tables.c | 2 +- sound/soc/codecs/cs35l45.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs35l45-tables.c b/sound/soc/codecs/cs35l45-tables.c index e1cebb9e4dc6..405dab137b3b 100644 --- a/sound/soc/codecs/cs35l45-tables.c +++ b/sound/soc/codecs/cs35l45-tables.c @@ -315,7 +315,7 @@ static const struct { { 0x3B, 24576000 }, }; -unsigned int cs35l45_get_clk_freq_id(unsigned int freq) +int cs35l45_get_clk_freq_id(unsigned int freq) { int i; diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h index e2ebcf58d7e0..7a790d2acac7 100644 --- a/sound/soc/codecs/cs35l45.h +++ b/sound/soc/codecs/cs35l45.h @@ -507,7 +507,7 @@ extern const struct dev_pm_ops cs35l45_pm_ops; extern const struct regmap_config cs35l45_i2c_regmap; extern const struct regmap_config cs35l45_spi_regmap; int cs35l45_apply_patch(struct cs35l45_private *cs35l45); -unsigned int cs35l45_get_clk_freq_id(unsigned int freq); +int cs35l45_get_clk_freq_id(unsigned int freq); int cs35l45_probe(struct cs35l45_private *cs35l45); void cs35l45_remove(struct cs35l45_private *cs35l45); -- GitLab From dc0dce6d63d22e8319e27b6a41be7368376f9471 Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Wed, 18 Sep 2024 09:05:03 -0700 Subject: [PATCH 258/970] drm/xe: Use helper for ASID -> VM in GPU faults and access counters Normalize both code paths with a helper. Fixes a possible leak access counter path too. Suggested-by: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918160503.2021315-1-matthew.brost@intel.com --- drivers/gpu/drm/xe/xe_gt_pagefault.c | 39 +++++++++++++++------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c index 5c3af2bb5402..79c426dc2505 100644 --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c @@ -185,6 +185,21 @@ static int handle_vma_pagefault(struct xe_tile *tile, struct pagefault *pf, return err; } +static struct xe_vm *asid_to_vm(struct xe_device *xe, u32 asid) +{ + struct xe_vm *vm; + + down_read(&xe->usm.lock); + vm = xa_load(&xe->usm.asid_to_vm, asid); + if (vm && xe_vm_in_fault_mode(vm)) + xe_vm_get(vm); + else + vm = ERR_PTR(-EINVAL); + up_read(&xe->usm.lock); + + return vm; +} + static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) { struct xe_device *xe = gt_to_xe(gt); @@ -197,16 +212,9 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) if (pf->trva_fault) return -EFAULT; - /* ASID to VM */ - down_read(&xe->usm.lock); - vm = xa_load(&xe->usm.asid_to_vm, pf->asid); - if (vm && xe_vm_in_fault_mode(vm)) - xe_vm_get(vm); - else - vm = NULL; - up_read(&xe->usm.lock); - if (!vm) - return -EINVAL; + vm = asid_to_vm(xe, pf->asid); + if (IS_ERR(vm)) + return PTR_ERR(vm); /* * TODO: Change to read lock? Using write lock for simplicity. @@ -548,14 +556,9 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc) if (acc->access_type != ACC_TRIGGER) return -EINVAL; - /* ASID to VM */ - down_read(&xe->usm.lock); - vm = xa_load(&xe->usm.asid_to_vm, acc->asid); - if (vm) - xe_vm_get(vm); - up_read(&xe->usm.lock); - if (!vm || !xe_vm_in_fault_mode(vm)) - return -EINVAL; + vm = asid_to_vm(xe, acc->asid); + if (IS_ERR(vm)) + return PTR_ERR(vm); down_read(&vm->lock); -- GitLab From 2facdd6002ad67357dd7f77a388ae602bc910ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom@linux.intel.com> Date: Fri, 28 Apr 2023 14:52:32 +0200 Subject: [PATCH 259/970] dma-buf/dma-fence: Use a successful read_trylock() annotation for dma_fence_begin_signalling() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Condsider the following call sequence: /* Upper layer */ dma_fence_begin_signalling(); lock(tainted_shared_lock); /* Driver callback */ dma_fence_begin_signalling(); ... The driver might here use a utility that is annotated as intended for the dma-fence signalling critical path. Now if the upper layer isn't correctly annotated yet for whatever reason, resulting in /* Upper layer */ lock(tainted_shared_lock); /* Driver callback */ dma_fence_begin_signalling(); We will receive a false lockdep locking order violation notification from dma_fence_begin_signalling(). However entering a dma-fence signalling critical section itself doesn't block and could not cause a deadlock. So use a successful read_trylock() annotation instead for dma_fence_begin_signalling(). That will make sure that the locking order is correctly registered in the first case, and doesn't register any locking order in the second case. The alternative is of course to make sure that the "Upper layer" is always correctly annotated. But experience shows that's not easily achievable in all cases. Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20230428125233.228353-1-thomas.hellstrom@linux.intel.com --- drivers/dma-buf/dma-fence.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 0393a9bba3a8..f8303ae99acf 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -309,8 +309,8 @@ bool dma_fence_begin_signalling(void) if (in_atomic()) return true; - /* ... and non-recursive readlock */ - lock_acquire(&dma_fence_lockdep_map, 0, 0, 1, 1, NULL, _RET_IP_); + /* ... and non-recursive successful read_trylock */ + lock_acquire(&dma_fence_lockdep_map, 0, 1, 1, 1, NULL, _RET_IP_); return false; } @@ -341,7 +341,7 @@ void __dma_fence_might_wait(void) lock_map_acquire(&dma_fence_lockdep_map); lock_map_release(&dma_fence_lockdep_map); if (tmp) - lock_acquire(&dma_fence_lockdep_map, 0, 0, 1, 1, NULL, _THIS_IP_); + lock_acquire(&dma_fence_lockdep_map, 0, 1, 1, 1, NULL, _THIS_IP_); } #endif -- GitLab From bf36793fa260cb68cc817f311f1f683788261796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@baylibre.com> Date: Fri, 20 Sep 2024 17:10:08 +0200 Subject: [PATCH 260/970] ALSA: Drop explicit initialization of struct i2c_device_id::driver_data to 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These drivers don't use the driver_data member of struct i2c_device_id, so don't explicitly initialize this member. This prepares putting driver_data in an anonymous union which requires either no initialization or named designators. But it's also a nice cleanup on its own. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Link: https://patch.msgid.link/20240920151009.499188-2-u.kleine-koenig@baylibre.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/aoa/codecs/onyx.c | 2 +- sound/aoa/codecs/tas.c | 2 +- sound/pci/hda/cs35l41_hda_i2c.c | 2 +- sound/pci/hda/tas2781_hda_i2c.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index e90e03bb0dc0..ac347a14f282 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -1040,7 +1040,7 @@ static void onyx_i2c_remove(struct i2c_client *client) } static const struct i2c_device_id onyx_i2c_id[] = { - { "MAC,pcm3052", 0 }, + { "MAC,pcm3052" }, { } }; MODULE_DEVICE_TABLE(i2c,onyx_i2c_id); diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index be9822ebf9f8..804b2ebbe28f 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -927,7 +927,7 @@ static void tas_i2c_remove(struct i2c_client *client) } static const struct i2c_device_id tas_i2c_id[] = { - { "MAC,tas3004", 0 }, + { "MAC,tas3004" }, { } }; MODULE_DEVICE_TABLE(i2c,tas_i2c_id); diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index 603e9bff3a71..bb84740c8520 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -39,7 +39,7 @@ static void cs35l41_hda_i2c_remove(struct i2c_client *clt) } static const struct i2c_device_id cs35l41_hda_i2c_id[] = { - { "cs35l41-hda", 0 }, + { "cs35l41-hda" }, {} }; diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index f58f434e7110..4b9dc84ce6bb 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -951,7 +951,7 @@ static const struct dev_pm_ops tas2781_hda_pm_ops = { }; static const struct i2c_device_id tas2781_hda_i2c_id[] = { - { "tas2781-hda", 0 }, + { "tas2781-hda" }, {} }; -- GitLab From 35667a0330612bb25a689e4d3a687d47cede1d7a Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com> Date: Thu, 12 Sep 2024 17:29:06 +0530 Subject: [PATCH 261/970] drm/xe/pciid: Add new PCI id for ARL Add new PCI id for ARL platform. v2: Fix typo in PCI id (SaiTeja) Signed-off-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com> Reviewed-by: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912115906.2730577-1-dnyaneshwar.bhadane@intel.com --- include/drm/intel/xe_pciids.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h index 67baa7c2246a..65520a90c17c 100644 --- a/include/drm/intel/xe_pciids.h +++ b/include/drm/intel/xe_pciids.h @@ -181,7 +181,8 @@ MACRO__(0x7D41, ## __VA_ARGS__), \ MACRO__(0x7D51, ## __VA_ARGS__), \ MACRO__(0x7D67, ## __VA_ARGS__), \ - MACRO__(0x7DD1, ## __VA_ARGS__) + MACRO__(0x7DD1, ## __VA_ARGS__), \ + MACRO__(0xB640, ## __VA_ARGS__) /* MTL */ #define XE_MTL_IDS(MACRO__, ...) \ -- GitLab From 79cc4d2bf2c7b90d9f06e3f67e541978e96b9a64 Mon Sep 17 00:00:00 2001 From: Vivek Kasireddy <vivek.kasireddy@intel.com> Date: Wed, 21 Aug 2024 21:58:06 -0700 Subject: [PATCH 262/970] MAINTAINERS: udmabuf: Add myself as co-maintainer for udmabuf driver I would like to help maintain the udmabuf driver, in light of the recent changes that converted the driver to use folios instead of pages. Furthermore, I also contribute to Qemu's virtio-gpu module (and UI modules), that are primary users of udmabuf driver. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240822045806.3563883-1-vivek.kasireddy@intel.com --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 333ed0718175..77efbded2bfe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -23912,6 +23912,7 @@ F: lib/iov_iter.c USERSPACE DMA BUFFER DRIVER M: Gerd Hoffmann <kraxel@redhat.com> +M: Vivek Kasireddy <vivek.kasireddy@intel.com> L: dri-devel@lists.freedesktop.org S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git -- GitLab From f0bbcc258e81288212c2092c587ae06428196598 Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:24 +0800 Subject: [PATCH 263/970] udmabuf: pre-fault when first page fault The current udmabuf mmap only fills the physical memory to the corresponding virtual address when the user actually accesses the virtual address. However, the current udmabuf has already obtained and pinned the folio upon completion of the creation.This means that the physical memory has already been acquired, rather than being accessed dynamically. As a result, the page fault has lost its purpose as a demanding page. Due to the fact that page fault requires trapping into kernel mode and filling in when accessing the corresponding virtual address in mmap, when creating a large size udmabuf, this represents a considerable overhead. This patch fill the pfn into page table, and then pre-fault each pfn into vma, when first access. Notice, if anything wrong , we do not return an error during this pre-fault step. However, an error will be returned if the failure occurs when the addr is truly accessed Suggested-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-2-link@vivo.com --- drivers/dma-buf/udmabuf.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 047c3cd2ceff..2170d975cc76 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -43,7 +43,8 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) struct vm_area_struct *vma = vmf->vma; struct udmabuf *ubuf = vma->vm_private_data; pgoff_t pgoff = vmf->pgoff; - unsigned long pfn; + unsigned long addr, pfn; + vm_fault_t ret; if (pgoff >= ubuf->pagecount) return VM_FAULT_SIGBUS; @@ -51,7 +52,35 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) pfn = folio_pfn(ubuf->folios[pgoff]); pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT; - return vmf_insert_pfn(vma, vmf->address, pfn); + ret = vmf_insert_pfn(vma, vmf->address, pfn); + if (ret & VM_FAULT_ERROR) + return ret; + + /* pre fault */ + pgoff = vma->vm_pgoff; + addr = vma->vm_start; + + for (; addr < vma->vm_end; pgoff++, addr += PAGE_SIZE) { + if (addr == vmf->address) + continue; + + if (WARN_ON(pgoff >= ubuf->pagecount)) + break; + + pfn = folio_pfn(ubuf->folios[pgoff]); + pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT; + + /** + * If the below vmf_insert_pfn() fails, we do not return an + * error here during this pre-fault step. However, an error + * will be returned if the failure occurs when the addr is + * truly accessed. + */ + if (vmf_insert_pfn(vma, addr, pfn) & VM_FAULT_ERROR) + break; + } + + return ret; } static const struct vm_operations_struct udmabuf_vm_ops = { -- GitLab From 1c0844c6184e658064e14c4335885785ad3bf84b Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:25 +0800 Subject: [PATCH 264/970] udmabuf: change folios array from kmalloc to kvmalloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When PAGE_SIZE 4096, MAX_PAGE_ORDER 10, 64bit machine, page_alloc only support 4MB. If above this, trigger this warn and return NULL. udmabuf can change size limit, if change it to 3072(3GB), and then alloc 3GB udmabuf, will fail create. [ 4080.876581] ------------[ cut here ]------------ [ 4080.876843] WARNING: CPU: 3 PID: 2015 at mm/page_alloc.c:4556 __alloc_pages+0x2c8/0x350 [ 4080.878839] RIP: 0010:__alloc_pages+0x2c8/0x350 [ 4080.879470] Call Trace: [ 4080.879473] <TASK> [ 4080.879473] ? __alloc_pages+0x2c8/0x350 [ 4080.879475] ? __warn.cold+0x8e/0xe8 [ 4080.880647] ? __alloc_pages+0x2c8/0x350 [ 4080.880909] ? report_bug+0xff/0x140 [ 4080.881175] ? handle_bug+0x3c/0x80 [ 4080.881556] ? exc_invalid_op+0x17/0x70 [ 4080.881559] ? asm_exc_invalid_op+0x1a/0x20 [ 4080.882077] ? udmabuf_create+0x131/0x400 Because MAX_PAGE_ORDER, kmalloc can max alloc 4096 * (1 << 10), 4MB memory, each array entry is pointer(8byte), so can save 524288 pages(2GB). Further more, costly order(order 3) may not be guaranteed that it can be applied for, due to fragmentation. This patch change udmabuf array use kvmalloc_array, this can fallback alloc into vmalloc, which can guarantee allocation for any size and does not affect the performance of kmalloc allocations. Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Christian König <christian.koenig@amd.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-3-link@vivo.com --- drivers/dma-buf/udmabuf.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 2170d975cc76..ba9dbc7caf71 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -109,7 +109,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) dma_resv_assert_held(buf->resv); - pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); if (!pages) return -ENOMEM; @@ -117,7 +117,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) pages[pg] = &ubuf->folios[pg]->page; vaddr = vm_map_ram(pages, ubuf->pagecount, -1); - kfree(pages); + kvfree(pages); if (!vaddr) return -EINVAL; @@ -225,8 +225,8 @@ static void release_udmabuf(struct dma_buf *buf) put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL); unpin_all_folios(&ubuf->unpin_list); - kfree(ubuf->offsets); - kfree(ubuf->folios); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); kfree(ubuf); } @@ -351,14 +351,14 @@ static long udmabuf_create(struct miscdevice *device, if (!ubuf->pagecount) goto err; - ubuf->folios = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), - GFP_KERNEL); + ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), + GFP_KERNEL); if (!ubuf->folios) { ret = -ENOMEM; goto err; } - ubuf->offsets = kcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), - GFP_KERNEL); + ubuf->offsets = kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), + GFP_KERNEL); if (!ubuf->offsets) { ret = -ENOMEM; goto err; @@ -372,7 +372,7 @@ static long udmabuf_create(struct miscdevice *device, goto err; pgcnt = list[i].size >> PAGE_SHIFT; - folios = kmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); + folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); if (!folios) { ret = -ENOMEM; goto err; @@ -382,7 +382,7 @@ static long udmabuf_create(struct miscdevice *device, ret = memfd_pin_folios(memfd, list[i].offset, end, folios, pgcnt, &pgoff); if (ret <= 0) { - kfree(folios); + kvfree(folios); if (!ret) ret = -EINVAL; goto err; @@ -411,7 +411,7 @@ static long udmabuf_create(struct miscdevice *device, } } - kfree(folios); + kvfree(folios); fput(memfd); memfd = NULL; } @@ -427,8 +427,8 @@ static long udmabuf_create(struct miscdevice *device, if (memfd) fput(memfd); unpin_all_folios(&ubuf->unpin_list); - kfree(ubuf->offsets); - kfree(ubuf->folios); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); kfree(ubuf); return ret; } -- GitLab From 18d7de823b7150344d242c3677e65d68c5271b04 Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:26 +0800 Subject: [PATCH 265/970] udmabuf: fix vmap_udmabuf error page set Currently vmap_udmabuf set page's array by each folio. But, ubuf->folios is only contain's the folio's head page. That mean we repeatedly mapped the folio head page to the vmalloc area. Due to udmabuf can use hugetlb, if HVO enabled, tail page may not exist, so, we can't use page array to map, instead, use pfn array. By this, we removed page usage in udmabuf totally. Fixes: 5e72b2b41a21 ("udmabuf: convert udmabuf driver to use folios") Suggested-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-4-link@vivo.com --- drivers/dma-buf/Kconfig | 1 + drivers/dma-buf/udmabuf.c | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index b46eb8a552d7..fee04fdb0822 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -36,6 +36,7 @@ config UDMABUF depends on DMA_SHARED_BUFFER depends on MEMFD_CREATE || COMPILE_TEST depends on MMU + select VMAP_PFN help A driver to let userspace turn memfd regions into dma-bufs. Qemu can use this to create host dmabufs for guest framebuffers. diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index ba9dbc7caf71..aa182a9dcdfa 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -103,21 +103,29 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) { struct udmabuf *ubuf = buf->priv; - struct page **pages; + unsigned long *pfns; void *vaddr; pgoff_t pg; dma_resv_assert_held(buf->resv); - pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); - if (!pages) + /** + * HVO may free tail pages, so just use pfn to map each folio + * into vmalloc area. + */ + pfns = kvmalloc_array(ubuf->pagecount, sizeof(*pfns), GFP_KERNEL); + if (!pfns) return -ENOMEM; - for (pg = 0; pg < ubuf->pagecount; pg++) - pages[pg] = &ubuf->folios[pg]->page; + for (pg = 0; pg < ubuf->pagecount; pg++) { + unsigned long pfn = folio_pfn(ubuf->folios[pg]); - vaddr = vm_map_ram(pages, ubuf->pagecount, -1); - kvfree(pages); + pfn += ubuf->offsets[pg] >> PAGE_SHIFT; + pfns[pg] = pfn; + } + + vaddr = vmap_pfn(pfns, ubuf->pagecount, PAGE_KERNEL); + kvfree(pfns); if (!vaddr) return -EINVAL; -- GitLab From 164fd9efd46531fddfaa933d394569259896642b Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:27 +0800 Subject: [PATCH 266/970] udmabuf: udmabuf_create pin folio codestyle cleanup This patch aim to simplify the memfd folio pin during the udmabuf create. No functional changes. This patch create a udmabuf_pin_folios function, in this, do the memfd pin folio and then record each pinned folio, offset. This patch simplify the pinned folio record, iter by each pinned folio, and then record each offset in it. Compare to iter by pgcnt, more readable. Suggested-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-5-link@vivo.com --- drivers/dma-buf/udmabuf.c | 137 +++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 61 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index aa182a9dcdfa..9d58c045b8eb 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -291,9 +291,6 @@ static int check_memfd_seals(struct file *memfd) { int seals; - if (!memfd) - return -EBADFD; - if (!shmem_file(memfd) && !is_file_hugepages(memfd)) return -EBADFD; @@ -328,17 +325,68 @@ static int export_udmabuf(struct udmabuf *ubuf, return dma_buf_fd(buf, flags); } +static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd, + loff_t start, loff_t size) +{ + pgoff_t pgoff, pgcnt, upgcnt = ubuf->pagecount; + struct folio **folios = NULL; + u32 cur_folio, cur_pgcnt; + long nr_folios; + long ret = 0; + loff_t end; + + pgcnt = size >> PAGE_SHIFT; + folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); + if (!folios) + return -ENOMEM; + + end = start + (pgcnt << PAGE_SHIFT) - 1; + nr_folios = memfd_pin_folios(memfd, start, end, folios, pgcnt, &pgoff); + if (nr_folios <= 0) { + ret = nr_folios ? nr_folios : -EINVAL; + goto end; + } + + cur_pgcnt = 0; + for (cur_folio = 0; cur_folio < nr_folios; ++cur_folio) { + pgoff_t subpgoff = pgoff; + size_t fsize = folio_size(folios[cur_folio]); + + ret = add_to_unpin_list(&ubuf->unpin_list, folios[cur_folio]); + if (ret < 0) + goto end; + + for (; subpgoff < fsize; subpgoff += PAGE_SIZE) { + ubuf->folios[upgcnt] = folios[cur_folio]; + ubuf->offsets[upgcnt] = subpgoff; + ++upgcnt; + + if (++cur_pgcnt >= pgcnt) + goto end; + } + + /** + * In a given range, only the first subpage of the first folio + * has an offset, that is returned by memfd_pin_folios(). + * The first subpages of other folios (in the range) have an + * offset of 0. + */ + pgoff = 0; + } +end: + ubuf->pagecount = upgcnt; + kvfree(folios); + return ret; +} + static long udmabuf_create(struct miscdevice *device, struct udmabuf_create_list *head, struct udmabuf_create_item *list) { - pgoff_t pgoff, pgcnt, pglimit, pgbuf = 0; - long nr_folios, ret = -EINVAL; - struct file *memfd = NULL; - struct folio **folios; + pgoff_t pgcnt = 0, pglimit; struct udmabuf *ubuf; - u32 i, j, k, flags; - loff_t end; + long ret = -EINVAL; + u32 i, flags; ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL); if (!ubuf) @@ -347,81 +395,50 @@ static long udmabuf_create(struct miscdevice *device, INIT_LIST_HEAD(&ubuf->unpin_list); pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; for (i = 0; i < head->count; i++) { - if (!IS_ALIGNED(list[i].offset, PAGE_SIZE)) + if (!PAGE_ALIGNED(list[i].offset)) goto err; - if (!IS_ALIGNED(list[i].size, PAGE_SIZE)) + if (!PAGE_ALIGNED(list[i].size)) goto err; - ubuf->pagecount += list[i].size >> PAGE_SHIFT; - if (ubuf->pagecount > pglimit) + + pgcnt += list[i].size >> PAGE_SHIFT; + if (pgcnt > pglimit) goto err; } - if (!ubuf->pagecount) + if (!pgcnt) goto err; - ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios), - GFP_KERNEL); + ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios), GFP_KERNEL); if (!ubuf->folios) { ret = -ENOMEM; goto err; } - ubuf->offsets = kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), - GFP_KERNEL); + + ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL); if (!ubuf->offsets) { ret = -ENOMEM; goto err; } - pgbuf = 0; for (i = 0; i < head->count; i++) { - memfd = fget(list[i].memfd); - ret = check_memfd_seals(memfd); - if (ret < 0) - goto err; + struct file *memfd = fget(list[i].memfd); - pgcnt = list[i].size >> PAGE_SHIFT; - folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); - if (!folios) { - ret = -ENOMEM; + if (!memfd) { + ret = -EBADFD; goto err; } - end = list[i].offset + (pgcnt << PAGE_SHIFT) - 1; - ret = memfd_pin_folios(memfd, list[i].offset, end, - folios, pgcnt, &pgoff); - if (ret <= 0) { - kvfree(folios); - if (!ret) - ret = -EINVAL; + ret = check_memfd_seals(memfd); + if (ret < 0) { + fput(memfd); goto err; } - nr_folios = ret; - pgoff >>= PAGE_SHIFT; - for (j = 0, k = 0; j < pgcnt; j++) { - ubuf->folios[pgbuf] = folios[k]; - ubuf->offsets[pgbuf] = pgoff << PAGE_SHIFT; - - if (j == 0 || ubuf->folios[pgbuf-1] != folios[k]) { - ret = add_to_unpin_list(&ubuf->unpin_list, - folios[k]); - if (ret < 0) { - kfree(folios); - goto err; - } - } - - pgbuf++; - if (++pgoff == folio_nr_pages(folios[k])) { - pgoff = 0; - if (++k == nr_folios) - break; - } - } - - kvfree(folios); + ret = udmabuf_pin_folios(ubuf, memfd, list[i].offset, + list[i].size); fput(memfd); - memfd = NULL; + if (ret) + goto err; } flags = head->flags & UDMABUF_FLAGS_CLOEXEC ? O_CLOEXEC : 0; @@ -432,8 +449,6 @@ static long udmabuf_create(struct miscdevice *device, return ret; err: - if (memfd) - fput(memfd); unpin_all_folios(&ubuf->unpin_list); kvfree(ubuf->offsets); kvfree(ubuf->folios); -- GitLab From 5d8157961fd183ce2a9be1f4fd9c775ae9e94536 Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:28 +0800 Subject: [PATCH 267/970] udmabuf: introduce udmabuf init and deinit helper After udmabuf is allocated, its resources need to be initialized, including various array structures. The current array structure has already been greatly expanded. Also, before udmabuf needs to be kfree, the occupied resources need to be released. This part is repetitive and maybe overlooked. This patch give a helper function when init and deinit, by this, reduce duplicate code. Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-6-link@vivo.com --- drivers/dma-buf/udmabuf.c | 52 +++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 9d58c045b8eb..40ebff2c77f4 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -224,6 +224,28 @@ static int add_to_unpin_list(struct list_head *unpin_list, return 0; } +static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt) +{ + INIT_LIST_HEAD(&ubuf->unpin_list); + + ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios), GFP_KERNEL); + if (!ubuf->folios) + return -ENOMEM; + + ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL); + if (!ubuf->offsets) + return -ENOMEM; + + return 0; +} + +static __always_inline void deinit_udmabuf(struct udmabuf *ubuf) +{ + unpin_all_folios(&ubuf->unpin_list); + kvfree(ubuf->offsets); + kvfree(ubuf->folios); +} + static void release_udmabuf(struct dma_buf *buf) { struct udmabuf *ubuf = buf->priv; @@ -232,9 +254,7 @@ static void release_udmabuf(struct dma_buf *buf) if (ubuf->sg) put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL); - unpin_all_folios(&ubuf->unpin_list); - kvfree(ubuf->offsets); - kvfree(ubuf->folios); + deinit_udmabuf(ubuf); kfree(ubuf); } @@ -392,33 +412,24 @@ static long udmabuf_create(struct miscdevice *device, if (!ubuf) return -ENOMEM; - INIT_LIST_HEAD(&ubuf->unpin_list); pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; for (i = 0; i < head->count; i++) { if (!PAGE_ALIGNED(list[i].offset)) - goto err; + goto err_noinit; if (!PAGE_ALIGNED(list[i].size)) - goto err; + goto err_noinit; pgcnt += list[i].size >> PAGE_SHIFT; if (pgcnt > pglimit) - goto err; + goto err_noinit; } if (!pgcnt) - goto err; + goto err_noinit; - ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios), GFP_KERNEL); - if (!ubuf->folios) { - ret = -ENOMEM; + ret = init_udmabuf(ubuf, pgcnt); + if (ret) goto err; - } - - ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL); - if (!ubuf->offsets) { - ret = -ENOMEM; - goto err; - } for (i = 0; i < head->count; i++) { struct file *memfd = fget(list[i].memfd); @@ -449,9 +460,8 @@ static long udmabuf_create(struct miscdevice *device, return ret; err: - unpin_all_folios(&ubuf->unpin_list); - kvfree(ubuf->offsets); - kvfree(ubuf->folios); + deinit_udmabuf(ubuf); +err_noinit: kfree(ubuf); return ret; } -- GitLab From 6b68b74a081b259e4a4bcbcb03d0f2e3156fe3c6 Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:29 +0800 Subject: [PATCH 268/970] udmabuf: remove udmabuf_folio Currently, udmabuf handles folio by create an unpin list to record each folio obtained from the list and unpinning them when released. To maintain this, many struct have been established. However, maintain this requires a significant amount of memory and iter the list is a substantial overhead, which is not friendly to the CPU cache. When create, we arranged the folio array in the order of pin and set the offset according to pgcnt. So, if record each pinned folio when create, then can easy unpin it. Compare to use list to record it, an array also can do this. Hence, this patch setup a pinned_folios array(size is the pgcnt) to instead of udmabuf_folio struct, it record each folio which pinned when invoke memfd_pin_folios, then unpin folio by iter pinned_folios. Note that, since a folio may be pinned multiple times, each folio can be added to pinned_folios multiple times, depend on how many times the folio has been pinned when create. Compare to udmabuf_folio(24 byte size), a folio pointer is 8 byte, if no large folio - each folio is PAGE_SIZE - and need to unpin when release. So need to record each folio, by this patch, each folio can save 16 byte. But if large folio used, depend on the large folio's number, the pinned_folios array may take more memory, but it still can makes unpin access more cache-friendly. Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-7-link@vivo.com --- drivers/dma-buf/udmabuf.c | 65 +++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 40ebff2c77f4..24badfefa6b4 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -27,15 +27,21 @@ MODULE_PARM_DESC(size_limit_mb, "Max size of a dmabuf, in megabytes. Default is struct udmabuf { pgoff_t pagecount; struct folio **folios; + + /** + * Unlike folios, pinned_folios is only used for unpin. + * So, nr_pinned is not the same to pagecount, the pinned_folios + * only set each folio which already pinned when udmabuf_create. + * Note that, since a folio may be pinned multiple times, each folio + * can be added to pinned_folios multiple times, depending on how many + * times the folio has been pinned when create. + */ + pgoff_t nr_pinned; + struct folio **pinned_folios; + struct sg_table *sg; struct miscdevice *device; pgoff_t *offsets; - struct list_head unpin_list; -}; - -struct udmabuf_folio { - struct folio *folio; - struct list_head list; }; static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) @@ -196,38 +202,18 @@ static void unmap_udmabuf(struct dma_buf_attachment *at, return put_sg_table(at->dev, sg, direction); } -static void unpin_all_folios(struct list_head *unpin_list) +static void unpin_all_folios(struct udmabuf *ubuf) { - struct udmabuf_folio *ubuf_folio; + pgoff_t i; - while (!list_empty(unpin_list)) { - ubuf_folio = list_first_entry(unpin_list, - struct udmabuf_folio, list); - unpin_folio(ubuf_folio->folio); + for (i = 0; i < ubuf->nr_pinned; ++i) + unpin_folio(ubuf->pinned_folios[i]); - list_del(&ubuf_folio->list); - kfree(ubuf_folio); - } -} - -static int add_to_unpin_list(struct list_head *unpin_list, - struct folio *folio) -{ - struct udmabuf_folio *ubuf_folio; - - ubuf_folio = kzalloc(sizeof(*ubuf_folio), GFP_KERNEL); - if (!ubuf_folio) - return -ENOMEM; - - ubuf_folio->folio = folio; - list_add_tail(&ubuf_folio->list, unpin_list); - return 0; + kvfree(ubuf->pinned_folios); } static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt) { - INIT_LIST_HEAD(&ubuf->unpin_list); - ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios), GFP_KERNEL); if (!ubuf->folios) return -ENOMEM; @@ -236,12 +222,18 @@ static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt) if (!ubuf->offsets) return -ENOMEM; + ubuf->pinned_folios = kvmalloc_array(pgcnt, + sizeof(*ubuf->pinned_folios), + GFP_KERNEL); + if (!ubuf->pinned_folios) + return -ENOMEM; + return 0; } static __always_inline void deinit_udmabuf(struct udmabuf *ubuf) { - unpin_all_folios(&ubuf->unpin_list); + unpin_all_folios(ubuf); kvfree(ubuf->offsets); kvfree(ubuf->folios); } @@ -348,9 +340,11 @@ static int export_udmabuf(struct udmabuf *ubuf, static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd, loff_t start, loff_t size) { - pgoff_t pgoff, pgcnt, upgcnt = ubuf->pagecount; + pgoff_t nr_pinned = ubuf->nr_pinned; + pgoff_t upgcnt = ubuf->pagecount; struct folio **folios = NULL; u32 cur_folio, cur_pgcnt; + pgoff_t pgoff, pgcnt; long nr_folios; long ret = 0; loff_t end; @@ -372,9 +366,7 @@ static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd, pgoff_t subpgoff = pgoff; size_t fsize = folio_size(folios[cur_folio]); - ret = add_to_unpin_list(&ubuf->unpin_list, folios[cur_folio]); - if (ret < 0) - goto end; + ubuf->pinned_folios[nr_pinned++] = folios[cur_folio]; for (; subpgoff < fsize; subpgoff += PAGE_SIZE) { ubuf->folios[upgcnt] = folios[cur_folio]; @@ -395,6 +387,7 @@ static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd, } end: ubuf->pagecount = upgcnt; + ubuf->nr_pinned = nr_pinned; kvfree(folios); return ret; } -- GitLab From c87a1268e9c589cd346e820298e5ef35f884aea0 Mon Sep 17 00:00:00 2001 From: Huan Yang <link@vivo.com> Date: Wed, 18 Sep 2024 10:52:30 +0800 Subject: [PATCH 269/970] udmabuf: reuse folio array when pin folios When invoke memfd_pin_folios, we need offer an array to save each folio which we pinned. The current way is dynamic alloc an array(use kvmalloc), get folios, save into udmabuf and then free. Depend on the size, kvmalloc can do something different: Below PAGE_SIZE, slab allocator will be used, which have good alloc performance, due to it cached page. PAGE_SIZE - PCP Order, PCP(per-cpu-pageset) also given buddy page a cache in each CPU, so different CPU no need to hold some lock(zone or some) to get the locally page. If PCP cached page, the access also fast. PAGE_SIZE - BUDDY_MAX, try to get page from buddy, due to kvmalloc adjusted the gfp flags, if zone freelist can't alloc page(fast path), we will not enter slowpath to reclaim memory. Due to need hold lock and check, may slow, but still fast than vmalloc. Anything wrong will fallback into vmalloc to alloc memory, it obtains contiguous virtual addresses by loop alloc order 0 page(PAGE_SIZE), and then map it into vmalloc area. If necessary, page alloc may enter slowpath to reclaim memory. Hence, if fallback into vmalloc, it's slow. When create, we need to iter each udmabuf item, then pin it's range folios, if each item's range folio's count is large, we may fallback each into vmalloc. This patch find the largest range folio in items, then alloc this size's folio array. When pin range folios, reuse this array. Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-8-link@vivo.com --- drivers/dma-buf/udmabuf.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 24badfefa6b4..8ce1f074c2d3 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -338,28 +338,20 @@ static int export_udmabuf(struct udmabuf *ubuf, } static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd, - loff_t start, loff_t size) + loff_t start, loff_t size, struct folio **folios) { pgoff_t nr_pinned = ubuf->nr_pinned; pgoff_t upgcnt = ubuf->pagecount; - struct folio **folios = NULL; u32 cur_folio, cur_pgcnt; pgoff_t pgoff, pgcnt; long nr_folios; - long ret = 0; loff_t end; pgcnt = size >> PAGE_SHIFT; - folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL); - if (!folios) - return -ENOMEM; - end = start + (pgcnt << PAGE_SHIFT) - 1; nr_folios = memfd_pin_folios(memfd, start, end, folios, pgcnt, &pgoff); - if (nr_folios <= 0) { - ret = nr_folios ? nr_folios : -EINVAL; - goto end; - } + if (nr_folios <= 0) + return nr_folios ? nr_folios : -EINVAL; cur_pgcnt = 0; for (cur_folio = 0; cur_folio < nr_folios; ++cur_folio) { @@ -388,14 +380,15 @@ static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd, end: ubuf->pagecount = upgcnt; ubuf->nr_pinned = nr_pinned; - kvfree(folios); - return ret; + return 0; } static long udmabuf_create(struct miscdevice *device, struct udmabuf_create_list *head, struct udmabuf_create_item *list) { + unsigned long max_nr_folios = 0; + struct folio **folios = NULL; pgoff_t pgcnt = 0, pglimit; struct udmabuf *ubuf; long ret = -EINVAL; @@ -407,14 +400,19 @@ static long udmabuf_create(struct miscdevice *device, pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; for (i = 0; i < head->count; i++) { + pgoff_t subpgcnt; + if (!PAGE_ALIGNED(list[i].offset)) goto err_noinit; if (!PAGE_ALIGNED(list[i].size)) goto err_noinit; - pgcnt += list[i].size >> PAGE_SHIFT; + subpgcnt = list[i].size >> PAGE_SHIFT; + pgcnt += subpgcnt; if (pgcnt > pglimit) goto err_noinit; + + max_nr_folios = max_t(unsigned long, subpgcnt, max_nr_folios); } if (!pgcnt) @@ -424,6 +422,12 @@ static long udmabuf_create(struct miscdevice *device, if (ret) goto err; + folios = kvmalloc_array(max_nr_folios, sizeof(*folios), GFP_KERNEL); + if (!folios) { + ret = -ENOMEM; + goto err; + } + for (i = 0; i < head->count; i++) { struct file *memfd = fget(list[i].memfd); @@ -439,7 +443,7 @@ static long udmabuf_create(struct miscdevice *device, } ret = udmabuf_pin_folios(ubuf, memfd, list[i].offset, - list[i].size); + list[i].size, folios); fput(memfd); if (ret) goto err; @@ -450,12 +454,14 @@ static long udmabuf_create(struct miscdevice *device, if (ret < 0) goto err; + kvfree(folios); return ret; err: deinit_udmabuf(ubuf); err_noinit: kfree(ubuf); + kvfree(folios); return ret; } -- GitLab From 1af01e14db7e0b45ae502d822776a58c86688763 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Thu, 12 Sep 2024 16:30:16 +0800 Subject: [PATCH 270/970] drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: 9021c317b770 ("drm/imx: Add initial support for DCSS on iMX8MQ") Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-2-ruanjinjie@huawei.com [DB: fixed the subject] Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/dcss/dcss-crtc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c index 31267c00782f..af91e45b5d13 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c +++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c @@ -206,15 +206,13 @@ int dcss_crtc_init(struct dcss_crtc *crtc, struct drm_device *drm) if (crtc->irq < 0) return crtc->irq; - ret = request_irq(crtc->irq, dcss_crtc_irq_handler, - 0, "dcss_drm", crtc); + ret = request_irq(crtc->irq, dcss_crtc_irq_handler, IRQF_NO_AUTOEN, + "dcss_drm", crtc); if (ret) { dev_err(dcss->dev, "irq request failed with %d.\n", ret); return ret; } - disable_irq(crtc->irq); - return 0; } -- GitLab From 4380f8624b8bff3637476726351ed7bb8850188a Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Thu, 12 Sep 2024 16:30:17 +0800 Subject: [PATCH 271/970] drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: 9021c317b770 ("drm/imx: Add initial support for DCSS on iMX8MQ") Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-3-ruanjinjie@huawei.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/dcss/dcss-dtg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-dtg.c b/drivers/gpu/drm/imx/dcss/dcss-dtg.c index 2968f5d5bd41..6bbfd9aa27ac 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dtg.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dtg.c @@ -134,14 +134,12 @@ static int dcss_dtg_irq_config(struct dcss_dtg *dtg, dtg->base_reg + DCSS_DTG_INT_MASK); ret = request_irq(dtg->ctxld_kick_irq, dcss_dtg_irq_handler, - 0, "dcss_ctxld_kick", dtg); + IRQF_NO_AUTOEN, "dcss_ctxld_kick", dtg); if (ret) { dev_err(dtg->dev, "dtg: irq request failed.\n"); return ret; } - disable_irq(dtg->ctxld_kick_irq); - dtg->ctxld_kick_irq_en = false; return 0; -- GitLab From 40004709a3d3b07041a473a163ca911ef04ab8bd Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Thu, 12 Sep 2024 16:30:18 +0800 Subject: [PATCH 272/970] drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: 47b1be5c0f4e ("staging: imx/drm: request irq only after adding the crtc") Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-4-ruanjinjie@huawei.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c index ef29c9a61a46..99db53e167bd 100644 --- a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c @@ -410,14 +410,12 @@ static int ipu_drm_bind(struct device *dev, struct device *master, void *data) } ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); - ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, - "imx_drm", ipu_crtc); + ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, + IRQF_NO_AUTOEN, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); return ret; } - /* Only enable IRQ when we actually need it to trigger work. */ - disable_irq(ipu_crtc->irq); return 0; } -- GitLab From 361ebf5ef843b0aa1704c72eb26b91cf76c3c5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= <samsagax@gmail.com> Date: Mon, 16 Sep 2024 15:18:51 +0200 Subject: [PATCH 273/970] drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add quirk orientation for AYA NEO 2. The name appears without spaces in DMI strings. That made it difficult to reuse the 2021 match. Also the display is larger in resolution. Tested by the JELOS team that has been patching their own kernel for a while now and confirmed by users in the AYA NEO and ChimeraOS discord servers. Signed-off-by: JoaquÃn Ignacio AramendÃa <samsagax@gmail.com> Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/2b35545b77a9fd8c9699b751ca282226dcecb1dd.1726492131.git.tjakobi@math.uni-bielefeld.de Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 0830cae9a4d0..035b6691f3d0 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -184,6 +184,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* AYA NEO AYANEO 2 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYANEO 2"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, }, { /* AYA NEO 2021 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYADEVICE"), -- GitLab From d7972d735ca80a40a571bf753c138263981a5698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= <samsagax@gmail.com> Date: Mon, 16 Sep 2024 15:18:53 +0200 Subject: [PATCH 274/970] drm: panel-orientation-quirks: Add quirk for AYA NEO Founder edition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add quirk orientation for AYA NEO Founder. The name appears with spaces in DMI strings as other devices of the brand. The panel is the same as the NEXT and 2021 models. Those could not be reused as the former has VENDOR name as "AYANEO" without spaces and the latter has "AYADEVICE". Tested by the JELOS team that has been patching their own kernel for a while now and confirmed by users in the AYA NEO and ChimeraOS discord servers. Signed-off-by: JoaquÃn Ignacio AramendÃa <samsagax@gmail.com> Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/f71889a0b39f13f4b78481bd030377ca15035680.1726492131.git.tjakobi@math.uni-bielefeld.de Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 035b6691f3d0..4dd9ecfa5f95 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -202,6 +202,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_MATCH(DMI_PRODUCT_NAME, "AIR"), }, .driver_data = (void *)&lcd1080x1920_leftside_up, + }, { /* AYA NEO Founder */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYA NEO"), + DMI_MATCH(DMI_PRODUCT_NAME, "AYA NEO Founder"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* AYA NEO NEXT */ .matches = { DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), -- GitLab From 428656feb972ca99200fc127b5aecb574efd9d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= <samsagax@gmail.com> Date: Mon, 16 Sep 2024 15:18:55 +0200 Subject: [PATCH 275/970] drm: panel-orientation-quirks: Add quirk for AYA NEO GEEK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add quirk orientation for AYA NEO GEEK. The name appears without spaces in DMI strings. The board name is completely different to the previous models making it difficult to reuse their quirks despite being the same resolution and using the same orientation. Tested by the JELOS team that has been patching their own kernel for a while now and confirmed by users in the AYA NEO and ChimeraOS discord servers. Signed-off-by: JoaquÃn Ignacio AramendÃa <samsagax@gmail.com> Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/40350b0d63fe2b54e7cba1e14be50917203f0079.1726492131.git.tjakobi@math.uni-bielefeld.de Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 4dd9ecfa5f95..3f2e2b851cbc 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -208,6 +208,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_MATCH(DMI_PRODUCT_NAME, "AYA NEO Founder"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* AYA NEO GEEK */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), + DMI_MATCH(DMI_PRODUCT_NAME, "GEEK"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* AYA NEO NEXT */ .matches = { DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), -- GitLab From f673055a46784ccea04465b9213e999f7bc5187e Mon Sep 17 00:00:00 2001 From: Alexander Stein <alexander.stein@ew.tq-group.com> Date: Fri, 6 Sep 2024 08:38:56 +0200 Subject: [PATCH 276/970] drm/imx: Add missing DRM_BRIDGE_CONNECTOR dependency When drm/bridge-connector was moved to DRM_DISPLAY_HELPER not all users were updated. Add missing Kconfig selections. Fixes: 9da7ec9b19d8 ("drm/bridge-connector: move to DRM_DISPLAY_HELPER module") Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240906063857.2223442-1-alexander.stein@ew.tq-group.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/imx/ipuv3/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig index 5a40c878ebb0..990e216c51cc 100644 --- a/drivers/gpu/drm/imx/ipuv3/Kconfig +++ b/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -13,6 +13,7 @@ config DRM_IMX_PARALLEL_DISPLAY tristate "Support for parallel displays" depends on DRM_IMX select DRM_BRIDGE + select DRM_BRIDGE_CONNECTOR select DRM_PANEL_BRIDGE select VIDEOMODE_HELPERS @@ -31,6 +32,7 @@ config DRM_IMX_LDB depends on COMMON_CLK select MFD_SYSCON select DRM_BRIDGE + select DRM_BRIDGE_CONNECTOR select DRM_PANEL_BRIDGE select DRM_IMX_LEGACY_BRIDGE help -- GitLab From 151ac45348afc5b56baa584c7cd4876addf461ff Mon Sep 17 00:00:00 2001 From: Aakash Menon <aakash.r.menon@gmail.com> Date: Mon, 16 Sep 2024 22:18:29 -0700 Subject: [PATCH 277/970] net: sparx5: Fix invalid timestamps Bit 270-271 are occasionally unexpectedly set by the hardware. This issue was observed with 10G SFPs causing huge time errors (> 30ms) in PTP. Only 30 bits are needed for the nanosecond part of the timestamp, clear 2 most significant bits before extracting timestamp from the internal frame header. Fixes: 70dfe25cd866 ("net: sparx5: Update extraction/injection for timestamping") Signed-off-by: Aakash Menon <aakash.menon@protempis.com> Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c index f3f5fb420468..70427643f777 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c @@ -45,8 +45,12 @@ void sparx5_ifh_parse(u32 *ifh, struct frame_info *info) fwd = (fwd >> 5); info->src_port = FIELD_GET(GENMASK(7, 1), fwd); + /* + * Bit 270-271 are occasionally unexpectedly set by the hardware, + * clear bits before extracting timestamp + */ info->timestamp = - ((u64)xtr_hdr[2] << 24) | + ((u64)(xtr_hdr[2] & GENMASK(5, 0)) << 24) | ((u64)xtr_hdr[3] << 16) | ((u64)xtr_hdr[4] << 8) | ((u64)xtr_hdr[5] << 0); -- GitLab From 2418aa8516b26c5e332a1a8c216d4d620f965a56 Mon Sep 17 00:00:00 2001 From: Linus Walleij <linus.walleij@linaro.org> Date: Sun, 8 Sep 2024 23:50:30 +0200 Subject: [PATCH 278/970] drm/panel: nt35510: Make new commands optional The commit introducing the Frida display started to write the SETVCMOFF registers unconditionally, and some (not all!) Hydis display seem to be affected by ghosting after the commit. Make SETVCMOFF optional and only send these commands on the Frida display for now. Reported-by: Stefan Hansson <newbyte@postmarketos.org> Fixes: 219a1f49094f ("drm/panel: nt35510: support FRIDA FRD400B25025-A-CTK") Acked-by: Jessica Zhang <quic_jesszhan@quicinc.com> Tested-by: Stefan Hansson <newbyte@postmarketos.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240908-fix-nt35510-v2-1-d4834b9cdb9b@linaro.org --- drivers/gpu/drm/panel/panel-novatek-nt35510.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35510.c b/drivers/gpu/drm/panel/panel-novatek-nt35510.c index 57686340de49..549b86f2cc28 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35510.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35510.c @@ -38,6 +38,7 @@ #define NT35510_CMD_CORRECT_GAMMA BIT(0) #define NT35510_CMD_CONTROL_DISPLAY BIT(1) +#define NT35510_CMD_SETVCMOFF BIT(2) #define MCS_CMD_MAUCCTR 0xF0 /* Manufacturer command enable */ #define MCS_CMD_READ_ID1 0xDA @@ -721,11 +722,13 @@ static int nt35510_setup_power(struct nt35510 *nt) if (ret) return ret; - ret = nt35510_send_long(nt, dsi, NT35510_P1_SETVCMOFF, - NT35510_P1_VCMOFF_LEN, - nt->conf->vcmoff); - if (ret) - return ret; + if (nt->conf->cmds & NT35510_CMD_SETVCMOFF) { + ret = nt35510_send_long(nt, dsi, NT35510_P1_SETVCMOFF, + NT35510_P1_VCMOFF_LEN, + nt->conf->vcmoff); + if (ret) + return ret; + } /* Typically 10 ms */ usleep_range(10000, 20000); @@ -1319,7 +1322,7 @@ static const struct nt35510_config nt35510_frida_frd400b25025 = { }, .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM, - .cmds = NT35510_CMD_CONTROL_DISPLAY, + .cmds = NT35510_CMD_CONTROL_DISPLAY | NT35510_CMD_SETVCMOFF, /* 0x03: AVDD = 6.2V */ .avdd = { 0x03, 0x03, 0x03 }, /* 0x46: PCK = 2 x Hsync, BTP = 2.5 x VDDB */ -- GitLab From 886d518ca9a6b433736f74723813d8917e407f40 Mon Sep 17 00:00:00 2001 From: Kees Cook <kees@kernel.org> Date: Sun, 22 Sep 2024 16:14:12 -0700 Subject: [PATCH 279/970] MAINTAINERS: Add unsafe_memcpy() to the FORTIFY review list Usually it's possible to avoid adding an unsafe_memcpy() uses, so give the FORTIFY reviewers a chance to help avoid lying to the compiler about the destination buffer's type/size/etc. Signed-off-by: Kees Cook <kees@kernel.org> --- --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 36c0af94cf08..3a29f123e1be 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8772,6 +8772,7 @@ F: include/linux/fortify-string.h F: lib/fortify_kunit.c F: lib/memcpy_kunit.c F: lib/test_fortify/* +K: \bunsafe_memcpy\b K: \b__NO_FORTIFY\b FPGA DFL DRIVERS -- GitLab From ee06d5f52c1d35e319bd240c8438ffe5ed02b24b Mon Sep 17 00:00:00 2001 From: Fabio Estevam <festevam@denx.de> Date: Tue, 3 Sep 2024 13:27:29 -0300 Subject: [PATCH 280/970] dt-bindings: lcdif: Document the dmas/dma-names properties i.MX28 has an RX DMA channel associated with the LCDIF controller. Document the 'dmas' and 'dma-names' properties to fix the following dt-schema warnings: lcdif@80030000: 'dma-names', 'dmas' do not match any of the regexes: 'pinctrl-[0-9]+' Signed-off-by: Fabio Estevam <festevam@denx.de> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240903162729.1151134-1-festevam@gmail.com [DB: added extra empty line, requested by Krzysztof] Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- .../bindings/display/fsl,lcdif.yaml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml index 0681fc49aa1b..8e3a98aeec32 100644 --- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml +++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml @@ -50,6 +50,14 @@ properties: - const: disp_axi minItems: 1 + dmas: + items: + - description: DMA specifier for the RX DMA channel. + + dma-names: + items: + - const: rx + interrupts: items: - description: LCDIF DMA interrupt @@ -156,6 +164,18 @@ allOf: interrupts: maxItems: 1 + - if: + not: + properties: + compatible: + contains: + enum: + - fsl,imx28-lcdif + then: + properties: + dmas: false + dma-names: false + examples: - | #include <dt-bindings/clock/imx6sx-clock.h> -- GitLab From 1e2ab24cd708b1c864ff983ee1504c0a409d2f8e Mon Sep 17 00:00:00 2001 From: Liao Chen <liaochen4@huawei.com> Date: Mon, 2 Sep 2024 11:33:18 +0000 Subject: [PATCH 281/970] drm/bridge: it6505: Enable module autoloading Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based on the alias from of_device_id table. Signed-off-by: Liao Chen <liaochen4@huawei.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240902113320.903147-2-liaochen4@huawei.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/ite-it6505.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 87b8545fccc0..f372c05360f2 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -3505,6 +3505,7 @@ static const struct of_device_id it6505_of_match[] = { { .compatible = "ite,it6505" }, { } }; +MODULE_DEVICE_TABLE(of, it6505_of_match); static struct i2c_driver it6505_i2c_driver = { .driver = { -- GitLab From 8a16b5cdae26207ff4c22834559384ad3d7bc970 Mon Sep 17 00:00:00 2001 From: Liao Chen <liaochen4@huawei.com> Date: Mon, 2 Sep 2024 11:33:20 +0000 Subject: [PATCH 282/970] drm/mcde: Enable module autoloading Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based on the alias from of_device_id table. Signed-off-by: Liao Chen <liaochen4@huawei.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240902113320.903147-4-liaochen4@huawei.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/mcde/mcde_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index 10c06440c7e7..f1bb38f4e673 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -473,6 +473,7 @@ static const struct of_device_id mcde_of_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, mcde_of_match); static struct platform_driver mcde_driver = { .driver = { -- GitLab From 87054ec00478573da0dfba2405d4bc1508471620 Mon Sep 17 00:00:00 2001 From: Tommy Chiang <ototot@chromium.org> Date: Fri, 19 Jan 2024 03:31:26 +0000 Subject: [PATCH 283/970] dma-buf: Add syntax highlighting to code listings in the document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch tries to improve the display of the code listing on The Linux Kernel documentation website for dma-buf [1] . Originally, it appears that it was attempting to escape the '*' character, but looks like it's not necessary (now), so we are seeing something like '\*' on the webite. This patch removes these unnecessary backslashes and adds syntax highlighting to improve the readability of the code listing. [1] https://docs.kernel.org/driver-api/dma-buf.html Signed-off-by: Tommy Chiang <ototot@chromium.org> Reviewed-by: T.J. Mercier <tjmercier@google.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240119033126.1802711-1-ototot@chromium.org Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/dma-buf/dma-buf.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 8892bc701a66..fbbb750bc5b1 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -1296,10 +1296,12 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF); * vmap interface is introduced. Note that on very old 32-bit architectures * vmalloc space might be limited and result in vmap calls failing. * - * Interfaces:: + * Interfaces: * - * void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct iosys_map \*map) - * void dma_buf_vunmap(struct dma_buf \*dmabuf, struct iosys_map \*map) + * .. code-block:: c + * + * void *dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map) + * void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) * * The vmap call can fail if there is no vmap support in the exporter, or if * it runs out of vmalloc space. Note that the dma-buf layer keeps a reference @@ -1356,10 +1358,11 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF); * enough, since adding interfaces to intercept pagefaults and allow pte * shootdowns would increase the complexity quite a bit. * - * Interface:: + * Interface: + * + * .. code-block:: c * - * int dma_buf_mmap(struct dma_buf \*, struct vm_area_struct \*, - * unsigned long); + * int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); * * If the importing subsystem simply provides a special-purpose mmap call to * set up a mapping in userspace, calling do_mmap with &dma_buf.file will -- GitLab From cac075706f298948898b1f63e81709df42afa75d Mon Sep 17 00:00:00 2001 From: Steven Price <steven.price@arm.com> Date: Mon, 23 Sep 2024 11:34:06 +0100 Subject: [PATCH 284/970] drm/panthor: Fix race when converting group handle to group object XArray provides it's own internal lock which protects the internal array when entries are being simultaneously added and removed. However there is still a race between retrieving the pointer from the XArray and incrementing the reference count. To avoid this race simply hold the internal XArray lock when incrementing the reference count, this ensures there cannot be a racing call to xa_erase(). Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block") Signed-off-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923103406.2509906-1-steven.price@arm.com --- drivers/gpu/drm/panthor/panthor_sched.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index 12b272a912f8..d21fe63ae228 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -3242,6 +3242,18 @@ int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle) return 0; } +static struct panthor_group *group_from_handle(struct panthor_group_pool *pool, + u32 group_handle) +{ + struct panthor_group *group; + + xa_lock(&pool->xa); + group = group_get(xa_load(&pool->xa, group_handle)); + xa_unlock(&pool->xa); + + return group; +} + int panthor_group_get_state(struct panthor_file *pfile, struct drm_panthor_group_get_state *get_state) { @@ -3253,7 +3265,7 @@ int panthor_group_get_state(struct panthor_file *pfile, if (get_state->pad) return -EINVAL; - group = group_get(xa_load(&gpool->xa, get_state->group_handle)); + group = group_from_handle(gpool, get_state->group_handle); if (!group) return -EINVAL; @@ -3384,7 +3396,7 @@ panthor_job_create(struct panthor_file *pfile, job->call_info.latest_flush = qsubmit->latest_flush; INIT_LIST_HEAD(&job->node); - job->group = group_get(xa_load(&gpool->xa, group_handle)); + job->group = group_from_handle(gpool, group_handle); if (!job->group) { ret = -EINVAL; goto err_put_job; -- GitLab From 21ae035ae5c33ef176f4062bd9d4aa973dde240b Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:15 -0300 Subject: [PATCH 285/970] drm/xe/mcr: Use Xe2_LPM steering tables for Xe2_HPM According to Bspec, Xe2 steering tables must be used for Xe2_HPM, just as it is with Xe2_LPM. Update our driver to reflect that. Bspec: 71186 Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-2-gustavo.sousa@intel.com --- drivers/gpu/drm/xe/xe_gt_mcr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index 2671ce6b1a76..4c0767403881 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -441,7 +441,7 @@ void xe_gt_mcr_init(struct xe_gt *gt) if (gt->info.type == XE_GT_TYPE_MEDIA) { drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13); - if (MEDIA_VER(xe) >= 20) { + if (MEDIA_VERx100(xe) >= 1301) { gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table; } else { -- GitLab From e1f813947ccf2326cfda4558b7d31430d7860c4b Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:16 -0300 Subject: [PATCH 286/970] drm/xe/xe2: Extend performance tuning to media GT With exception of "Tuning: L3 cache - media", we are currently applying recommended performance tuning settings only for the primary GT. Let's also implement them for the media GT when applicable. According to our spec, media GT registers CCCHKNREG1 and L3SQCREG* exist only in Xe2_LPM and their offsets do not match their primary GT counterparts. Furthermore, the range where CCCHKNREG1 belongs is not listed as a multicast range on the media GT. As such, we need to have Xe2_LPM-specific definitions for those registers and apply the setting only for that specific IP. Both Xe2_HPM and Xe2_LPM contain STATELESS_COMPRESSION_CTRL and the offset on the media GT matches the one on the primary one. So we can simply have a copy of "Tuning: Stateless compression control" for the media GT. v2: - Fix implementation with respect to multicast vs non-multicast registers. (Matt) - Add missing XE2LPM_CCCHKNREG1 on second action of "Tuning: Compression Overfetch - media". v3: - STATELESS_COMPRESSION_CTRL on Xe2_HPM is also a multicast register, do not define a XE2HPM_STATELESS_COMPRESSION_CTRL register. (Tejas) Bspec: 72161 Cc: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-3-gustavo.sousa@intel.com --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 6 ++++++ drivers/gpu/drm/xe/xe_tuning.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index cf21de3adca6..07315eb72eff 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -169,6 +169,8 @@ #define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED) #define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14) +#define XE2LPM_CCCHKNREG1 XE_REG(0x82a8) + #define VF_PREEMPTION XE_REG(0x83a4, XE_REG_OPTION_MASKED) #define PREEMPTION_VERTEX_COUNT REG_GENMASK(15, 0) @@ -399,6 +401,10 @@ #define SCRATCH1LPFC XE_REG(0xb474) #define EN_L3_RW_CCS_CACHE_FLUSH REG_BIT(0) +#define XE2LPM_L3SQCREG2 XE_REG_MCR(0xb604) + +#define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) + #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) #define XE2_TDF_CTRL XE_REG(0xb418) diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index faa1bf42e50e..c798ae1b3f75 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -42,20 +42,40 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { XE_RTP_ACTIONS(CLR(CCCHKNREG1, ENCOMPPERFFIX), SET(CCCHKNREG1, L3CMPCTRL)) }, + { XE_RTP_NAME("Tuning: Compression Overfetch - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(CLR(XE2LPM_CCCHKNREG1, ENCOMPPERFFIX), + SET(XE2LPM_CCCHKNREG1, L3CMPCTRL)) + }, { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(SET(L3SQCREG3, COMPPWOVERFETCHEN)) }, + { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3 - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG3, COMPPWOVERFETCHEN)) + }, { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(SET(L3SQCREG2, COMPMEMRD256BOVRFETCHEN)) }, + { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG2, + COMPMEMRD256BOVRFETCHEN)) + }, { XE_RTP_NAME("Tuning: Stateless compression control"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) }, + { XE_RTP_NAME("Tuning: Stateless compression control - media"), + XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, 2000)), + XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, + REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) + }, + {} }; -- GitLab From f5b463fd7c75474e184e24395e9703cec7c676e3 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:17 -0300 Subject: [PATCH 287/970] drm/xe/xe2: Assume tuning settings also apply for future media GT We already make the assumption that recommended tuning settings for primary GT on Xe2 will also apply for future releases. Let's make the same assumption for the media GT. We can come back and define closed ranges when that becomes necessary. Bspec: 72161 Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-4-gustavo.sousa@intel.com --- drivers/gpu/drm/xe/xe_tuning.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index c798ae1b3f75..230369f108ab 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -33,7 +33,7 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f))) }, { XE_RTP_NAME("Tuning: L3 cache - media"), - XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_RULES(MEDIA_VERSION_RANGE(2000, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(FIELD_SET(XE2LPM_L3SQCREG5, L3_PWM_TIMER_INIT_VAL_MASK, REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f))) }, @@ -43,7 +43,7 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { SET(CCCHKNREG1, L3CMPCTRL)) }, { XE_RTP_NAME("Tuning: Compression Overfetch - media"), - XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_RULES(MEDIA_VERSION_RANGE(2000, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(CLR(XE2LPM_CCCHKNREG1, ENCOMPPERFFIX), SET(XE2LPM_CCCHKNREG1, L3CMPCTRL)) }, @@ -52,7 +52,7 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { XE_RTP_ACTIONS(SET(L3SQCREG3, COMPPWOVERFETCHEN)) }, { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3 - media"), - XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_RULES(MEDIA_VERSION_RANGE(2000, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG3, COMPPWOVERFETCHEN)) }, { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"), @@ -61,7 +61,7 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { COMPMEMRD256BOVRFETCHEN)) }, { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only - media"), - XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_RULES(MEDIA_VERSION_RANGE(2000, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG2, COMPMEMRD256BOVRFETCHEN)) }, @@ -71,7 +71,7 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) }, { XE_RTP_NAME("Tuning: Stateless compression control - media"), - XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, 2000)), + XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) }, -- GitLab From 876253165f3eaaacacb8c8bed16a9df4b6081479 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:18 -0300 Subject: [PATCH 288/970] drm/xe/xe2: Add performance tuning for L3 cache flushing A recommended performance tuning for LNL related to L3 cache flushing was recently introduced in Bspec. Implement it. Unlike the other existing tuning settings, we limit this one for LNL only, since there is no info about whether this would be applicable to other platforms yet. In the future we can come back and use IP version ranges if applicable. v2: - Fix reference to Bspec. (Sai Teja, Tejas) - Use correct register name for "Tuning: L3 RW flush all Cache". (Sai Teja) - Use SCRATCH3_LBCF (with the underscore) for better readability. v3: - Limit setting to LNL only. (Matt) Bspec: 72161 Cc: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-5-gustavo.sousa@intel.com --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 +++++ drivers/gpu/drm/xe/xe_tuning.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 07315eb72eff..8d8f6a113a86 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -388,6 +388,9 @@ #define L3SQCREG3 XE_REG_MCR(0xb108) #define COMPPWOVERFETCHEN REG_BIT(28) +#define SCRATCH3_LBCF XE_REG_MCR(0xb154) +#define RWFLUSHALLEN REG_BIT(17) + #define XEHP_L3SQCREG5 XE_REG_MCR(0xb158) #define L3_PWM_TIMER_INIT_VAL_MASK REG_GENMASK(9, 0) @@ -405,6 +408,8 @@ #define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) +#define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) + #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) #define XE2_TDF_CTRL XE_REG(0xb418) diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index 230369f108ab..d449de0fb6ec 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -75,6 +75,14 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) }, + { XE_RTP_NAME("Tuning: L3 RW flush all Cache"), + XE_RTP_RULES(GRAPHICS_VERSION(2004)), + XE_RTP_ACTIONS(SET(SCRATCH3_LBCF, RWFLUSHALLEN)) + }, + { XE_RTP_NAME("Tuning: L3 RW flush all cache - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(SET(XE2LPM_SCRATCH3_LBCF, RWFLUSHALLEN)) + }, {} }; -- GitLab From c1ab40a1fdfee732c7e6ff2fb8253760293e47e8 Mon Sep 17 00:00:00 2001 From: Ma Ke <make24@iscas.ac.cn> Date: Fri, 13 Sep 2024 17:09:26 +0800 Subject: [PATCH 289/970] drm/sti: avoid potential dereference of error pointers in sti_hqvdp_atomic_check The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure. Cc: stable@vger.kernel.org Fixes: dd86dc2f9ae1 ("drm/sti: implement atomic_check for the planes") Signed-off-by: Ma Ke <make24@iscas.ac.cn> Link: https://patchwork.freedesktop.org/patch/msgid/20240913090926.2023716-1-make24@iscas.ac.cn Signed-off-by: Alain Volmat <alain.volmat@foss.st.com> --- drivers/gpu/drm/sti/sti_hqvdp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index acbf70b95aeb..5793cf2cb897 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -1037,6 +1037,9 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, return 0; crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y; -- GitLab From e965e771b069421c233d674c3c8cd8c7f7245f42 Mon Sep 17 00:00:00 2001 From: Ma Ke <make24@iscas.ac.cn> Date: Mon, 9 Sep 2024 14:33:59 +0800 Subject: [PATCH 290/970] drm/sti: avoid potential dereference of error pointers in sti_gdp_atomic_check The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure. Cc: stable@vger.kernel.org Fixes: dd86dc2f9ae1 ("drm/sti: implement atomic_check for the planes") Signed-off-by: Ma Ke <make24@iscas.ac.cn> Acked-by: Alain Volmat <alain.volmat@foss.st.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240909063359.1197065-1-make24@iscas.ac.cn Signed-off-by: Alain Volmat <alain.volmat@foss.st.com> --- drivers/gpu/drm/sti/sti_gdp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c index 43c72c2604a0..f046f5f7ad25 100644 --- a/drivers/gpu/drm/sti/sti_gdp.c +++ b/drivers/gpu/drm/sti/sti_gdp.c @@ -638,6 +638,9 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane, mixer = to_sti_mixer(crtc); crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y; -- GitLab From 831214f77037de02afc287eae93ce97f218d8c04 Mon Sep 17 00:00:00 2001 From: Ma Ke <make24@iscas.ac.cn> Date: Fri, 13 Sep 2024 17:04:12 +0800 Subject: [PATCH 291/970] drm/sti: avoid potential dereference of error pointers The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure. Cc: stable@vger.kernel.org Fixes: dd86dc2f9ae1 ("drm/sti: implement atomic_check for the planes") Signed-off-by: Ma Ke <make24@iscas.ac.cn> Link: https://patchwork.freedesktop.org/patch/msgid/20240913090412.2022848-1-make24@iscas.ac.cn Signed-off-by: Alain Volmat <alain.volmat@foss.st.com> --- drivers/gpu/drm/sti/sti_cursor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c index db0a1eb53532..c59fcb4dca32 100644 --- a/drivers/gpu/drm/sti/sti_cursor.c +++ b/drivers/gpu/drm/sti/sti_cursor.c @@ -200,6 +200,9 @@ static int sti_cursor_atomic_check(struct drm_plane *drm_plane, return 0; crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y; -- GitLab From a3096328462b1e022c6294898c440708ea11509a Mon Sep 17 00:00:00 2001 From: Philipp Stanner <pstanner@redhat.com> Date: Mon, 16 Sep 2024 20:52:00 +0200 Subject: [PATCH 292/970] MAINTAINERS: drm/sched: Add new maintainers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRM's GPU scheduler is arguably in need of more intensive maintenance. Danilo and Philipp volunteer to help with the maintainership. Signed-off-by: Philipp Stanner <pstanner@redhat.com> Cc: Christian König <christian.koenig@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Danilo Krummrich <dakr@kernel.org> Cc: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Acked-by: Christian König <christian.koenig@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Matthew Brost <matthew.brost@intel.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240916185159.35727-3-pstanner@redhat.com --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 515e7f4b6cd9..71f2afae81b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7704,6 +7704,8 @@ F: drivers/gpu/drm/xlnx/ DRM GPU SCHEDULER M: Luben Tuikov <ltuikov89@gmail.com> M: Matthew Brost <matthew.brost@intel.com> +M: Danilo Krummrich <dakr@kernel.org> +M: Philipp Stanner <pstanner@redhat.com> L: dri-devel@lists.freedesktop.org S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git -- GitLab From 440d52b370b03b366fd26ace36bab20552116145 Mon Sep 17 00:00:00 2001 From: Rob Clark <robdclark@chromium.org> Date: Fri, 13 Sep 2024 13:23:01 -0700 Subject: [PATCH 293/970] drm/sched: Fix dynamic job-flow control race Fixes a race condition reported here: https://github.com/AsahiLinux/linux/issues/309#issuecomment-2238968609 The whole premise of lockless access to a single-producer-single- consumer queue is that there is just a single producer and single consumer. That means we can't call drm_sched_can_queue() (which is about queueing more work to the hw, not to the spsc queue) from anywhere other than the consumer (wq). This call in the producer is just an optimization to avoid scheduling the consuming worker if it cannot yet queue more work to the hw. It is safe to drop this optimization to avoid the race condition. Suggested-by: Asahi Lina <lina@asahilina.net> Fixes: a78422e9dff3 ("drm/sched: implement dynamic job-flow control") Closes: https://github.com/AsahiLinux/linux/issues/309 Cc: stable@vger.kernel.org Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Danilo Krummrich <dakr@kernel.org> Tested-by: Janne Grunau <j@jannau.net> Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240913202301.16772-1-robdclark@gmail.com --- drivers/gpu/drm/scheduler/sched_entity.c | 4 ++-- drivers/gpu/drm/scheduler/sched_main.c | 7 ++----- include/drm/gpu_scheduler.h | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 58c8161289fe..567e5ace6d0c 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -380,7 +380,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f, container_of(cb, struct drm_sched_entity, cb); drm_sched_entity_clear_dep(f, cb); - drm_sched_wakeup(entity->rq->sched, entity); + drm_sched_wakeup(entity->rq->sched); } /** @@ -612,7 +612,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) drm_sched_rq_update_fifo(entity, submit_ts); - drm_sched_wakeup(entity->rq->sched, entity); + drm_sched_wakeup(entity->rq->sched); } } EXPORT_SYMBOL(drm_sched_entity_push_job); diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 7e90c9f95611..a124d5e77b5e 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -1022,15 +1022,12 @@ EXPORT_SYMBOL(drm_sched_job_cleanup); /** * drm_sched_wakeup - Wake up the scheduler if it is ready to queue * @sched: scheduler instance - * @entity: the scheduler entity * * Wake up the scheduler if we can queue jobs. */ -void drm_sched_wakeup(struct drm_gpu_scheduler *sched, - struct drm_sched_entity *entity) +void drm_sched_wakeup(struct drm_gpu_scheduler *sched) { - if (drm_sched_can_queue(sched, entity)) - drm_sched_run_job_queue(sched); + drm_sched_run_job_queue(sched); } /** diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 5acc64954a88..e28bc649b5c9 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -574,7 +574,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched); void drm_sched_job_cleanup(struct drm_sched_job *job); -void drm_sched_wakeup(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity); +void drm_sched_wakeup(struct drm_gpu_scheduler *sched); bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched); void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched); void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched); -- GitLab From e0a8f8c623aa5368d69ba1aabf727453a2136d44 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Thu, 19 Sep 2024 20:53:43 +0200 Subject: [PATCH 294/970] drm: Link drm_rect.o into DRM core module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several places in drm.ko use struct drm_rect and its helpers. This only works as the called interfaces are declared as static inline in the header file. Fix the issue by linking drm_rect.o into drm.ko. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240919185436.86790-1-tzimmermann@suse.de --- drivers/gpu/drm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 784229d4504d..fc061fd424ed 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -68,6 +68,7 @@ drm-y := \ drm_prime.o \ drm_print.o \ drm_property.o \ + drm_rect.o \ drm_syncobj.o \ drm_sysfs.o \ drm_trace_points.o \ @@ -140,7 +141,6 @@ drm_kms_helper-y := \ drm_modeset_helper.o \ drm_plane_helper.o \ drm_probe_helper.o \ - drm_rect.o \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o -- GitLab From 284a8908f5ec25355a831e3e2d87975d748e98dc Mon Sep 17 00:00:00 2001 From: Andrew Kreimer <algonell@gmail.com> Date: Mon, 9 Sep 2024 16:56:38 +0300 Subject: [PATCH 295/970] accel/ivpu: Fix a typo Fix a typo in comments. Reported-by: Matthew Wilcox <willy@infradead.org> Signed-off-by: Andrew Kreimer <algonell@gmail.com> Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20240909135655.45938-1-algonell@gmail.com --- drivers/accel/ivpu/vpu_boot_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index 82954b91b748..d474bc7b15c0 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -8,7 +8,7 @@ /* * =========== FW API version information beginning ================ - * The bellow values will be used to construct the version info this way: + * The below values will be used to construct the version info this way: * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | * VPU_BOOT_API_VER_MINOR; * VPU_BOOT_API_VER_PATCH will be ignored. KMD and compatibility is not affected if this changes -- GitLab From bff1709b3980bd7f80be6786f64cc9a9ee9e56da Mon Sep 17 00:00:00 2001 From: Jiawei Ye <jiawei.ye@foxmail.com> Date: Tue, 24 Sep 2024 06:58:05 +0000 Subject: [PATCH 296/970] mac802154: Fix potential RCU dereference issue in mac802154_scan_worker In the `mac802154_scan_worker` function, the `scan_req->type` field was accessed after the RCU read-side critical section was unlocked. According to RCU usage rules, this is illegal and can lead to unpredictable behavior, such as accessing memory that has been updated or causing use-after-free issues. This possible bug was identified using a static analysis tool developed by myself, specifically designed to detect RCU-related issues. To address this, the `scan_req->type` value is now stored in a local variable `scan_req_type` while still within the RCU read-side critical section. The `scan_req_type` is then used after the RCU lock is released, ensuring that the type value is safely accessed without violating RCU rules. Fixes: e2c3e6f53a7a ("mac802154: Handle active scanning") Cc: stable@vger.kernel.org Signed-off-by: Jiawei Ye <jiawei.ye@foxmail.com> Acked-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Link: https://lore.kernel.org/tencent_3B2F4F2B4DA30FAE2F51A9634A16B3AD4908@qq.com Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org> --- net/mac802154/scan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index 1c0eeaa76560..a6dab3cc3ad8 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -176,6 +176,7 @@ void mac802154_scan_worker(struct work_struct *work) struct ieee802154_local *local = container_of(work, struct ieee802154_local, scan_work.work); struct cfg802154_scan_request *scan_req; + enum nl802154_scan_types scan_req_type; struct ieee802154_sub_if_data *sdata; unsigned int scan_duration = 0; struct wpan_phy *wpan_phy; @@ -209,6 +210,7 @@ void mac802154_scan_worker(struct work_struct *work) } wpan_phy = scan_req->wpan_phy; + scan_req_type = scan_req->type; scan_req_duration = scan_req->duration; /* Look for the next valid chan */ @@ -246,7 +248,7 @@ void mac802154_scan_worker(struct work_struct *work) goto end_scan; } - if (scan_req->type == NL802154_SCAN_ACTIVE) { + if (scan_req_type == NL802154_SCAN_ACTIVE) { ret = mac802154_transmit_beacon_req(local, sdata); if (ret) dev_err(&sdata->dev->dev, -- GitLab From 1e436f4fff1fd1fcc904ee18139f7e284001dc81 Mon Sep 17 00:00:00 2001 From: Shuicheng Lin <shuicheng.lin@intel.com> Date: Tue, 17 Sep 2024 14:47:32 +0000 Subject: [PATCH 297/970] drm/scheduler: Improve documentation Function drm_sched_entity_push_job() doesn't have a return value, remove the return value description for it. Correct several other typo errors. v2 (Philipp): - more correction with related comments. Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com> Reviewed-by: Philipp Stanner <pstanner@redhat.com> Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20240917144732.2758572-1-shuicheng.lin@intel.com --- drivers/gpu/drm/scheduler/sched_entity.c | 10 ++++------ drivers/gpu/drm/scheduler/sched_main.c | 4 ++-- include/drm/gpu_scheduler.h | 12 ++++++------ include/linux/dma-resv.h | 6 +++--- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 58c8161289fe..ffa3e765f5db 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -51,7 +51,7 @@ * drm_sched_entity_set_priority(). For changing the set of schedulers * @sched_list at runtime see drm_sched_entity_modify_sched(). * - * An entity is cleaned up by callind drm_sched_entity_fini(). See also + * An entity is cleaned up by calling drm_sched_entity_fini(). See also * drm_sched_entity_destroy(). * * Returns 0 on success or a negative error code on failure. @@ -370,8 +370,8 @@ static void drm_sched_entity_clear_dep(struct dma_fence *f, } /* - * drm_sched_entity_clear_dep - callback to clear the entities dependency and - * wake up scheduler + * drm_sched_entity_wakeup - callback to clear the entity's dependency and + * wake up the scheduler */ static void drm_sched_entity_wakeup(struct dma_fence *f, struct dma_fence_cb *cb) @@ -389,7 +389,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f, * @entity: scheduler entity * @priority: scheduler priority * - * Update the priority of runqueus used for the entity. + * Update the priority of runqueues used for the entity. */ void drm_sched_entity_set_priority(struct drm_sched_entity *entity, enum drm_sched_priority priority) @@ -574,8 +574,6 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity) * fence sequence number this function should be called with drm_sched_job_arm() * under common lock for the struct drm_sched_entity that was set up for * @sched_job in drm_sched_job_init(). - * - * Returns 0 for success, negative error code otherwise. */ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) { diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index f093616fe53c..b5e9f657d829 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -41,7 +41,7 @@ * 4. Entities themselves maintain a queue of jobs that will be scheduled on * the hardware. * - * The jobs in a entity are always scheduled in the order that they were pushed. + * The jobs in an entity are always scheduled in the order in which they were pushed. * * Note that once a job was taken from the entities queue and pushed to the * hardware, i.e. the pending queue, the entity must not be referenced anymore @@ -1340,7 +1340,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched) list_for_each_entry(s_entity, &rq->entities, list) /* * Prevents reinsertion and marks job_queue as idle, - * it will removed from rq in drm_sched_entity_fini + * it will be removed from the rq in drm_sched_entity_fini() * eventually */ s_entity->stopped = true; diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index a8d19b10f9b8..f83e1209b11d 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -33,11 +33,11 @@ #define MAX_WAIT_SCHED_ENTITY_Q_EMPTY msecs_to_jiffies(1000) /** - * DRM_SCHED_FENCE_DONT_PIPELINE - Prefent dependency pipelining + * DRM_SCHED_FENCE_DONT_PIPELINE - Prevent dependency pipelining * * Setting this flag on a scheduler fence prevents pipelining of jobs depending * on this fence. In other words we always insert a full CPU round trip before - * dependen jobs are pushed to the hw queue. + * dependent jobs are pushed to the hw queue. */ #define DRM_SCHED_FENCE_DONT_PIPELINE DMA_FENCE_FLAG_USER_BITS @@ -71,7 +71,7 @@ enum drm_sched_priority { DRM_SCHED_PRIORITY_COUNT }; -/* Used to chose between FIFO and RR jobs scheduling */ +/* Used to choose between FIFO and RR job-scheduling */ extern int drm_sched_policy; #define DRM_SCHED_POLICY_RR 0 @@ -198,7 +198,7 @@ struct drm_sched_entity { * * Points to the finished fence of the last scheduled job. Only written * by the scheduler thread, can be accessed locklessly from - * drm_sched_job_arm() iff the queue is empty. + * drm_sched_job_arm() if the queue is empty. */ struct dma_fence __rcu *last_scheduled; @@ -247,7 +247,7 @@ struct drm_sched_entity { * @sched: the scheduler to which this rq belongs to. * @entities: list of the entities to be scheduled. * @current_entity: the entity which is to be scheduled. - * @rb_tree_root: root of time based priory queue of entities for FIFO scheduling + * @rb_tree_root: root of time based priority queue of entities for FIFO scheduling * * Run queue is a set of entities scheduling command submissions for * one specific ring. It implements the scheduling policy that selects @@ -321,7 +321,7 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); * @s_fence: contains the fences for the scheduling of job. * @finish_cb: the callback for the finished fence. * @credits: the number of credits this job contributes to the scheduler - * @work: Helper to reschdeule job kill to different context. + * @work: Helper to reschedule job kill to different context. * @id: a unique id assigned to each job scheduled on the scheduler. * @karma: increment on every hang caused by this job. If this exceeds the hang * limit of the scheduler then the job is marked guilty and will not diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h index 8d0e34dad446..c5ab6fd9ebe8 100644 --- a/include/linux/dma-resv.h +++ b/include/linux/dma-resv.h @@ -105,10 +105,10 @@ enum dma_resv_usage { * This should be used by submissions which don't want to participate in * any implicit synchronization. * - * The most common case are preemption fences, page table updates, TLB - * flushes as well as explicit synced user submissions. + * The most common cases are preemption fences, page table updates, TLB + * flushes as well as explicitly synced user submissions. * - * Explicit synced user user submissions can be promoted to + * Explicitly synced user submissions can be promoted to * DMA_RESV_USAGE_READ or DMA_RESV_USAGE_WRITE as needed using * dma_buf_import_sync_file() when implicit synchronization should * become necessary after initial adding of the fence. -- GitLab From 09cfc6a532d249a51d3af5022d37ebbe9c3d31f6 Mon Sep 17 00:00:00 2001 From: Andrei Simion <andrei.simion@microchip.com> Date: Tue, 24 Sep 2024 11:12:38 +0300 Subject: [PATCH 298/970] ASoC: atmel: mchp-pdmc: Skip ALSA restoration if substream runtime is uninitialized Update the driver to prevent alsa-restore.service from failing when reading data from /var/lib/alsa/asound.state at boot. Ensure that the restoration of ALSA mixer configurations is skipped if substream->runtime is NULL. Fixes: 50291652af52 ("ASoC: atmel: mchp-pdmc: add PDMC driver") Signed-off-by: Andrei Simion <andrei.simion@microchip.com> Link: https://patch.msgid.link/20240924081237.50046-1-andrei.simion@microchip.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/atmel/mchp-pdmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c index 939cd44ebc8a..06dc3c48e7e8 100644 --- a/sound/soc/atmel/mchp-pdmc.c +++ b/sound/soc/atmel/mchp-pdmc.c @@ -302,6 +302,9 @@ static int mchp_pdmc_chmap_ctl_put(struct snd_kcontrol *kcontrol, if (!substream) return -ENODEV; + if (!substream->runtime) + return 0; /* just for avoiding error from alsactl restore */ + map = mchp_pdmc_chmap_get(substream, info); if (!map) return -EINVAL; -- GitLab From 59e1c9d0682b86dafdc825707638cd87f3012dc6 Mon Sep 17 00:00:00 2001 From: Vignesh Raman <vignesh.raman@collabora.com> Date: Tue, 10 Sep 2024 18:49:24 +0530 Subject: [PATCH 299/970] drm/ci: uprev mesa, IGT and deqp-runner Uprev mesa, IGT to the latest version and deqp-runner to v0.20.0. Also update expectation files. Acked-by: Helen Koike <helen.koike@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Vignesh Raman <vignesh.raman@collabora.com> Signed-off-by: Helen Koike <helen.koike@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910131927.161883-1-vignesh.raman@collabora.com --- drivers/gpu/drm/ci/gitlab-ci.yml | 14 +++-- drivers/gpu/drm/ci/image-tags.yml | 2 +- .../gpu/drm/ci/xfails/amdgpu-stoney-fails.txt | 2 +- .../drm/ci/xfails/amdgpu-stoney-flakes.txt | 7 +++ drivers/gpu/drm/ci/xfails/i915-amly-fails.txt | 2 +- .../gpu/drm/ci/xfails/i915-amly-flakes.txt | 7 +++ drivers/gpu/drm/ci/xfails/i915-apl-fails.txt | 1 - drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt | 7 +++ drivers/gpu/drm/ci/xfails/i915-cml-fails.txt | 10 ++-- drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt | 14 +++++ drivers/gpu/drm/ci/xfails/i915-glk-fails.txt | 1 + drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt | 2 - drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt | 34 ++++++++++-- drivers/gpu/drm/ci/xfails/i915-whl-fails.txt | 9 ++-- .../drm/ci/xfails/mediatek-mt8173-fails.txt | 11 +--- .../drm/ci/xfails/mediatek-mt8183-fails.txt | 6 --- .../gpu/drm/ci/xfails/meson-g12b-fails.txt | 1 - .../gpu/drm/ci/xfails/msm-apq8016-fails.txt | 5 -- .../gpu/drm/ci/xfails/msm-apq8096-fails.txt | 5 -- .../msm-sc7180-trogdor-kingoftown-fails.txt | 27 ---------- ...sm-sc7180-trogdor-lazor-limozeen-fails.txt | 27 ---------- .../gpu/drm/ci/xfails/msm-sdm845-fails.txt | 6 +-- .../gpu/drm/ci/xfails/msm-sdm845-flakes.txt | 14 +++++ .../gpu/drm/ci/xfails/msm-sdm845-skips.txt | 5 ++ .../gpu/drm/ci/xfails/panfrost-g12b-fails.txt | 1 + .../drm/ci/xfails/panfrost-mt8183-fails.txt | 1 + .../drm/ci/xfails/panfrost-rk3288-fails.txt | 1 + .../drm/ci/xfails/panfrost-rk3399-fails.txt | 1 + .../drm/ci/xfails/rockchip-rk3288-fails.txt | 22 +++++--- .../drm/ci/xfails/rockchip-rk3288-flakes.txt | 28 ++++++++++ .../drm/ci/xfails/rockchip-rk3399-fails.txt | 7 --- .../drm/ci/xfails/rockchip-rk3399-flakes.txt | 28 ++++++++++ drivers/gpu/drm/ci/xfails/vkms-none-fails.txt | 21 -------- drivers/gpu/drm/ci/xfails/vkms-none-skips.txt | 53 +++++++++++++++++++ 34 files changed, 234 insertions(+), 148 deletions(-) diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml index eca47d4f816f..90bde9f00cc3 100644 --- a/drivers/gpu/drm/ci/gitlab-ci.yml +++ b/drivers/gpu/drm/ci/gitlab-ci.yml @@ -1,14 +1,14 @@ variables: DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa - DRM_CI_COMMIT_SHA: &drm-ci-commit-sha d9849ac46623797a9f56fb9d46dc52460ac477de + DRM_CI_COMMIT_SHA: &drm-ci-commit-sha c6a9a9c3bce90923f7700219354e0b6e5a3c9ba6 UPSTREAM_REPO: https://gitlab.freedesktop.org/drm/kernel.git TARGET_BRANCH: drm-next - IGT_VERSION: f13702b8e4e847c56da3ef6f0969065d686049c5 + IGT_VERSION: a73311079a5d8ac99eb25336a8369a2c3c6b519b DEQP_RUNNER_GIT_URL: https://gitlab.freedesktop.org/mesa/deqp-runner.git - DEQP_RUNNER_GIT_TAG: v0.15.0 + DEQP_RUNNER_GIT_TAG: v0.20.0 FDO_UPSTREAM_REPO: helen.fornazier/linux # The repo where the git-archive daily runs MESA_TEMPLATES_COMMIT: &ci-templates-commit d5aa3941aa03c2f716595116354fb81eb8012acb @@ -153,6 +153,14 @@ stages: # Pre-merge pipeline for Marge Bot - if: &is-pre-merge-for-marge '$GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"' when: on_success + # Push to a branch on a fork + - &is-fork-push '$CI_PROJECT_NAMESPACE != "mesa" && $CI_PIPELINE_SOURCE == "push"' + +# Rules applied to every job in the pipeline +.common-rules: + rules: + - if: *is-fork-push + when: manual .never-post-merge-rules: rules: diff --git a/drivers/gpu/drm/ci/image-tags.yml b/drivers/gpu/drm/ci/image-tags.yml index 2c340d063a96..8d8b9e71852e 100644 --- a/drivers/gpu/drm/ci/image-tags.yml +++ b/drivers/gpu/drm/ci/image-tags.yml @@ -1,5 +1,5 @@ variables: - CONTAINER_TAG: "2024-08-07-mesa-uprev" + CONTAINER_TAG: "2024-09-09-uprevs" DEBIAN_X86_64_BUILD_BASE_IMAGE: "debian/x86_64_build-base" DEBIAN_BASE_TAG: "${CONTAINER_TAG}" diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt index 8e2fed6d76a3..f44dbce3151a 100644 --- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt +++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt @@ -2,6 +2,7 @@ amdgpu/amd_abm@abm_enabled,Fail amdgpu/amd_abm@abm_gradual,Fail amdgpu/amd_abm@backlight_monotonic_abm,Fail amdgpu/amd_abm@backlight_monotonic_basic,Fail +amdgpu/amd_abm@dpms_cycle,Fail amdgpu/amd_assr@assr-links,Fail amdgpu/amd_assr@assr-links-dpms,Fail amdgpu/amd_mall@static-screen,Crash @@ -14,7 +15,6 @@ amdgpu/amd_plane@mpo-scale-p010,Fail amdgpu/amd_plane@mpo-scale-rgb,Crash amdgpu/amd_plane@mpo-swizzle-toggle,Fail amdgpu/amd_uvd_dec@amdgpu_uvd_decode,Fail -dumb_buffer@invalid-bpp,Fail kms_addfb_basic@bad-pitch-65536,Fail kms_addfb_basic@bo-too-small,Fail kms_addfb_basic@too-high,Fail diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt index e4faa96fa000..e70bd9d447ca 100644 --- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt @@ -18,3 +18,10 @@ kms_async_flips@crc # IGT Version: 1.28-g0df7b9b97 # Linux Version: 6.9.0-rc7 kms_plane@pixel-format-source-clamping + +# Board Name: hp-11A-G6-EE-grunt +# Bug Report: https://lore.kernel.org/amd-gfx/09ee1862-3a0e-4085-ac1b-262601b1122b@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_async_flips@async-flip-with-page-flip-events diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt index 9b84f68a5122..0907cb0f6d9e 100644 --- a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt @@ -1,3 +1,4 @@ +core_setmaster@master-drop-set-shared-fd,Fail core_setmaster@master-drop-set-user,Fail core_setmaster_vs_auth,Fail i915_module_load@load,Fail @@ -6,7 +7,6 @@ i915_module_load@reload-no-display,Fail i915_module_load@resize-bar,Fail i915_pm_rpm@gem-execbuf-stress,Timeout i915_pm_rpm@module-reload,Fail -kms_ccs@crc-primary-rotation-180-yf-tiled-ccs,Timeout kms_cursor_legacy@short-flip-before-cursor-atomic-transitions,Timeout kms_fb_coherency@memset-crc,Crash kms_flip@busy-flip,Timeout diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt index 581f0da4d0f2..0207c9807bee 100644 --- a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt @@ -46,3 +46,10 @@ i915_hangman@engine-engine-hang # IGT Version: 1.28-gf13702b8e # Linux Version: 6.10.0-rc5 kms_pm_rpm@modeset-lpsp-stress + +# Board Name: asus-C433TA-AJ0005-rammus +# Bug Report: https://lore.kernel.org/intel-gfx/61f62c86-3e82-4eff-bd3c-8123fa0ca332@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_pm_rpm@drm-resources-equal diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt index e612281149aa..64772fedaed5 100644 --- a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt @@ -8,7 +8,6 @@ kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail -kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt index 4663d4d13f35..e8bddda56737 100644 --- a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt @@ -4,3 +4,10 @@ # IGT Version: 1.28-g0df7b9b97 # Linux Version: 6.9.0-rc7 kms_fb_coherency@memset-crc + +# Board Name: asus-C523NA-A20057-coral +# Bug Report: https://lore.kernel.org/intel-gfx/61f62c86-3e82-4eff-bd3c-8123fa0ca332@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_universal_plane@cursor-fb-leak diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt index 2723e2832797..f352b719cf7d 100644 --- a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt @@ -1,5 +1,5 @@ +core_setmaster@master-drop-set-shared-fd,Fail core_setmaster@master-drop-set-user,Fail -core_setmaster_vs_auth,Fail i915_module_load@load,Fail i915_module_load@reload,Fail i915_module_load@reload-no-display,Fail @@ -9,10 +9,10 @@ i915_pipe_stress@stress-xrgb8888-ytiled,Fail i915_pm_rpm@gem-execbuf-stress,Timeout i915_pm_rpm@module-reload,Fail i915_pm_rpm@system-suspend-execbuf,Timeout -kms_ccs@crc-primary-rotation-180-yf-tiled-ccs,Timeout +i915_pm_rps@engine-order,Fail +kms_big_fb@linear-16bpp-rotate-180,Timeout kms_fb_coherency@memset-crc,Crash kms_flip@busy-flip,Timeout -kms_flip@single-buffer-flip-vs-dpms-off-vs-modeset-interruptible,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail @@ -40,14 +40,11 @@ kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail kms_plane_alpha_blend@alpha-transparent-fb,Fail kms_plane_alpha_blend@constant-alpha-max,Fail -kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation,Timeout kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-5,Timeout kms_pm_rpm@modeset-stress-extra-wait,Timeout kms_pm_rpm@universal-planes,Timeout kms_pm_rpm@universal-planes-dpms,Timeout -kms_prop_blob@invalid-set-prop,Fail kms_psr2_sf@cursor-plane-update-sf,Fail -kms_psr2_sf@fbc-plane-move-sf-dmg-area,Timeout kms_psr2_sf@overlay-plane-update-continuous-sf,Fail kms_psr2_sf@overlay-plane-update-sf-dmg-area,Fail kms_psr2_sf@overlay-primary-update-sf-dmg-area,Fail @@ -55,7 +52,6 @@ kms_psr2_sf@plane-move-sf-dmg-area,Fail kms_psr2_sf@primary-plane-update-sf-dmg-area,Fail kms_psr2_sf@primary-plane-update-sf-dmg-area-big-fb,Fail kms_psr2_su@page_flip-NV12,Fail -kms_psr2_su@page_flip-P010,Fail kms_rotation_crc@primary-rotation-180,Timeout kms_setmode@basic,Fail kms_vblank@query-forked-hang,Timeout diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt index 58a6001abb28..d8401251e5f4 100644 --- a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt @@ -11,3 +11,17 @@ kms_plane_alpha_blend@constant-alpha-min # IGT Version: 1.28-gf13702b8e # Linux Version: 6.10.0-rc5 kms_atomic_transition@plane-all-modeset-transition-internal-panels + +# Board Name: asus-C436FA-Flip-hatch +# Bug Report: https://lore.kernel.org/intel-gfx/61f62c86-3e82-4eff-bd3c-8123fa0ca332@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_plane_alpha_blend@constant-alpha-min + +# Board Name: asus-C436FA-Flip-hatch +# Bug Report: https://lore.kernel.org/intel-gfx/61f62c86-3e82-4eff-bd3c-8123fa0ca332@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_async_flips@crc diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt index 4821c9adefd1..6eb64c672f7d 100644 --- a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt @@ -63,3 +63,4 @@ xe_module_load@load,Fail xe_module_load@many-reload,Fail xe_module_load@reload,Fail xe_module_load@reload-no-display,Fail +core_setmaster@master-drop-set-shared-fd,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt index 1de04a3308c4..d4fba4f55ec1 100644 --- a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt @@ -17,12 +17,10 @@ perf@i915-ref-count,Fail perf_pmu@busy-accuracy-50,Fail perf_pmu@module-unload,Fail perf_pmu@rc6,Crash -prime_busy@after,Fail sysfs_heartbeat_interval@long,Timeout sysfs_heartbeat_interval@off,Timeout sysfs_preempt_timeout@off,Timeout sysfs_timeslice_duration@off,Timeout -testdisplay,Timeout xe_module_load@force-load,Fail xe_module_load@load,Fail xe_module_load@many-reload,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt index e728ccc62326..461ef69ef08a 100644 --- a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt @@ -1,40 +1,64 @@ +api_intel_allocator@fork-simple-stress-signal,Timeout +api_intel_allocator@open-vm,Timeout api_intel_allocator@simple-allocator,Timeout +api_intel_bb@lot-of-buffers,Timeout api_intel_bb@object-reloc-keep-cache,Timeout api_intel_bb@offset-control,Timeout -core_auth@getclient-simple,Timeout -core_hotunplug@hotunbind-rebind,Timeout +api_intel_bb@render-ccs,Timeout +api_intel_bb@reset-bb,Timeout +core_auth@basic-auth,Timeout +core_hotunplug@hotrebind,Timeout +core_setmaster@master-drop-set-user,Fail debugfs_test@read_all_entries_display_on,Timeout -drm_read@invalid-buffer,Timeout -drm_read@short-buffer-nonblock,Timeout +drm_read@empty-block,Timeout +dumb_buffer@create-clear,Timeout +dumb_buffer@invalid-bpp,Timeout gen3_render_tiledx_blits,Timeout gen7_exec_parse@basic-allocation,Timeout -gen7_exec_parse@batch-without-end,Timeout gen9_exec_parse@batch-invalid-length,Timeout gen9_exec_parse@bb-secure,Timeout gen9_exec_parse@secure-batches,Timeout gen9_exec_parse@shadow-peek,Timeout gen9_exec_parse@unaligned-jump,Timeout +i915_getparams_basic@basic-subslice-total,Timeout +i915_hangman@gt-engine-hang,Timeout i915_module_load@load,Fail i915_module_load@reload,Fail i915_module_load@reload-no-display,Fail i915_module_load@resize-bar,Fail +i915_pciid,Timeout +i915_pipe_stress@stress-xrgb8888-ytiled,Timeout +i915_pm_rpm@gem-execbuf-stress,Timeout +i915_pm_rps@engine-order,Timeout +i915_pm_rps@thresholds-idle-park,Timeout i915_query@engine-info,Timeout i915_query@query-topology-kernel-writes,Timeout i915_query@test-query-geometry-subslices,Timeout kms_lease@lease-uevent,Fail kms_rotation_crc@multiplane-rotation,Fail perf@i915-ref-count,Fail +perf_pmu@busy,Timeout perf_pmu@enable-race,Timeout perf_pmu@event-wait,Timeout +perf_pmu@faulting-read,Timeout perf_pmu@gt-awake,Timeout perf_pmu@interrupts,Timeout perf_pmu@module-unload,Fail +perf_pmu@most-busy-idle-check-all,Timeout perf_pmu@rc6,Crash +perf_pmu@render-node-busy-idle,Fail +perf_pmu@semaphore-wait-idle,Timeout +prime_busy@after,Timeout +prime_mmap@test_aperture_limit,Timeout prime_mmap@test_map_unmap,Timeout prime_mmap@test_refcounting,Timeout prime_self_import@basic-with_one_bo,Timeout +sriov_basic@enable-vfs-autoprobe-off,Timeout +syncobj_basic@bad-destroy,Timeout syncobj_basic@bad-flags-fd-to-handle,Timeout +syncobj_basic@create-signaled,Timeout syncobj_eventfd@invalid-bad-pad,Timeout +syncobj_eventfd@timeline-wait-before-signal,Timeout syncobj_wait@invalid-multi-wait-unsubmitted-signaled,Timeout syncobj_wait@invalid-signal-illegal-handle,Timeout syncobj_wait@invalid-single-wait-all-unsubmitted,Timeout diff --git a/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt index 2adae2175501..0ce240e3aa07 100644 --- a/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt +++ b/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt @@ -1,5 +1,5 @@ +core_setmaster@master-drop-set-shared-fd,Fail core_setmaster@master-drop-set-user,Fail -core_setmaster_vs_auth,Fail i915_module_load@load,Fail i915_module_load@reload,Fail i915_module_load@reload-no-display,Fail @@ -7,7 +7,8 @@ i915_module_load@resize-bar,Fail i915_pm_rpm@gem-execbuf-stress,Timeout i915_pm_rpm@module-reload,Fail i915_pm_rpm@system-suspend-execbuf,Timeout -kms_ccs@crc-primary-rotation-180-yf-tiled-ccs,Timeout +i915_pm_rps@engine-order,Fail +kms_big_fb@linear-16bpp-rotate-180,Timeout kms_cursor_legacy@short-flip-before-cursor-atomic-transitions,Timeout kms_dirtyfb@default-dirtyfb-ioctl,Fail kms_dirtyfb@fbc-dirtyfb-ioctl,Fail @@ -32,19 +33,17 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail -kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-cpu,Timeout kms_frontbuffer_tracking@fbc-tiling-linear,Fail +kms_frontbuffer_tracking@fbc-1p-indfb-fliptrack-mmap-gtt,Timeout kms_lease@lease-uevent,Fail kms_plane_alpha_blend@alpha-basic,Fail kms_plane_alpha_blend@alpha-opaque-fb,Fail kms_plane_alpha_blend@alpha-transparent-fb,Fail kms_plane_alpha_blend@constant-alpha-max,Fail -kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation,Timeout kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-5,Timeout kms_pm_rpm@modeset-stress-extra-wait,Timeout kms_pm_rpm@universal-planes,Timeout kms_pm_rpm@universal-planes-dpms,Timeout -kms_prop_blob@invalid-set-prop,Fail kms_rotation_crc@primary-rotation-180,Timeout kms_vblank@query-forked-hang,Timeout perf@i915-ref-count,Fail diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt index a14349a1967f..8e0efc80d510 100644 --- a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt +++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt @@ -1,8 +1,3 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail fbdev@eof,Fail fbdev@read,Fail kms_3d,Fail @@ -27,10 +22,6 @@ kms_cursor_legacy@cursor-vs-flip-atomic,Fail kms_cursor_legacy@cursor-vs-flip-legacy,Fail kms_flip@flip-vs-modeset-vs-hang,Fail kms_flip@flip-vs-panning-vs-hang,Fail -kms_flip@flip-vs-suspend,Fail -kms_flip@flip-vs-suspend-interruptible,Fail kms_lease@lease-uevent,Fail -kms_properties@get_properties-sanity-atomic,Fail -kms_properties@plane-properties-atomic,Fail -kms_properties@plane-properties-legacy,Fail kms_rmfb@close-fd,Fail +kms_flip@flip-vs-suspend-interruptible,Fail diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt index 8cb2cb67853d..845f852bb4a0 100644 --- a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt +++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt @@ -1,10 +1,5 @@ core_setmaster@master-drop-set-shared-fd,Fail -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail dumb_buffer@create-clear,Crash -dumb_buffer@invalid-bpp,Fail fbdev@eof,Fail fbdev@pan,Fail fbdev@read,Fail @@ -18,5 +13,4 @@ kms_color@invalid-gamma-lut-sizes,Fail kms_flip@flip-vs-panning-vs-hang,Fail kms_flip@flip-vs-suspend,Fail kms_lease@lease-uevent,Fail -kms_properties@plane-properties-atomic,Fail kms_rmfb@close-fd,Fail diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt index 328967d3e23d..fc3745180683 100644 --- a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt +++ b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt @@ -1,4 +1,3 @@ -dumb_buffer@invalid-bpp,Fail kms_3d,Fail kms_cursor_legacy@forked-bo,Fail kms_cursor_legacy@forked-move,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt index 4ac46168eff3..066d24ee3e08 100644 --- a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt @@ -1,8 +1,3 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail kms_3d,Fail kms_cursor_legacy@torture-bo,Fail kms_force_connector_basic@force-edid,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt index bd0653caf7a0..2893f98a6b97 100644 --- a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt @@ -1,7 +1,2 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail kms_3d,Fail kms_lease@lease-uevent,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt index d42004cd6977..6dbc2080347d 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt @@ -1,8 +1,3 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail kms_color@ctm-0-25,Fail kms_color@ctm-0-50,Fail kms_color@ctm-0-75,Fail @@ -11,35 +6,13 @@ kms_color@ctm-green-to-red,Fail kms_color@ctm-negative,Fail kms_color@ctm-red-to-blue,Fail kms_color@ctm-signed,Fail -kms_content_protection@atomic,Crash -kms_content_protection@atomic-dpms,Crash -kms_content_protection@content-type-change,Crash -kms_content_protection@lic-type-0,Crash -kms_content_protection@lic-type-1,Crash -kms_content_protection@srm,Crash -kms_content_protection@type1,Crash -kms_content_protection@uevent,Crash -kms_cursor_legacy@2x-cursor-vs-flip-atomic,Fail -kms_cursor_legacy@2x-cursor-vs-flip-legacy,Fail -kms_cursor_legacy@2x-flip-vs-cursor-atomic,Fail -kms_cursor_legacy@2x-flip-vs-cursor-legacy,Fail -kms_cursor_legacy@2x-long-cursor-vs-flip-atomic,Fail -kms_cursor_legacy@2x-long-cursor-vs-flip-legacy,Fail -kms_cursor_legacy@2x-long-flip-vs-cursor-atomic,Fail -kms_cursor_legacy@2x-long-flip-vs-cursor-legacy,Fail kms_cursor_legacy@cursor-vs-flip-toggle,Fail kms_cursor_legacy@cursor-vs-flip-varying-size,Fail -kms_display_modes@extended-mode-basic,Fail -kms_flip@2x-flip-vs-modeset-vs-hang,Fail -kms_flip@2x-flip-vs-panning-vs-hang,Fail kms_flip@flip-vs-modeset-vs-hang,Fail kms_flip@flip-vs-panning-vs-hang,Fail kms_lease@lease-uevent,Fail -kms_multipipe_modeset@basic-max-pipe-crc-check,Fail kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail kms_plane_alpha_blend@alpha-7efc,Fail kms_plane_alpha_blend@coverage-7efc,Fail kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail -kms_plane_lowres@tiling-none,Fail kms_rmfb@close-fd,Fail -kms_vblank@ts-continuation-dpms-rpm,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt index d42004cd6977..6dbc2080347d 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt @@ -1,8 +1,3 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail kms_color@ctm-0-25,Fail kms_color@ctm-0-50,Fail kms_color@ctm-0-75,Fail @@ -11,35 +6,13 @@ kms_color@ctm-green-to-red,Fail kms_color@ctm-negative,Fail kms_color@ctm-red-to-blue,Fail kms_color@ctm-signed,Fail -kms_content_protection@atomic,Crash -kms_content_protection@atomic-dpms,Crash -kms_content_protection@content-type-change,Crash -kms_content_protection@lic-type-0,Crash -kms_content_protection@lic-type-1,Crash -kms_content_protection@srm,Crash -kms_content_protection@type1,Crash -kms_content_protection@uevent,Crash -kms_cursor_legacy@2x-cursor-vs-flip-atomic,Fail -kms_cursor_legacy@2x-cursor-vs-flip-legacy,Fail -kms_cursor_legacy@2x-flip-vs-cursor-atomic,Fail -kms_cursor_legacy@2x-flip-vs-cursor-legacy,Fail -kms_cursor_legacy@2x-long-cursor-vs-flip-atomic,Fail -kms_cursor_legacy@2x-long-cursor-vs-flip-legacy,Fail -kms_cursor_legacy@2x-long-flip-vs-cursor-atomic,Fail -kms_cursor_legacy@2x-long-flip-vs-cursor-legacy,Fail kms_cursor_legacy@cursor-vs-flip-toggle,Fail kms_cursor_legacy@cursor-vs-flip-varying-size,Fail -kms_display_modes@extended-mode-basic,Fail -kms_flip@2x-flip-vs-modeset-vs-hang,Fail -kms_flip@2x-flip-vs-panning-vs-hang,Fail kms_flip@flip-vs-modeset-vs-hang,Fail kms_flip@flip-vs-panning-vs-hang,Fail kms_lease@lease-uevent,Fail -kms_multipipe_modeset@basic-max-pipe-crc-check,Fail kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail kms_plane_alpha_blend@alpha-7efc,Fail kms_plane_alpha_blend@coverage-7efc,Fail kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail -kms_plane_lowres@tiling-none,Fail kms_rmfb@close-fd,Fail -kms_vblank@ts-continuation-dpms-rpm,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt index 770a1c685fde..fa8c7e663858 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt @@ -1,8 +1,4 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail +drm_read@invalid-buffer,Fail kms_color@ctm-0-25,Fail kms_color@ctm-0-50,Fail kms_color@ctm-0-75,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt index 2aa96b1241c3..38ec0305c1f4 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt @@ -116,3 +116,17 @@ kms_cursor_legacy@flip-vs-cursor-toggle # IGT Version: 1.28-gf13702b8e # Linux Version: 6.10.0-rc5 msm/msm_shrink@copy-mmap-oom-8 + +# Board Name: sdm845-cheza-r3 +# Bug Report: https://lore.kernel.org/linux-arm-msm/64bc4bcf-de51-4e60-a9f7-1295a1e64c65@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_lease@page-flip-implicit-plane + +# Board Name: sdm845-cheza-r3 +# Bug Report: https://lore.kernel.org/linux-arm-msm/64bc4bcf-de51-4e60-a9f7-1295a1e64c65@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc5 +kms_flip@flip-vs-expired-vblank diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt index 90651048ab61..94783cafc21a 100644 --- a/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt +++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt @@ -25,3 +25,8 @@ core_hotunplug.* # Whole machine hangs kms_cursor_crc.* + +# IGT test crash +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_content_protection@uevent diff --git a/drivers/gpu/drm/ci/xfails/panfrost-g12b-fails.txt b/drivers/gpu/drm/ci/xfails/panfrost-g12b-fails.txt index fe8ce2ce33e6..abd1ccb71561 100644 --- a/drivers/gpu/drm/ci/xfails/panfrost-g12b-fails.txt +++ b/drivers/gpu/drm/ci/xfails/panfrost-g12b-fails.txt @@ -1 +1,2 @@ panfrost/panfrost_prime@gem-prime-import,Fail +panfrost/panfrost_submit@pan-submit-error-bad-requirements,Fail diff --git a/drivers/gpu/drm/ci/xfails/panfrost-mt8183-fails.txt b/drivers/gpu/drm/ci/xfails/panfrost-mt8183-fails.txt index fe8ce2ce33e6..abd1ccb71561 100644 --- a/drivers/gpu/drm/ci/xfails/panfrost-mt8183-fails.txt +++ b/drivers/gpu/drm/ci/xfails/panfrost-mt8183-fails.txt @@ -1 +1,2 @@ panfrost/panfrost_prime@gem-prime-import,Fail +panfrost/panfrost_submit@pan-submit-error-bad-requirements,Fail diff --git a/drivers/gpu/drm/ci/xfails/panfrost-rk3288-fails.txt b/drivers/gpu/drm/ci/xfails/panfrost-rk3288-fails.txt index 4a2f4b6b14c1..8330b934602a 100644 --- a/drivers/gpu/drm/ci/xfails/panfrost-rk3288-fails.txt +++ b/drivers/gpu/drm/ci/xfails/panfrost-rk3288-fails.txt @@ -1 +1,2 @@ panfrost/panfrost_prime@gem-prime-import,Crash +panfrost/panfrost_submit@pan-submit-error-bad-requirements,Crash diff --git a/drivers/gpu/drm/ci/xfails/panfrost-rk3399-fails.txt b/drivers/gpu/drm/ci/xfails/panfrost-rk3399-fails.txt index fe8ce2ce33e6..abd1ccb71561 100644 --- a/drivers/gpu/drm/ci/xfails/panfrost-rk3399-fails.txt +++ b/drivers/gpu/drm/ci/xfails/panfrost-rk3399-fails.txt @@ -1 +1,2 @@ panfrost/panfrost_prime@gem-prime-import,Fail +panfrost/panfrost_submit@pan-submit-error-bad-requirements,Fail diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt index ea7b2ceb95b9..90282dfa19f4 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt @@ -1,18 +1,24 @@ -core_setmaster@master-drop-set-root,Crash core_setmaster@master-drop-set-user,Crash -core_setmaster_vs_auth,Crash -device_reset@cold-reset-bound,Crash -device_reset@reset-bound,Crash -device_reset@unbind-cold-reset-rebind,Crash -device_reset@unbind-reset-rebind,Crash dumb_buffer@create-clear,Crash -dumb_buffer@invalid-bpp,Crash fbdev@pan,Crash +kms_bw@linear-tiling-2-displays-1920x1080p,Fail kms_cursor_crc@cursor-onscreen-32x10,Crash kms_cursor_crc@cursor-onscreen-32x32,Crash +kms_cursor_crc@cursor-onscreen-64x64,Crash kms_cursor_crc@cursor-random-32x10,Crash +kms_cursor_crc@cursor-sliding-32x10,Crash kms_cursor_crc@cursor-sliding-32x32,Crash +kms_cursor_crc@cursor-sliding-64x21,Crash kms_cursor_legacy@basic-flip-before-cursor-atomic,Fail kms_cursor_legacy@cursor-vs-flip-legacy,Fail +kms_cursor_legacy@flip-vs-cursor-crc-atomic,Crash +kms_flip@flip-vs-panning-vs-hang,Crash +kms_invalid_mode@int-max-clock,Crash +kms_lease@invalid-create-leases,Fail +kms_pipe_crc_basic@read-crc-frame-sequence,Crash +kms_plane@pixel-format,Crash +kms_plane@pixel-format-source-clamping,Crash kms_prop_blob@invalid-set-prop,Crash -kms_prop_blob@invalid-set-prop-any,Crash +kms_properties@get_properties-sanity-atomic,Crash +kms_properties@get_properties-sanity-non-atomic,Crash +kms_rmfb@close-fd,Crash diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt index 7ede273aab20..cd0b27d8b636 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt @@ -4,3 +4,31 @@ # IGT Version: 1.28-gf13702b8e # Linux Version: 6.10.0-rc5 kms_cursor_legacy@flip-vs-cursor-atomic + +# Board Name: rk3288-veyron-jaq +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_cursor_crc@cursor-offscreen-32x10 + +# Board Name: rk3288-veyron-jaq +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_cursor_edge_walk@64x64-left-edge + +# Board Name: rk3288-veyron-jaq +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_flip@plain-flip-ts-check + +# Board Name: rk3288-veyron-jaq +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_cursor_crc@cursor-alpha-opaque diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt index 9309ff15e23a..83a38853b4af 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt @@ -1,9 +1,4 @@ -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail dumb_buffer@create-clear,Crash -dumb_buffer@invalid-bpp,Fail kms_atomic_transition@modeset-transition,Fail kms_atomic_transition@modeset-transition-fencing,Fail kms_atomic_transition@plane-toggle-modeset-transition,Fail @@ -46,7 +41,6 @@ kms_cursor_legacy@flip-vs-cursor-legacy,Fail kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic,Fail kms_flip@basic-flip-vs-wf_vblank,Fail kms_flip@blocking-wf_vblank,Fail -kms_flip@dpms-vs-vblank-race,Fail kms_flip@flip-vs-absolute-wf_vblank,Fail kms_flip@flip-vs-blocking-wf-vblank,Fail kms_flip@flip-vs-modeset-vs-hang,Fail @@ -59,7 +53,6 @@ kms_flip@plain-flip-fb-recreate,Fail kms_flip@plain-flip-fb-recreate-interruptible,Fail kms_flip@plain-flip-ts-check,Fail kms_flip@plain-flip-ts-check-interruptible,Fail -kms_flip@wf_vblank-ts-check,Fail kms_flip@wf_vblank-ts-check-interruptible,Fail kms_invalid_mode@int-max-clock,Fail kms_lease@lease-uevent,Fail diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt index d98f6a17343c..56f7d4f1ed15 100644 --- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt +++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt @@ -46,3 +46,31 @@ kms_setmode@basic # IGT Version: 1.28-gf13702b8e # Linux Version: 6.10.0-rc5 kms_bw@connected-linear-tiling-1-displays-2560x1440p + +# Board Name: rk3399-gru-kevin +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc2 +kms_flip@wf_vblank-ts-check + +# Board Name: rk3399-gru-kevin +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc5 +kms_flip@dpms-vs-vblank-race + +# Board Name: rk3399-gru-kevin +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc5 +kms_bw@linear-tiling-2-displays-2160x1440p + +# Board Name: rk3399-gru-kevin +# Bug Report: https://lore.kernel.org/linux-rockchip/7505ac00-29ef-4ad9-8904-94b4c024c02b@collabora.com/T/#t +# Failure Rate: 50 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.11.0-rc5 +kms_flip@flip-vs-expired-vblank diff --git a/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt b/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt index 5408110f4c60..71c02104a683 100644 --- a/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt +++ b/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt @@ -1,24 +1,3 @@ -core_hotunplug@hotrebind,Fail -core_hotunplug@hotrebind-lateclose,Fail -core_hotunplug@hotreplug,Fail -core_hotunplug@hotreplug-lateclose,Fail -core_hotunplug@hotunbind-rebind,Fail -core_hotunplug@hotunplug-rescan,Fail -core_hotunplug@unbind-rebind,Fail -core_hotunplug@unplug-rescan,Fail -device_reset@cold-reset-bound,Fail -device_reset@reset-bound,Fail -device_reset@unbind-cold-reset-rebind,Fail -device_reset@unbind-reset-rebind,Fail -dumb_buffer@invalid-bpp,Fail -kms_content_protection@atomic,Crash -kms_content_protection@atomic-dpms,Crash -kms_content_protection@content-type-change,Crash -kms_content_protection@lic-type-0,Crash -kms_content_protection@lic-type-1,Crash -kms_content_protection@srm,Crash -kms_content_protection@type1,Crash -kms_content_protection@uevent,Crash kms_cursor_crc@cursor-rapid-movement-128x128,Fail kms_cursor_crc@cursor-rapid-movement-128x42,Fail kms_cursor_crc@cursor-rapid-movement-256x256,Fail diff --git a/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt b/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt index 5ccc771fbb36..b3d16e82e9a2 100644 --- a/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt +++ b/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt @@ -205,6 +205,59 @@ kms_cursor_edge_walk@128x128-right-edge # R10: ffffa2c181790000 R11: 0000000000000000 R12: ffffa2c1814fa810 # R13: 0000000000000031 R14: 0000000000000031 R15: 000000000000 +kms_cursor_edge_walk@128x128-left-edge +# DEBUG - Begin test kms_cursor_edge_walk@128x128-left-edge +# Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI +# CPU: 0 UID: 0 PID: 27 Comm: kworker/u8:1 Not tainted 6.11.0-rc5-g5d3429a7e9aa #1 +# Hardware name: ChromiumOS crosvm, BIOS 0 +# Workqueue: vkms_composer vkms_composer_worker [vkms] +# RIP: 0010:compose_active_planes+0x344/0x4e0 [vkms] +# Code: 6a 34 0f 8e 91 fe ff ff 44 89 ea 48 8d 7c 24 48 e8 71 f0 ff ff 4b 8b 04 fc 48 8b 4c 24 50 48 8b 7c 24 40 48 8b 80 48 01 00 00 <48> 63 70 18 8b 40 20 48 89 f2 48 c1 e6 03 29 d0 48 8b 54 24 48 48 +# RSP: 0018:ffffa437800ebd58 EFLAGS: 00010282 +# RAX: 0000000000000000 RBX: 0000000000000002 RCX: ffffa0e841904000 +# RDX: 00000000000000ff RSI: ffffa0e841905ff8 RDI: ffffa0e841902000 +# RBP: 0000000000000000 R08: ffffa0e84158a600 R09: 00000000000003ff +# R10: 0000000078b2bcd2 R11: 00000000278b2bcd R12: ffffa0e84870fc60 +# R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +# FS: 0000000000000000(0000) GS:ffffa0e86bc00000(0000) knlGS:0000000000000000 +# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +# CR2: 0000000000000018 CR3: 0000000101710000 CR4: 0000000000350ef0 +# Call Trace: +# <TASK> +# ? __die+0x1e/0x60 +# ? page_fault_oops+0x17b/0x4a0 +# ? exc_page_fault+0x6d/0x230 +# ? asm_exc_page_fault+0x26/0x30 +# ? compose_active_planes+0x344/0x4e0 [vkms] +# ? compose_active_planes+0x32f/0x4e0 [vkms] +# ? srso_return_thunk+0x5/0x5f +# vkms_composer_worker+0x205/0x240 [vkms] +# process_one_work+0x201/0x6c0 +# ? lock_is_held_type+0x9e/0x110 +# worker_thread+0x17e/0x310 +# ? __pfx_worker_thread+0x10/0x10 +# kthread+0xce/0x100 +# ? __pfx_kthread+0x10/0x10 +# ret_from_fork+0x2f/0x50 +# ? __pfx_kthread+0x10/0x10 +# ret_from_fork_asm+0x1a/0x30 +# </TASK> +# Modules linked in: vkms +# CR2: 0000000000000018 +# ---[ end trace 0000000000000000 ]--- +# RIP: 0010:compose_active_planes+0x344/0x4e0 [vkms] +# Code: 6a 34 0f 8e 91 fe ff ff 44 89 ea 48 8d 7c 24 48 e8 71 f0 ff ff 4b 8b 04 fc 48 8b 4c 24 50 48 8b 7c 24 40 48 8b 80 48 01 00 00 <48> 63 70 18 8b 40 20 48 89 f2 48 c1 e6 03 29 d0 48 8b 54 24 48 48 +# RSP: 0018:ffffa437800ebd58 EFLAGS: 00010282 +# RAX: 0000000000000000 RBX: 0000000000000002 RCX: ffffa0e841904000 +# RDX: 00000000000000ff RSI: ffffa0e841905ff8 RDI: ffffa0e841902000 +# RBP: 0000000000000000 R08: ffffa0e84158a600 R09: 00000000000003ff +# R10: 0000000078b2bcd2 R11: 00000000278b2bcd R12: ffffa0e84870fc60 +# R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +# FS: 0000000000000000(0000) GS:ffffa0e86bc00000(0000) knlGS:0000000000000000 +# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +# CR2: 0000000000000018 CR3: 0000000101710000 CR4: 0000000000350ef0 +# vkms_vblank_simulate: vblank timer overrun + # Skip driver specific tests ^amdgpu.* ^msm.* -- GitLab From b37918090b2e84133c6eb9a1e227b2b7092d219e Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Tue, 24 Sep 2024 11:19:07 +0100 Subject: [PATCH 300/970] drm/sched: Add locking to drm_sched_entity_modify_sched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without the locking amdgpu currently can race between amdgpu_ctx_set_entity_priority() (via drm_sched_entity_modify_sched()) and drm_sched_job_arm(), leading to the latter accesing potentially inconsitent entity->sched_list and entity->num_sched_list pair. v2: * Improve commit message. (Philipp) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Fixes: b37aced31eb0 ("drm/scheduler: implement a function to modify sched list") Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: David Airlie <airlied@gmail.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: dri-devel@lists.freedesktop.org Cc: Philipp Stanner <pstanner@redhat.com> Cc: <stable@vger.kernel.org> # v5.7+ Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924101914.2713-2-tursulin@igalia.com Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/scheduler/sched_entity.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index ffa3e765f5db..b06c0696f970 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -133,8 +133,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, { WARN_ON(!num_sched_list || !sched_list); + spin_lock(&entity->rq_lock); entity->sched_list = sched_list; entity->num_sched_list = num_sched_list; + spin_unlock(&entity->rq_lock); } EXPORT_SYMBOL(drm_sched_entity_modify_sched); -- GitLab From f0fa69b5011a45394554fb8061d74fee4d7cd72c Mon Sep 17 00:00:00 2001 From: Derek Foreman <derek.foreman@collabora.com> Date: Tue, 27 Aug 2024 11:39:04 -0500 Subject: [PATCH 301/970] drm/connector: hdmi: Fix writing Dynamic Range Mastering infoframes The largest infoframe we create is the DRM (Dynamic Range Mastering) infoframe which is 26 bytes + a 4 byte header, for a total of 30 bytes. With HDMI_MAX_INFOFRAME_SIZE set to 29 bytes, as it is now, we allocate too little space to pack a DRM infoframe in write_device_infoframe(), leading to an ENOSPC return from hdmi_infoframe_pack(), and never calling the connector's write_infoframe() vfunc. Instead of having HDMI_MAX_INFOFRAME_SIZE defined in two places, replace HDMI_MAX_INFOFRAME_SIZE with HDMI_INFOFRAME_SIZE(MAX) and make MAX 27 bytes - which is defined by the HDMI specification to be the largest infoframe payload. Fixes: f378b77227bc ("drm/connector: hdmi: Add Infoframes generation") Fixes: c602e4959a0c ("drm/connector: hdmi: Create Infoframe DebugFS entries") Signed-off-by: Derek Foreman <derek.foreman@collabora.com> Acked-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240827163918.48160-1-derek.foreman@collabora.com Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 4 +--- drivers/gpu/drm/drm_debugfs.c | 4 +--- include/linux/hdmi.h | 9 +++++++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 7854820089ec..feb7a3a75981 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -521,8 +521,6 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); -#define HDMI_MAX_INFOFRAME_SIZE 29 - static int clear_device_infoframe(struct drm_connector *connector, enum hdmi_infoframe_type type) { @@ -563,7 +561,7 @@ static int write_device_infoframe(struct drm_connector *connector, { const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; struct drm_device *dev = connector->dev; - u8 buffer[HDMI_MAX_INFOFRAME_SIZE]; + u8 buffer[HDMI_INFOFRAME_SIZE(MAX)]; int ret; int len; diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 6b239a24f1df..9d3e6dd68810 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -520,8 +520,6 @@ static const struct file_operations drm_connector_fops = { .write = connector_write }; -#define HDMI_MAX_INFOFRAME_SIZE 29 - static ssize_t audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) { @@ -579,7 +577,7 @@ static ssize_t _f##_read_infoframe(struct file *filp, \ struct drm_connector *connector; \ union hdmi_infoframe *frame; \ struct drm_device *dev; \ - u8 buf[HDMI_MAX_INFOFRAME_SIZE]; \ + u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \ ssize_t len = 0; \ \ connector = filp->private_data; \ diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 3bb87bf6bc65..455f855bc084 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -59,6 +59,15 @@ enum hdmi_infoframe_type { #define HDMI_DRM_INFOFRAME_SIZE 26 #define HDMI_VENDOR_INFOFRAME_SIZE 4 +/* + * HDMI 1.3a table 5-14 states that the largest InfoFrame_length is 27, + * not including the packet header or checksum byte. We include the + * checksum byte in HDMI_INFOFRAME_HEADER_SIZE, so this should allow + * HDMI_INFOFRAME_SIZE(MAX) to be the largest buffer we could ever need + * for any HDMI infoframe. + */ +#define HDMI_MAX_INFOFRAME_SIZE 27 + #define HDMI_INFOFRAME_SIZE(type) \ (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE) -- GitLab From 8ae5bfb0d96eda4699463f21bcb4947a8d4dcde0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven <geert+renesas@glider.be> Date: Mon, 27 May 2024 15:34:48 +0200 Subject: [PATCH 302/970] drm: renesas: shmobile: Add drm_panic support Add support for the drm_panic module, which displays a message on the screen when a kernel panic occurs. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Acked-by: Sui Jingfeng <sui.jingfeng@linux.dev> Link: https://patchwork.freedesktop.org/patch/msgid/292638fde9aef8b00e984245f43dc02a818cf322.1716816827.git.geert+renesas@glider.be Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c index 07ad17d24294..9d166ab2af8b 100644 --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c @@ -273,6 +273,13 @@ static const struct drm_plane_helper_funcs shmob_drm_plane_helper_funcs = { .atomic_disable = shmob_drm_plane_atomic_disable, }; +static const struct drm_plane_helper_funcs shmob_drm_primary_plane_helper_funcs = { + .atomic_check = shmob_drm_plane_atomic_check, + .atomic_update = shmob_drm_plane_atomic_update, + .atomic_disable = shmob_drm_plane_atomic_disable, + .get_scanout_buffer = drm_fb_dma_get_scanout_buffer, +}; + static const struct drm_plane_funcs shmob_drm_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -310,7 +317,12 @@ struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev, splane->index = index; - drm_plane_helper_add(&splane->base, &shmob_drm_plane_helper_funcs); + if (type == DRM_PLANE_TYPE_PRIMARY) + drm_plane_helper_add(&splane->base, + &shmob_drm_primary_plane_helper_funcs); + else + drm_plane_helper_add(&splane->base, + &shmob_drm_plane_helper_funcs); return &splane->base; } -- GitLab From b558053fcf05e85d3924d4d9ad15df57c588730f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven <geert+renesas@glider.be> Date: Mon, 27 May 2024 15:35:49 +0200 Subject: [PATCH 303/970] drm: renesas: rcar-du: Add drm_panic support for non-vsp Add support for the drm_panic module for DU variants not using the VSP-compositor, to display a message on the screen when a kernel panic occurs. Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Acked-by: Sui Jingfeng <sui.jingfeng@linux.dev> Link: https://patchwork.freedesktop.org/patch/msgid/b633568d2e3f405b21debdd60854fe39780254d6.1716816897.git.geert+renesas@glider.be Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c index e445fac8e0b4..c546ab0805d6 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c @@ -680,6 +680,12 @@ static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = { .atomic_update = rcar_du_plane_atomic_update, }; +static const struct drm_plane_helper_funcs rcar_du_primary_plane_helper_funcs = { + .atomic_check = rcar_du_plane_atomic_check, + .atomic_update = rcar_du_plane_atomic_update, + .get_scanout_buffer = drm_fb_dma_get_scanout_buffer, +}; + static struct drm_plane_state * rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane) { @@ -812,8 +818,12 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp) if (ret < 0) return ret; - drm_plane_helper_add(&plane->plane, - &rcar_du_plane_helper_funcs); + if (type == DRM_PLANE_TYPE_PRIMARY) + drm_plane_helper_add(&plane->plane, + &rcar_du_primary_plane_helper_funcs); + else + drm_plane_helper_add(&plane->plane, + &rcar_du_plane_helper_funcs); drm_plane_create_alpha_property(&plane->plane); -- GitLab From fe4f5d4b661666a45b48fe7f95443f8fefc09c8c Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Fri, 20 Sep 2024 18:17:12 -0700 Subject: [PATCH 304/970] drm/xe: Clean up VM / exec queue file lock usage. Both the VM / exec queue file lock protect the lookup and reference to the object, nothing more. These locks are not intended anything else underneath them. XA have their own locking too, so no need to take the VM / exec queue file lock aside from when doing a lookup and reference get. Add some kernel doc to make this clear and cleanup a few typos too. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240921011712.2681510-1-matthew.brost@intel.com --- drivers/gpu/drm/xe/xe_device.c | 2 -- drivers/gpu/drm/xe/xe_device_types.h | 14 +++++++++++--- drivers/gpu/drm/xe/xe_drm_client.c | 9 ++++++++- drivers/gpu/drm/xe/xe_exec_queue.c | 2 -- drivers/gpu/drm/xe/xe_vm.c | 4 ---- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index cb5a9fd820cf..53dcece40fc5 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -171,10 +171,8 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file) xe_exec_queue_kill(q); xe_exec_queue_put(q); } - mutex_lock(&xef->vm.lock); xa_for_each(&xef->vm.xa, idx, vm) xe_vm_close_and_put(vm); - mutex_unlock(&xef->vm.lock); xe_file_put(xef); diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 5ad96d283a71..484fb34dde98 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -593,15 +593,23 @@ struct xe_file { struct { /** @vm.xe: xarray to store VMs */ struct xarray xa; - /** @vm.lock: protects file VM state */ + /** + * @vm.lock: Protects VM lookup + reference and removal a from + * file xarray. Not an intended to be an outer lock which does + * thing while being held. + */ struct mutex lock; } vm; /** @exec_queue: Submission exec queue state for file */ struct { - /** @exec_queue.xe: xarray to store engines */ + /** @exec_queue.xa: xarray to store exece queues */ struct xarray xa; - /** @exec_queue.lock: protects file engine state */ + /** + * @exec_queue.lock: Protects exec queue lookup + reference and + * removal a frommfile xarray. Not an intended to be an outer + * lock which does thing while being held. + */ struct mutex lock; } exec_queue; diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c index c4add8b38bbd..fb52a23e28f8 100644 --- a/drivers/gpu/drm/xe/xe_drm_client.c +++ b/drivers/gpu/drm/xe/xe_drm_client.c @@ -283,8 +283,15 @@ static void show_run_ticks(struct drm_printer *p, struct drm_file *file) /* Accumulate all the exec queues from this client */ mutex_lock(&xef->exec_queue.lock); - xa_for_each(&xef->exec_queue.xa, i, q) + xa_for_each(&xef->exec_queue.xa, i, q) { + xe_exec_queue_get(q); + mutex_unlock(&xef->exec_queue.lock); + xe_exec_queue_update_run_ticks(q); + + mutex_lock(&xef->exec_queue.lock); + xe_exec_queue_put(q); + } mutex_unlock(&xef->exec_queue.lock); /* Get the total GPU cycles */ diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 7f28b7fc68d5..7743ebdcbf4b 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -635,9 +635,7 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data, } } - mutex_lock(&xef->exec_queue.lock); err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); - mutex_unlock(&xef->exec_queue.lock); if (err) goto kill_exec_queue; diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index a3d7cb7cfd22..31fe31db3fdc 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1765,9 +1765,7 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, if (IS_ERR(vm)) return PTR_ERR(vm); - mutex_lock(&xef->vm.lock); err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); - mutex_unlock(&xef->vm.lock); if (err) goto err_close_and_put; @@ -1799,9 +1797,7 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, return 0; err_free_id: - mutex_lock(&xef->vm.lock); xa_erase(&xef->vm.xa, id); - mutex_unlock(&xef->vm.lock); err_close_and_put: xe_vm_close_and_put(vm); -- GitLab From 3a87e264290d71ec86a210ab3e8d23b715ad266d Mon Sep 17 00:00:00 2001 From: Guixin Liu <kanie@linux.alibaba.com> Date: Mon, 23 Sep 2024 18:05:12 +0800 Subject: [PATCH 305/970] io_uring: fix memory leak when cache init fail Exit the percpu ref when cache init fails to free the data memory with in struct percpu_ref. Fixes: 206aefde4f88 ("io_uring: reduce/pack size of io_ring_ctx") Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de> Link: https://lore.kernel.org/r/20240923100512.64638-1-kanie@linux.alibaba.com Signed-off-by: Jens Axboe <axboe@kernel.dk> --- io_uring/io_uring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index feb61d68dca6..c406f5d4c248 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -321,7 +321,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) sizeof(struct io_kiocb)); ret |= io_futex_cache_init(ctx); if (ret) - goto err; + goto free_ref; init_completion(&ctx->ref_comp); xa_init_flags(&ctx->personalities, XA_FLAGS_ALLOC1); mutex_init(&ctx->uring_lock); @@ -349,6 +349,9 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) io_napi_init(ctx); return ctx; + +free_ref: + percpu_ref_exit(&ctx->refs); err: io_alloc_cache_free(&ctx->rsrc_node_cache, kfree); io_alloc_cache_free(&ctx->apoll_cache, kfree); -- GitLab From 17ea56b752b6ba58fdd1fcfd24f0fd2fa2b0ade2 Mon Sep 17 00:00:00 2001 From: Min-Hua Chen <minhuadotchen@gmail.com> Date: Sun, 22 Sep 2024 18:41:29 +0800 Subject: [PATCH 306/970] io_uring: fix casts to io_req_flags_t Apply __force cast to restricted io_req_flags_t type to fix the following sparse warning: io_uring/io_uring.c:2026:23: sparse: warning: cast to restricted io_req_flags_t No functional changes intended. Signed-off-by: Min-Hua Chen <minhuadotchen@gmail.com> Link: https://lore.kernel.org/r/20240922104132.157055-1-minhuadotchen@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk> --- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index c406f5d4c248..b2736e3491b8 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2041,7 +2041,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, req->opcode = opcode = READ_ONCE(sqe->opcode); /* same numerical values with corresponding REQ_F_*, safe to copy */ sqe_flags = READ_ONCE(sqe->flags); - req->flags = (io_req_flags_t) sqe_flags; + req->flags = (__force io_req_flags_t) sqe_flags; req->cqe.user_data = READ_ONCE(sqe->user_data); req->file = NULL; req->rsrc_node = NULL; -- GitLab From 42268ad0eb4142245ea40ab01a5690a40e9c3b41 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Tue, 24 Sep 2024 11:10:07 -1000 Subject: [PATCH 307/970] sched_ext: Build fix for !CONFIG_SMP move_remote_task_to_local_dsq() is only defined on SMP configs but scx_disaptch_from_dsq() was calling move_remote_task_to_local_dsq() on UP configs too causing build failures. Add a dummy move_remote_task_to_local_dsq() which triggers a warning. Signed-off-by: Tejun Heo <tj@kernel.org> Fixes: 4c30f5ce4f7a ("sched_ext: Implement scx_bpf_dispatch[_vtime]_from_dsq()") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409241108.jaocHiDJ-lkp@intel.com/ --- kernel/sched/ext.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index c09e3dc38c34..d74d1fe06999 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -2357,6 +2357,7 @@ static bool consume_remote_task(struct rq *this_rq, struct task_struct *p, } } #else /* CONFIG_SMP */ +static inline void move_remote_task_to_local_dsq(struct task_struct *p, u64 enq_flags, struct rq *src_rq, struct rq *dst_rq) { WARN_ON_ONCE(1); } static inline bool task_can_run_on_remote_rq(struct task_struct *p, struct rq *rq, bool trigger_error) { return false; } static inline bool consume_remote_task(struct rq *this_rq, struct task_struct *p, struct scx_dispatch_q *dsq, struct rq *task_rq) { return false; } #endif /* CONFIG_SMP */ -- GitLab From f2a4bcb2532881655ee546305f2a4fc6e1399a3e Mon Sep 17 00:00:00 2001 From: Christian Gmeiner <cgmeiner@igalia.com> Date: Mon, 23 Sep 2024 17:19:59 +0200 Subject: [PATCH 308/970] drm/v3d: Use v3d_perfmon_find() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the open-coded v3d_perfmon_find() with the real thing. Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com> Reviewed-by: MaÃra Canal <mcanal@igalia.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923152000.185980-1-christian.gmeiner@gmail.com --- drivers/gpu/drm/v3d/v3d_perfmon.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c index cd7f1eedf17f..54a486a9b74c 100644 --- a/drivers/gpu/drm/v3d/v3d_perfmon.c +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c @@ -402,11 +402,7 @@ int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data, if (req->pad != 0) return -EINVAL; - mutex_lock(&v3d_priv->perfmon.lock); - perfmon = idr_find(&v3d_priv->perfmon.idr, req->id); - v3d_perfmon_get(perfmon); - mutex_unlock(&v3d_priv->perfmon.lock); - + perfmon = v3d_perfmon_find(v3d_priv, req->id); if (!perfmon) return -EINVAL; -- GitLab From 65676a6fc0ab83cc368ec4fae0f55422ecb1464d Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> Date: Wed, 11 Sep 2024 07:50:46 -0600 Subject: [PATCH 309/970] MAINTAINERS: remove myself as a VKMS maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I haven't been able to follow or review the work on the driver for a long time and I don't see the situation improving anytime soon. Hence, this commit removes me from the maintainers list. Signed-off-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> Acked-by: MaÃra Canal <mcanal@igalia.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911135051.44579-1-rodrigosiqueiramelo@gmail.com --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 77efbded2bfe..16a27a0abb9d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7346,7 +7346,6 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/udl/ DRM DRIVER FOR VIRTUAL KERNEL MODESETTING (VKMS) -M: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> M: MaÃra Canal <mairacanal@riseup.net> R: Haneen Mohammed <hamohammed.sa@gmail.com> R: Simona Vetter <simona@ffwll.ch> -- GitLab From 80fd814e93f10fe60d02d8a31c46718ff9e9edec Mon Sep 17 00:00:00 2001 From: Louis Chauvet <louis.chauvet@bootlin.com> Date: Tue, 10 Sep 2024 17:10:45 +0200 Subject: [PATCH 310/970] MAINTAINERS: Add myself as VKMS Maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I've been actively working on VKMS to provide new features and participated in reviews and testing. To help Maìra with her work, add myself as co-maintainer of VKMS. Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> Acked-by: MaÃra Canal <mcanal@igalia.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240910-vkms-maintainer-v1-1-e7a6c7a4ae71@bootlin.com --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 16a27a0abb9d..3340ccc37c29 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7347,6 +7347,7 @@ F: drivers/gpu/drm/udl/ DRM DRIVER FOR VIRTUAL KERNEL MODESETTING (VKMS) M: MaÃra Canal <mairacanal@riseup.net> +M: Louis Chauvet <louis.chauvet@bootlin.com> R: Haneen Mohammed <hamohammed.sa@gmail.com> R: Simona Vetter <simona@ffwll.ch> R: Melissa Wen <melissa.srw@gmail.com> -- GitLab From 6e5eb6dcb3042adcda432a3498d0d62d91588c4d Mon Sep 17 00:00:00 2001 From: Louis Chauvet <louis.chauvet@bootlin.com> Date: Thu, 5 Sep 2024 15:27:06 +0200 Subject: [PATCH 311/970] drm/vkms: Add documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation around vkms_output and its initialization. Add some documentation on pixel conversion functions. Update of outdated comments for pixel_write functions. Reviewed-by: José Expósito <jose.exposito89@gmail.com> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905-google-clarifications-v4-1-e43c1f2e3d87@bootlin.com --- drivers/gpu/drm/vkms/vkms_composer.c | 7 ++ drivers/gpu/drm/vkms/vkms_drv.h | 101 +++++++++++++++++++++++---- drivers/gpu/drm/vkms/vkms_formats.c | 62 +++++++++++++--- drivers/gpu/drm/vkms/vkms_output.c | 14 +++- 4 files changed, 161 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index e7441b227b3c..57a5769fc994 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -189,6 +189,13 @@ static void blend(struct vkms_writeback_job *wb, size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay; + /* + * The planes are composed line-by-line to avoid heavy memory usage. It is a necessary + * complexity to avoid poor blending performance. + * + * The function vkms_compose_row() is used to read a line, pixel-by-pixel, into the staging + * buffer. + */ for (size_t y = 0; y < crtc_y_limit; y++) { fill_background(&background_color, output_buffer); diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 5e46ea5b96dc..672fe191e239 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -25,6 +25,17 @@ #define VKMS_LUT_SIZE 256 +/** + * struct vkms_frame_info - Structure to store the state of a frame + * + * @fb: backing drm framebuffer + * @src: source rectangle of this frame in the source framebuffer, stored in 16.16 fixed-point form + * @dst: destination rectangle in the crtc buffer, stored in whole pixel units + * @map: see @drm_shadow_plane_state.data + * @rotation: rotation applied to the source. + * + * @src and @dst should have the same size modulo the rotation. + */ struct vkms_frame_info { struct drm_framebuffer *fb; struct drm_rect src, dst; @@ -52,9 +63,11 @@ struct vkms_writeback_job { }; /** - * vkms_plane_state - Driver specific plane state + * struct vkms_plane_state - Driver specific plane state * @base: base plane state * @frame_info: data required for composing computation + * @pixel_read: function to read a pixel in this plane. The creator of a struct vkms_plane_state + * must ensure that this pointer is valid */ struct vkms_plane_state { struct drm_shadow_plane_state base; @@ -73,29 +86,56 @@ struct vkms_color_lut { }; /** - * vkms_crtc_state - Driver specific CRTC state + * struct vkms_crtc_state - Driver specific CRTC state + * * @base: base CRTC state * @composer_work: work struct to compose and add CRC entries - * @n_frame_start: start frame number for computed CRC - * @n_frame_end: end frame number for computed CRC + * + * @num_active_planes: Number of active planes + * @active_planes: List containing all the active planes (counted by + * @num_active_planes). They should be stored in z-order. + * @active_writeback: Current active writeback job + * @gamma_lut: Look up table for gamma used in this CRTC + * @crc_pending: Protected by @vkms_output.composer_lock, true when the frame CRC is not computed + * yet. Used by vblank to detect if the composer is too slow. + * @wb_pending: Protected by @vkms_output.composer_lock, true when a writeback frame is requested. + * @frame_start: Protected by @vkms_output.composer_lock, saves the frame number before the start + * of the composition process. + * @frame_end: Protected by @vkms_output.composer_lock, saves the last requested frame number. + * This is used to generate enough CRC entries when the composition worker is too slow. */ struct vkms_crtc_state { struct drm_crtc_state base; struct work_struct composer_work; int num_active_planes; - /* stack of active planes for crc computation, should be in z order */ struct vkms_plane_state **active_planes; struct vkms_writeback_job *active_writeback; struct vkms_color_lut gamma_lut; - /* below four are protected by vkms_output.composer_lock */ bool crc_pending; bool wb_pending; u64 frame_start; u64 frame_end; }; +/** + * struct vkms_output - Internal representation of all output components in VKMS + * + * @crtc: Base CRTC in DRM + * @encoder: DRM encoder used for this output + * @connector: DRM connector used for this output + * @wb_connecter: DRM writeback connector used for this output + * @vblank_hrtimer: Timer used to trigger the vblank + * @period_ns: vblank period, in nanoseconds, used to configure @vblank_hrtimer and to compute + * vblank timestamps + * @composer_workq: Ordered workqueue for @composer_state.composer_work. + * @lock: Lock used to protect concurrent access to the composer + * @composer_enabled: Protected by @lock, true when the VKMS composer is active (crc needed or + * writeback) + * @composer_state: Protected by @lock, current state of this VKMS output + * @composer_lock: Lock used internally to protect @composer_state members + */ struct vkms_output { struct drm_crtc crtc; struct drm_encoder encoder; @@ -103,28 +143,38 @@ struct vkms_output { struct drm_writeback_connector wb_connector; struct hrtimer vblank_hrtimer; ktime_t period_ns; - /* ordered wq for composer_work */ struct workqueue_struct *composer_workq; - /* protects concurrent access to composer */ spinlock_t lock; - /* protected by @lock */ bool composer_enabled; struct vkms_crtc_state *composer_state; spinlock_t composer_lock; }; -struct vkms_device; - +/** + * struct vkms_config - General configuration for VKMS driver + * + * @writeback: If true, a writeback buffer can be attached to the CRTC + * @cursor: If true, a cursor plane is created in the VKMS device + * @overlay: If true, NUM_OVERLAY_PLANES will be created for the VKMS device + * @dev: Used to store the current VKMS device. Only set when the device is instantiated. + */ struct vkms_config { bool writeback; bool cursor; bool overlay; - /* only set when instantiated */ struct vkms_device *dev; }; +/** + * struct vkms_device - Description of a VKMS device + * + * @drm - Base device in DRM + * @platform - Associated platform device + * @output - Configuration and sub-components of the VKMS device + * @config: Configuration used in this VKMS device + */ struct vkms_device { struct drm_device drm; struct platform_device *platform; @@ -132,6 +182,10 @@ struct vkms_device { const struct vkms_config *config; }; +/* + * The following helpers are used to convert a member of a struct into its parent. + */ + #define drm_crtc_to_vkms_output(target) \ container_of(target, struct vkms_output, crtc) @@ -144,12 +198,33 @@ struct vkms_device { #define to_vkms_plane_state(target)\ container_of(target, struct vkms_plane_state, base.base) -/* CRTC */ +/** + * vkms_crtc_init() - Initialize a CRTC for VKMS + * @dev: DRM device associated with the VKMS buffer + * @crtc: uninitialized CRTC device + * @primary: primary plane to attach to the CRTC + * @cursor: plane to attach to the CRTC + */ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor); +/** + * vkms_output_init() - Initialize all sub-components needed for a VKMS device. + * + * @vkmsdev: VKMS device to initialize + * @index: CRTC which can be attached to the planes. The caller must ensure that + * @index is positive and less or equals to 31. + */ int vkms_output_init(struct vkms_device *vkmsdev, int index); +/** + * vkms_plane_init() - Initialize a plane + * + * @vkmsdev: VKMS device containing the plane + * @type: type of plane to initialize + * @index: CRTC which can be attached to the plane. The caller must ensure that + * @index is positive and less or equals to 31. + */ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, enum drm_plane_type type, int index); diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 040b7f113a3b..e8a5cc235ebb 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -9,24 +9,40 @@ #include "vkms_formats.h" +/** + * pixel_offset() - Get the offset of the pixel at coordinates x/y in the first plane + * + * @frame_info: Buffer metadata + * @x: The x coordinate of the wanted pixel in the buffer + * @y: The y coordinate of the wanted pixel in the buffer + * + * The caller must ensure that the framebuffer associated with this request uses a pixel format + * where block_h == block_w == 1. + * If this requirement is not fulfilled, the resulting offset can point to an other pixel or + * outside of the buffer. + */ static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, int y) { return frame_info->offset + (y * frame_info->pitch) + (x * frame_info->cpp); } -/* - * packed_pixels_addr - Get the pointer to pixel of a given pair of coordinates +/** + * packed_pixels_addr() - Get the pointer to the block containing the pixel at the given + * coordinates * * @frame_info: Buffer metadata - * @x: The x(width) coordinate of the 2D buffer - * @y: The y(Heigth) coordinate of the 2D buffer + * @x: The x (width) coordinate inside the plane + * @y: The y (height) coordinate inside the plane * * Takes the information stored in the frame_info, a pair of coordinates, and * returns the address of the first color channel. * This function assumes the channels are packed together, i.e. a color channel * comes immediately after another in the memory. And therefore, this function * doesn't work for YUV with chroma subsampling (e.g. YUV420 and NV21). + * + * The caller must ensure that the framebuffer associated with this request uses a pixel format + * where block_h == block_w == 1, otherwise the returned pointer can be outside the buffer. */ static void *packed_pixels_addr(const struct vkms_frame_info *frame_info, int x, int y) @@ -51,6 +67,13 @@ static int get_x_position(const struct vkms_frame_info *frame_info, int limit, i return x; } +/* + * The following functions take pixel data from the buffer and convert them to the format + * ARGB16161616 in @out_pixel. + * + * They are used in the vkms_compose_row() function to handle multiple formats. + */ + static void ARGB8888_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 *out_pixel) { /* @@ -143,12 +166,11 @@ void vkms_compose_row(struct line_buffer *stage_buffer, struct vkms_plane_state } /* - * The following functions take an line of argb_u16 pixels from the - * src_buffer, convert them to a specific format, and store them in the - * destination. + * The following functions take one &struct pixel_argb_u16 and convert it to a specific format. + * The result is stored in @dst_pixels. * - * They are used in the `compose_active_planes` to convert and store a line - * from the src_buffer to the writeback buffer. + * They are used in vkms_writeback_row() to convert and store a pixel from the src_buffer to + * the writeback buffer. */ static void argb_u16_to_ARGB8888(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) { @@ -214,6 +236,14 @@ static void argb_u16_to_RGB565(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel) *pixels = cpu_to_le16(r << 11 | g << 5 | b); } +/** + * vkms_writeback_row() - Generic loop for all supported writeback format. It is executed just + * after the blending to write a line in the writeback buffer. + * + * @wb: Job where to insert the final image + * @src_buffer: Line to write + * @y: Row to write in the writeback buffer + */ void vkms_writeback_row(struct vkms_writeback_job *wb, const struct line_buffer *src_buffer, int y) { @@ -227,6 +257,13 @@ void vkms_writeback_row(struct vkms_writeback_job *wb, wb->pixel_write(dst_pixels, &in_pixels[x]); } +/** + * get_pixel_conversion_function() - Retrieve the correct read_pixel function for a specific + * format. The returned pointer is NULL for unsupported pixel formats. The caller must ensure that + * the pointer is valid before using it in a vkms_plane_state. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + */ void *get_pixel_conversion_function(u32 format) { switch (format) { @@ -245,6 +282,13 @@ void *get_pixel_conversion_function(u32 format) } } +/** + * get_pixel_write_function() - Retrieve the correct write_pixel function for a specific format. + * The returned pointer is NULL for unsupported pixel formats. The caller must ensure that the + * pointer is valid before using it in a vkms_writeback_job. + * + * @format: DRM_FORMAT_* value for which to obtain a conversion function (see [drm_fourcc.h]) + */ void *get_pixel_write_function(u32 format) { switch (format) { diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c index 5ce70dd946aa..0a5a185aa0b0 100644 --- a/drivers/gpu/drm/vkms/vkms_output.c +++ b/drivers/gpu/drm/vkms/vkms_output.c @@ -21,6 +21,7 @@ static int vkms_conn_get_modes(struct drm_connector *connector) { int count; + /* Use the default modes list from DRM */ count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); @@ -58,6 +59,12 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) int writeback; unsigned int n; + /* + * Initialize used plane. One primary plane is required to perform the composition. + * + * The overlay and cursor planes are not mandatory, but can be used to perform complex + * composition. + */ primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY, index); if (IS_ERR(primary)) return PTR_ERR(primary); @@ -76,6 +83,7 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) return PTR_ERR(cursor); } + /* [1]: Allocation of a CRTC, its index will be BIT(0) = 1 */ ret = vkms_crtc_init(dev, crtc, &primary->base, &cursor->base); if (ret) return ret; @@ -95,7 +103,11 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) DRM_ERROR("Failed to init encoder\n"); goto err_encoder; } - encoder->possible_crtcs = 1; + /* + * This is a hardcoded value to select crtc for the encoder. + * BIT(0) here designate the first registered CRTC, the one allocated in [1] + */ + encoder->possible_crtcs = BIT(0); ret = drm_connector_attach_encoder(connector, encoder); if (ret) { -- GitLab From 2b75feb312894f87d0539d46eeb364f447df723f Mon Sep 17 00:00:00 2001 From: Louis Chauvet <louis.chauvet@bootlin.com> Date: Thu, 12 Sep 2024 17:25:33 +0200 Subject: [PATCH 312/970] drm/vkms: Suppress context imbalance detected by sparse warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functions `vkms_crtc_atomic_begin` and `vkms_crtc_atomic_flush` are responsible for locking and unlocking a mutex, respectively. Add the `__acquires` and `__releases` annotations to these functions to prevent the associated sparse warning about context imbalance. Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> Reviewed-by: José Expósito <jose.exposito89@gmail.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912-vkms-warnings-v1-1-59f3e13ea8e5@bootlin.com --- drivers/gpu/drm/vkms/vkms_crtc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 40b4d084e3ce..2ad164b518fb 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -232,6 +232,7 @@ static void vkms_crtc_atomic_disable(struct drm_crtc *crtc, static void vkms_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) + __acquires(&vkms_output->lock) { struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc); @@ -243,6 +244,7 @@ static void vkms_crtc_atomic_begin(struct drm_crtc *crtc, static void vkms_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) + __releases(&vkms_output->lock) { struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc); -- GitLab From 2f7bd9d66e638e1ce4a20fea83c9d44c25c3dae8 Mon Sep 17 00:00:00 2001 From: Louis Chauvet <louis.chauvet@bootlin.com> Date: Fri, 6 Sep 2024 18:15:03 +0200 Subject: [PATCH 313/970] drm/vkms: Add missing check for CRTC initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CRTC initialization call drm_mode_crtc_set_gamma_size without the proper checks, introduce this check to avoid issues. Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> Reviewed-by: José Expósito <jose.exposito89@gmail.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240906-vkms-add-missing-check-v1-1-1afb3bf3d0a6@bootlin.com --- drivers/gpu/drm/vkms/vkms_crtc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 2ad164b518fb..a40295c18b48 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -289,7 +289,12 @@ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, drm_crtc_helper_add(crtc, &vkms_crtc_helper_funcs); - drm_mode_crtc_set_gamma_size(crtc, VKMS_LUT_SIZE); + ret = drm_mode_crtc_set_gamma_size(crtc, VKMS_LUT_SIZE); + if (ret) { + DRM_ERROR("Failed to set gamma size\n"); + return ret; + } + drm_crtc_enable_color_mgmt(crtc, 0, false, VKMS_LUT_SIZE); spin_lock_init(&vkms_out->lock); -- GitLab From 8b0d2f61545545ab5eef923ed6e59fc3be2385e0 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 23 Sep 2024 09:58:14 +0200 Subject: [PATCH 314/970] drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FB_DAMAGE_CLIPS is a plane property for damage handling. Its UAPI should only use UAPI types. Hence replace struct drm_rect with struct drm_mode_rect in drm_atomic_plane_set_property(). Both types are identical in practice, so there's no change in behavior. Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Closes: https://lore.kernel.org/dri-devel/Zu1Ke1TuThbtz15E@intel.com/ Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Fixes: d3b21767821e ("drm: Add a new plane property to send damage during plane update") Cc: Lukasz Spintzyk <lukasz.spintzyk@displaylink.com> Cc: Deepak Rawat <drawat@vmware.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Thomas Hellstrom <thellstrom@vmware.com> Cc: David Airlie <airlied@gmail.com> Cc: Simona Vetter <simona@ffwll.ch> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: dri-devel@lists.freedesktop.org Cc: <stable@vger.kernel.org> # v5.0+ Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240923075841.16231-1-tzimmermann@suse.de --- drivers/gpu/drm/drm_atomic_uapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 7936c2023955..370dc676e3aa 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -543,7 +543,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, &state->fb_damage_clips, val, -1, - sizeof(struct drm_rect), + sizeof(struct drm_mode_rect), &replaced); return ret; } else if (property == plane->scaling_filter_property) { -- GitLab From cf1becb7f996a0a23ea2c270cf6bb0911ec3ca1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:05 -0300 Subject: [PATCH 315/970] drm/v3d: Address race-condition in MMU flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We must first flush the MMU cache and then, flush the TLB, not the other way around. Currently, we can see a race condition between the MMU cache and the TLB when running multiple rendering processes at the same time. This is evidenced by MMU errors triggered by the IRQ. Fix the MMU flush order by flushing the MMU cache and then the TLB. Also, in order to address the race condition, wait for the MMU cache flush to finish before starting the TLB flush. Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-2-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_mmu.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c index 14f3af40d6f6..e36ec3343b06 100644 --- a/drivers/gpu/drm/v3d/v3d_mmu.c +++ b/drivers/gpu/drm/v3d/v3d_mmu.c @@ -32,32 +32,23 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d) { int ret; - /* Make sure that another flush isn't already running when we - * start this one. - */ - ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & - V3D_MMU_CTL_TLB_CLEARING), 100); - if (ret) - dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n"); - - V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) | - V3D_MMU_CTL_TLB_CLEAR); - - V3D_WRITE(V3D_MMUC_CONTROL, - V3D_MMUC_CONTROL_FLUSH | + V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH | V3D_MMUC_CONTROL_ENABLE); - ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & - V3D_MMU_CTL_TLB_CLEARING), 100); + ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) & + V3D_MMUC_CONTROL_FLUSHING), 100); if (ret) { - dev_err(v3d->drm.dev, "TLB clear wait idle failed\n"); + dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); return ret; } - ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) & - V3D_MMUC_CONTROL_FLUSHING), 100); + V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) | + V3D_MMU_CTL_TLB_CLEAR); + + ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & + V3D_MMU_CTL_TLB_CLEARING), 100); if (ret) - dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); + dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n"); return ret; } -- GitLab From d2fb8811108b2c1285c56f4fba4fff8fe3525593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:06 -0300 Subject: [PATCH 316/970] drm/v3d: Flush the MMU before we supply more memory to the binner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We must ensure that the MMU is flushed before we supply more memory to the binner, otherwise we might end up with invalid MMU accesses by the GPU. Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-3-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_drv.h | 1 + drivers/gpu/drm/v3d/v3d_irq.c | 2 ++ drivers/gpu/drm/v3d/v3d_mmu.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index cf4b23369dc4..75b4725d49c7 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -553,6 +553,7 @@ void v3d_irq_disable(struct v3d_dev *v3d); void v3d_irq_reset(struct v3d_dev *v3d); /* v3d_mmu.c */ +int v3d_mmu_flush_all(struct v3d_dev *v3d); int v3d_mmu_set_page_table(struct v3d_dev *v3d); void v3d_mmu_insert_ptes(struct v3d_bo *bo); void v3d_mmu_remove_ptes(struct v3d_bo *bo); diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index d469bda52c1a..20bf33702c3c 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -70,6 +70,8 @@ v3d_overflow_mem_work(struct work_struct *work) list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list); spin_unlock_irqrestore(&v3d->job_lock, irqflags); + v3d_mmu_flush_all(v3d); + V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << V3D_MMU_PAGE_SHIFT); V3D_CORE_WRITE(0, V3D_PTB_BPOS, obj->size); diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c index e36ec3343b06..5bb7821c0243 100644 --- a/drivers/gpu/drm/v3d/v3d_mmu.c +++ b/drivers/gpu/drm/v3d/v3d_mmu.c @@ -28,7 +28,7 @@ #define V3D_PTE_WRITEABLE BIT(29) #define V3D_PTE_VALID BIT(28) -static int v3d_mmu_flush_all(struct v3d_dev *v3d) +int v3d_mmu_flush_all(struct v3d_dev *v3d) { int ret; -- GitLab From 56cf76ed784fe5347c9305f7f0f3d0f9cb8d8a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:07 -0300 Subject: [PATCH 317/970] drm/v3d: Fix return if scheduler initialization fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the scheduler initialization fails, GEM initialization must fail as well. Therefore, if `v3d_sched_init()` fails, free the DMA memory allocated and return the error value in `v3d_gem_init()`. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-4-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_gem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index da8faf3b9011..b3b76332f2c5 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -291,8 +291,9 @@ v3d_gem_init(struct drm_device *dev) ret = v3d_sched_init(v3d); if (ret) { drm_mm_takedown(&v3d->mm); - dma_free_coherent(v3d->drm.dev, 4096 * 1024, (void *)v3d->pt, + dma_free_coherent(v3d->drm.dev, pt_size, (void *)v3d->pt, v3d->pt_paddr); + return ret; } return 0; -- GitLab From 0992b2541e1cd9580c2e70fab7a78558de054bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:08 -0300 Subject: [PATCH 318/970] drm/gem: Create a drm_gem_object_init_with_mnt() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some applications, such as applications that uses huge pages, we might want to have a different mountpoint, for which we pass mount flags that better match our usecase. Therefore, create a new function `drm_gem_object_init_with_mnt()` that allow us to define the tmpfs mountpoint where the GEM object will be created. If this parameter is NULL, then we fallback to `shmem_file_setup()`. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-5-mcanal@igalia.com --- drivers/gpu/drm/drm_gem.c | 34 ++++++++++++++++++++++++++++++---- include/drm/drm_gem.h | 3 +++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 149b8e25da5b..ee811764c3df 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -114,22 +114,32 @@ drm_gem_init(struct drm_device *dev) } /** - * drm_gem_object_init - initialize an allocated shmem-backed GEM object + * drm_gem_object_init_with_mnt - initialize an allocated shmem-backed GEM + * object in a given shmfs mountpoint + * * @dev: drm_device the object should be initialized for * @obj: drm_gem_object to initialize * @size: object size + * @gemfs: tmpfs mount where the GEM object will be created. If NULL, use + * the usual tmpfs mountpoint (`shm_mnt`). * * Initialize an already allocated GEM object of the specified size with * shmfs backing store. */ -int drm_gem_object_init(struct drm_device *dev, - struct drm_gem_object *obj, size_t size) +int drm_gem_object_init_with_mnt(struct drm_device *dev, + struct drm_gem_object *obj, size_t size, + struct vfsmount *gemfs) { struct file *filp; drm_gem_private_object_init(dev, obj, size); - filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); + if (gemfs) + filp = shmem_file_setup_with_mnt(gemfs, "drm mm object", size, + VM_NORESERVE); + else + filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); + if (IS_ERR(filp)) return PTR_ERR(filp); @@ -137,6 +147,22 @@ int drm_gem_object_init(struct drm_device *dev, return 0; } +EXPORT_SYMBOL(drm_gem_object_init_with_mnt); + +/** + * drm_gem_object_init - initialize an allocated shmem-backed GEM object + * @dev: drm_device the object should be initialized for + * @obj: drm_gem_object to initialize + * @size: object size + * + * Initialize an already allocated GEM object of the specified size with + * shmfs backing store. + */ +int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, + size_t size) +{ + return drm_gem_object_init_with_mnt(dev, obj, size, NULL); +} EXPORT_SYMBOL(drm_gem_object_init); /** diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index bae4865b2101..2ebf6e10cc44 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -472,6 +472,9 @@ void drm_gem_object_release(struct drm_gem_object *obj); void drm_gem_object_free(struct kref *kref); int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size); +int drm_gem_object_init_with_mnt(struct drm_device *dev, + struct drm_gem_object *obj, size_t size, + struct vfsmount *gemfs); void drm_gem_private_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size); void drm_gem_private_object_fini(struct drm_gem_object *obj); -- GitLab From eb8d395f68421449c6201d3019f51011d034f00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:09 -0300 Subject: [PATCH 319/970] drm/v3d: Introduce gemfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a separate "tmpfs" kernel mount for V3D. This will allow us to move away from the shmemfs `shm_mnt` and gives the flexibility to do things like set our own mount options. Here, the interest is to use "huge=", which should allow us to enable the use of THP for our shmem-backed objects. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-6-mcanal@igalia.com --- drivers/gpu/drm/v3d/Makefile | 3 ++- drivers/gpu/drm/v3d/v3d_drv.h | 9 +++++++ drivers/gpu/drm/v3d/v3d_gem.c | 3 +++ drivers/gpu/drm/v3d/v3d_gemfs.c | 46 +++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/v3d/v3d_gemfs.c diff --git a/drivers/gpu/drm/v3d/Makefile b/drivers/gpu/drm/v3d/Makefile index b7d673f1153b..fcf710926057 100644 --- a/drivers/gpu/drm/v3d/Makefile +++ b/drivers/gpu/drm/v3d/Makefile @@ -13,7 +13,8 @@ v3d-y := \ v3d_trace_points.o \ v3d_sched.o \ v3d_sysfs.o \ - v3d_submit.o + v3d_submit.o \ + v3d_gemfs.o v3d-$(CONFIG_DEBUG_FS) += v3d_debugfs.o diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 75b4725d49c7..41b09c828848 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -137,6 +137,11 @@ struct v3d_dev { struct drm_mm mm; spinlock_t mm_lock; + /* + * tmpfs instance used for shmem backed objects + */ + struct vfsmount *gemfs; + struct work_struct overflow_mem_work; struct v3d_bin_job *bin_job; @@ -534,6 +539,10 @@ void v3d_reset(struct v3d_dev *v3d); void v3d_invalidate_caches(struct v3d_dev *v3d); void v3d_clean_caches(struct v3d_dev *v3d); +/* v3d_gemfs.c */ +void v3d_gemfs_init(struct v3d_dev *v3d); +void v3d_gemfs_fini(struct v3d_dev *v3d); + /* v3d_submit.c */ void v3d_job_cleanup(struct v3d_job *job); void v3d_job_put(struct v3d_job *job); diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index b3b76332f2c5..b1e681630ded 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -288,6 +288,8 @@ v3d_gem_init(struct drm_device *dev) v3d_init_hw_state(v3d); v3d_mmu_set_page_table(v3d); + v3d_gemfs_init(v3d); + ret = v3d_sched_init(v3d); if (ret) { drm_mm_takedown(&v3d->mm); @@ -305,6 +307,7 @@ v3d_gem_destroy(struct drm_device *dev) struct v3d_dev *v3d = to_v3d_dev(dev); v3d_sched_fini(v3d); + v3d_gemfs_fini(v3d); /* Waiting for jobs to finish would need to be done before * unregistering V3D. diff --git a/drivers/gpu/drm/v3d/v3d_gemfs.c b/drivers/gpu/drm/v3d/v3d_gemfs.c new file mode 100644 index 000000000000..31cf5bd11e39 --- /dev/null +++ b/drivers/gpu/drm/v3d/v3d_gemfs.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2024 Raspberry Pi */ + +#include <linux/fs.h> +#include <linux/mount.h> + +#include "v3d_drv.h" + +void v3d_gemfs_init(struct v3d_dev *v3d) +{ + char huge_opt[] = "huge=within_size"; + struct file_system_type *type; + struct vfsmount *gemfs; + + /* + * By creating our own shmemfs mountpoint, we can pass in + * mount flags that better match our usecase. However, we + * only do so on platforms which benefit from it. + */ + if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) + goto err; + + type = get_fs_type("tmpfs"); + if (!type) + goto err; + + gemfs = vfs_kern_mount(type, SB_KERNMOUNT, type->name, huge_opt); + if (IS_ERR(gemfs)) + goto err; + + v3d->gemfs = gemfs; + drm_info(&v3d->drm, "Using Transparent Hugepages\n"); + + return; + +err: + v3d->gemfs = NULL; + drm_notice(&v3d->drm, + "Transparent Hugepage support is recommended for optimal performance on this platform!\n"); +} + +void v3d_gemfs_fini(struct v3d_dev *v3d) +{ + if (v3d->gemfs) + kern_unmount(v3d->gemfs); +} -- GitLab From be431dfec976e553a08883e26d0d0cc2598a8dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:10 -0300 Subject: [PATCH 320/970] drm/gem: Create shmem GEM object in a given mountpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a function `drm_gem_shmem_create_with_mnt()`, similar to `drm_gem_shmem_create()`, that has a mountpoint as a argument. This function will create a shmem GEM object in a given tmpfs mountpoint. This function will be useful for drivers that have a special mountpoint with flags enabled. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-7-mcanal@igalia.com --- drivers/gpu/drm/drm_gem_shmem_helper.c | 30 ++++++++++++++++++++++---- include/drm/drm_gem_shmem_helper.h | 3 +++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 53c003983ad1..8508060a1a95 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -49,7 +49,8 @@ static const struct drm_gem_object_funcs drm_gem_shmem_funcs = { }; static struct drm_gem_shmem_object * -__drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private) +__drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private, + struct vfsmount *gemfs) { struct drm_gem_shmem_object *shmem; struct drm_gem_object *obj; @@ -76,7 +77,7 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private) drm_gem_private_object_init(dev, obj, size); shmem->map_wc = false; /* dma-buf mappings use always writecombine */ } else { - ret = drm_gem_object_init(dev, obj, size); + ret = drm_gem_object_init_with_mnt(dev, obj, size, gemfs); } if (ret) { drm_gem_private_object_fini(obj); @@ -123,10 +124,31 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private) */ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size) { - return __drm_gem_shmem_create(dev, size, false); + return __drm_gem_shmem_create(dev, size, false, NULL); } EXPORT_SYMBOL_GPL(drm_gem_shmem_create); +/** + * drm_gem_shmem_create_with_mnt - Allocate an object with the given size in a + * given mountpoint + * @dev: DRM device + * @size: Size of the object to allocate + * @gemfs: tmpfs mount where the GEM object will be created + * + * This function creates a shmem GEM object in a given tmpfs mountpoint. + * + * Returns: + * A struct drm_gem_shmem_object * on success or an ERR_PTR()-encoded negative + * error code on failure. + */ +struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev, + size_t size, + struct vfsmount *gemfs) +{ + return __drm_gem_shmem_create(dev, size, false, gemfs); +} +EXPORT_SYMBOL_GPL(drm_gem_shmem_create_with_mnt); + /** * drm_gem_shmem_free - Free resources associated with a shmem GEM object * @shmem: shmem GEM object to free @@ -765,7 +787,7 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, size_t size = PAGE_ALIGN(attach->dmabuf->size); struct drm_gem_shmem_object *shmem; - shmem = __drm_gem_shmem_create(dev, size, true); + shmem = __drm_gem_shmem_create(dev, size, true, NULL); if (IS_ERR(shmem)) return ERR_CAST(shmem); diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h index efbc9f27312b..d22e3fb53631 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -97,6 +97,9 @@ struct drm_gem_shmem_object { container_of(obj, struct drm_gem_shmem_object, base) struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size); +struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev, + size_t size, + struct vfsmount *gemfs); void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); -- GitLab From 8dd6074d4719644b676adf9f07d71292bee28e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:11 -0300 Subject: [PATCH 321/970] drm/v3d: Reduce the alignment of the node allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, we are using an alignment of 128 kB to insert a node, which ends up wasting memory as we perform plenty of small BOs allocations (<= 4 kB). We require that allocations are aligned to 128Kb so for any allocation smaller than that, we are wasting the difference. This implies that we cannot effectively use the whole 4 GB address space available for the GPU in the RPi 4. Currently, we can allocate up to 32000 BOs of 4 kB (~140 MB) and 3000 BOs of 400 kB (~1,3 GB). This can be quite limiting for applications that have a high memory requirement, such as vkoverhead [1]. By reducing the page alignment to 4 kB, we can allocate up to 1000000 BOs of 4 kB (~4 GB) and 10000 BOs of 400 kB (~4 GB). Moreover, by performing benchmarks, we were able to attest that reducing the page alignment to 4 kB can provide a general performance improvement in OpenGL applications (e.g. glmark2). Therefore, this patch reduces the alignment of the node allocation to 4 kB, which will allow RPi users to explore the whole 4GB virtual address space provided by the hardware. Also, this patch allow users to fully run vkoverhead in the RPi 4/5, solving the issue reported in [1]. [1] https://github.com/zmike/vkoverhead/issues/14 Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-8-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_bo.c | 2 +- drivers/gpu/drm/v3d/v3d_drv.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c index ecb80fd75b1a..427a1c405b19 100644 --- a/drivers/gpu/drm/v3d/v3d_bo.c +++ b/drivers/gpu/drm/v3d/v3d_bo.c @@ -123,7 +123,7 @@ v3d_bo_create_finish(struct drm_gem_object *obj) */ ret = drm_mm_insert_node_generic(&v3d->mm, &bo->node, obj->size >> V3D_MMU_PAGE_SHIFT, - GMP_GRANULARITY >> V3D_MMU_PAGE_SHIFT, 0, 0); + SZ_4K >> V3D_MMU_PAGE_SHIFT, 0, 0); spin_unlock(&v3d->mm_lock); if (ret) return ret; diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 41b09c828848..82d6e869dd41 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -19,8 +19,6 @@ struct clk; struct platform_device; struct reset_control; -#define GMP_GRANULARITY (128 * 1024) - #define V3D_MMU_PAGE_SHIFT 12 #define V3D_MAX_QUEUES (V3D_CPU + 1) -- GitLab From e4c17720262f394f6320a2b6e17a128bfdabb37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:12 -0300 Subject: [PATCH 322/970] drm/v3d: Support Big/Super Pages when writing out PTEs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The V3D MMU also supports 64KB and 1MB pages, called big and super pages, respectively. In order to set a 64KB page or 1MB page in the MMU, we need to make sure that page table entries for all 4KB pages within a big/super page must be correctly configured. In order to create a big/super page, we need a contiguous memory region. That's why we use a separate mountpoint with THP enabled. In order to place the page table entries in the MMU, we iterate over the 16 4KB pages (for big pages) or 256 4KB pages (for super pages) and insert the PTE. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-9-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_drv.h | 1 + drivers/gpu/drm/v3d/v3d_mmu.c | 54 ++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 82d6e869dd41..a98543290fa8 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -20,6 +20,7 @@ struct platform_device; struct reset_control; #define V3D_MMU_PAGE_SHIFT 12 +#define V3D_PAGE_FACTOR (PAGE_SIZE >> V3D_MMU_PAGE_SHIFT) #define V3D_MAX_QUEUES (V3D_CPU + 1) diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c index 5bb7821c0243..0f564fd7160c 100644 --- a/drivers/gpu/drm/v3d/v3d_mmu.c +++ b/drivers/gpu/drm/v3d/v3d_mmu.c @@ -25,9 +25,16 @@ * superpage bit set. */ #define V3D_PTE_SUPERPAGE BIT(31) +#define V3D_PTE_BIGPAGE BIT(30) #define V3D_PTE_WRITEABLE BIT(29) #define V3D_PTE_VALID BIT(28) +static bool v3d_mmu_is_aligned(u32 page, u32 page_address, size_t alignment) +{ + return IS_ALIGNED(page, alignment >> V3D_MMU_PAGE_SHIFT) && + IS_ALIGNED(page_address, alignment >> V3D_MMU_PAGE_SHIFT); +} + int v3d_mmu_flush_all(struct v3d_dev *v3d) { int ret; @@ -78,19 +85,40 @@ void v3d_mmu_insert_ptes(struct v3d_bo *bo) struct drm_gem_shmem_object *shmem_obj = &bo->base; struct v3d_dev *v3d = to_v3d_dev(shmem_obj->base.dev); u32 page = bo->node.start; - u32 page_prot = V3D_PTE_WRITEABLE | V3D_PTE_VALID; - struct sg_dma_page_iter dma_iter; - - for_each_sgtable_dma_page(shmem_obj->sgt, &dma_iter, 0) { - dma_addr_t dma_addr = sg_page_iter_dma_address(&dma_iter); - u32 page_address = dma_addr >> V3D_MMU_PAGE_SHIFT; - u32 pte = page_prot | page_address; - u32 i; - - BUG_ON(page_address + (PAGE_SIZE >> V3D_MMU_PAGE_SHIFT) >= - BIT(24)); - for (i = 0; i < PAGE_SIZE >> V3D_MMU_PAGE_SHIFT; i++) - v3d->pt[page++] = pte + i; + struct scatterlist *sgl; + unsigned int count; + + for_each_sgtable_dma_sg(shmem_obj->sgt, sgl, count) { + dma_addr_t dma_addr = sg_dma_address(sgl); + u32 pfn = dma_addr >> V3D_MMU_PAGE_SHIFT; + unsigned int len = sg_dma_len(sgl); + + while (len > 0) { + u32 page_prot = V3D_PTE_WRITEABLE | V3D_PTE_VALID; + u32 page_address = page_prot | pfn; + unsigned int i, page_size; + + BUG_ON(pfn + V3D_PAGE_FACTOR >= BIT(24)); + + if (len >= SZ_1M && + v3d_mmu_is_aligned(page, page_address, SZ_1M)) { + page_size = SZ_1M; + page_address |= V3D_PTE_SUPERPAGE; + } else if (len >= SZ_64K && + v3d_mmu_is_aligned(page, page_address, SZ_64K)) { + page_size = SZ_64K; + page_address |= V3D_PTE_BIGPAGE; + } else { + page_size = SZ_4K; + } + + for (i = 0; i < page_size >> V3D_MMU_PAGE_SHIFT; i++) { + v3d->pt[page++] = page_address + i; + pfn++; + } + + len -= page_size; + } } WARN_ON_ONCE(page - bo->node.start != -- GitLab From 20d69e8905fc36818ab585cb50f6de48fb8f6de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:13 -0300 Subject: [PATCH 323/970] drm/v3d: Use gemfs/THP in BO creation if available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although Big/Super Pages could appear naturally, it would be quite hard to have 1MB or 64KB allocated contiguously naturally. Therefore, we can force the creation of large pages allocated contiguously by using a mountpoint with "huge=within_size" enabled. Therefore, as V3D has a mountpoint with "huge=within_size" (if user has THP enabled), use this mountpoint for BO creation if available. This will allow us to create large pages allocated contiguously and make use of Big/Super Pages. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-10-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_bo.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c index 427a1c405b19..cd85f997b058 100644 --- a/drivers/gpu/drm/v3d/v3d_bo.c +++ b/drivers/gpu/drm/v3d/v3d_bo.c @@ -107,6 +107,7 @@ v3d_bo_create_finish(struct drm_gem_object *obj) struct v3d_dev *v3d = to_v3d_dev(obj->dev); struct v3d_bo *bo = to_v3d_bo(obj); struct sg_table *sgt; + u64 align; int ret; /* So far we pin the BO in the MMU for its lifetime, so use @@ -116,6 +117,15 @@ v3d_bo_create_finish(struct drm_gem_object *obj) if (IS_ERR(sgt)) return PTR_ERR(sgt); + if (!v3d->gemfs) + align = SZ_4K; + else if (obj->size >= SZ_1M) + align = SZ_1M; + else if (obj->size >= SZ_64K) + align = SZ_64K; + else + align = SZ_4K; + spin_lock(&v3d->mm_lock); /* Allocate the object's space in the GPU's page tables. * Inserting PTEs will happen later, but the offset is for the @@ -123,7 +133,7 @@ v3d_bo_create_finish(struct drm_gem_object *obj) */ ret = drm_mm_insert_node_generic(&v3d->mm, &bo->node, obj->size >> V3D_MMU_PAGE_SHIFT, - SZ_4K >> V3D_MMU_PAGE_SHIFT, 0, 0); + align >> V3D_MMU_PAGE_SHIFT, 0, 0); spin_unlock(&v3d->mm_lock); if (ret) return ret; @@ -143,10 +153,17 @@ struct v3d_bo *v3d_bo_create(struct drm_device *dev, struct drm_file *file_priv, size_t unaligned_size) { struct drm_gem_shmem_object *shmem_obj; + struct v3d_dev *v3d = to_v3d_dev(dev); struct v3d_bo *bo; int ret; - shmem_obj = drm_gem_shmem_create(dev, unaligned_size); + /* Let the user opt out of allocating the BOs with THP */ + if (v3d->gemfs) + shmem_obj = drm_gem_shmem_create_with_mnt(dev, unaligned_size, + v3d->gemfs); + else + shmem_obj = drm_gem_shmem_create(dev, unaligned_size); + if (IS_ERR(shmem_obj)) return ERR_CAST(shmem_obj); bo = to_v3d_bo(&shmem_obj->base); -- GitLab From 0df4a13ca8bed29cbc362c99b958fbb8b27b1675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:14 -0300 Subject: [PATCH 324/970] drm/v3d: Add modparam for turning off Big/Super Pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a modparam for turning off Big/Super Pages to make sure that if an user doesn't want Big/Super Pages enabled, it can disabled it by setting the modparam to false. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-11-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_drv.c | 7 +++++++ drivers/gpu/drm/v3d/v3d_drv.h | 1 + drivers/gpu/drm/v3d/v3d_gemfs.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index d7ff1f5fa481..8be8c6dd9b35 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -36,6 +36,13 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 +/* Only expose the `super_pages` modparam if THP is enabled. */ +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +bool super_pages = true; +module_param_named(super_pages, super_pages, bool, 0400); +MODULE_PARM_DESC(super_pages, "Enable/Disable Super Pages support."); +#endif + static int v3d_get_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index a98543290fa8..de73eefff9ac 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -539,6 +539,7 @@ void v3d_invalidate_caches(struct v3d_dev *v3d); void v3d_clean_caches(struct v3d_dev *v3d); /* v3d_gemfs.c */ +extern bool super_pages; void v3d_gemfs_init(struct v3d_dev *v3d); void v3d_gemfs_fini(struct v3d_dev *v3d); diff --git a/drivers/gpu/drm/v3d/v3d_gemfs.c b/drivers/gpu/drm/v3d/v3d_gemfs.c index 31cf5bd11e39..4c5e18590a5c 100644 --- a/drivers/gpu/drm/v3d/v3d_gemfs.c +++ b/drivers/gpu/drm/v3d/v3d_gemfs.c @@ -20,6 +20,10 @@ void v3d_gemfs_init(struct v3d_dev *v3d) if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) goto err; + /* The user doesn't want to enable Super Pages */ + if (!super_pages) + goto err; + type = get_fs_type("tmpfs"); if (!type) goto err; -- GitLab From 9f8e1c93a0d459463819d8bd222196b2655c279f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Mon, 23 Sep 2024 10:55:15 -0300 Subject: [PATCH 325/970] drm/v3d: Expose Super Pages capability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new V3D parameter to expose the support of Super Pages to userspace. The userspace might want to know this information to apply optimizations that are specific to kernels with Super Pages enabled. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-12-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_drv.c | 3 +++ include/uapi/drm/v3d_drm.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 8be8c6dd9b35..fb35c5c3f1a7 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -104,6 +104,9 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, case DRM_V3D_PARAM_MAX_PERF_COUNTERS: args->value = v3d->perfmon_info.max_counters; return 0; + case DRM_V3D_PARAM_SUPPORTS_SUPER_PAGES: + args->value = !!v3d->gemfs; + return 0; default: DRM_DEBUG("Unknown parameter %d\n", args->param); return -EINVAL; diff --git a/include/uapi/drm/v3d_drm.h b/include/uapi/drm/v3d_drm.h index 87fc5bb0a61e..2376c73abca1 100644 --- a/include/uapi/drm/v3d_drm.h +++ b/include/uapi/drm/v3d_drm.h @@ -290,6 +290,7 @@ enum drm_v3d_param { DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT, DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE, DRM_V3D_PARAM_MAX_PERF_COUNTERS, + DRM_V3D_PARAM_SUPPORTS_SUPER_PAGES, }; struct drm_v3d_get_param { -- GitLab From e249786b2188107a7c50e7174d35f955a60988a1 Mon Sep 17 00:00:00 2001 From: Alexey Klimov <alexey.klimov@linaro.org> Date: Wed, 25 Sep 2024 05:38:23 +0100 Subject: [PATCH 326/970] ASoC: codecs: lpass-rx-macro: add missing CDC_RX_BCL_VBAT_RF_PROC2 to default regs values CDC_RX_BCL_VBAT_RF_PROC1 is listed twice and its default value is 0x2a which is overwriten by its next occurence in rx_defaults[]. The second one should be missing CDC_RX_BCL_VBAT_RF_PROC2 instead and its default value is expected 0x0. Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org> Link: https://patch.msgid.link/20240925043823.520218-2-alexey.klimov@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/codecs/lpass-rx-macro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 71e0d3bffd3f..ef7a70fa6966 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -958,7 +958,7 @@ static const struct reg_default rx_defaults[] = { { CDC_RX_BCL_VBAT_PK_EST2, 0x01 }, { CDC_RX_BCL_VBAT_PK_EST3, 0x40 }, { CDC_RX_BCL_VBAT_RF_PROC1, 0x2A }, - { CDC_RX_BCL_VBAT_RF_PROC1, 0x00 }, + { CDC_RX_BCL_VBAT_RF_PROC2, 0x00 }, { CDC_RX_BCL_VBAT_TAC1, 0x00 }, { CDC_RX_BCL_VBAT_TAC2, 0x18 }, { CDC_RX_BCL_VBAT_TAC3, 0x18 }, -- GitLab From f73716fd4550d588a811f11c370e90c303f0829b Mon Sep 17 00:00:00 2001 From: Mary Guillemard <mary.guillemard@collabora.com> Date: Mon, 9 Sep 2024 08:48:20 +0200 Subject: [PATCH 327/970] drm/panthor: Add PANTHOR_GROUP_PRIORITY_REALTIME group priority This adds a new value to drm_panthor_group_priority exposing the realtime priority to userspace. This is required to implement NV_context_priority_realtime in Mesa. v2: - Add Steven Price r-b v3: - Add Boris Brezillon r-b Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Steven Price <steven.price@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240909064820.34982-3-mary.guillemard@collabora.com --- drivers/gpu/drm/panthor/panthor_drv.c | 2 +- drivers/gpu/drm/panthor/panthor_sched.c | 2 -- include/uapi/drm/panthor_drm.h | 7 +++++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 0caf9e9a8c45..7b1db2adcb4c 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -1041,7 +1041,7 @@ static int group_priority_permit(struct drm_file *file, u8 priority) { /* Ensure that priority is valid */ - if (priority > PANTHOR_GROUP_PRIORITY_HIGH) + if (priority > PANTHOR_GROUP_PRIORITY_REALTIME) return -EINVAL; /* Medium priority and below are always allowed */ diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index 42afdf0ddb7e..a9e3b1ccccc7 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -137,8 +137,6 @@ enum panthor_csg_priority { * non-real-time groups. When such a group becomes executable, * it will evict the group with the lowest non-rt priority if * there's no free group slot available. - * - * Currently not exposed to userspace. */ PANTHOR_CSG_PRIORITY_RT, diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index 1fd8473548ac..011a555e4674 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -720,6 +720,13 @@ enum drm_panthor_group_priority { * Requires CAP_SYS_NICE or DRM_MASTER. */ PANTHOR_GROUP_PRIORITY_HIGH, + + /** + * @PANTHOR_GROUP_PRIORITY_REALTIME: Realtime priority group. + * + * Requires CAP_SYS_NICE or DRM_MASTER. + */ + PANTHOR_GROUP_PRIORITY_REALTIME, }; /** -- GitLab From f70000ef23527f6d928d1175c66c5fafa968814b Mon Sep 17 00:00:00 2001 From: Mary Guillemard <mary.guillemard@collabora.com> Date: Mon, 9 Sep 2024 08:48:21 +0200 Subject: [PATCH 328/970] drm/panthor: Add DEV_QUERY_GROUP_PRIORITIES_INFO dev query Expose allowed group priorities with a new device query. This new uAPI will be used in Mesa to properly report what priorities a user can use for EGL_IMG_context_priority. Since this extends the uAPI and because userland needs a way to advertise priorities accordingly, this also bumps the driver minor version. v2: - Remove drm_panthor_group_allow_priority_flags definition - Document that allowed_mask is a bitmask of drm_panthor_group_priority v3: - Use BIT macro in panthor_query_group_priorities_info - Add r-b from Steven Price and Boris Brezillon Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Steven Price <steven.price@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240909064820.34982-4-mary.guillemard@collabora.com --- drivers/gpu/drm/panthor/panthor_drv.c | 61 ++++++++++++++++++--------- include/uapi/drm/panthor_drm.h | 22 ++++++++++ 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 7b1db2adcb4c..0d825d63d712 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -170,6 +170,7 @@ panthor_get_uobj_array(const struct drm_panthor_obj_array *in, u32 min_stride, PANTHOR_UOBJ_DECL(struct drm_panthor_gpu_info, tiler_present), \ PANTHOR_UOBJ_DECL(struct drm_panthor_csif_info, pad), \ PANTHOR_UOBJ_DECL(struct drm_panthor_timestamp_info, current_timestamp), \ + PANTHOR_UOBJ_DECL(struct drm_panthor_group_priorities_info, pad), \ PANTHOR_UOBJ_DECL(struct drm_panthor_sync_op, timeline_value), \ PANTHOR_UOBJ_DECL(struct drm_panthor_queue_submit, syncs), \ PANTHOR_UOBJ_DECL(struct drm_panthor_queue_create, ringbuf_size), \ @@ -777,11 +778,41 @@ static int panthor_query_timestamp_info(struct panthor_device *ptdev, return 0; } +static int group_priority_permit(struct drm_file *file, + u8 priority) +{ + /* Ensure that priority is valid */ + if (priority > PANTHOR_GROUP_PRIORITY_REALTIME) + return -EINVAL; + + /* Medium priority and below are always allowed */ + if (priority <= PANTHOR_GROUP_PRIORITY_MEDIUM) + return 0; + + /* Higher priorities require CAP_SYS_NICE or DRM_MASTER */ + if (capable(CAP_SYS_NICE) || drm_is_current_master(file)) + return 0; + + return -EACCES; +} + +static void panthor_query_group_priorities_info(struct drm_file *file, + struct drm_panthor_group_priorities_info *arg) +{ + int prio; + + for (prio = PANTHOR_GROUP_PRIORITY_REALTIME; prio >= 0; prio--) { + if (!group_priority_permit(file, prio)) + arg->allowed_mask |= BIT(prio); + } +} + static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct drm_file *file) { struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base); struct drm_panthor_dev_query *args = data; struct drm_panthor_timestamp_info timestamp_info; + struct drm_panthor_group_priorities_info priorities_info; int ret; if (!args->pointer) { @@ -798,6 +829,10 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d args->size = sizeof(timestamp_info); return 0; + case DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO: + args->size = sizeof(priorities_info); + return 0; + default: return -EINVAL; } @@ -818,6 +853,10 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d return PANTHOR_UOBJ_SET(args->pointer, args->size, timestamp_info); + case DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO: + panthor_query_group_priorities_info(file, &priorities_info); + return PANTHOR_UOBJ_SET(args->pointer, args->size, priorities_info); + default: return -EINVAL; } @@ -1037,24 +1076,6 @@ static int panthor_ioctl_group_destroy(struct drm_device *ddev, void *data, return panthor_group_destroy(pfile, args->group_handle); } -static int group_priority_permit(struct drm_file *file, - u8 priority) -{ - /* Ensure that priority is valid */ - if (priority > PANTHOR_GROUP_PRIORITY_REALTIME) - return -EINVAL; - - /* Medium priority and below are always allowed */ - if (priority <= PANTHOR_GROUP_PRIORITY_MEDIUM) - return 0; - - /* Higher priorities require CAP_SYS_NICE or DRM_MASTER */ - if (capable(CAP_SYS_NICE) || drm_is_current_master(file)) - return 0; - - return -EACCES; -} - static int panthor_ioctl_group_create(struct drm_device *ddev, void *data, struct drm_file *file) { @@ -1436,6 +1457,8 @@ static void panthor_debugfs_init(struct drm_minor *minor) * PanCSF driver version: * - 1.0 - initial interface * - 1.1 - adds DEV_QUERY_TIMESTAMP_INFO query + * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query + * - adds PANTHOR_GROUP_PRIORITY_REALTIME priority */ static const struct drm_driver panthor_drm_driver = { .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ | @@ -1449,7 +1472,7 @@ static const struct drm_driver panthor_drm_driver = { .desc = "Panthor DRM driver", .date = "20230801", .major = 1, - .minor = 1, + .minor = 2, .gem_create_object = panthor_gem_create_object, .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index 011a555e4674..87c9cb555dd1 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -263,6 +263,11 @@ enum drm_panthor_dev_query_type { /** @DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO: Query timestamp information. */ DRM_PANTHOR_DEV_QUERY_TIMESTAMP_INFO, + + /** + * @DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO: Query allowed group priorities information. + */ + DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO, }; /** @@ -399,6 +404,23 @@ struct drm_panthor_timestamp_info { __u64 timestamp_offset; }; +/** + * struct drm_panthor_group_priorities_info - Group priorities information + * + * Structure grouping all queryable information relating to the allowed group priorities. + */ +struct drm_panthor_group_priorities_info { + /** + * @allowed_mask: Bitmask of the allowed group priorities. + * + * Each bit represents a variant of the enum drm_panthor_group_priority. + */ + __u8 allowed_mask; + + /** @pad: Padding fields, MBZ. */ + __u8 pad[3]; +}; + /** * struct drm_panthor_dev_query - Arguments passed to DRM_PANTHOR_IOCTL_DEV_QUERY */ -- GitLab From b4ad4ef374d66cc8df3188bb1ddb65bce5fc9e50 Mon Sep 17 00:00:00 2001 From: Thierry Reding <treding@nvidia.com> Date: Mon, 16 Sep 2024 15:33:20 +0200 Subject: [PATCH 329/970] gpu: host1x: Set up device DMA parameters In order to store device DMA parameters, the DMA framework depends on the device's dma_parms field to point at a valid memory location. Add backing storage for this in struct host1x_memory_context and point to it. Reported-by: Jonathan Hunter <jonathanh@nvidia.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240916133320.368620-1-thierry.reding@gmail.com --- drivers/gpu/host1x/context.c | 1 + include/linux/host1x.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c index 955c971c528d..a6f6779662a3 100644 --- a/drivers/gpu/host1x/context.c +++ b/drivers/gpu/host1x/context.c @@ -58,6 +58,7 @@ int host1x_memory_context_list_init(struct host1x *host1x) ctx->dev.parent = host1x->dev; ctx->dev.release = host1x_memory_context_release; + ctx->dev.dma_parms = &ctx->dma_parms; dma_set_max_seg_size(&ctx->dev, UINT_MAX); err = device_add(&ctx->dev); diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 5a7a81e5f9bd..9fa9c30a34e6 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -471,6 +471,7 @@ struct host1x_memory_context { refcount_t ref; struct pid *owner; + struct device_dma_parameters dma_parms; struct device dev; u64 dma_mask; u32 stream_id; -- GitLab From dc56f8428e5f34418f3243a60cec13166efe4fdb Mon Sep 17 00:00:00 2001 From: Jon Hunter <jonathanh@nvidia.com> Date: Wed, 25 Sep 2024 17:05:04 +0100 Subject: [PATCH 330/970] gpu: host1x: Fix boot regression for Tegra Commit 4c27ac45e622 ("gpu: host1x: Request syncpoint IRQs only during probe") caused a boot regression for the Tegra186 device. Following this update the function host1x_intr_init() now calls host1x_hw_intr_disable_all_syncpt_intrs() during probe. However, host1x_intr_init() is called before runtime power-management is enabled for Host1x and the function host1x_hw_intr_disable_all_syncpt_intrs() is accessing hardware registers. So if the Host1x hardware is not enabled prior to probing then the device will now hang on attempting to access the registers. So far this is only observed on Tegra186, but potentially could be seen on other devices. Fix this by moving the call to the function host1x_intr_init() in probe to after enabling the runtime power-management in the probe and update the failure path in probe as necessary. Fixes: 4c27ac45e622 ("gpu: host1x: Request syncpoint IRQs only during probe") Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925160504.60221-1-jonathanh@nvidia.com --- drivers/gpu/host1x/dev.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index bc3cda4625d0..be2ad7203d7b 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -619,12 +619,6 @@ static int host1x_probe(struct platform_device *pdev) goto free_contexts; } - err = host1x_intr_init(host); - if (err) { - dev_err(&pdev->dev, "failed to initialize interrupts\n"); - goto deinit_syncpt; - } - pm_runtime_enable(&pdev->dev); err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); @@ -636,6 +630,12 @@ static int host1x_probe(struct platform_device *pdev) if (err) goto pm_disable; + err = host1x_intr_init(host); + if (err) { + dev_err(&pdev->dev, "failed to initialize interrupts\n"); + goto pm_put; + } + host1x_debug_init(host); err = host1x_register(host); @@ -652,13 +652,11 @@ static int host1x_probe(struct platform_device *pdev) host1x_unregister(host); deinit_debugfs: host1x_debug_deinit(host); - + host1x_intr_deinit(host); +pm_put: pm_runtime_put_sync_suspend(&pdev->dev); pm_disable: pm_runtime_disable(&pdev->dev); - - host1x_intr_deinit(host); -deinit_syncpt: host1x_syncpt_deinit(host); free_contexts: host1x_memory_context_list_free(&host->context_list); -- GitLab From 2bcae12c795f32ddfbf8c80d1b5f1d3286341c32 Mon Sep 17 00:00:00 2001 From: Gerd Bayer <gbayer@linux.ibm.com> Date: Tue, 10 Sep 2024 10:53:51 +0200 Subject: [PATCH 331/970] net/mlx5: Fix error path in multi-packet WQE transmit Remove the erroneous unmap in case no DMA mapping was established The multi-packet WQE transmit code attempts to obtain a DMA mapping for the skb. This could fail, e.g. under memory pressure, when the IOMMU driver just can't allocate more memory for page tables. While the code tries to handle this in the path below the err_unmap label it erroneously unmaps one entry from the sq's FIFO list of active mappings. Since the current map attempt failed this unmap is removing some random DMA mapping that might still be required. If the PCI function now presents that IOVA, the IOMMU may assumes a rogue DMA access and e.g. on s390 puts the PCI function in error state. The erroneous behavior was seen in a stress-test environment that created memory pressure. Fixes: 5af75c747e2a ("net/mlx5e: Enhanced TX MPWQE for SKBs") Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com> Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev> Acked-by: Maxim Mikityanskiy <maxtram95@gmail.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index b09e9abd39f3..f8c7912abe0e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -642,7 +642,6 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb, return; err_unmap: - mlx5e_dma_unmap_wqe_err(sq, 1); sq->stats->dropped++; dev_kfree_skb_any(skb); mlx5e_tx_flush(sq); -- GitLab From ec793155894140df7421d25903de2e6bc12c695b Mon Sep 17 00:00:00 2001 From: Mohamed Khalfella <mkhalfella@purestorage.com> Date: Wed, 4 Sep 2024 22:02:48 -0600 Subject: [PATCH 332/970] net/mlx5: Added cond_resched() to crdump collection Collecting crdump involves reading vsc registers from pci config space of mlx device, which can take long time to complete. This might result in starving other threads waiting to run on the cpu. Numbers I got from testing ConnectX-5 Ex MCX516A-CDAT in the lab: - mlx5_vsc_gw_read_block_fast() was called with length = 1310716. - mlx5_vsc_gw_read_fast() reads 4 bytes at a time. It was not used to read the entire 1310716 bytes. It was called 53813 times because there are jumps in read_addr. - On average mlx5_vsc_gw_read_fast() took 35284.4ns. - In total mlx5_vsc_wait_on_flag() called vsc_read() 54707 times. The average time for each call was 17548.3ns. In some instances vsc_read() was called more than one time when the flag was not set. As expected the thread released the cpu after 16 iterations in mlx5_vsc_wait_on_flag(). - Total time to read crdump was 35284.4ns * 53813 ~= 1.898s. It was seen in the field that crdump can take more than 5 seconds to complete. During that time mlx5_vsc_wait_on_flag() did not release the cpu because it did not complete 16 iterations. It is believed that pci config reads were slow. Adding cond_resched() every 128 register read improves the situation. In the common case the, crdump takes ~1.8989s, the thread yields the cpu every ~4.51ms. If crdump takes ~5s, the thread yields the cpu every ~18.0ms. Fixes: 8b9d8baae1de ("net/mlx5: Add Crdump support") Reviewed-by: Yuanyuan Zhong <yzhong@purestorage.com> Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com> Reviewed-by: Moshe Shemesh <moshe@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c index d0b595ba6110..432c98f2626d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c @@ -24,6 +24,11 @@ pci_write_config_dword((dev)->pdev, (dev)->vsc_addr + (offset), (val)) #define VSC_MAX_RETRIES 2048 +/* Reading VSC registers can take relatively long time. + * Yield the cpu every 128 registers read. + */ +#define VSC_GW_READ_BLOCK_COUNT 128 + enum { VSC_CTRL_OFFSET = 0x4, VSC_COUNTER_OFFSET = 0x8, @@ -273,6 +278,7 @@ int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data, { unsigned int next_read_addr = 0; unsigned int read_addr = 0; + unsigned int count = 0; while (read_addr < length) { if (mlx5_vsc_gw_read_fast(dev, read_addr, &next_read_addr, @@ -280,6 +286,10 @@ int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data, return read_addr; read_addr = next_read_addr; + if (++count == VSC_GW_READ_BLOCK_COUNT) { + cond_resched(); + count = 0; + } } return length; } -- GitLab From f25389e779500cf4a59ef9804534237841bce536 Mon Sep 17 00:00:00 2001 From: Elena Salomatkina <esalomatkina@ispras.ru> Date: Tue, 24 Sep 2024 19:00:18 +0300 Subject: [PATCH 333/970] net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc() In mlx5e_tir_builder_alloc() kvzalloc() may return NULL which is dereferenced on the next line in a reference to the modify field. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: a6696735d694 ("net/mlx5e: Convert TIR to a dedicated object") Signed-off-by: Elena Salomatkina <esalomatkina@ispras.ru> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Reviewed-by: Gal Pressman <gal@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- drivers/net/ethernet/mellanox/mlx5/core/en/tir.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c index d4239e3b3c88..11f724ad90db 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c @@ -23,6 +23,9 @@ struct mlx5e_tir_builder *mlx5e_tir_builder_alloc(bool modify) struct mlx5e_tir_builder *builder; builder = kvzalloc(sizeof(*builder), GFP_KERNEL); + if (!builder) + return NULL; + builder->modify = modify; return builder; -- GitLab From 19da17010a55924f2b5540b0f61652cc5781af85 Mon Sep 17 00:00:00 2001 From: Yevgeny Kliteynik <kliteyn@nvidia.com> Date: Mon, 23 Sep 2024 11:44:30 +0300 Subject: [PATCH 334/970] net/mlx5: Fix wrong reserved field in hca_cap_2 in mlx5_ifc Fixing the wrong size of a field in hca_cap_2. The bug was introduced by adding new fields for HWS and not fixing the reserved field size. Fixes: 34c626c3004a ("net/mlx5: Added missing mlx5_ifc definition for HW Steering") Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- include/linux/mlx5/mlx5_ifc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 620a5c305123..04df1610736e 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -2115,7 +2115,7 @@ struct mlx5_ifc_cmd_hca_cap_2_bits { u8 ts_cqe_metadata_size2wqe_counter[0x5]; u8 reserved_at_250[0x10]; - u8 reserved_at_260[0x120]; + u8 reserved_at_260[0x20]; u8 format_select_dw_gtpu_dw_0[0x8]; u8 format_select_dw_gtpu_dw_1[0x8]; -- GitLab From d8c561741ef83980114b3f7f95ffac54600f3f16 Mon Sep 17 00:00:00 2001 From: Yevgeny Kliteynik <kliteyn@nvidia.com> Date: Thu, 19 Sep 2024 12:17:59 +0300 Subject: [PATCH 335/970] net/mlx5: HWS, fixed double-free in error flow of creating SQ When SQ creation fails, call the appropriate mlx5_core destroy function. This fixes the following smatch warnings: divers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_send.c:739 hws_send_ring_open_sq() warn: 'sq->dep_wqe' double freed hws_send_ring_open_sq() warn: 'sq->wq_ctrl.buf.frags' double freed hws_send_ring_open_sq() warn: 'sq->wr_priv' double freed Fixes: 2ca62599aa0b ("net/mlx5: HWS, added send engine and context handling") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/all/e4ebc227-4b25-49bf-9e4c-14b7ea5c6a07@stanley.mountain/ Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- .../mellanox/mlx5/core/steering/hws/mlx5hws_send.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_send.c index a1adbb48735c..0c7989184c30 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_send.c @@ -653,6 +653,12 @@ static int hws_send_ring_create_sq(struct mlx5_core_dev *mdev, u32 pdn, return err; } +static void hws_send_ring_destroy_sq(struct mlx5_core_dev *mdev, + struct mlx5hws_send_ring_sq *sq) +{ + mlx5_core_destroy_sq(mdev, sq->sqn); +} + static int hws_send_ring_set_sq_rdy(struct mlx5_core_dev *mdev, u32 sqn) { void *in, *sqc; @@ -696,7 +702,7 @@ static int hws_send_ring_create_sq_rdy(struct mlx5_core_dev *mdev, u32 pdn, err = hws_send_ring_set_sq_rdy(mdev, sq->sqn); if (err) - hws_send_ring_close_sq(sq); + hws_send_ring_destroy_sq(mdev, sq); return err; } -- GitLab From d15525f300109fac5477dce1b8fef244c5dc9ec3 Mon Sep 17 00:00:00 2001 From: Yevgeny Kliteynik <kliteyn@nvidia.com> Date: Mon, 16 Sep 2024 14:13:39 +0300 Subject: [PATCH 336/970] net/mlx5: HWS, changed E2BIG error to a negative return code Fixed all the 'E2BIG' returns in error flow of functions to the negative '-E2BIG' as we are using negative error codes everywhere in HWS code. This also fixes the following smatch warnings: "warn: was negative '-E2BIG' intended?" Fixes: 74a778b4a63f ("net/mlx5: HWS, added definers handling") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/all/f8c77688-7d83-4937-baba-ac844dfe2e0b@stanley.mountain/ Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- .../mellanox/mlx5/core/steering/hws/mlx5hws_bwc_complex.c | 2 +- .../mellanox/mlx5/core/steering/hws/mlx5hws_definer.c | 4 ++-- .../mellanox/mlx5/core/steering/hws/mlx5hws_matcher.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_bwc_complex.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_bwc_complex.c index bb563f50ef09..601fad5fc54a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_bwc_complex.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_bwc_complex.c @@ -33,7 +33,7 @@ bool mlx5hws_bwc_match_params_is_complex(struct mlx5hws_context *ctx, * and let the usual match creation path handle it, * both for good and bad flows. */ - if (ret == E2BIG) { + if (ret == -E2BIG) { is_complex = true; mlx5hws_dbg(ctx, "Matcher definer layout: need complex matcher\n"); } else { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_definer.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_definer.c index 3bdb5c90efff..d566d2ddf424 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_definer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_definer.c @@ -1845,7 +1845,7 @@ hws_definer_find_best_match_fit(struct mlx5hws_context *ctx, return 0; } - return E2BIG; + return -E2BIG; } static void @@ -1931,7 +1931,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, /* Find the match definer layout for header layout match union */ ret = hws_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { - if (ret == E2BIG) + if (ret == -E2BIG) mlx5hws_dbg(ctx, "Failed to create match definer from header layout - E2BIG\n"); else diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_matcher.c index 33d2b31e4b46..61a1155d4b4f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_matcher.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_matcher.c @@ -675,7 +675,7 @@ static int hws_matcher_bind_mt(struct mlx5hws_matcher *matcher) if (!(matcher->flags & MLX5HWS_MATCHER_FLAGS_COLLISION)) { ret = mlx5hws_definer_mt_init(ctx, matcher->mt); if (ret) { - if (ret == E2BIG) + if (ret == -E2BIG) mlx5hws_err(ctx, "Failed to set matcher templates with match definers\n"); return ret; } -- GitLab From 023d2a43ed0d9ab73d4a35757121e4c8e01298e5 Mon Sep 17 00:00:00 2001 From: Dragos Tatulea <dtatulea@nvidia.com> Date: Tue, 13 Aug 2024 13:34:54 +0300 Subject: [PATCH 337/970] net/mlx5e: SHAMPO, Fix overflow of hd_per_wq When having larger RQ sizes and small MTUs sizes, the hd_per_wq variable can overflow. Like in the following case: $> ethtool --set-ring eth1 rx 8192 $> ip link set dev eth1 mtu 144 $> ethtool --features eth1 rx-gro-hw on ... yields in dmesg: mlx5_core 0000:08:00.1: mlx5_cmd_out_err:808:(pid 194797): CREATE_MKEY(0x200) op_mod(0x0) failed, status bad parameter(0x3), syndrome (0x3bf6f), err(-22) because hd_per_wq is 64K which overflows to 0 and makes the command fail. This patch increases the variable size to 32 bit. Fixes: 99be56171fa9 ("net/mlx5e: SHAMPO, Re-enable HW-GRO") Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index da0a1c65ec4a..57b7298a0e79 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -627,7 +627,7 @@ struct mlx5e_shampo_hd { struct mlx5e_dma_info *info; struct mlx5e_frag_page *pages; u16 curr_page_index; - u16 hd_per_wq; + u32 hd_per_wq; u16 hd_per_wqe; unsigned long *bitmap; u16 pi; -- GitLab From 7b124695db40d5c9c5295a94ae928a8d67a01c3d Mon Sep 17 00:00:00 2001 From: Jianbo Liu <jianbol@nvidia.com> Date: Mon, 2 Sep 2024 09:40:58 +0300 Subject: [PATCH 338/970] net/mlx5e: Fix crash caused by calling __xfrm_state_delete() twice The km.state is not checked in driver's delayed work. When xfrm_state_check_expire() is called, the state can be reset to XFRM_STATE_EXPIRED, even if it is XFRM_STATE_DEAD already. This happens when xfrm state is deleted, but not freed yet. As __xfrm_state_delete() is called again in xfrm timer, the following crash occurs. To fix this issue, skip xfrm_state_check_expire() if km.state is not XFRM_STATE_VALID. Oops: general protection fault, probably for non-canonical address 0xdead000000000108: 0000 [#1] SMP CPU: 5 UID: 0 PID: 7448 Comm: kworker/u102:2 Not tainted 6.11.0-rc2+ #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 Workqueue: mlx5e_ipsec: eth%d mlx5e_ipsec_handle_sw_limits [mlx5_core] RIP: 0010:__xfrm_state_delete+0x3d/0x1b0 Code: 0f 84 8b 01 00 00 48 89 fd c6 87 c8 00 00 00 05 48 8d bb 40 10 00 00 e8 11 04 1a 00 48 8b 95 b8 00 00 00 48 8b 85 c0 00 00 00 <48> 89 42 08 48 89 10 48 8b 55 10 48 b8 00 01 00 00 00 00 ad de 48 RSP: 0018:ffff88885f945ec8 EFLAGS: 00010246 RAX: dead000000000122 RBX: ffffffff82afa940 RCX: 0000000000000036 RDX: dead000000000100 RSI: 0000000000000000 RDI: ffffffff82afb980 RBP: ffff888109a20340 R08: ffff88885f945ea0 R09: 0000000000000000 R10: 0000000000000000 R11: ffff88885f945ff8 R12: 0000000000000246 R13: ffff888109a20340 R14: ffff88885f95f420 R15: ffff88885f95f400 FS: 0000000000000000(0000) GS:ffff88885f940000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f2163102430 CR3: 00000001128d6001 CR4: 0000000000370eb0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <IRQ> ? die_addr+0x33/0x90 ? exc_general_protection+0x1a2/0x390 ? asm_exc_general_protection+0x22/0x30 ? __xfrm_state_delete+0x3d/0x1b0 ? __xfrm_state_delete+0x2f/0x1b0 xfrm_timer_handler+0x174/0x350 ? __xfrm_state_delete+0x1b0/0x1b0 __hrtimer_run_queues+0x121/0x270 hrtimer_run_softirq+0x88/0xd0 handle_softirqs+0xcc/0x270 do_softirq+0x3c/0x50 </IRQ> <TASK> __local_bh_enable_ip+0x47/0x50 mlx5e_ipsec_handle_sw_limits+0x7d/0x90 [mlx5_core] process_one_work+0x137/0x2d0 worker_thread+0x28d/0x3a0 ? rescuer_thread+0x480/0x480 kthread+0xb8/0xe0 ? kthread_park+0x80/0x80 ret_from_fork+0x2d/0x50 ? kthread_park+0x80/0x80 ret_from_fork_asm+0x11/0x20 </TASK> Fixes: b2f7b01d36a9 ("net/mlx5e: Simulate missing IPsec TX limits hardware functionality") Signed-off-by: Jianbo Liu <jianbol@nvidia.com> Reviewed-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 3d274599015b..ca92e518be76 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -67,7 +67,6 @@ static void mlx5e_ipsec_handle_sw_limits(struct work_struct *_work) return; spin_lock_bh(&x->lock); - xfrm_state_check_expire(x); if (x->km.state == XFRM_STATE_EXPIRED) { sa_entry->attrs.drop = true; spin_unlock_bh(&x->lock); @@ -75,6 +74,13 @@ static void mlx5e_ipsec_handle_sw_limits(struct work_struct *_work) mlx5e_accel_ipsec_fs_modify(sa_entry); return; } + + if (x->km.state != XFRM_STATE_VALID) { + spin_unlock_bh(&x->lock); + return; + } + + xfrm_state_check_expire(x); spin_unlock_bh(&x->lock); queue_delayed_work(sa_entry->ipsec->wq, &dwork->dwork, -- GitLab From 1e123fd73deb16cb362ecefb55c90c9196f4a6c2 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Wed, 25 Sep 2024 11:58:44 -1000 Subject: [PATCH 339/970] sched_ext: Add __COMPAT helpers for features added during v6.12 devel cycle cgroup support and scx_bpf_dispatch[_vtime]_from_dsq() are newly added since 8bb30798fd6e ("sched_ext: Fixes incorrect type in bpf_scx_init()") which is the current earliest commit targeted by BPF schedulers. Add compat helpers for them and apply them in the example schedulers. These will be dropped after a few kernel releases. The exact backward compatibility window hasn't been decided yet. Signed-off-by: Tejun Heo <tj@kernel.org> --- tools/sched_ext/include/scx/compat.bpf.h | 19 +++++++++++++++++++ tools/sched_ext/scx_flatcg.bpf.c | 10 +++++----- tools/sched_ext/scx_qmap.bpf.c | 12 ++++++------ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/tools/sched_ext/include/scx/compat.bpf.h b/tools/sched_ext/include/scx/compat.bpf.h index 3d2fe1208900..e5afe9efd3f3 100644 --- a/tools/sched_ext/include/scx/compat.bpf.h +++ b/tools/sched_ext/include/scx/compat.bpf.h @@ -15,6 +15,25 @@ __ret; \ }) +/* v6.12: 819513666966 ("sched_ext: Add cgroup support") */ +#define __COMPAT_scx_bpf_task_cgroup(p) \ + (bpf_ksym_exists(scx_bpf_task_cgroup) ? \ + scx_bpf_task_cgroup((p)) : NULL) + +/* v6.12: 4c30f5ce4f7a ("sched_ext: Implement scx_bpf_dispatch[_vtime]_from_dsq()") */ +#define __COMPAT_scx_bpf_dispatch_from_dsq_set_slice(it, slice) \ + (bpf_ksym_exists(scx_bpf_dispatch_from_dsq_set_slice) ? \ + scx_bpf_dispatch_from_dsq_set_slice((it), (slice)) : (void)0) +#define __COMPAT_scx_bpf_dispatch_from_dsq_set_vtime(it, vtime) \ + (bpf_ksym_exists(scx_bpf_dispatch_from_dsq_set_vtime) ? \ + scx_bpf_dispatch_from_dsq_set_vtime((it), (vtime)) : (void)0) +#define __COMPAT_scx_bpf_dispatch_from_dsq(it, p, dsq_id, enq_flags) \ + (bpf_ksym_exists(scx_bpf_dispatch_from_dsq) ? \ + scx_bpf_dispatch_from_dsq((it), (p), (dsq_id), (enq_flags)) : false) +#define __COMPAT_scx_bpf_dispatch_vtime_from_dsq(it, p, dsq_id, enq_flags) \ + (bpf_ksym_exists(scx_bpf_dispatch_vtime_from_dsq) ? \ + scx_bpf_dispatch_vtime_from_dsq((it), (p), (dsq_id), (enq_flags)) : false) + /* * Define sched_ext_ops. This may be expanded to define multiple variants for * backward compatibility. See compat.h::SCX_OPS_LOAD/ATTACH(). diff --git a/tools/sched_ext/scx_flatcg.bpf.c b/tools/sched_ext/scx_flatcg.bpf.c index 3ab2b60781a0..936415b98ae7 100644 --- a/tools/sched_ext/scx_flatcg.bpf.c +++ b/tools/sched_ext/scx_flatcg.bpf.c @@ -383,7 +383,7 @@ void BPF_STRUCT_OPS(fcg_enqueue, struct task_struct *p, u64 enq_flags) return; } - cgrp = scx_bpf_task_cgroup(p); + cgrp = __COMPAT_scx_bpf_task_cgroup(p); cgc = find_cgrp_ctx(cgrp); if (!cgc) goto out_release; @@ -509,7 +509,7 @@ void BPF_STRUCT_OPS(fcg_runnable, struct task_struct *p, u64 enq_flags) { struct cgroup *cgrp; - cgrp = scx_bpf_task_cgroup(p); + cgrp = __COMPAT_scx_bpf_task_cgroup(p); update_active_weight_sums(cgrp, true); bpf_cgroup_release(cgrp); } @@ -522,7 +522,7 @@ void BPF_STRUCT_OPS(fcg_running, struct task_struct *p) if (fifo_sched) return; - cgrp = scx_bpf_task_cgroup(p); + cgrp = __COMPAT_scx_bpf_task_cgroup(p); cgc = find_cgrp_ctx(cgrp); if (cgc) { /* @@ -565,7 +565,7 @@ void BPF_STRUCT_OPS(fcg_stopping, struct task_struct *p, bool runnable) if (!taskc->bypassed_at) return; - cgrp = scx_bpf_task_cgroup(p); + cgrp = __COMPAT_scx_bpf_task_cgroup(p); cgc = find_cgrp_ctx(cgrp); if (cgc) { __sync_fetch_and_add(&cgc->cvtime_delta, @@ -579,7 +579,7 @@ void BPF_STRUCT_OPS(fcg_quiescent, struct task_struct *p, u64 deq_flags) { struct cgroup *cgrp; - cgrp = scx_bpf_task_cgroup(p); + cgrp = __COMPAT_scx_bpf_task_cgroup(p); update_active_weight_sums(cgrp, false); bpf_cgroup_release(cgrp); } diff --git a/tools/sched_ext/scx_qmap.bpf.c b/tools/sched_ext/scx_qmap.bpf.c index 83c8f54c1e31..67e2a7968cc9 100644 --- a/tools/sched_ext/scx_qmap.bpf.c +++ b/tools/sched_ext/scx_qmap.bpf.c @@ -318,11 +318,11 @@ static bool dispatch_highpri(bool from_timer) if (tctx->highpri) { /* exercise the set_*() and vtime interface too */ - scx_bpf_dispatch_from_dsq_set_slice( + __COMPAT_scx_bpf_dispatch_from_dsq_set_slice( BPF_FOR_EACH_ITER, slice_ns * 2); - scx_bpf_dispatch_from_dsq_set_vtime( + __COMPAT_scx_bpf_dispatch_from_dsq_set_vtime( BPF_FOR_EACH_ITER, highpri_seq++); - scx_bpf_dispatch_vtime_from_dsq( + __COMPAT_scx_bpf_dispatch_vtime_from_dsq( BPF_FOR_EACH_ITER, p, HIGHPRI_DSQ, 0); } } @@ -340,9 +340,9 @@ static bool dispatch_highpri(bool from_timer) else cpu = scx_bpf_pick_any_cpu(p->cpus_ptr, 0); - if (scx_bpf_dispatch_from_dsq(BPF_FOR_EACH_ITER, p, - SCX_DSQ_LOCAL_ON | cpu, - SCX_ENQ_PREEMPT)) { + if (__COMPAT_scx_bpf_dispatch_from_dsq(BPF_FOR_EACH_ITER, p, + SCX_DSQ_LOCAL_ON | cpu, + SCX_ENQ_PREEMPT)) { if (cpu == this_cpu) { dispatched = true; __sync_fetch_and_add(&nr_expedited_local, 1); -- GitLab From a748db0c8c6a88da66c3ab3791bd1a229f4a7fee Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Wed, 25 Sep 2024 12:22:37 -1000 Subject: [PATCH 340/970] tools/sched_ext: Receive misc updates from SCX repo Receive misc tools/sched_ext updates from https://github.com/sched-ext/scx to sync userspace bits. - LSP macros to help language servers. - bpf_cpumask_weight() declaration and cast_mask() helper. - Cosmetic updates to scx_flatcg.bpf.c. Signed-off-by: Tejun Heo <tj@kernel.org> --- tools/sched_ext/include/scx/common.bpf.h | 15 +++++++++++++++ tools/sched_ext/include/scx/user_exit_info.h | 4 ++++ tools/sched_ext/scx_flatcg.bpf.c | 5 ++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h index f538c75db183..225f61f9bfca 100644 --- a/tools/sched_ext/include/scx/common.bpf.h +++ b/tools/sched_ext/include/scx/common.bpf.h @@ -7,7 +7,13 @@ #ifndef __SCX_COMMON_BPF_H #define __SCX_COMMON_BPF_H +#ifdef LSP +#define __bpf__ +#include "../vmlinux/vmlinux.h" +#else #include "vmlinux.h" +#endif + #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h> #include <asm-generic/errno.h> @@ -309,6 +315,15 @@ void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym u32 bpf_cpumask_any_distribute(const struct cpumask *cpumask) __ksym; u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1, const struct cpumask *src2) __ksym; +u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym; + +/* + * Access a cpumask in read-only mode (typically to check bits). + */ +const struct cpumask *cast_mask(struct bpf_cpumask *mask) +{ + return (const struct cpumask *)mask; +} /* rcu */ void bpf_rcu_read_lock(void) __ksym; diff --git a/tools/sched_ext/include/scx/user_exit_info.h b/tools/sched_ext/include/scx/user_exit_info.h index 891693ee604e..8ce2734402e1 100644 --- a/tools/sched_ext/include/scx/user_exit_info.h +++ b/tools/sched_ext/include/scx/user_exit_info.h @@ -25,7 +25,11 @@ struct user_exit_info { #ifdef __bpf__ +#ifdef LSP +#include "../vmlinux/vmlinux.h" +#else #include "vmlinux.h" +#endif #include <bpf/bpf_core_read.h> #define UEI_DEFINE(__name) \ diff --git a/tools/sched_ext/scx_flatcg.bpf.c b/tools/sched_ext/scx_flatcg.bpf.c index 936415b98ae7..e272bc39bbbd 100644 --- a/tools/sched_ext/scx_flatcg.bpf.c +++ b/tools/sched_ext/scx_flatcg.bpf.c @@ -225,7 +225,7 @@ static void cgrp_refresh_hweight(struct cgroup *cgrp, struct fcg_cgrp_ctx *cgc) break; /* - * We can be oppotunistic here and not grab the + * We can be opportunistic here and not grab the * cgv_tree_lock and deal with the occasional races. * However, hweight updates are already cached and * relatively low-frequency. Let's just do the @@ -258,8 +258,7 @@ static void cgrp_cap_budget(struct cgv_node *cgv_node, struct fcg_cgrp_ctx *cgc) * and thus can't be updated and repositioned. Instead, we collect the * vtime deltas separately and apply it asynchronously here. */ - delta = cgc->cvtime_delta; - __sync_fetch_and_sub(&cgc->cvtime_delta, delta); + delta = __sync_fetch_and_sub(&cgc->cvtime_delta, cgc->cvtime_delta); cvtime = cgv_node->cvtime + delta; /* -- GitLab From ad604f0a4c040dcb8faf44dc72db25e457c28076 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 10:41:03 +0200 Subject: [PATCH 341/970] firmware/sysfb: Disable sysfb for firmware buffers with unknown parent The sysfb framebuffer handling only operates on graphics devices that provide the system's firmware framebuffer. If that device is not known, assume that any graphics device has been initialized by firmware. Fixes a problem on i915 where sysfb does not release the firmware framebuffer after the native graphics driver loaded. Reported-by: Borah, Chaitanya Kumar <chaitanya.kumar.borah@intel.com> Closes: https://lore.kernel.org/dri-devel/SJ1PR11MB6129EFB8CE63D1EF6D932F94B96F2@SJ1PR11MB6129.namprd11.prod.outlook.com/ Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12160 Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Fixes: b49420d6a1ae ("video/aperture: optionally match the device in sysfb_disable()") Cc: Javier Martinez Canillas <javierm@redhat.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Helge Deller <deller@gmx.de> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: dri-devel@lists.freedesktop.org Cc: Linux regression tracking (Thorsten Leemhuis) <regressions@leemhuis.info> Cc: <stable@vger.kernel.org> # v6.11+ Acked-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924084227.262271-1-tzimmermann@suse.de --- drivers/firmware/sysfb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 02a07d3d0d40..a3df782fa687 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -67,9 +67,11 @@ static bool sysfb_unregister(void) void sysfb_disable(struct device *dev) { struct screen_info *si = &screen_info; + struct device *parent; mutex_lock(&disable_lock); - if (!dev || dev == sysfb_parent_dev(si)) { + parent = sysfb_parent_dev(si); + if (!dev || !parent || dev == parent) { sysfb_unregister(); disabled = true; } -- GitLab From eb1f4adf9101573fc2347978a60d71c4f1176cca Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:11:59 +0200 Subject: [PATCH 342/970] drm/fbdev-helper: Move color-mode lookup into 4CC format helper The color mode as specified on the kernel command line gives the user's preferred color depth and number of bits per pixel. Move the color-mode-to-format conversion from fbdev helpers into a 4CC helper, so that it can be shared among DRM clients. v2: - fix grammar in commit message (Laurent) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-2-tzimmermann@suse.de --- drivers/gpu/drm/drm_fb_helper.c | 70 +++++++-------------------------- drivers/gpu/drm/drm_fourcc.c | 30 +++++++++++++- include/drm/drm_fourcc.h | 1 + 3 files changed, 45 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 29c53f9f449c..af1fe79c701d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1441,67 +1441,27 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, EXPORT_SYMBOL(drm_fb_helper_pan_display); static uint32_t drm_fb_helper_find_format(struct drm_fb_helper *fb_helper, const uint32_t *formats, - size_t format_count, uint32_t bpp, uint32_t depth) + size_t format_count, unsigned int color_mode) { struct drm_device *dev = fb_helper->dev; uint32_t format; size_t i; - /* - * Do not consider YUV or other complicated formats - * for framebuffers. This means only legacy formats - * are supported (fmt->depth is a legacy field), but - * the framebuffer emulation can only deal with such - * formats, specifically RGB/BGA formats. - */ - format = drm_mode_legacy_fb_format(bpp, depth); - if (!format) - goto err; + format = drm_driver_color_mode_format(dev, color_mode); + if (!format) { + drm_info(dev, "unsupported color mode of %d\n", color_mode); + return DRM_FORMAT_INVALID; + } for (i = 0; i < format_count; ++i) { if (formats[i] == format) return format; } - -err: - /* We found nothing. */ - drm_warn(dev, "bpp/depth value of %u/%u not supported\n", bpp, depth); + drm_warn(dev, "format %p4cc not supported\n", &format); return DRM_FORMAT_INVALID; } -static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_helper, - const uint32_t *formats, size_t format_count, - unsigned int color_mode) -{ - struct drm_device *dev = fb_helper->dev; - uint32_t bpp, depth; - - switch (color_mode) { - case 1: - case 2: - case 4: - case 8: - case 16: - case 24: - bpp = depth = color_mode; - break; - case 15: - bpp = 16; - depth = 15; - break; - case 32: - bpp = 32; - depth = 24; - break; - default: - drm_info(dev, "unsupported color mode of %d\n", color_mode); - return DRM_FORMAT_INVALID; - } - - return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth); -} - static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) { @@ -1531,10 +1491,10 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, if (!cmdline_mode->bpp_specified) continue; - surface_format = drm_fb_helper_find_color_mode_format(fb_helper, - plane->format_types, - plane->format_count, - cmdline_mode->bpp); + surface_format = drm_fb_helper_find_format(fb_helper, + plane->format_types, + plane->format_count, + cmdline_mode->bpp); if (surface_format != DRM_FORMAT_INVALID) break; /* found supported format */ } @@ -1544,10 +1504,10 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, break; /* found supported format */ /* try preferred color mode */ - surface_format = drm_fb_helper_find_color_mode_format(fb_helper, - plane->format_types, - plane->format_count, - fb_helper->preferred_bpp); + surface_format = drm_fb_helper_find_format(fb_helper, + plane->format_types, + plane->format_count, + fb_helper->preferred_bpp); if (surface_format != DRM_FORMAT_INVALID) break; /* found supported format */ } diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index 193cf8ed7912..3a94ca211f9c 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -36,7 +36,6 @@ * @depth: bit depth per pixel * * Computes a drm fourcc pixel format code for the given @bpp/@depth values. - * Useful in fbdev emulation code, since that deals in those values. */ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) { @@ -140,6 +139,35 @@ uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, } EXPORT_SYMBOL(drm_driver_legacy_fb_format); +/** + * drm_driver_color_mode_format - Compute DRM 4CC code from color mode + * @dev: DRM device + * @color_mode: command-line color mode + * + * Computes a DRM 4CC pixel format code for the given color mode using + * drm_driver_color_mode(). The color mode is in the format used and the + * kernel command line. It specifies the number of bits per pixel + * and color depth in a single value. + * + * Useful in fbdev emulation code, since that deals in those values. The + * helper does not consider YUV or other complicated formats. This means + * only legacy formats are supported (fmt->depth is a legacy field), but + * the framebuffer emulation can only deal with such formats, specifically + * RGB/BGA formats. + */ +uint32_t drm_driver_color_mode_format(struct drm_device *dev, unsigned int color_mode) +{ + switch (color_mode) { + case 15: + return drm_driver_legacy_fb_format(dev, 16, 15); + case 32: + return drm_driver_legacy_fb_format(dev, 32, 24); + default: + return drm_driver_legacy_fb_format(dev, color_mode, color_mode); + } +} +EXPORT_SYMBOL(drm_driver_color_mode_format); + /* * Internal function to query information for a given format. See * drm_format_info() for the public API. diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index ccf91daa4307..c3f4405d6662 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h @@ -313,6 +313,7 @@ drm_get_format_info(struct drm_device *dev, uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); uint32_t drm_driver_legacy_fb_format(struct drm_device *dev, uint32_t bpp, uint32_t depth); +uint32_t drm_driver_color_mode_format(struct drm_device *dev, unsigned int color_mode); unsigned int drm_format_info_block_width(const struct drm_format_info *info, int plane); unsigned int drm_format_info_block_height(const struct drm_format_info *info, -- GitLab From 02257549daf7ff839e2be6d4f3cac975e522fd7a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:00 +0200 Subject: [PATCH 343/970] drm/fbdev-helper: Set and clear VGA switcheroo client from fb_info Call vga_switcheroo_client_fb_set() with the PCI device from the instance of struct fb_info. All fbdev clients now run these calls. For non-PCI devices or drivers without vga-switcheroo, this does nothing. For i915 and radeon, it allows these drivers to use a common fbdev client. The device is the same as the one stored in struct drm_client and struct drm_fb_helper, so there is no difference in behavior. Some NULL-pointer checks are being removed, where those pointers cannot be NULL. v4: - clarify call semantics for drm_fb_helper_unregister_info() (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-3-tzimmermann@suse.de --- drivers/gpu/drm/drm_fb_helper.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index af1fe79c701d..550fa69311cb 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -554,7 +554,7 @@ EXPORT_SYMBOL(drm_fb_helper_release_info); /** * drm_fb_helper_unregister_info - unregister fb_info framebuffer device - * @fb_helper: driver-allocated fbdev helper, can be NULL + * @fb_helper: driver-allocated fbdev helper, must not be NULL * * A wrapper around unregister_framebuffer, to release the fb_info * framebuffer device. This must be called before releasing all resources for @@ -562,8 +562,12 @@ EXPORT_SYMBOL(drm_fb_helper_release_info); */ void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper) { - if (fb_helper && fb_helper->info) - unregister_framebuffer(fb_helper->info); + struct fb_info *info = fb_helper->info; + struct device *dev = info->device; + + if (dev_is_pci(dev)) + vga_switcheroo_client_fb_set(to_pci_dev(dev), NULL); + unregister_framebuffer(fb_helper->info); } EXPORT_SYMBOL(drm_fb_helper_unregister_info); @@ -1615,6 +1619,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) struct drm_client_dev *client = &fb_helper->client; struct drm_device *dev = fb_helper->dev; struct drm_fb_helper_surface_size sizes; + struct fb_info *info; int ret; ret = drm_fb_helper_find_sizes(fb_helper, &sizes); @@ -1632,9 +1637,11 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) strcpy(fb_helper->fb->comm, "[fbcon]"); + info = fb_helper->info; + /* Set the fb info for vgaswitcheroo clients. Does nothing otherwise. */ - if (dev_is_pci(dev->dev)) - vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), fb_helper->info); + if (dev_is_pci(info->device)) + vga_switcheroo_client_fb_set(to_pci_dev(info->device), info); return 0; } -- GitLab From 5d08c44e47b9d41366714552bdd374ac4b595591 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:01 +0200 Subject: [PATCH 344/970] drm/fbdev: Add memory-agnostic fbdev client Add an fbdev client that can work with any memory manager. The client implementation is the same as existing code in fbdev-dma or fbdev-shmem. Provide struct drm_driver.fbdev_probe for the new client to allocate the surface GEM buffer. The new callback replaces fb_probe of struct drm_fb_helper_funcs, which does the same. To use the new client, DRM drivers set fbdev_probe in their struct drm_driver instance and call drm_fbdev_client_setup(). Probing and creating the fbdev surface buffer is now independent from the other operations in struct drm_fb_helper. For the pixel format, the fbdev client either uses a specified format, the value in preferred_depth or 32-bit RGB. v2: - test for struct drm_fb_helper.funcs for NULL (Sui) - respect struct drm_mode_config.preferred_depth for default format Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-4-tzimmermann@suse.de --- drivers/gpu/drm/Makefile | 4 +- drivers/gpu/drm/drm_fb_helper.c | 15 +-- drivers/gpu/drm/drm_fbdev_client.c | 141 +++++++++++++++++++++++++++++ include/drm/drm_drv.h | 18 ++++ include/drm/drm_fbdev_client.h | 19 ++++ 5 files changed, 190 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/drm_fbdev_client.c create mode 100644 include/drm/drm_fbdev_client.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index fc061fd424ed..a8f726a05abf 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -144,7 +144,9 @@ drm_kms_helper-y := \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o -drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o +drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \ + drm_fbdev_client.o \ + drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o # diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 550fa69311cb..d5e8994345bb 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -492,8 +492,8 @@ EXPORT_SYMBOL(drm_fb_helper_init); * @fb_helper: driver-allocated fbdev helper * * A helper to alloc fb_info and the member cmap. Called by the driver - * within the fb_probe fb_helper callback function. Drivers do not - * need to release the allocated fb_info structure themselves, this is + * within the struct &drm_driver.fbdev_probe callback function. Drivers do + * not need to release the allocated fb_info structure themselves, this is * automatically done when calling drm_fb_helper_fini(). * * RETURNS: @@ -1612,7 +1612,7 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, /* * Allocates the backing storage and sets up the fbdev info structure through - * the ->fb_probe callback. + * the ->fbdev_probe callback. */ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) { @@ -1631,7 +1631,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) } /* push down into drivers */ - ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); + if (dev->driver->fbdev_probe) + ret = dev->driver->fbdev_probe(fb_helper, &sizes); + else if (fb_helper->funcs) + ret = fb_helper->funcs->fb_probe(fb_helper, &sizes); if (ret < 0) return ret; @@ -1705,7 +1708,7 @@ static void drm_fb_helper_fill_var(struct fb_info *info, * instance and the drm framebuffer allocated in &drm_fb_helper.fb. * * Drivers should call this (or their equivalent setup code) from their - * &drm_fb_helper_funcs.fb_probe callback after having allocated the fbdev + * &drm_driver.fbdev_probe callback after having allocated the fbdev * backing storage framebuffer. */ void drm_fb_helper_fill_info(struct fb_info *info, @@ -1861,7 +1864,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper) * Note that this also registers the fbdev and so allows userspace to call into * the driver through the fbdev interfaces. * - * This function will call down into the &drm_fb_helper_funcs.fb_probe callback + * This function will call down into the &drm_driver.fbdev_probe callback * to let the driver allocate and initialize the fbdev info structure and the * drm framebuffer used to back the fbdev. drm_fb_helper_fill_info() is provided * as a helper to setup simple default values for the fbdev info structure. diff --git a/drivers/gpu/drm/drm_fbdev_client.c b/drivers/gpu/drm/drm_fbdev_client.c new file mode 100644 index 000000000000..a09382afe2fb --- /dev/null +++ b/drivers/gpu/drm/drm_fbdev_client.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT + +#include <drm/drm_client.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_fbdev_client.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_print.h> + +/* + * struct drm_client_funcs + */ + +static void drm_fbdev_client_unregister(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (fb_helper->info) { + drm_fb_helper_unregister_info(fb_helper); + } else { + drm_client_release(&fb_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + } +} + +static int drm_fbdev_client_restore(struct drm_client_dev *client) +{ + drm_fb_helper_lastclose(client->dev); + + return 0; +} + +static int drm_fbdev_client_hotplug(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = client->dev; + int ret; + + if (dev->fb_helper) + return drm_fb_helper_hotplug_event(dev->fb_helper); + + ret = drm_fb_helper_init(dev, fb_helper); + if (ret) + goto err_drm_err; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper); + if (ret) + goto err_drm_fb_helper_fini; + + return 0; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(fb_helper); +err_drm_err: + drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret); + return ret; +} + +static const struct drm_client_funcs drm_fbdev_client_funcs = { + .owner = THIS_MODULE, + .unregister = drm_fbdev_client_unregister, + .restore = drm_fbdev_client_restore, + .hotplug = drm_fbdev_client_hotplug, +}; + +/** + * drm_fbdev_client_setup() - Setup fbdev emulation + * @dev: DRM device + * @format: Preferred color format for the device. DRM_FORMAT_XRGB8888 + * is used if this is zero. + * + * This function sets up fbdev emulation. Restore, hotplug events and + * teardown are all taken care of. Drivers that do suspend/resume need + * to call drm_fb_helper_set_suspend_unlocked() themselves. Simple + * drivers might use drm_mode_config_helper_suspend(). + * + * This function is safe to call even when there are no connectors present. + * Setup will be retried on the next hotplug event. + * + * The fbdev client is destroyed by drm_dev_unregister(). + * + * Returns: + * 0 on success, or a negative errno code otherwise. + */ +int drm_fbdev_client_setup(struct drm_device *dev, const struct drm_format_info *format) +{ + struct drm_fb_helper *fb_helper; + unsigned int color_mode; + int ret; + + /* TODO: Use format info throughout DRM */ + if (format) { + unsigned int bpp = drm_format_info_bpp(format, 0); + + switch (bpp) { + case 16: + color_mode = format->depth; // could also be 15 + break; + default: + color_mode = bpp; + } + } else { + switch (dev->mode_config.preferred_depth) { + case 0: + case 24: + color_mode = 32; + break; + default: + color_mode = dev->mode_config.preferred_depth; + } + } + + drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); + drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); + + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) + return -ENOMEM; + drm_fb_helper_prepare(dev, fb_helper, color_mode, NULL); + + ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs); + if (ret) { + drm_err(dev, "Failed to register client: %d\n", ret); + goto err_drm_client_init; + } + + drm_client_register(&fb_helper->client); + + return 0; + +err_drm_client_init: + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + return ret; +} +EXPORT_SYMBOL(drm_fbdev_client_setup); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 02ea4e3248fd..36a606af4ba1 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -34,6 +34,8 @@ #include <drm/drm_device.h> +struct drm_fb_helper; +struct drm_fb_helper_surface_size; struct drm_file; struct drm_gem_object; struct drm_master; @@ -366,6 +368,22 @@ struct drm_driver { struct drm_device *dev, uint32_t handle, uint64_t *offset); + /** + * @fbdev_probe + * + * Allocates and initialize the fb_info structure for fbdev emulation. + * Furthermore it also needs to allocate the DRM framebuffer used to + * back the fbdev. + * + * This callback is mandatory for fbdev support. + * + * Returns: + * + * 0 on success ot a negative error code otherwise. + */ + int (*fbdev_probe)(struct drm_fb_helper *fbdev_helper, + struct drm_fb_helper_surface_size *sizes); + /** * @show_fdinfo: * diff --git a/include/drm/drm_fbdev_client.h b/include/drm/drm_fbdev_client.h new file mode 100644 index 000000000000..e11a5614f127 --- /dev/null +++ b/include/drm/drm_fbdev_client.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_FBDEV_CLIENT_H +#define DRM_FBDEV_CLIENT_H + +struct drm_device; +struct drm_format_info; + +#ifdef CONFIG_DRM_FBDEV_EMULATION +int drm_fbdev_client_setup(struct drm_device *dev, const struct drm_format_info *format); +#else +static inline int drm_fbdev_client_setup(struct drm_device *dev, + const struct drm_format_info *format) +{ + return 0; +} +#endif + +#endif -- GitLab From d07fdf9225922d3e36ebd13ccab3df62b1ccdab3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:02 +0200 Subject: [PATCH 345/970] drm: Add client-agnostic setup helper DRM may support multiple in-kernel clients that run as soon as a DRM driver has been registered. To select the client(s) in a single place, introduce drm_client_setup(). Drivers that call the new helper automatically instantiate the kernel's configured default clients. Only fbdev emulation is currently supported. Later versions can add support for DRM-based logging, a boot logo or even a console. Some drivers handle the color mode for clients internally. Provide the helper drm_client_setup_with_color_mode() for them. Using the new interface requires the driver to select DRM_CLIENT_SELECTION in its Kconfig. For now this only enables the client-setup helpers if the fbdev client has been configured by the user. A future patchset will further modularize client support and rework DRM_CLIENT_SELECTION to select the correct dependencies for all its clients. v5: - add CONFIG_DRM_CLIENT_SELECTION und DRM_CLIENT_SETUP v4: - fix docs for drm_client_setup_with_fourcc() (Geert) v3: - fix build error v2: - add drm_client_setup_with_fourcc() (Laurent) - push default-format handling into actual clients Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-5-tzimmermann@suse.de --- drivers/gpu/drm/Kconfig | 12 ++++++ drivers/gpu/drm/Makefile | 2 + drivers/gpu/drm/drm_client_setup.c | 66 ++++++++++++++++++++++++++++++ include/drm/drm_client_setup.h | 26 ++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 drivers/gpu/drm/drm_client_setup.c create mode 100644 include/drm/drm_client_setup.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 1cb5a4f19293..f045ff0e8c99 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -210,6 +210,18 @@ config DRM_DEBUG_MODESET_LOCK If in doubt, say "N". +config DRM_CLIENT_SELECTION + bool + depends on DRM + select DRM_CLIENT_SETUP if DRM_FBDEV_EMULATION + help + Drivers that support in-kernel DRM clients have to select this + option. + +config DRM_CLIENT_SETUP + bool + depends on DRM_CLIENT_SELECTION + config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index a8f726a05abf..3894f43f6d47 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -143,6 +143,8 @@ drm_kms_helper-y := \ drm_probe_helper.o \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o +drm_kms_helper-$(CONFIG_DRM_CLIENT_SETUP) += \ + drm_client_setup.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \ drm_fbdev_client.o \ diff --git a/drivers/gpu/drm/drm_client_setup.c b/drivers/gpu/drm/drm_client_setup.c new file mode 100644 index 000000000000..5969c4ffe31b --- /dev/null +++ b/drivers/gpu/drm/drm_client_setup.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT + +#include <drm/drm_client_setup.h> +#include <drm/drm_device.h> +#include <drm/drm_fbdev_client.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_print.h> + +/** + * drm_client_setup() - Setup in-kernel DRM clients + * @dev: DRM device + * @format: Preferred pixel format for the device. Use NULL, unless + * there is clearly a driver-preferred format. + * + * This function sets up the in-kernel DRM clients. Restore, hotplug + * events and teardown are all taken care of. + * + * Drivers should call drm_client_setup() after registering the new + * DRM device with drm_dev_register(). This function is safe to call + * even when there are no connectors present. Setup will be retried + * on the next hotplug event. + * + * The clients are destroyed by drm_dev_unregister(). + */ +void drm_client_setup(struct drm_device *dev, const struct drm_format_info *format) +{ + int ret; + + ret = drm_fbdev_client_setup(dev, format); + if (ret) + drm_warn(dev, "Failed to set up DRM client; error %d\n", ret); +} +EXPORT_SYMBOL(drm_client_setup); + +/** + * drm_client_setup_with_fourcc() - Setup in-kernel DRM clients for color mode + * @dev: DRM device + * @fourcc: Preferred pixel format as 4CC code for the device + * + * This function sets up the in-kernel DRM clients. It is equivalent + * to drm_client_setup(), but expects a 4CC code as second argument. + */ +void drm_client_setup_with_fourcc(struct drm_device *dev, u32 fourcc) +{ + drm_client_setup(dev, drm_format_info(fourcc)); +} +EXPORT_SYMBOL(drm_client_setup_with_fourcc); + +/** + * drm_client_setup_with_color_mode() - Setup in-kernel DRM clients for color mode + * @dev: DRM device + * @color_mode: Preferred color mode for the device + * + * This function sets up the in-kernel DRM clients. It is equivalent + * to drm_client_setup(), but expects a color mode as second argument. + * + * Do not use this function in new drivers. Prefer drm_client_setup() with a + * format of NULL. + */ +void drm_client_setup_with_color_mode(struct drm_device *dev, unsigned int color_mode) +{ + u32 fourcc = drm_driver_color_mode_format(dev, color_mode); + + drm_client_setup_with_fourcc(dev, fourcc); +} +EXPORT_SYMBOL(drm_client_setup_with_color_mode); diff --git a/include/drm/drm_client_setup.h b/include/drm/drm_client_setup.h new file mode 100644 index 000000000000..46aab3fb46be --- /dev/null +++ b/include/drm/drm_client_setup.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_CLIENT_SETUP_H +#define DRM_CLIENT_SETUP_H + +#include <linux/types.h> + +struct drm_device; +struct drm_format_info; + +#if defined(CONFIG_DRM_CLIENT_SETUP) +void drm_client_setup(struct drm_device *dev, const struct drm_format_info *format); +void drm_client_setup_with_fourcc(struct drm_device *dev, u32 fourcc); +void drm_client_setup_with_color_mode(struct drm_device *dev, unsigned int color_mode); +#else +static inline void drm_client_setup(struct drm_device *dev, + const struct drm_format_info *format) +{ } +static inline void drm_client_setup_with_fourcc(struct drm_device *dev, u32 fourcc) +{ } +static inline void drm_client_setup_with_color_mode(struct drm_device *dev, + unsigned int color_mode) +{ } +#endif + +#endif -- GitLab From 8998eedda2539d2528cfebdc7c17eed0ad35b714 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:03 +0200 Subject: [PATCH 346/970] drm/fbdev-dma: Support struct drm_driver.fbdev_probe Rework fbdev probing to support fbdev_probe in struct drm_driver and reimplement the old fb_probe callback on top of it. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. This change allows the common fbdev client to run on top of DMA- based DRM drivers. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-6-tzimmermann@suse.de --- drivers/gpu/drm/drm_fbdev_dma.c | 60 ++++++++++++++++++++------------- include/drm/drm_fbdev_dma.h | 12 +++++++ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index b0602c4f3628..9ce754ebe18e 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -104,6 +104,40 @@ static const struct fb_ops drm_fbdev_dma_deferred_fb_ops = { static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) +{ + return drm_fbdev_dma_driver_fbdev_probe(fb_helper, sizes); +} + +static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + +static const struct drm_fb_helper_funcs drm_fbdev_dma_helper_funcs = { + .fb_probe = drm_fbdev_dma_helper_fb_probe, + .fb_dirty = drm_fbdev_dma_helper_fb_dirty, +}; + +/* + * struct drm_fb_helper + */ + +int drm_fbdev_dma_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_client_dev *client = &fb_helper->client; struct drm_device *dev = fb_helper->dev; @@ -147,6 +181,7 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, goto err_drm_client_buffer_delete; } + fb_helper->funcs = &drm_fbdev_dma_helper_funcs; fb_helper->buffer = buffer; fb_helper->fb = fb; @@ -210,30 +245,7 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, drm_client_framebuffer_delete(buffer); return ret; } - -static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper, - struct drm_clip_rect *clip) -{ - struct drm_device *dev = helper->dev; - int ret; - - /* Call damage handlers only if necessary */ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->fb->funcs->dirty) { - ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) - return ret; - } - - return 0; -} - -static const struct drm_fb_helper_funcs drm_fbdev_dma_helper_funcs = { - .fb_probe = drm_fbdev_dma_helper_fb_probe, - .fb_dirty = drm_fbdev_dma_helper_fb_dirty, -}; +EXPORT_SYMBOL(drm_fbdev_dma_driver_fbdev_probe); /* * struct drm_client_funcs diff --git a/include/drm/drm_fbdev_dma.h b/include/drm/drm_fbdev_dma.h index 2da7ee784133..6ae4de46497c 100644 --- a/include/drm/drm_fbdev_dma.h +++ b/include/drm/drm_fbdev_dma.h @@ -4,12 +4,24 @@ #define DRM_FBDEV_DMA_H struct drm_device; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; #ifdef CONFIG_DRM_FBDEV_EMULATION +int drm_fbdev_dma_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes); + +#define DRM_FBDEV_DMA_DRIVER_OPS \ + .fbdev_probe = drm_fbdev_dma_driver_fbdev_probe + void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp); #else static inline void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp) { } + +#define DRM_FBDEV_DMA_DRIVER_OPS \ + .fbdev_probe = NULL + #endif #endif -- GitLab From 68146a681dd426ea1aaaa7dff2109bff13bad1a9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:04 +0200 Subject: [PATCH 347/970] drm/arcgpu: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alexey Brodkin <abrodkin@synopsys.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-7-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/arcpgu.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 8f206c6387ec..750616a8ee05 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -3,6 +3,7 @@ config DRM_ARCPGU tristate "ARC PGU" depends on DRM && OF + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER help diff --git a/drivers/gpu/drm/tiny/arcpgu.c b/drivers/gpu/drm/tiny/arcpgu.c index 4f8f3172379e..81abedec435d 100644 --- a/drivers/gpu/drm/tiny/arcpgu.c +++ b/drivers/gpu/drm/tiny/arcpgu.c @@ -7,6 +7,7 @@ #include <linux/clk.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_debugfs.h> #include <drm/drm_device.h> #include <drm/drm_drv.h> @@ -371,6 +372,7 @@ static const struct drm_driver arcpgu_drm_driver = { .patchlevel = 0, .fops = &arcpgu_drm_ops, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, #ifdef CONFIG_DEBUG_FS .debugfs_init = arcpgu_debugfs_init, #endif @@ -394,7 +396,7 @@ static int arcpgu_probe(struct platform_device *pdev) if (ret) goto err_unload; - drm_fbdev_dma_setup(&arcpgu->drm, 16); + drm_client_setup_with_fourcc(&arcpgu->drm, DRM_FORMAT_RGB565); return 0; -- GitLab From dd5891e7a4099eac2490794af232f9a683e43875 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:05 +0200 Subject: [PATCH 348/970] drm/arm/komeda: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The komeda driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Liviu Dudau <liviu.dudau@arm.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-8-tzimmermann@suse.de --- drivers/gpu/drm/arm/display/Kconfig | 1 + drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 4 ++-- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/arm/display/Kconfig b/drivers/gpu/drm/arm/display/Kconfig index 4acc4285a4eb..415c10a6374b 100644 --- a/drivers/gpu/drm/arm/display/Kconfig +++ b/drivers/gpu/drm/arm/display/Kconfig @@ -3,6 +3,7 @@ config DRM_KOMEDA tristate "ARM Komeda display driver" depends on DRM && OF depends on COMMON_CLK + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select VIDEOMODE_HELPERS diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c index 55c3773befde..6d475bb34002 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -9,7 +9,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drm_fbdev_dma.h> +#include <drm/drm_client_setup.h> #include <drm/drm_module.h> #include <drm/drm_of.h> #include "komeda_dev.h" @@ -84,7 +84,7 @@ static int komeda_platform_probe(struct platform_device *pdev) } dev_set_drvdata(dev, mdrv); - drm_fbdev_dma_setup(&mdrv->kms->base, 32); + drm_client_setup(&mdrv->kms->base, NULL); return 0; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index e5eb5d672bcd..1e7b1fcb2848 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -9,6 +9,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_managed.h> @@ -58,6 +59,7 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data) static const struct drm_driver komeda_kms_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(komeda_gem_dma_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &komeda_cma_fops, .name = "komeda", .desc = "Arm Komeda Display Processor driver", -- GitLab From 34d99a5e278750bb91f653f3dadccd9feef0778b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:06 +0200 Subject: [PATCH 349/970] drm/arm/hdlcd: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The hdlcd driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Liviu Dudau <liviu.dudau@arm.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-9-tzimmermann@suse.de --- drivers/gpu/drm/arm/Kconfig | 1 + drivers/gpu/drm/arm/hdlcd_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig index ddf20708370f..ed218e5f7901 100644 --- a/drivers/gpu/drm/arm/Kconfig +++ b/drivers/gpu/drm/arm/Kconfig @@ -6,6 +6,7 @@ config DRM_HDLCD tristate "ARM HDLCD" depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST) depends on COMMON_CLK + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER help diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 32be9e370049..f5d358f3893b 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -23,6 +23,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_crtc.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> @@ -228,6 +229,7 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver hdlcd_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &fops, .name = "hdlcd", .desc = "ARM HDLCD Controller DRM", @@ -299,7 +301,7 @@ static int hdlcd_drm_bind(struct device *dev) if (ret) goto err_register; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From fcbcf29993abeda4151bc136ba0ca784dd76954d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:07 +0200 Subject: [PATCH 350/970] drm/arm/malidp: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The malidp driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Liviu Dudau <liviu.dudau@arm.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-10-tzimmermann@suse.de --- drivers/gpu/drm/arm/Kconfig | 1 + drivers/gpu/drm/arm/malidp_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig index ed218e5f7901..c901ac00c0c3 100644 --- a/drivers/gpu/drm/arm/Kconfig +++ b/drivers/gpu/drm/arm/Kconfig @@ -28,6 +28,7 @@ config DRM_MALI_DISPLAY tristate "ARM Mali Display Processor" depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST) depends on COMMON_CLK + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select VIDEOMODE_HELPERS diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index 6682131d2910..4cb25004b84f 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c @@ -18,6 +18,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_crtc.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -562,6 +563,7 @@ static void malidp_debugfs_init(struct drm_minor *minor) static const struct drm_driver malidp_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(malidp_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, #ifdef CONFIG_DEBUG_FS .debugfs_init = malidp_debugfs_init, #endif @@ -852,7 +854,7 @@ static int malidp_bind(struct device *dev) if (ret) goto register_fail; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From 1a4d815f5c870f6a357f4c1ce46c63748a82b825 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:08 +0200 Subject: [PATCH 351/970] drm/aspeed: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The aspeed driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION v3: - add DRM_FBDEV_DMA_DRIVER_OPS macro Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Joel Stanley <joel@jms.id.au> Cc: Andrew Jeffery <andrew@codeconstruct.com.au> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-11-tzimmermann@suse.de --- drivers/gpu/drm/aspeed/Kconfig | 1 + drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/aspeed/Kconfig b/drivers/gpu/drm/aspeed/Kconfig index 8137c39b057b..6e68f20aac21 100644 --- a/drivers/gpu/drm/aspeed/Kconfig +++ b/drivers/gpu/drm/aspeed/Kconfig @@ -4,6 +4,7 @@ config DRM_ASPEED_GFX depends on DRM && OF depends on (COMPILE_TEST || ARCH_ASPEED) depends on MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DMA_CMA if HAVE_DMA_CONTIGUOUS diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index a7a6b70220eb..109023815fa2 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -14,6 +14,7 @@ #include <linux/reset.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_device.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -247,6 +248,7 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver aspeed_gfx_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &fops, .name = "aspeed-gfx-drm", .desc = "ASPEED GFX DRM", @@ -339,7 +341,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev) if (ret) goto err_unload; - drm_fbdev_dma_setup(&priv->drm, 32); + drm_client_setup(&priv->drm, NULL); return 0; err_unload: -- GitLab From 5db4f4b3e342da43164661d509d05e07eff18936 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:09 +0200 Subject: [PATCH 352/970] drm/atmel-hdlcd: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v3: - add DRM_FBDEV_DMA_DRIVER_OPS macro (Sam) v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Boris Brezillon <bbrezillon@kernel.org> Cc: Nicolas Ferre <nicolas.ferre@microchip.com> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev> Acked-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-12-tzimmermann@suse.de --- drivers/gpu/drm/atmel-hlcdc/Kconfig | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/Kconfig b/drivers/gpu/drm/atmel-hlcdc/Kconfig index 945f3aa7bb24..f8b9c91907d8 100644 --- a/drivers/gpu/drm/atmel-hlcdc/Kconfig +++ b/drivers/gpu/drm/atmel-hlcdc/Kconfig @@ -2,6 +2,7 @@ config DRM_ATMEL_HLCDC tristate "DRM Support for ATMEL HLCDC Display Controller" depends on DRM && OF && COMMON_CLK && ((MFD_ATMEL_HLCDC && ARM) || COMPILE_TEST) + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_PANEL diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 9ce429f889ca..792dcc19e8e7 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -18,8 +18,10 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> @@ -840,6 +842,7 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver atmel_hlcdc_dc_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &fops, .name = "atmel-hlcdc", .desc = "Atmel HLCD Controller DRM", @@ -865,7 +868,7 @@ static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev) if (ret) goto err_unload; - drm_fbdev_dma_setup(ddev, 24); + drm_client_setup_with_fourcc(ddev, DRM_FORMAT_RGB888); return 0; -- GitLab From 15d5e4d4da306fff298b78fb50fd1d3c2b134878 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:10 +0200 Subject: [PATCH 353/970] drm/fsl-dcu: Run DRM default client setup Call drm_client_setup_with_color_mode() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Stefan Agner <stefan@agner.ch> Cc: Alison Wang <alison.wang@nxp.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-13-tzimmermann@suse.de --- drivers/gpu/drm/fsl-dcu/Kconfig | 1 + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig index 5ca71ef87325..588ce2420af2 100644 --- a/drivers/gpu/drm/fsl-dcu/Kconfig +++ b/drivers/gpu/drm/fsl-dcu/Kconfig @@ -3,6 +3,7 @@ config DRM_FSL_DCU tristate "DRM Support for Freescale DCU" depends on DRM && OF && ARM && COMMON_CLK select BACKLIGHT_CLASS_DEVICE + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_PANEL diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index ab6c0c6cd0e2..2b3f15f0dc56 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -19,6 +19,7 @@ #include <linux/regmap.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -156,6 +157,7 @@ static const struct drm_driver fsl_dcu_drm_driver = { .load = fsl_dcu_load, .unload = fsl_dcu_unload, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &fsl_dcu_drm_fops, .name = "fsl-dcu-drm", .desc = "Freescale DCU DRM", @@ -333,7 +335,7 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) if (ret < 0) goto put; - drm_fbdev_dma_setup(drm, legacyfb_depth); + drm_client_setup_with_color_mode(drm, legacyfb_depth); return 0; -- GitLab From 21f71431892da02e7ce2dea3511b2bfb64d1d496 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:11 +0200 Subject: [PATCH 354/970] drm/hisilicon/kirin: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The kirin driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Xinliang Liu <xinliang.liu@linaro.org> Cc: Tian Tao <tiantao6@hisilicon.com> Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: Yongqin Liu <yongqin.liu@linaro.org> Cc: John Stultz <jstultz@google.com> Acked-by: John Stultz <jstultz@google.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-14-tzimmermann@suse.de --- drivers/gpu/drm/hisilicon/kirin/Kconfig | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 ++ drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/Kconfig b/drivers/gpu/drm/hisilicon/kirin/Kconfig index 0772f79567ef..43e8a4fd2d11 100644 --- a/drivers/gpu/drm/hisilicon/kirin/Kconfig +++ b/drivers/gpu/drm/hisilicon/kirin/Kconfig @@ -2,6 +2,7 @@ config DRM_HISI_KIRIN tristate "DRM Support for Hisilicon Kirin series SoCs Platform" depends on DRM && OF && (ARM64 || COMPILE_TEST) + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DSI diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index 871f79a6b17e..5616c3917c03 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -25,6 +25,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> +#include <drm/drm_fbdev_dma.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_dma_helper.h> @@ -925,6 +926,7 @@ static const struct drm_driver ade_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &ade_fops, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "kirin", .desc = "Hisilicon Kirin620 SoC DRM Driver", .date = "20150718", diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 12666985686b..86a3a1faff49 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -18,8 +18,8 @@ #include <linux/platform_device.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> -#include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> @@ -237,7 +237,7 @@ static int kirin_drm_bind(struct device *dev) if (ret) goto err_kms_cleanup; - drm_fbdev_dma_setup(drm_dev, 32); + drm_client_setup(drm_dev, NULL); return 0; -- GitLab From 2e430d7a67045caf86d82a7d3344a8e6e16dd867 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:12 +0200 Subject: [PATCH 355/970] drm/hx8357d: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-15-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/hx8357d.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 750616a8ee05..5e0dd0dfc55f 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -98,6 +98,7 @@ config DRM_SIMPLEDRM config TINYDRM_HX8357D tristate "DRM support for HX8357D display panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c index 2e631282edeb..6b0d1846cfcf 100644 --- a/drivers/gpu/drm/tiny/hx8357d.c +++ b/drivers/gpu/drm/tiny/hx8357d.c @@ -17,6 +17,7 @@ #include <linux/spi/spi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -194,6 +195,7 @@ static const struct drm_driver hx8357d_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &hx8357d_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "hx8357d", .desc = "HX8357D", @@ -256,7 +258,7 @@ static int hx8357d_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From e7f1082dccb9ccaddc986dda0585855194538f7d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:13 +0200 Subject: [PATCH 356/970] drm/ili9163: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-16-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/ili9163.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 5e0dd0dfc55f..f666aa6ae2ed 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -113,6 +113,7 @@ config TINYDRM_ILI9163 tristate "DRM support for ILI9163 display panels" depends on DRM && SPI select BACKLIGHT_CLASS_DEVICE + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c index 86f9d8834901..5eb39ca1a855 100644 --- a/drivers/gpu/drm/tiny/ili9163.c +++ b/drivers/gpu/drm/tiny/ili9163.c @@ -8,6 +8,7 @@ #include <linux/spi/spi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -113,6 +114,7 @@ static struct drm_driver ili9163_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &ili9163_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "ili9163", .desc = "Ilitek ILI9163", @@ -185,7 +187,7 @@ static int ili9163_probe(struct spi_device *spi) if (ret) return ret; - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 00855c607b3a547845346571cf692d021ca71f62 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:14 +0200 Subject: [PATCH 357/970] drm/ili9225: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Lechner <david@lechnology.com> Acked-by: David Lechner <david@lechnology.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-17-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/ili9225.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index f666aa6ae2ed..b16bd3a2ebdf 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -126,6 +126,7 @@ config TINYDRM_ILI9163 config TINYDRM_ILI9225 tristate "DRM support for ILI9225 display panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c index b6b7a49147bf..875e2d09729a 100644 --- a/drivers/gpu/drm/tiny/ili9225.c +++ b/drivers/gpu/drm/tiny/ili9225.c @@ -17,6 +17,7 @@ #include <video/mipi_display.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> @@ -360,6 +361,7 @@ static const struct drm_driver ili9225_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &ili9225_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "ili9225", .desc = "Ilitek ILI9225", .date = "20171106", @@ -426,7 +428,7 @@ static int ili9225_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From df0cc9eaff170edf294cc6c6c46caf9e0946b515 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:15 +0200 Subject: [PATCH 358/970] drm/ili9341: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-18-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/ili9341.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index b16bd3a2ebdf..337ac65390c6 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -139,6 +139,7 @@ config TINYDRM_ILI9225 config TINYDRM_ILI9341 tristate "DRM support for ILI9341 display panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c index 8bcada30af71..c1dfdfbbd30c 100644 --- a/drivers/gpu/drm/tiny/ili9341.c +++ b/drivers/gpu/drm/tiny/ili9341.c @@ -16,6 +16,7 @@ #include <linux/spi/spi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -150,6 +151,7 @@ static const struct drm_driver ili9341_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &ili9341_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "ili9341", .desc = "Ilitek ILI9341", @@ -218,7 +220,7 @@ static int ili9341_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 6b2d3bc3e2e130c47807b7be0ea59499f2224172 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:16 +0200 Subject: [PATCH 359/970] drm/ili9486: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Kamlesh Gurudasani <kamlesh.gurudasani@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-19-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/ili9486.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 337ac65390c6..7ee887b55aee 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -153,6 +153,7 @@ config TINYDRM_ILI9341 config TINYDRM_ILI9486 tristate "DRM support for ILI9486 display panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index 70d366260041..7e46a720d5e2 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -15,6 +15,7 @@ #include <video/mipi_display.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -172,6 +173,7 @@ static const struct drm_driver ili9486_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &ili9486_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "ili9486", .desc = "Ilitek ILI9486", @@ -247,7 +249,7 @@ static int ili9486_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From a5f72909ccc6004c4c4d0b422d67c7c740411a62 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:17 +0200 Subject: [PATCH 360/970] drm/imx/dcss: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The dcss driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> Cc: Lucas Stach <l.stach@pengutronix.de> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-20-tzimmermann@suse.de --- drivers/gpu/drm/imx/dcss/Kconfig | 1 + drivers/gpu/drm/imx/dcss/dcss-kms.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/dcss/Kconfig b/drivers/gpu/drm/imx/dcss/Kconfig index 59e3b6a1dff0..9d58f41bd00c 100644 --- a/drivers/gpu/drm/imx/dcss/Kconfig +++ b/drivers/gpu/drm/imx/dcss/Kconfig @@ -1,6 +1,7 @@ config DRM_IMX_DCSS tristate "i.MX8MQ DCSS" select IMX_IRQSTEER + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index d0ea4e97cded..3ec721afc30c 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -6,6 +6,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge_connector.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -28,6 +29,7 @@ static const struct drm_mode_config_funcs dcss_drm_mode_config_funcs = { static const struct drm_driver dcss_kms_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &dcss_cma_fops, .name = "imx-dcss", .desc = "i.MX8MQ Display Subsystem", @@ -145,7 +147,7 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss) if (ret) goto cleanup_crtc; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return kms; -- GitLab From 4aeef9938961150e24f2c03042d3d23ca9534fc6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:18 +0200 Subject: [PATCH 361/970] drm/imx/ipuv3: Run DRM default client setup Call drm_client_setup_with_color_mode() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Philipp Zabel <p.zabel@pengutronix.de> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-21-tzimmermann@suse.de --- drivers/gpu/drm/imx/ipuv3/Kconfig | 1 + drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig index 990e216c51cc..0ea1feb84672 100644 --- a/drivers/gpu/drm/imx/ipuv3/Kconfig +++ b/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config DRM_IMX tristate "DRM Support for Freescale i.MX" + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select VIDEOMODE_HELPERS select DRM_GEM_DMA_HELPER diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c index 189d395349b8..ced06bd8eae8 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c @@ -15,6 +15,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -156,6 +157,7 @@ static int imx_drm_dumb_create(struct drm_file *file_priv, static const struct drm_driver imx_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(imx_drm_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, .ioctls = imx_drm_ioctls, .num_ioctls = ARRAY_SIZE(imx_drm_ioctls), .fops = &imx_drm_driver_fops, @@ -242,7 +244,7 @@ static int imx_drm_bind(struct device *dev) if (ret) goto err_poll_fini; - drm_fbdev_dma_setup(drm, legacyfb_depth); + drm_client_setup_with_color_mode(drm, legacyfb_depth); return 0; -- GitLab From b9a14d54ab2bf0c09409f373a2120de65046178a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:19 +0200 Subject: [PATCH 362/970] drm/imx/lcdc: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-22-tzimmermann@suse.de --- drivers/gpu/drm/imx/lcdc/Kconfig | 1 + drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/lcdc/Kconfig b/drivers/gpu/drm/imx/lcdc/Kconfig index 9c28bb0f4662..75869489b0e6 100644 --- a/drivers/gpu/drm/imx/lcdc/Kconfig +++ b/drivers/gpu/drm/imx/lcdc/Kconfig @@ -1,6 +1,7 @@ config DRM_IMX_LCDC tristate "Freescale i.MX LCDC displays" depends on DRM && (ARCH_MXC || COMPILE_TEST) + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c index 36668455aee8..3215c4acd675 100644 --- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c @@ -3,6 +3,7 @@ #include <drm/drm_bridge.h> #include <drm/drm_bridge_connector.h> +#include <drm/drm_client_setup.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -348,6 +349,7 @@ static struct drm_driver imx_lcdc_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &imx_lcdc_drm_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "imx-lcdc", .desc = "i.MX LCDC driver", .date = "20200716", @@ -501,7 +503,7 @@ static int imx_lcdc_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "Cannot register device\n"); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From becaf035b0b33759f0e35e008bde255b46e40d87 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:20 +0200 Subject: [PATCH 363/970] drm/ingenic: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The ingenic driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Paul Cercueil <paul@crapouillou.net> Acked-by: Paul Cercueil <paul@crapouillou.net> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-23-tzimmermann@suse.de --- drivers/gpu/drm/ingenic/Kconfig | 1 + drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ingenic/Kconfig b/drivers/gpu/drm/ingenic/Kconfig index 8cd7b750dffe..04ecfb0c5dd6 100644 --- a/drivers/gpu/drm/ingenic/Kconfig +++ b/drivers/gpu/drm/ingenic/Kconfig @@ -6,6 +6,7 @@ config DRM_INGENIC depends on OF depends on COMMON_CLK select DRM_BRIDGE + select DRM_CLIENT_SELECTION select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 39fa291f43dd..056b70b63554 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -24,6 +24,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_bridge_connector.h> +#include <drm/drm_client_setup.h> #include <drm/drm_color_mgmt.h> #include <drm/drm_crtc.h> #include <drm/drm_damage_helper.h> @@ -960,6 +961,7 @@ static const struct drm_driver ingenic_drm_driver_data = { .fops = &ingenic_drm_fops, .gem_create_object = ingenic_drm_gem_create_object, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, }; static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = { @@ -1399,7 +1401,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) goto err_clk_notifier_unregister; } - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From 56e3fd4e543077616ace028c72c585b8c1120d7a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:21 +0200 Subject: [PATCH 364/970] drm/kmb: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Anitha Chrisanthus <anitha.chrisanthus@intel.com> Cc: Edmund Dea <edmund.j.dea@intel.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-24-tzimmermann@suse.de --- drivers/gpu/drm/kmb/Kconfig | 1 + drivers/gpu/drm/kmb/kmb_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/kmb/Kconfig b/drivers/gpu/drm/kmb/Kconfig index e5ae3ec52392..7a2aa892a957 100644 --- a/drivers/gpu/drm/kmb/Kconfig +++ b/drivers/gpu/drm/kmb/Kconfig @@ -2,6 +2,7 @@ config DRM_KMB_DISPLAY tristate "Intel Keembay Display" depends on DRM depends on ARCH_KEEMBAY || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c index 169b83987ce2..0274ab9caa85 100644 --- a/drivers/gpu/drm/kmb/kmb_drv.c +++ b/drivers/gpu/drm/kmb/kmb_drv.c @@ -14,6 +14,7 @@ #include <linux/regmap.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -441,6 +442,7 @@ static const struct drm_driver kmb_driver = { /* GEM Operations */ .fops = &fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "kmb-drm", .desc = "KEEMBAY DISPLAY DRIVER", .date = DRIVER_DATE, @@ -561,7 +563,7 @@ static int kmb_probe(struct platform_device *pdev) if (ret) goto err_register; - drm_fbdev_dma_setup(&kmb->drm, 0); + drm_client_setup(&kmb->drm, NULL); return 0; -- GitLab From ba79ba18fe37ff9345e6fbdd529da3689e930ef1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:22 +0200 Subject: [PATCH 365/970] drm/logicvc: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The logicvc driver specifies a preferred color mode from the value in struct drm_mode_config.preferred_depth. The fbdev client also looks at this value for the default pixel format. Thus remove the format selection from logicvc. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Paul Kocialkowski <paul.kocialkowski@bootlin.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-25-tzimmermann@suse.de --- drivers/gpu/drm/logicvc/Kconfig | 1 + drivers/gpu/drm/logicvc/logicvc_drm.c | 16 ++++------------ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/logicvc/Kconfig b/drivers/gpu/drm/logicvc/Kconfig index 1df22a852a23..579a358ed5cf 100644 --- a/drivers/gpu/drm/logicvc/Kconfig +++ b/drivers/gpu/drm/logicvc/Kconfig @@ -2,6 +2,7 @@ config DRM_LOGICVC tristate "LogiCVC DRM" depends on DRM depends on OF || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_KMS_DMA_HELPER select DRM_GEM_DMA_HELPER diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c index 01a37e28c080..e4d90701b29d 100644 --- a/drivers/gpu/drm/logicvc/logicvc_drm.c +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c @@ -16,8 +16,10 @@ #include <linux/types.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_print.h> @@ -55,6 +57,7 @@ static struct drm_driver logicvc_drm_driver = { .minor = 0, DRM_GEM_DMA_DRIVER_OPS_VMAP_WITH_DUMB_CREATE(logicvc_drm_gem_dma_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, }; static struct regmap_config logicvc_drm_regmap_config = { @@ -301,7 +304,6 @@ static int logicvc_drm_probe(struct platform_device *pdev) struct regmap *regmap = NULL; struct resource res; void __iomem *base; - unsigned int preferred_bpp; int irq; int ret; @@ -439,17 +441,7 @@ static int logicvc_drm_probe(struct platform_device *pdev) goto error_mode; } - switch (drm_dev->mode_config.preferred_depth) { - case 16: - preferred_bpp = 16; - break; - case 24: - case 32: - default: - preferred_bpp = 32; - break; - } - drm_fbdev_dma_setup(drm_dev, preferred_bpp); + drm_client_setup(drm_dev, NULL); return 0; -- GitLab From 8545a6f5d65d2bc11a1396acfae1fc229261df91 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:23 +0200 Subject: [PATCH 366/970] drm/mcde: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The mcde driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Linus Walleij <linus.walleij@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-26-tzimmermann@suse.de --- drivers/gpu/drm/mcde/Kconfig | 1 + drivers/gpu/drm/mcde/mcde_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mcde/Kconfig b/drivers/gpu/drm/mcde/Kconfig index 907460b69d4f..3516c8d2a5d9 100644 --- a/drivers/gpu/drm/mcde/Kconfig +++ b/drivers/gpu/drm/mcde/Kconfig @@ -6,6 +6,7 @@ config DRM_MCDE depends on OF depends on COMMON_CLK select MFD_SYSCON + select DRM_CLIENT_SELECTION select DRM_MIPI_DSI select DRM_BRIDGE select DRM_PANEL_BRIDGE diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c index f1bb38f4e673..f60bdd7b6c13 100644 --- a/drivers/gpu/drm/mcde/mcde_drv.c +++ b/drivers/gpu/drm/mcde/mcde_drv.c @@ -67,6 +67,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> #include <drm/drm_fbdev_dma.h> @@ -212,6 +213,7 @@ static const struct drm_driver mcde_drm_driver = { .minor = 0, .patchlevel = 0, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, }; static int mcde_drm_bind(struct device *dev) @@ -237,7 +239,7 @@ static int mcde_drm_bind(struct device *dev) if (ret < 0) goto unbind; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From 6dc1f816f793dfedd97c4f75838883e46cb596d7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:24 +0200 Subject: [PATCH 367/970] drm/mediatek: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The mediatek driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Chun-KuaIng Hu <chunkuang.hu@kernel.org> Cc: Philipp Zabel <p.zabel@pengutronix.de> Cc: Matthias Brugger <matthias.bgg@gmail.com> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-27-tzimmermann@suse.de --- drivers/gpu/drm/mediatek/Kconfig | 1 + drivers/gpu/drm/mediatek/mtk_drm_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig index 417ac8c9af41..3d2436272ff2 100644 --- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig @@ -7,6 +7,7 @@ config DRM_MEDIATEK depends on HAVE_ARM_SMCCC depends on OF depends on MTK_MMSYS + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER if DRM_FBDEV_EMULATION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 77b50c56c124..b1309a70fdcd 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -14,6 +14,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_fourcc.h> @@ -610,6 +611,7 @@ static const struct drm_driver mtk_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, .dumb_create = mtk_gem_dumb_create, + DRM_FBDEV_DMA_DRIVER_OPS, .gem_prime_import = mtk_gem_prime_import, .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, @@ -666,7 +668,7 @@ static int mtk_drm_bind(struct device *dev) if (ret < 0) goto err_deinit; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From 57a03512c49a2e3136d7dcc36bcb2074c749fcdd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:25 +0200 Subject: [PATCH 368/970] drm/meson: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The meson driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Neil Armstrong <neil.armstrong@linaro.org> Cc: Kevin Hilman <khilman@baylibre.com> Cc: Jerome Brunet <jbrunet@baylibre.com> Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-28-tzimmermann@suse.de --- drivers/gpu/drm/meson/Kconfig | 1 + drivers/gpu/drm/meson/meson_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index 2544756538cc..b410e0d8015a 100644 --- a/drivers/gpu/drm/meson/Kconfig +++ b/drivers/gpu/drm/meson/Kconfig @@ -3,6 +3,7 @@ config DRM_MESON tristate "DRM Support for Amlogic Meson Display Controller" depends on DRM && OF && (ARM || ARM64) depends on ARCH_MESON || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 4bd0baa2a4f5..2f76f48da38d 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -17,6 +17,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -98,6 +99,7 @@ static const struct drm_driver meson_driver = { /* DMA Ops */ DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(meson_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, /* Misc */ .fops = &fops, @@ -353,7 +355,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (ret) goto uninstall_irq; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From c58fde06563f8af94ae50662453bbbf8fdf9e9e2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:26 +0200 Subject: [PATCH 369/970] drm/mi0283qt: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: "Noralf Trønnes" <noralf@tronnes.org> Acked-by: Noralf Trønnes <noralf@tronnes.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-29-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/mi0283qt.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 7ee887b55aee..17e0160b05ac 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -168,6 +168,7 @@ config TINYDRM_ILI9486 config TINYDRM_MI0283QT tristate "DRM support for MI0283QT" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c index cdc5423990ca..f1461c55dba6 100644 --- a/drivers/gpu/drm/tiny/mi0283qt.c +++ b/drivers/gpu/drm/tiny/mi0283qt.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -154,6 +155,7 @@ static const struct drm_driver mi0283qt_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &mi0283qt_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "mi0283qt", .desc = "Multi-Inno MI0283QT", @@ -226,7 +228,7 @@ static int mi0283qt_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 04d131d83c73388a1b62232e1f0ebace69d4dbc8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:27 +0200 Subject: [PATCH 370/970] drm/mxsfb/lcdif: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The lcdif driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Marek Vasut <marex@denx.de> Cc: Stefan Agner <stefan@agner.ch> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-30-tzimmermann@suse.de --- drivers/gpu/drm/mxsfb/Kconfig | 1 + drivers/gpu/drm/mxsfb/lcdif_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig index 518b53345354..ac368c20a0fe 100644 --- a/drivers/gpu/drm/mxsfb/Kconfig +++ b/drivers/gpu/drm/mxsfb/Kconfig @@ -26,6 +26,7 @@ config DRM_IMX_LCDIF depends on DRM && OF depends on COMMON_CLK depends on ARCH_MXC || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_MXS select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdif_drv.c index 0f895b8a99d6..58ccad9c425d 100644 --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c @@ -16,6 +16,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_encoder.h> #include <drm/drm_fbdev_dma.h> @@ -243,6 +244,7 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver lcdif_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &fops, .name = "imx-lcdif", .desc = "i.MX LCDIF Controller DRM", @@ -275,7 +277,7 @@ static int lcdif_probe(struct platform_device *pdev) if (ret) goto err_unload; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From 1dacbdb159a15fdf0fc299e8f7aefa77e15bcf77 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:28 +0200 Subject: [PATCH 371/970] drm/mxsfb: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The mxsfb driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION v3: - fix driver name "msxfb" to "mxsfb" Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Marek Vasut <marex@denx.de> Cc: Stefan Agner <stefan@agner.ch> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Pengutronix Kernel Team <kernel@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-31-tzimmermann@suse.de --- drivers/gpu/drm/mxsfb/Kconfig | 1 + drivers/gpu/drm/mxsfb/mxsfb_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig index ac368c20a0fe..264e74f45554 100644 --- a/drivers/gpu/drm/mxsfb/Kconfig +++ b/drivers/gpu/drm/mxsfb/Kconfig @@ -9,6 +9,7 @@ config DRM_MXSFB depends on DRM && OF depends on COMMON_CLK depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_MXS select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index cb5ce4e81fc7..34a98717b72c 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -19,6 +19,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -331,6 +332,7 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver mxsfb_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &fops, .name = "mxsfb-drm", .desc = "MXSFB Controller DRM", @@ -364,7 +366,7 @@ static int mxsfb_probe(struct platform_device *pdev) if (ret) goto err_unload; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; -- GitLab From 1b0caa5f5ac20bcaf82fc89a5c849b21ce3bfdf6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:29 +0200 Subject: [PATCH 372/970] drm/panel-mipi-dbi: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: "Noralf Trønnes" <noralf@tronnes.org> Acked-by: Noralf Trønnes <noralf@tronnes.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-32-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/panel-mipi-dbi.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 17e0160b05ac..98af6fd6aa70 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -66,6 +66,7 @@ config DRM_OFDRM config DRM_PANEL_MIPI_DBI tristate "DRM support for MIPI DBI compatible panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c index f753cdffe6f8..e66729b31bd6 100644 --- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c @@ -15,6 +15,7 @@ #include <linux/spi/spi.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -264,6 +265,7 @@ static const struct drm_driver panel_mipi_dbi_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &panel_mipi_dbi_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "panel-mipi-dbi", .desc = "MIPI DBI compatible display panel", @@ -388,7 +390,7 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From d8c7ca410bdad03cd7a4897cd86bd82f1771d168 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:30 +0200 Subject: [PATCH 373/970] drm/pl111: Run DRM default client setup Call drm_client_setup_with_color_mode() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-33-tzimmermann@suse.de --- drivers/gpu/drm/pl111/Kconfig | 1 + drivers/gpu/drm/pl111/pl111_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig index 20fe1d2c0aaf..82e918820950 100644 --- a/drivers/gpu/drm/pl111/Kconfig +++ b/drivers/gpu/drm/pl111/Kconfig @@ -5,6 +5,7 @@ config DRM_PL111 depends on ARM || ARM64 || COMPILE_TEST depends on VEXPRESS_CONFIG || VEXPRESS_CONFIG=n depends on COMMON_CLK + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_BRIDGE diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 02e6b74d5016..13362150b9c6 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -47,6 +47,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_fourcc.h> @@ -225,6 +226,7 @@ static const struct drm_driver pl111_drm_driver = { .patchlevel = 0, .dumb_create = drm_gem_dma_dumb_create, .gem_prime_import_sg_table = pl111_gem_import_sg_table, + DRM_FBDEV_DMA_DRIVER_OPS, #if defined(CONFIG_DEBUG_FS) .debugfs_init = pl111_debugfs_init, @@ -305,7 +307,7 @@ static int pl111_amba_probe(struct amba_device *amba_dev, if (ret < 0) goto dev_put; - drm_fbdev_dma_setup(drm, priv->variant->fb_depth); + drm_client_setup_with_color_mode(drm, priv->variant->fb_depth); return 0; -- GitLab From f214aa79b2a29d65fe53457560a1f7b401fef655 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:31 +0200 Subject: [PATCH 374/970] drm/renesas/rcar-du: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The rcar-du driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-34-tzimmermann@suse.de --- drivers/gpu/drm/renesas/rcar-du/Kconfig | 1 + drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/renesas/rcar-du/Kconfig b/drivers/gpu/drm/renesas/rcar-du/Kconfig index e1f41468a9a6..840305fdeb49 100644 --- a/drivers/gpu/drm/renesas/rcar-du/Kconfig +++ b/drivers/gpu/drm/renesas/rcar-du/Kconfig @@ -4,6 +4,7 @@ config DRM_RCAR_DU depends on DRM && OF depends on ARM || ARM64 || COMPILE_TEST depends on ARCH_RENESAS || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c index fb719d9aff10..4e0bafc86f50 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c @@ -19,6 +19,7 @@ #include <linux/wait.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -606,6 +607,7 @@ static const struct drm_driver rcar_du_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .dumb_create = rcar_du_dumb_create, .gem_prime_import_sg_table = rcar_du_gem_prime_import_sg_table, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &rcar_du_fops, .name = "rcar-du", .desc = "Renesas R-Car Display Unit", @@ -716,7 +718,7 @@ static int rcar_du_probe(struct platform_device *pdev) drm_info(&rcdu->ddev, "Device %s probed\n", dev_name(&pdev->dev)); - drm_fbdev_dma_setup(&rcdu->ddev, 32); + drm_client_setup(&rcdu->ddev, NULL); return 0; -- GitLab From f75b3903af32aa557422d0b37d82a6202c2be813 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:32 +0200 Subject: [PATCH 375/970] drm/renesas/rz-du: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The rz-du driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Biju Das <biju.das.jz@bp.renesas.com> Tested-by: Biju Das <biju.das.jz@bp.renesas.com> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-35-tzimmermann@suse.de --- drivers/gpu/drm/renesas/rz-du/Kconfig | 1 + drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/renesas/rz-du/Kconfig b/drivers/gpu/drm/renesas/rz-du/Kconfig index 89bdb598e0ae..7c1817240846 100644 --- a/drivers/gpu/drm/renesas/rz-du/Kconfig +++ b/drivers/gpu/drm/renesas/rz-du/Kconfig @@ -4,6 +4,7 @@ config DRM_RZG2L_DU depends on ARCH_RZG2L || COMPILE_TEST depends on DRM && OF depends on VIDEO_RENESAS_VSP1 + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c index bc7c381f92ac..bbd7003335da 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c @@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -79,6 +80,7 @@ DEFINE_DRM_GEM_DMA_FOPS(rzg2l_du_fops); static const struct drm_driver rzg2l_du_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .dumb_create = rzg2l_du_dumb_create, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &rzg2l_du_fops, .name = "rzg2l-du", .desc = "Renesas RZ/G2L Display Unit", @@ -160,7 +162,7 @@ static int rzg2l_du_probe(struct platform_device *pdev) drm_info(&rcdu->ddev, "Device %s probed\n", dev_name(&pdev->dev)); - drm_fbdev_dma_setup(&rcdu->ddev, 32); + drm_client_setup(&rcdu->ddev, NULL); return 0; -- GitLab From aaa6216b3f71e7a2c53f6be15cd51a045a058872 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:33 +0200 Subject: [PATCH 376/970] drm/renesas/shmobile: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-36-tzimmermann@suse.de --- drivers/gpu/drm/renesas/shmobile/Kconfig | 1 + drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/renesas/shmobile/Kconfig b/drivers/gpu/drm/renesas/shmobile/Kconfig index c329ab8a7a8b..52e160464001 100644 --- a/drivers/gpu/drm/renesas/shmobile/Kconfig +++ b/drivers/gpu/drm/renesas/shmobile/Kconfig @@ -4,6 +4,7 @@ config DRM_SHMOBILE depends on DRM && PM depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST select BACKLIGHT_CLASS_DEVICE + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c index ff2883c7fd46..8d3effe3f598 100644 --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c @@ -18,8 +18,10 @@ #include <linux/slab.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_modeset_helper.h> #include <drm/drm_module.h> @@ -101,6 +103,7 @@ DEFINE_DRM_GEM_DMA_FOPS(shmob_drm_fops); static const struct drm_driver shmob_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &shmob_drm_fops, .name = "shmob-drm", .desc = "Renesas SH Mobile DRM", @@ -257,7 +260,7 @@ static int shmob_drm_probe(struct platform_device *pdev) if (ret < 0) goto err_modeset_cleanup; - drm_fbdev_dma_setup(ddev, 16); + drm_client_setup_with_fourcc(ddev, DRM_FORMAT_RGB565); return 0; -- GitLab From 1622e61129cb14e184569368ba57005911a7a326 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:34 +0200 Subject: [PATCH 377/970] drm/repaper: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: "Noralf Trønnes" <noralf@tronnes.org> Acked-by: Noralf Trønnes <noralf@tronnes.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-37-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/repaper.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 98af6fd6aa70..1bceb34a09dd 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -181,6 +181,7 @@ config TINYDRM_MI0283QT config TINYDRM_REPAPER tristate "DRM support for Pervasive Displays RePaper panels (V231)" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER help diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 1f78aa3d26bb..77944eb17b3c 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -22,6 +22,7 @@ #include <linux/thermal.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> @@ -913,6 +914,7 @@ static const struct drm_driver repaper_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &repaper_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "repaper", .desc = "Pervasive Displays RePaper e-ink panels", .date = "20170405", @@ -1118,7 +1120,7 @@ static int repaper_probe(struct spi_device *spi) DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 905df8f19e1a7042ddeae1e39d0920b60dfe8c0d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:35 +0200 Subject: [PATCH 378/970] drm/rockchip: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Sandy Huang <hjc@rock-chips.com> Cc: "Heiko Stübner" <heiko@sntech.de> Cc: Andy Yan <andy.yan@rock-chips.com> Acked-by: Heiko Stuebner <heiko@sntech.de> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-38-tzimmermann@suse.de --- drivers/gpu/drm/rockchip/Kconfig | 1 + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 23c49e91f1cc..258dd38e1a8e 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -2,6 +2,7 @@ config DRM_ROCKCHIP tristate "DRM Support for Rockchip" depends on DRM && ROCKCHIP_IOMMU + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_PANEL diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index b84451d59187..d86ec0c5c3a6 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -17,6 +17,7 @@ #include <linux/iommu.h> #include <drm/drm_aperture.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -191,7 +192,7 @@ static int rockchip_drm_bind(struct device *dev) if (ret) goto err_kms_helper_poll_fini; - drm_fbdev_dma_setup(drm_dev, 0); + drm_client_setup(drm_dev, NULL); return 0; err_kms_helper_poll_fini: @@ -226,6 +227,7 @@ static const struct drm_driver rockchip_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, .dumb_create = rockchip_gem_dumb_create, .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table, + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &rockchip_drm_driver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, -- GitLab From df467da5b7ed8463718f08646a696e1e7b5341e1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:36 +0200 Subject: [PATCH 379/970] drm/sti: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The sti driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alain Volmat <alain.volmat@foss.st.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-39-tzimmermann@suse.de --- drivers/gpu/drm/sti/Kconfig | 1 + drivers/gpu/drm/sti/sti_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig index 75c301aadcbc..ec341a4720d4 100644 --- a/drivers/gpu/drm/sti/Kconfig +++ b/drivers/gpu/drm/sti/Kconfig @@ -3,6 +3,7 @@ config DRM_STI tristate "DRM Support for STMicroelectronics SoC stiH4xx Series" depends on OF && DRM && (ARCH_STI || COMPILE_TEST) select RESET_CONTROLLER + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_PANEL diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index 1799c12babf5..65f180c8e8e2 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -15,6 +15,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -136,6 +137,7 @@ static const struct drm_driver sti_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, .fops = &sti_driver_fops, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = sti_drm_dbg_init, @@ -203,7 +205,7 @@ static int sti_bind(struct device *dev) drm_mode_config_reset(ddev); - drm_fbdev_dma_setup(ddev, 32); + drm_client_setup(ddev, NULL); return 0; -- GitLab From 9360547eb5815e639e640662bd6d6368a5b84c9b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:37 +0200 Subject: [PATCH 380/970] drm/stm: Run DRM default client setup Call drm_client_setup_with-fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v4: - remove duplicated S-o-b tag (Gerd) v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Yannick Fertre <yannick.fertre@foss.st.com> Cc: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com> Cc: Philippe Cornu <philippe.cornu@foss.st.com> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com> Acked-by: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-40-tzimmermann@suse.de --- drivers/gpu/drm/stm/Kconfig | 1 + drivers/gpu/drm/stm/drv.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig index d7f41a87808e..635be0ac00af 100644 --- a/drivers/gpu/drm/stm/Kconfig +++ b/drivers/gpu/drm/stm/Kconfig @@ -3,6 +3,7 @@ config DRM_STM tristate "DRM Support for STMicroelectronics SoC Series" depends on DRM && (ARCH_STM32 || COMPILE_TEST) depends on COMMON_CLK + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_PANEL_BRIDGE diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index e1232f74dfa5..fee274a60623 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -18,8 +18,10 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> @@ -66,6 +68,7 @@ static const struct drm_driver drv_driver = { .patchlevel = 0, .fops = &drv_driver_fops, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(stm_gem_dma_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, }; static int drv_load(struct drm_device *ddev) @@ -206,7 +209,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev) if (ret) goto err_unload; - drm_fbdev_dma_setup(ddev, 16); + drm_client_setup_with_fourcc(ddev, DRM_FORMAT_RGB565); return 0; -- GitLab From a4e2e54be9bf30ccdd72f70151735e534daea19b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:38 +0200 Subject: [PATCH 381/970] drm/sun4i: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The sun4i driver specifies as preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Maxime Ripard <mripard@kernel.org> Cc: Chen-Yu Tsai <wens@csie.org> Cc: Jernej Skrabec <jernej.skrabec@gmail.com> Cc: Samuel Holland <samuel@sholland.org> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-41-tzimmermann@suse.de --- drivers/gpu/drm/sun4i/Kconfig | 1 + drivers/gpu/drm/sun4i/sun4i_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig index 4037e085430e..b56ba00aabca 100644 --- a/drivers/gpu/drm/sun4i/Kconfig +++ b/drivers/gpu/drm/sun4i/Kconfig @@ -3,6 +3,7 @@ config DRM_SUN4I tristate "DRM Support for Allwinner A10 Display Engine" depends on DRM && COMMON_CLK depends on ARCH_SUNXI || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select DRM_PANEL diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 35d7a7ffd208..c3342789e3b0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -16,6 +16,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_dma_helper.h> @@ -55,6 +56,7 @@ static const struct drm_driver sun4i_drv_driver = { /* GEM Operations */ DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(drm_sun4i_gem_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, }; static int sun4i_drv_bind(struct device *dev) @@ -111,7 +113,7 @@ static int sun4i_drv_bind(struct device *dev) if (ret) goto finish_poll; - drm_fbdev_dma_setup(drm, 32); + drm_client_setup(drm, NULL); dev_set_drvdata(dev, drm); -- GitLab From db2c190a54bf24746ace253b1b0dacbe92d2ca57 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:39 +0200 Subject: [PATCH 382/970] drm/tidss: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The tidss driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jyri Sarha <jyri.sarha@iki.fi> Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-42-tzimmermann@suse.de --- drivers/gpu/drm/tidss/Kconfig | 1 + drivers/gpu/drm/tidss/tidss_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tidss/Kconfig b/drivers/gpu/drm/tidss/Kconfig index 2385c56493b9..31ad582b7602 100644 --- a/drivers/gpu/drm/tidss/Kconfig +++ b/drivers/gpu/drm/tidss/Kconfig @@ -2,6 +2,7 @@ config DRM_TIDSS tristate "DRM Support for TI Keystone" depends on DRM && OF depends on ARM || ARM64 || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c index d15f836dca95..2428b9aaa003 100644 --- a/drivers/gpu/drm/tidss/tidss_drv.c +++ b/drivers/gpu/drm/tidss/tidss_drv.c @@ -11,6 +11,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_crtc.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -109,6 +110,7 @@ static const struct drm_driver tidss_driver = { .fops = &tidss_fops, .release = tidss_release, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "tidss", .desc = "TI Keystone DSS", .date = "20180215", @@ -186,7 +188,7 @@ static int tidss_probe(struct platform_device *pdev) goto err_irq_uninstall; } - drm_fbdev_dma_setup(ddev, 32); + drm_client_setup(ddev, NULL); dev_dbg(dev, "%s done\n", __func__); -- GitLab From 41fe82e739479911431fea41d7f3aa4c65db9a67 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:40 +0200 Subject: [PATCH 383/970] drm/tilcdc: Run DRM default client setup Call drm_client_setup_with_color_mode() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v3: - add DRM_FBDEV_DMA_DRIVER_OPS macro Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jyri Sarha <jyri.sarha@iki.fi> Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-43-tzimmermann@suse.de --- drivers/gpu/drm/tilcdc/Kconfig | 1 + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig index d3bd2d7a181e..24f9a245ba59 100644 --- a/drivers/gpu/drm/tilcdc/Kconfig +++ b/drivers/gpu/drm/tilcdc/Kconfig @@ -2,6 +2,7 @@ config DRM_TILCDC tristate "DRM Support for TI LCDC Display Controller" depends on DRM && OF && ARM + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_BRIDGE diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index cd5eefa06060..8c9f3705aa6c 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -14,6 +14,7 @@ #include <linux/pm_runtime.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -374,7 +375,8 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; priv->is_registered = true; - drm_fbdev_dma_setup(ddev, bpp); + drm_client_setup_with_color_mode(ddev, bpp); + return 0; init_failed: @@ -472,6 +474,7 @@ DEFINE_DRM_GEM_DMA_FOPS(fops); static const struct drm_driver tilcdc_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, #ifdef CONFIG_DEBUG_FS .debugfs_init = tilcdc_debugfs_init, #endif -- GitLab From 13ff8e79533f41c902bf94c3ff6af1e5b6aa5417 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:41 +0200 Subject: [PATCH 384/970] drm/st7586: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Lechner <david@lechnology.com> Acked-by: David Lechner <david@lechnology.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-44-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/st7586.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 1bceb34a09dd..111113fa86a2 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -196,6 +196,7 @@ config TINYDRM_REPAPER config TINYDRM_ST7586 tristate "DRM support for Sitronix ST7586 display panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c index b9c6ed352182..97013685c62f 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/tiny/st7586.c @@ -13,6 +13,7 @@ #include <video/mipi_display.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> @@ -290,6 +291,7 @@ static const struct drm_driver st7586_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &st7586_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "st7586", .desc = "Sitronix ST7586", @@ -371,7 +373,7 @@ static int st7586_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 74f1b2b09d69d604181ad8fd6acd0fc489918a47 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:42 +0200 Subject: [PATCH 385/970] drm/st7735r: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Lechner <david@lechnology.com> Acked-by: David Lechner <david@lechnology.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-45-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/st7735r.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 111113fa86a2..7ab8d6c02dab 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -209,6 +209,7 @@ config TINYDRM_ST7586 config TINYDRM_ST7735R tristate "DRM support for Sitronix ST7715R/ST7735R display panels" depends on DRM && SPI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index 1676da00883d..0747ebd999cc 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -17,6 +17,7 @@ #include <video/mipi_display.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> #include <drm/drm_gem_atomic_helper.h> @@ -155,6 +156,7 @@ static const struct drm_driver st7735r_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &st7735r_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .debugfs_init = mipi_dbi_debugfs_init, .name = "st7735r", .desc = "Sitronix ST7735R", @@ -241,7 +243,7 @@ static int st7735r_probe(struct spi_device *spi) spi_set_drvdata(spi, drm); - drm_fbdev_dma_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 40d51545cc9a15372ba2dafc662e682f4a82b3b4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:43 +0200 Subject: [PATCH 386/970] drm/tve200: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Linus Walleij <linus.walleij@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-46-tzimmermann@suse.de --- drivers/gpu/drm/tve200/Kconfig | 1 + drivers/gpu/drm/tve200/tve200_drv.c | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tve200/Kconfig b/drivers/gpu/drm/tve200/Kconfig index 5121fed571a5..a9d6fe535d88 100644 --- a/drivers/gpu/drm/tve200/Kconfig +++ b/drivers/gpu/drm/tve200/Kconfig @@ -6,6 +6,7 @@ config DRM_TVE200 depends on ARM || COMPILE_TEST depends on OF select DRM_BRIDGE + select DRM_CLIENT_SELECTION select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c index acce210e2554..b30340a2141d 100644 --- a/drivers/gpu/drm/tve200/tve200_drv.c +++ b/drivers/gpu/drm/tve200/tve200_drv.c @@ -39,8 +39,10 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_module.h> @@ -149,6 +151,7 @@ static const struct drm_driver tve200_drm_driver = { .minor = 0, .patchlevel = 0, DRM_GEM_DMA_DRIVER_OPS, + DRM_FBDEV_DMA_DRIVER_OPS, }; static int tve200_probe(struct platform_device *pdev) @@ -221,11 +224,7 @@ static int tve200_probe(struct platform_device *pdev) if (ret < 0) goto clk_disable; - /* - * Passing in 16 here will make the RGB565 mode the default - * Passing in 32 will use XRGB8888 mode - */ - drm_fbdev_dma_setup(drm, 16); + drm_client_setup_with_fourcc(drm, DRM_FORMAT_RGB565); return 0; -- GitLab From 45903624e9fc57e38eb7f023717205cce2d5e4a3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:44 +0200 Subject: [PATCH 387/970] drm/vc4: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Maxime Ripard <mripard@kernel.org> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com> Cc: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com> Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-47-tzimmermann@suse.de --- drivers/gpu/drm/vc4/Kconfig | 1 + drivers/gpu/drm/vc4/vc4_drv.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig index 269b5f26b2ea..c5f30b317698 100644 --- a/drivers/gpu/drm/vc4/Kconfig +++ b/drivers/gpu/drm/vc4/Kconfig @@ -9,6 +9,7 @@ config DRM_VC4 depends on SND && SND_SOC depends on COMMON_CLK depends on PM + select DRM_CLIENT_SELECTION select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HDMI_STATE_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 8c104ace3dc6..13a1ecddbca3 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -32,8 +32,10 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> +#include <drm/drm_fourcc.h> #include <drm/drm_vblank.h> #include <soc/bcm2835/raspberrypi-firmware.h> @@ -212,6 +214,7 @@ const struct drm_driver vc4_drm_driver = { .gem_create_object = vc4_create_object, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, .ioctls = vc4_drm_ioctls, .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), @@ -393,7 +396,7 @@ static int vc4_drm_bind(struct device *dev) if (ret < 0) goto err; - drm_fbdev_dma_setup(drm, 16); + drm_client_setup_with_fourcc(drm, DRM_FORMAT_RGB565); return 0; -- GitLab From c08810e97a67db13c8cabc6dfbdb07b4ce9a8423 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:45 +0200 Subject: [PATCH 388/970] drm/xlnx: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Cc: Michal Simek <michal.simek@amd.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-48-tzimmermann@suse.de --- drivers/gpu/drm/xlnx/Kconfig | 1 + drivers/gpu/drm/xlnx/zynqmp_kms.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig index 626e5ac4c33d..4197f44e202f 100644 --- a/drivers/gpu/drm/xlnx/Kconfig +++ b/drivers/gpu/drm/xlnx/Kconfig @@ -6,6 +6,7 @@ config DRM_ZYNQMP_DPSUB depends on PHY_XILINX_ZYNQMP depends on XILINX_ZYNQMP_DPDMA select DMA_ENGINE + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c index bd1368df7870..2452c2f09161 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c @@ -14,6 +14,7 @@ #include <drm/drm_blend.h> #include <drm/drm_bridge.h> #include <drm/drm_bridge_connector.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_crtc.h> #include <drm/drm_device.h> @@ -402,6 +403,7 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = { DRIVER_ATOMIC, DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(zynqmp_dpsub_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &zynqmp_dpsub_drm_fops, @@ -523,7 +525,7 @@ int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) goto err_poll_fini; /* Initialize fbdev generic emulation. */ - drm_fbdev_dma_setup(drm, 24); + drm_client_setup_with_fourcc(drm, DRM_FORMAT_RGB888); return 0; -- GitLab From 731fddf4302ec00871fd5ae252c0aa765d61a9ad Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:46 +0200 Subject: [PATCH 389/970] drm/fbdev-dma: Remove obsolete setup function The old setup function drm_fbdev_dma_setup() is unused. Remove it and its internal callbacks. New drivers should call drm_client_setup() instead. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-49-tzimmermann@suse.de --- drivers/gpu/drm/drm_fbdev_dma.c | 120 +------------------------------- include/drm/drm_fbdev_dma.h | 7 -- 2 files changed, 1 insertion(+), 126 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c index 9ce754ebe18e..2343af1b09bc 100644 --- a/drivers/gpu/drm/drm_fbdev_dma.c +++ b/drivers/gpu/drm/drm_fbdev_dma.c @@ -2,15 +2,13 @@ #include <linux/fb.h> -#include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_dma.h> #include <drm/drm_fb_dma_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_dma_helper.h> -#include <drm/drm_fbdev_dma.h> - /* * struct fb_ops */ @@ -102,12 +100,6 @@ static const struct fb_ops drm_fbdev_dma_deferred_fb_ops = { * struct drm_fb_helper */ -static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) -{ - return drm_fbdev_dma_driver_fbdev_probe(fb_helper, sizes); -} - static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) { @@ -128,7 +120,6 @@ static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper, } static const struct drm_fb_helper_funcs drm_fbdev_dma_helper_funcs = { - .fb_probe = drm_fbdev_dma_helper_fb_probe, .fb_dirty = drm_fbdev_dma_helper_fb_dirty, }; @@ -246,112 +237,3 @@ int drm_fbdev_dma_driver_fbdev_probe(struct drm_fb_helper *fb_helper, return ret; } EXPORT_SYMBOL(drm_fbdev_dma_driver_fbdev_probe); - -/* - * struct drm_client_funcs - */ - -static void drm_fbdev_dma_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_dma_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_dma_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev-dma: Failed to setup generic emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs drm_fbdev_dma_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_dma_client_unregister, - .restore = drm_fbdev_dma_client_restore, - .hotplug = drm_fbdev_dma_client_hotplug, -}; - -/** - * drm_fbdev_dma_setup() - Setup fbdev emulation for GEM DMA helpers - * @dev: DRM device - * @preferred_bpp: Preferred bits per pixel for the device. - * 32 is used if this is zero. - * - * This function sets up fbdev emulation for GEM DMA drivers that support - * dumb buffers with a virtual address and that can be mmap'ed. - * drm_fbdev_dma_setup() shall be called after the DRM driver registered - * the new DRM device with drm_dev_register(). - * - * Restore, hotplug events and teardown are all taken care of. Drivers that do - * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. - * Simple drivers might use drm_mode_config_helper_suspend(). - * - * This function is safe to call even when there are no connectors present. - * Setup will be retried on the next hotplug event. - * - * The fbdev is destroyed by drm_dev_unregister(). - */ -void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ - struct drm_fb_helper *fb_helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_dma_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_dma_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_client_init; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); -} -EXPORT_SYMBOL(drm_fbdev_dma_setup); diff --git a/include/drm/drm_fbdev_dma.h b/include/drm/drm_fbdev_dma.h index 6ae4de46497c..fb3f2a9aa01a 100644 --- a/include/drm/drm_fbdev_dma.h +++ b/include/drm/drm_fbdev_dma.h @@ -3,7 +3,6 @@ #ifndef DRM_FBDEV_DMA_H #define DRM_FBDEV_DMA_H -struct drm_device; struct drm_fb_helper; struct drm_fb_helper_surface_size; @@ -13,15 +12,9 @@ int drm_fbdev_dma_driver_fbdev_probe(struct drm_fb_helper *fb_helper, #define DRM_FBDEV_DMA_DRIVER_OPS \ .fbdev_probe = drm_fbdev_dma_driver_fbdev_probe - -void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp); #else -static inline void drm_fbdev_dma_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ } - #define DRM_FBDEV_DMA_DRIVER_OPS \ .fbdev_probe = NULL - #endif #endif -- GitLab From f0f195d1a3aedef126c3ed159712ed57a34daa1c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:47 +0200 Subject: [PATCH 390/970] drm/fbdev-shmem: Support struct drm_driver.fbdev_probe Rework fbdev probing to support fbdev_probe in struct drm_driver and reimplement the old fb_probe callback on top of it. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. This change allows the common fbdev client to run on top of SHMEM- based DRM drivers. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-50-tzimmermann@suse.de --- drivers/gpu/drm/drm_fbdev_shmem.c | 60 ++++++++++++++++++------------- include/drm/drm_fbdev_shmem.h | 11 ++++++ 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c index 0c785007f11b..3bca333917d1 100644 --- a/drivers/gpu/drm/drm_fbdev_shmem.c +++ b/drivers/gpu/drm/drm_fbdev_shmem.c @@ -107,6 +107,40 @@ static struct page *drm_fbdev_shmem_get_page(struct fb_info *info, unsigned long static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) +{ + return drm_fbdev_shmem_driver_fbdev_probe(fb_helper, sizes); +} + +static int drm_fbdev_shmem_helper_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + +static const struct drm_fb_helper_funcs drm_fbdev_shmem_helper_funcs = { + .fb_probe = drm_fbdev_shmem_helper_fb_probe, + .fb_dirty = drm_fbdev_shmem_helper_fb_dirty, +}; + +/* + * struct drm_driver + */ + +int drm_fbdev_shmem_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_client_dev *client = &fb_helper->client; struct drm_device *dev = fb_helper->dev; @@ -139,6 +173,7 @@ static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper, goto err_drm_client_buffer_delete; } + fb_helper->funcs = &drm_fbdev_shmem_helper_funcs; fb_helper->buffer = buffer; fb_helper->fb = fb; @@ -182,30 +217,7 @@ static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper, drm_client_framebuffer_delete(buffer); return ret; } - -static int drm_fbdev_shmem_helper_fb_dirty(struct drm_fb_helper *helper, - struct drm_clip_rect *clip) -{ - struct drm_device *dev = helper->dev; - int ret; - - /* Call damage handlers only if necessary */ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->fb->funcs->dirty) { - ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) - return ret; - } - - return 0; -} - -static const struct drm_fb_helper_funcs drm_fbdev_shmem_helper_funcs = { - .fb_probe = drm_fbdev_shmem_helper_fb_probe, - .fb_dirty = drm_fbdev_shmem_helper_fb_dirty, -}; +EXPORT_SYMBOL(drm_fbdev_shmem_driver_fbdev_probe); /* * struct drm_client_funcs diff --git a/include/drm/drm_fbdev_shmem.h b/include/drm/drm_fbdev_shmem.h index fb43cadd1950..3a5d1efa9d55 100644 --- a/include/drm/drm_fbdev_shmem.h +++ b/include/drm/drm_fbdev_shmem.h @@ -4,12 +4,23 @@ #define DRM_FBDEV_SHMEM_H struct drm_device; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; #ifdef CONFIG_DRM_FBDEV_EMULATION +int drm_fbdev_shmem_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes); + +#define DRM_FBDEV_SHMEM_DRIVER_OPS \ + .fbdev_probe = drm_fbdev_shmem_driver_fbdev_probe + void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp); #else static inline void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp) { } + +#define DRM_FBDEV_SHMEM_DRIVER_OPS \ + .fbdev_probe = NULL #endif #endif -- GitLab From 5db3d78fc3b916ac3d111d54cff7585882f3975f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:48 +0200 Subject: [PATCH 391/970] drm/ast: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The ast driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jocelyn Falempe <jfalempe@redhat.com> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-51-tzimmermann@suse.de --- drivers/gpu/drm/ast/Kconfig | 1 + drivers/gpu/drm/ast/ast_drv.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index 563fa7a3b546..da0663542e8a 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig @@ -2,6 +2,7 @@ config DRM_AST tristate "AST server chips" depends on DRM && PCI && MMU + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER select I2C diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 63b7ef02513d..9d4f7f6955af 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -32,6 +32,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_gem_shmem_helper.h> @@ -64,7 +65,8 @@ static const struct drm_driver ast_driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - DRM_GEM_SHMEM_DRIVER_OPS + DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; /* @@ -360,7 +362,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - drm_fbdev_shmem_setup(drm, 32); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 66843697a5ab1f80777a1570d1aca19cf2a9b177 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:49 +0200 Subject: [PATCH 392/970] drm/bochs: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The bochs driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION v4: - rebase on top of GEM-SHMEM Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-52-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/bochs.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 7ab8d6c02dab..5e047ba8a30d 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -14,6 +14,7 @@ config DRM_ARCPGU config DRM_BOCHS tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" depends on DRM && PCI && MMU + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 9055b1dd66df..5d2d34976d4b 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -6,6 +6,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> @@ -674,6 +675,7 @@ static const struct drm_driver bochs_driver = { .major = 1, .minor = 0, DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; /* ---------------------------------------------------------------------- */ @@ -732,7 +734,8 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent if (ret) goto err_free_dev; - drm_fbdev_shmem_setup(dev, 32); + drm_client_setup(dev, NULL); + return ret; err_free_dev: -- GitLab From c8d7b065f2f802a73fd444dd30f90e43c172a5a6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:50 +0200 Subject: [PATCH 393/970] drm/cirrus: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The cirrus driver requests the same client pixel format as the value stored in struct drm_mode_config.preferred_depth. The fbdev client also looks at this value for the default pixel format. Thus remove the format selection from cirrus. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-53-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/cirrus.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 5e047ba8a30d..d6194296d6da 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -26,6 +26,7 @@ config DRM_BOCHS config DRM_CIRRUS_QEMU tristate "Cirrus driver for QEMU emulated device" depends on DRM && PCI && MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER help diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 751326e3d9c3..20c4479ed4c3 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -27,6 +27,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> @@ -662,6 +663,7 @@ static const struct drm_driver cirrus_driver = { .fops = &cirrus_fops, DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; static int cirrus_pci_probe(struct pci_dev *pdev, @@ -716,7 +718,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev, if (ret) return ret; - drm_fbdev_shmem_setup(dev, 16); + drm_client_setup(dev, NULL); return 0; } -- GitLab From a96edda1c604e5108c4b667541421276b72e43c7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:51 +0200 Subject: [PATCH 394/970] drm/gm12u320: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Hans de Goede <hdegoede@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-54-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/gm12u320.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index d6194296d6da..86abd90d19aa 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -46,6 +46,7 @@ config DRM_CIRRUS_QEMU config DRM_GM12U320 tristate "GM12U320 driver for USB projectors" depends on DRM && USB && MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER help diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 0bd7707c053e..0c17ae532fb4 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -9,6 +9,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> @@ -632,6 +633,7 @@ static const struct drm_driver gm12u320_drm_driver = { .fops = &gm12u320_fops, DRM_GEM_SHMEM_DRIVER_OPS, .gem_prime_import = gm12u320_gem_prime_import, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { @@ -706,7 +708,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface, if (ret) goto err_put_device; - drm_fbdev_shmem_setup(dev, 0); + drm_client_setup(dev, NULL); return 0; -- GitLab From 3284948f22672fd3c2ad8411a194288c040d8fc8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:52 +0200 Subject: [PATCH 395/970] drm/gud: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: "Noralf Trønnes" <noralf@tronnes.org> Acked-by: Noralf Trønnes <noralf@tronnes.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-55-tzimmermann@suse.de --- drivers/gpu/drm/gud/Kconfig | 1 + drivers/gpu/drm/gud/gud_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/gud/Kconfig b/drivers/gpu/drm/gud/Kconfig index 9c1e61f9eec3..b4d2136942f0 100644 --- a/drivers/gpu/drm/gud/Kconfig +++ b/drivers/gpu/drm/gud/Kconfig @@ -4,6 +4,7 @@ config DRM_GUD tristate "GUD USB Display" depends on DRM && USB && MMU select LZ4_COMPRESS + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER select BACKLIGHT_CLASS_DEVICE diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index ac6bbf920c72..09ccdc1dc1a2 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -15,6 +15,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> +#include <drm/drm_client_setup.h> #include <drm/drm_damage_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> @@ -376,6 +377,7 @@ static const struct drm_driver gud_drm_driver = { .fops = &gud_fops, DRM_GEM_SHMEM_DRIVER_OPS, .gem_prime_import = gud_gem_prime_import, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = "gud", .desc = "Generic USB Display", @@ -622,7 +624,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) drm_kms_helper_poll_init(drm); - drm_fbdev_shmem_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -- GitLab From 663269cebc7157e487400c4aeee1f765546a9c98 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:53 +0200 Subject: [PATCH 396/970] drm/hyperv_drm: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Deepak Rawat <drawat.floss@gmail.com> Reviewed-by: Deepak Rawat <drawat.floss@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-56-tzimmermann@suse.de --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index f045ff0e8c99..1df4e627e3d3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -484,6 +484,7 @@ source "drivers/gpu/drm/imagination/Kconfig" config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER help diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index ff93e08d5036..3077ce5470f6 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -10,6 +10,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_gem_shmem_helper.h> @@ -36,6 +37,7 @@ static struct drm_driver hyperv_driver = { .fops = &hv_fops, DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; static int hyperv_pci_probe(struct pci_dev *pdev, @@ -149,7 +151,7 @@ static int hyperv_vmbus_probe(struct hv_device *hdev, goto err_free_mmio; } - drm_fbdev_shmem_setup(dev, 0); + drm_client_setup(dev, NULL); return 0; -- GitLab From 9455d656035c4f69a97895ced207b4681faf2d7c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:54 +0200 Subject: [PATCH 397/970] drm/mgag200: Run DRM default client setup Call drm_client_setup_with_fourcc() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION v2: - use drm_client_setup_with_fourcc() Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jocelyn Falempe <jfalempe@redhat.com> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-57-tzimmermann@suse.de --- drivers/gpu/drm/mgag200/Kconfig | 3 ++- drivers/gpu/drm/mgag200/mgag200_drv.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index 3096944a8f0a..412dcbea0e2d 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -2,6 +2,7 @@ config DRM_MGAG200 tristate "Matrox G200" depends on DRM && PCI && MMU + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER select I2C @@ -20,4 +21,4 @@ config DRM_MGAG200_DISABLE_WRITECOMBINE performances. This can interfere with real-time tasks; even if they are running on other CPU cores than the graphics output. Enable this option only if you run realtime tasks on a server with a - Matrox G200. \ No newline at end of file + Matrox G200. diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 6623ee4e3277..29087e2398df 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -11,9 +11,11 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h> +#include <drm/drm_fourcc.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> #include <drm/drm_module.h> @@ -129,6 +131,7 @@ static const struct drm_driver mgag200_driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; /* @@ -314,7 +317,7 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * FIXME: A 24-bit color depth does not work with 24 bpp on * G200ER. Force 32 bpp. */ - drm_fbdev_shmem_setup(dev, 32); + drm_client_setup_with_fourcc(dev, DRM_FORMAT_XRGB8888); return 0; } -- GitLab From bcd11b3a9378bb0ee05830b910dbb3bb15811970 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:55 +0200 Subject: [PATCH 398/970] drm/ofdrm: Use DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-58-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/ofdrm.c | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 86abd90d19aa..02db304c0cac 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -57,6 +57,7 @@ config DRM_OFDRM tristate "Open Firmware display driver" depends on DRM && MMU && OF && (PPC || COMPILE_TEST) select APERTURE_HELPERS + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index 35996f7eedac..04ffa93de44a 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -7,6 +7,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> #include <drm/drm_device.h> @@ -1344,6 +1345,7 @@ DEFINE_DRM_GEM_FOPS(ofdrm_fops); static struct drm_driver ofdrm_driver = { DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, @@ -1361,7 +1363,6 @@ static int ofdrm_probe(struct platform_device *pdev) { struct ofdrm_device *odev; struct drm_device *dev; - unsigned int color_mode; int ret; odev = ofdrm_device_create(&ofdrm_driver, pdev); @@ -1373,11 +1374,7 @@ static int ofdrm_probe(struct platform_device *pdev) if (ret) return ret; - color_mode = drm_format_info_bpp(odev->format, 0); - if (color_mode == 16) - color_mode = odev->format->depth; // can be 15 or 16 - - drm_fbdev_shmem_setup(dev, color_mode); + drm_client_setup(dev, odev->format); return 0; } -- GitLab From 47e35599630852e899c7bf02e147b9d75b5540c0 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:56 +0200 Subject: [PATCH 399/970] drm/simpledrm: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-59-tzimmermann@suse.de --- drivers/gpu/drm/tiny/Kconfig | 1 + drivers/gpu/drm/tiny/simpledrm.c | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 02db304c0cac..f542aae334d5 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -87,6 +87,7 @@ config DRM_SIMPLEDRM tristate "Simple framebuffer driver" depends on DRM && MMU select APERTURE_HELPERS + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index d19e10289428..484901e5e2f4 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -12,6 +12,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_connector.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> @@ -1009,6 +1010,7 @@ DEFINE_DRM_GEM_FOPS(simpledrm_fops); static struct drm_driver simpledrm_driver = { DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, @@ -1026,7 +1028,6 @@ static int simpledrm_probe(struct platform_device *pdev) { struct simpledrm_device *sdev; struct drm_device *dev; - unsigned int color_mode; int ret; sdev = simpledrm_device_create(&simpledrm_driver, pdev); @@ -1038,11 +1039,7 @@ static int simpledrm_probe(struct platform_device *pdev) if (ret) return ret; - color_mode = drm_format_info_bpp(sdev->format, 0); - if (color_mode == 16) - color_mode = sdev->format->depth; // can be 15 or 16 - - drm_fbdev_shmem_setup(dev, color_mode); + drm_client_setup(dev, sdev->format); return 0; } -- GitLab From 301e6d7d637f1be9b6a5f377f7a4d0160e13ab90 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:57 +0200 Subject: [PATCH 400/970] drm/solomon: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The solomon driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-60-tzimmermann@suse.de --- drivers/gpu/drm/solomon/Kconfig | 1 + drivers/gpu/drm/solomon/ssd130x.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index c3ee956c2bb9..400a6cab3a67 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -2,6 +2,7 @@ config DRM_SSD130X tristate "DRM support for Solomon SSD13xx OLED displays" depends on DRM && MMU select BACKLIGHT_CLASS_DEVICE + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 6f51bcf774e2..29b2f82d81f8 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -20,6 +20,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_edid.h> @@ -1780,6 +1781,7 @@ DEFINE_DRM_GEM_FOPS(ssd130x_fops); static const struct drm_driver ssd130x_drm_driver = { DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, @@ -2029,7 +2031,7 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap) if (ret) return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n")); - drm_fbdev_shmem_setup(drm, 32); + drm_client_setup(drm, NULL); return ssd130x; } -- GitLab From 266e9dee8bbb1f902e27a8b3b038131036d264cb Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:58 +0200 Subject: [PATCH 401/970] drm/udl: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Sean Paul <sean@poorly.run> Cc: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-61-tzimmermann@suse.de --- drivers/gpu/drm/udl/Kconfig | 1 + drivers/gpu/drm/udl/udl_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index c744175c6992..d7a6abef7d78 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig @@ -5,6 +5,7 @@ config DRM_UDL depends on USB depends on USB_ARCH_HAS_HCD depends on MMU + select DRM_CLIENT_SELECTION select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 280a09a6e2ad..8d8ae40f945c 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -6,6 +6,7 @@ #include <linux/module.h> #include <drm/drm_drv.h> +#include <drm/drm_client_setup.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h> #include <drm/drm_gem_shmem_helper.h> @@ -73,6 +74,7 @@ static const struct drm_driver driver = { .fops = &udl_driver_fops, DRM_GEM_SHMEM_DRIVER_OPS, .gem_prime_import = udl_driver_gem_prime_import, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -117,7 +119,7 @@ static int udl_usb_probe(struct usb_interface *interface, DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index); - drm_fbdev_shmem_setup(&udl->drm, 0); + drm_client_setup(&udl->drm, NULL); return 0; } -- GitLab From a24a487abf7cdb14f3fbedbdbed753caed41f695 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:12:59 +0200 Subject: [PATCH 402/970] drm/virtgpu: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The virtgpu driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Gurchetan Singh <gurchetansingh@chromium.org> Cc: Chia-I Wu <olvaffe@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-62-tzimmermann@suse.de --- drivers/gpu/drm/virtio/Kconfig | 1 + drivers/gpu/drm/virtio/virtgpu_drv.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/Kconfig b/drivers/gpu/drm/virtio/Kconfig index ea06ff2aa4b4..fc884fb57b7e 100644 --- a/drivers/gpu/drm/virtio/Kconfig +++ b/drivers/gpu/drm/virtio/Kconfig @@ -3,6 +3,7 @@ config DRM_VIRTIO_GPU tristate "Virtio GPU driver" depends on DRM && VIRTIO_MENU && MMU select VIRTIO + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER select VIRTIO_DMA_SHARED_BUFFER diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index e5a2665e50ea..1e08d91a4d17 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -34,6 +34,7 @@ #include <drm/drm.h> #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h> @@ -103,7 +104,8 @@ static int virtio_gpu_probe(struct virtio_device *vdev) if (ret) goto err_deinit; - drm_fbdev_shmem_setup(vdev->priv, 32); + drm_client_setup(vdev->priv, NULL); + return 0; err_deinit: @@ -184,6 +186,8 @@ static const struct drm_driver driver = { .dumb_create = virtio_gpu_mode_dumb_create, .dumb_map_offset = virtio_gpu_mode_dumb_mmap, + DRM_FBDEV_SHMEM_DRIVER_OPS, + #if defined(CONFIG_DEBUG_FS) .debugfs_init = virtio_gpu_debugfs_init, #endif -- GitLab From 7e31ad9bb0f59185dcb57fbe7e994865a6b7afe0 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:00 +0200 Subject: [PATCH 403/970] drm/vkms: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> Cc: Melissa Wen <melissa.srw@gmail.com> Cc: "MaÃra Canal" <mairacanal@riseup.net> Cc: Haneen Mohammed <hamohammed.sa@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-63-tzimmermann@suse.de --- drivers/gpu/drm/vkms/Kconfig | 1 + drivers/gpu/drm/vkms/vkms_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index b9ecdebecb0b..9def079f685b 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -3,6 +3,7 @@ config DRM_VKMS tristate "Virtual KMS (EXPERIMENTAL)" depends on DRM && MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER select CRC32 diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 0c1a713b7b7b..2d1e95cb66e5 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -16,6 +16,7 @@ #include <drm/drm_gem.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h> @@ -112,6 +113,7 @@ static const struct drm_driver vkms_driver = { .release = vkms_release, .fops = &vkms_driver_fops, DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -225,7 +227,7 @@ static int vkms_create(struct vkms_config *config) if (ret) goto out_devres; - drm_fbdev_shmem_setup(&vkms_device->drm, 0); + drm_client_setup(&vkms_device->drm, NULL); return 0; -- GitLab From bf0978203a746137ce5074a465f83a6cf12e813f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:01 +0200 Subject: [PATCH 404/970] drm/fbdev-shmem: Remove obsolete setup function The old setup function drm_fbdev_shmem_setup() is unused. Remove it and its internal callbacks. New drivers should call drm_client_setup() instead. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-64-tzimmermann@suse.de --- drivers/gpu/drm/drm_fbdev_shmem.c | 120 +----------------------------- include/drm/drm_fbdev_shmem.h | 6 -- 2 files changed, 1 insertion(+), 125 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c index 3bca333917d1..f824369baacd 100644 --- a/drivers/gpu/drm/drm_fbdev_shmem.c +++ b/drivers/gpu/drm/drm_fbdev_shmem.c @@ -2,15 +2,13 @@ #include <linux/fb.h> -#include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fbdev_shmem.h> #include <drm/drm_fb_helper.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_shmem_helper.h> -#include <drm/drm_fbdev_shmem.h> - /* * struct fb_ops */ @@ -105,12 +103,6 @@ static struct page *drm_fbdev_shmem_get_page(struct fb_info *info, unsigned long * struct drm_fb_helper */ -static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) -{ - return drm_fbdev_shmem_driver_fbdev_probe(fb_helper, sizes); -} - static int drm_fbdev_shmem_helper_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) { @@ -131,7 +123,6 @@ static int drm_fbdev_shmem_helper_fb_dirty(struct drm_fb_helper *helper, } static const struct drm_fb_helper_funcs drm_fbdev_shmem_helper_funcs = { - .fb_probe = drm_fbdev_shmem_helper_fb_probe, .fb_dirty = drm_fbdev_shmem_helper_fb_dirty, }; @@ -218,112 +209,3 @@ int drm_fbdev_shmem_driver_fbdev_probe(struct drm_fb_helper *fb_helper, return ret; } EXPORT_SYMBOL(drm_fbdev_shmem_driver_fbdev_probe); - -/* - * struct drm_client_funcs - */ - -static void drm_fbdev_shmem_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_shmem_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev-shmem: Failed to setup emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs drm_fbdev_shmem_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_shmem_client_unregister, - .restore = drm_fbdev_shmem_client_restore, - .hotplug = drm_fbdev_shmem_client_hotplug, -}; - -/** - * drm_fbdev_shmem_setup() - Setup fbdev emulation for GEM SHMEM helpers - * @dev: DRM device - * @preferred_bpp: Preferred bits per pixel for the device. - * 32 is used if this is zero. - * - * This function sets up fbdev emulation for GEM DMA drivers that support - * dumb buffers with a virtual address and that can be mmap'ed. - * drm_fbdev_shmem_setup() shall be called after the DRM driver registered - * the new DRM device with drm_dev_register(). - * - * Restore, hotplug events and teardown are all taken care of. Drivers that do - * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. - * Simple drivers might use drm_mode_config_helper_suspend(). - * - * This function is safe to call even when there are no connectors present. - * Setup will be retried on the next hotplug event. - * - * The fbdev is destroyed by drm_dev_unregister(). - */ -void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ - struct drm_fb_helper *fb_helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_shmem_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_shmem_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_client_init; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); -} -EXPORT_SYMBOL(drm_fbdev_shmem_setup); diff --git a/include/drm/drm_fbdev_shmem.h b/include/drm/drm_fbdev_shmem.h index 3a5d1efa9d55..2fc708964d75 100644 --- a/include/drm/drm_fbdev_shmem.h +++ b/include/drm/drm_fbdev_shmem.h @@ -3,7 +3,6 @@ #ifndef DRM_FBDEV_SHMEM_H #define DRM_FBDEV_SHMEM_H -struct drm_device; struct drm_fb_helper; struct drm_fb_helper_surface_size; @@ -13,12 +12,7 @@ int drm_fbdev_shmem_driver_fbdev_probe(struct drm_fb_helper *fb_helper, #define DRM_FBDEV_SHMEM_DRIVER_OPS \ .fbdev_probe = drm_fbdev_shmem_driver_fbdev_probe - -void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp); #else -static inline void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ } - #define DRM_FBDEV_SHMEM_DRIVER_OPS \ .fbdev_probe = NULL #endif -- GitLab From c7c1b9e1d52b0a0dbb0ee552efdc3360c0f5363c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:02 +0200 Subject: [PATCH 405/970] drm/fbdev-ttm: Support struct drm_driver.fbdev_probe Rework fbdev probing to support fbdev_probe in struct drm_driver and reimplement the old fb_probe callback on top of it. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. This change allows the common fbdev client to run on top of TTM- based DRM drivers. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-65-tzimmermann@suse.de --- drivers/gpu/drm/drm_fbdev_ttm.c | 142 +++++++++++++++++--------------- include/drm/drm_fbdev_ttm.h | 13 +++ 2 files changed, 90 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_ttm.c b/drivers/gpu/drm/drm_fbdev_ttm.c index 119ffb28aaf9..d799cbe944cd 100644 --- a/drivers/gpu/drm/drm_fbdev_ttm.c +++ b/drivers/gpu/drm/drm_fbdev_ttm.c @@ -71,71 +71,7 @@ static const struct fb_ops drm_fbdev_ttm_fb_ops = { static int drm_fbdev_ttm_helper_fb_probe(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) { - struct drm_client_dev *client = &fb_helper->client; - struct drm_device *dev = fb_helper->dev; - struct drm_client_buffer *buffer; - struct fb_info *info; - size_t screen_size; - void *screen_buffer; - u32 format; - int ret; - - drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); - - format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, - sizes->surface_depth); - buffer = drm_client_framebuffer_create(client, sizes->surface_width, - sizes->surface_height, format); - if (IS_ERR(buffer)) - return PTR_ERR(buffer); - - fb_helper->buffer = buffer; - fb_helper->fb = buffer->fb; - - screen_size = buffer->gem->size; - screen_buffer = vzalloc(screen_size); - if (!screen_buffer) { - ret = -ENOMEM; - goto err_drm_client_framebuffer_delete; - } - - info = drm_fb_helper_alloc_info(fb_helper); - if (IS_ERR(info)) { - ret = PTR_ERR(info); - goto err_vfree; - } - - drm_fb_helper_fill_info(info, fb_helper, sizes); - - info->fbops = &drm_fbdev_ttm_fb_ops; - - /* screen */ - info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; - info->screen_buffer = screen_buffer; - info->fix.smem_len = screen_size; - - /* deferred I/O */ - fb_helper->fbdefio.delay = HZ / 20; - fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; - - info->fbdefio = &fb_helper->fbdefio; - ret = fb_deferred_io_init(info); - if (ret) - goto err_drm_fb_helper_release_info; - - return 0; - -err_drm_fb_helper_release_info: - drm_fb_helper_release_info(fb_helper); -err_vfree: - vfree(screen_buffer); -err_drm_client_framebuffer_delete: - fb_helper->fb = NULL; - fb_helper->buffer = NULL; - drm_client_framebuffer_delete(buffer); - return ret; + return drm_fbdev_ttm_driver_fbdev_probe(fb_helper, sizes); } static void drm_fbdev_ttm_damage_blit_real(struct drm_fb_helper *fb_helper, @@ -240,6 +176,82 @@ static const struct drm_fb_helper_funcs drm_fbdev_ttm_helper_funcs = { .fb_dirty = drm_fbdev_ttm_helper_fb_dirty, }; +/* + * struct drm_driver + */ + +int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; + struct drm_client_buffer *buffer; + struct fb_info *info; + size_t screen_size; + void *screen_buffer; + u32 format; + int ret; + + drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); + + format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, + sizes->surface_depth); + buffer = drm_client_framebuffer_create(client, sizes->surface_width, + sizes->surface_height, format); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); + + fb_helper->funcs = &drm_fbdev_ttm_helper_funcs; + fb_helper->buffer = buffer; + fb_helper->fb = buffer->fb; + + screen_size = buffer->gem->size; + screen_buffer = vzalloc(screen_size); + if (!screen_buffer) { + ret = -ENOMEM; + goto err_drm_client_framebuffer_delete; + } + + info = drm_fb_helper_alloc_info(fb_helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); + goto err_vfree; + } + + drm_fb_helper_fill_info(info, fb_helper, sizes); + + info->fbops = &drm_fbdev_ttm_fb_ops; + + /* screen */ + info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; + info->screen_buffer = screen_buffer; + info->fix.smem_len = screen_size; + + /* deferred I/O */ + fb_helper->fbdefio.delay = HZ / 20; + fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; + + info->fbdefio = &fb_helper->fbdefio; + ret = fb_deferred_io_init(info); + if (ret) + goto err_drm_fb_helper_release_info; + + return 0; + +err_drm_fb_helper_release_info: + drm_fb_helper_release_info(fb_helper); +err_vfree: + vfree(screen_buffer); +err_drm_client_framebuffer_delete: + fb_helper->fb = NULL; + fb_helper->buffer = NULL; + drm_client_framebuffer_delete(buffer); + return ret; +} +EXPORT_SYMBOL(drm_fbdev_ttm_driver_fbdev_probe); + static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client) { struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); diff --git a/include/drm/drm_fbdev_ttm.h b/include/drm/drm_fbdev_ttm.h index 9e6c3bdf3537..243685d02eb1 100644 --- a/include/drm/drm_fbdev_ttm.h +++ b/include/drm/drm_fbdev_ttm.h @@ -3,11 +3,24 @@ #ifndef DRM_FBDEV_TTM_H #define DRM_FBDEV_TTM_H +#include <linux/stddef.h> + struct drm_device; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; #ifdef CONFIG_DRM_FBDEV_EMULATION +int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes); + +#define DRM_FBDEV_TTM_DRIVER_OPS \ + .fbdev_probe = drm_fbdev_ttm_driver_fbdev_probe + void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp); #else +#define DRM_FBDEV_TTM_DRIVER_OPS \ + .fbdev_probe = NULL + static inline void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp) { } #endif -- GitLab From 32acc286b29724f6d7a17fff9564326d4503e507 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:03 +0200 Subject: [PATCH 406/970] drm/amdgpu: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The amdgpu driver specifies a preferred color mode depending on the available video memory, with a default of 32. Adapt this for the new client interface. v5: - select DRM_CLIENT_SELECTION v2: - style changes Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Tested-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-66-tzimmermann@suse.de --- drivers/gpu/drm/amd/amdgpu/Kconfig | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index fc3237da8090..680a94c361ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -5,6 +5,7 @@ config DRM_AMDGPU depends on DRM && PCI && MMU depends on !UML select FW_LOADER + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDMI_HELPER diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8dee7c62c801..ee193ddc5402 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -23,6 +23,7 @@ */ #include <drm/amdgpu_drm.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_gem.h> @@ -2347,11 +2348,15 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, */ if (adev->mode_info.mode_config_initialized && !list_empty(&adev_to_drm(adev)->mode_config.connector_list)) { + const struct drm_format_info *format; + /* select 8 bpp console on low vram cards */ if (adev->gmc.real_vram_size <= (32*1024*1024)) - drm_fbdev_ttm_setup(adev_to_drm(adev), 8); + format = drm_format_info(DRM_FORMAT_C8); else - drm_fbdev_ttm_setup(adev_to_drm(adev), 32); + format = NULL; + + drm_client_setup(adev_to_drm(adev), format); } ret = amdgpu_debugfs_init(adev); @@ -2963,6 +2968,7 @@ static const struct drm_driver amdgpu_kms_driver = { .num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms), .dumb_create = amdgpu_mode_dumb_create, .dumb_map_offset = amdgpu_mode_dumb_mmap, + DRM_FBDEV_TTM_DRIVER_OPS, .fops = &amdgpu_driver_kms_fops, .release = &amdgpu_driver_release_kms, #ifdef CONFIG_PROC_FS @@ -2989,6 +2995,7 @@ const struct drm_driver amdgpu_partition_driver = { .num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms), .dumb_create = amdgpu_mode_dumb_create, .dumb_map_offset = amdgpu_mode_dumb_mmap, + DRM_FBDEV_TTM_DRIVER_OPS, .fops = &amdgpu_driver_kms_fops, .release = &amdgpu_driver_release_kms, -- GitLab From 677a7cf28695f6dbd7bd5abfb512d823dff1946b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:04 +0200 Subject: [PATCH 407/970] drm/hisilicon/hibmc: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The hibmc driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Xinliang Liu <xinliang.liu@linaro.org> Cc: Tian Tao <tiantao6@hisilicon.com> Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: Yongqin Liu <yongqin.liu@linaro.org> Cc: John Stultz <jstultz@google.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-67-tzimmermann@suse.de --- drivers/gpu/drm/hisilicon/hibmc/Kconfig | 1 + drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig b/drivers/gpu/drm/hisilicon/hibmc/Kconfig index 126504318a4f..80253d39664a 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig +++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig @@ -3,6 +3,7 @@ config DRM_HISI_HIBMC tristate "DRM Support for Hisilicon Hibmc" depends on DRM && PCI && (ARM64 || COMPILE_TEST) depends on MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_VRAM_HELPER select DRM_TTM diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 9f9b19ea0587..866a9ecaf8b9 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 <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_gem_framebuffer_helper.h> @@ -63,6 +64,7 @@ static const struct drm_driver hibmc_driver = { .debugfs_init = drm_vram_mm_debugfs_init, .dumb_create = hibmc_dumb_create, .dumb_map_offset = drm_gem_ttm_dumb_map_offset, + DRM_FBDEV_TTM_DRIVER_OPS, }; static int __maybe_unused hibmc_pm_suspend(struct device *dev) @@ -339,7 +341,7 @@ static int hibmc_pci_probe(struct pci_dev *pdev, goto err_unload; } - drm_fbdev_ttm_setup(dev, 32); + drm_client_setup(dev, NULL); return 0; -- GitLab From 4269f5c878fc19a0ac5b7c770053cabe794010b7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:05 +0200 Subject: [PATCH 408/970] drm/loongson: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The loongson driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Sui Jingfeng <suijingfeng@loongson.cn> Acked-by: Sui Jingfeng <sui.jingfeng@linux.dev> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-68-tzimmermann@suse.de --- drivers/gpu/drm/loongson/Kconfig | 1 + drivers/gpu/drm/loongson/lsdc_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/loongson/Kconfig b/drivers/gpu/drm/loongson/Kconfig index 9ed463a76ae2..552edfec7afb 100644 --- a/drivers/gpu/drm/loongson/Kconfig +++ b/drivers/gpu/drm/loongson/Kconfig @@ -4,6 +4,7 @@ config DRM_LOONGSON tristate "DRM support for Loongson Graphics" depends on DRM && PCI && MMU depends on LOONGARCH || MIPS || COMPILE_TEST + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_TTM select DRM_TTM_HELPER diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c index adc7344d2f80..a19dce35c839 100644 --- a/drivers/gpu/drm/loongson/lsdc_drv.c +++ b/drivers/gpu/drm/loongson/lsdc_drv.c @@ -9,6 +9,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_gem_framebuffer_helper.h> @@ -47,6 +48,7 @@ static const struct drm_driver lsdc_drm_driver = { .dumb_create = lsdc_dumb_create, .dumb_map_offset = lsdc_dumb_map_offset, .gem_prime_import_sg_table = lsdc_prime_import_sg_table, + DRM_FBDEV_TTM_DRIVER_OPS, }; static const struct drm_mode_config_funcs lsdc_mode_config_funcs = { @@ -314,7 +316,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - drm_fbdev_ttm_setup(ddev, 32); + drm_client_setup(ddev, NULL); return 0; } -- GitLab From ef350898ae22db832ada972476fa2999f8ea978c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:06 +0200 Subject: [PATCH 409/970] drm/nouveau: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The nouveau driver specifies a preferred color mode depending on the available video memory, with a default of 32. Adapt this for the new client interface. v5: - select DRM_CLIENT_SELECTION v2: - style changes Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Karol Herbst <kherbst@redhat.com> Cc: Lyude Paul <lyude@redhat.com> Cc: Danilo Krummrich <dakr@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-69-tzimmermann@suse.de --- drivers/gpu/drm/nouveau/Kconfig | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index ceef470c9fbf..ce840300578d 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -4,6 +4,7 @@ config DRM_NOUVEAU depends on DRM && PCI && MMU select IOMMU_API select FW_LOADER + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 4a9a9b9c3935..628c47a60de5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -31,6 +31,7 @@ #include <linux/dynamic_debug.h> #include <drm/drm_aperture.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_gem_ttm_helper.h> @@ -836,6 +837,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev, { struct nvkm_device *device; struct nouveau_drm *drm; + const struct drm_format_info *format; int ret; if (vga_switcheroo_client_probe_defer(pdev)) @@ -873,9 +875,11 @@ static int nouveau_drm_probe(struct pci_dev *pdev, goto fail_pci; if (drm->client.device.info.ram_size <= 32 * 1024 * 1024) - drm_fbdev_ttm_setup(drm->dev, 8); + format = drm_format_info(DRM_FORMAT_C8); else - drm_fbdev_ttm_setup(drm->dev, 32); + format = NULL; + + drm_client_setup(drm->dev, format); quirk_broken_nv_runpm(pdev); return 0; @@ -1317,6 +1321,8 @@ driver_stub = { .dumb_create = nouveau_display_dumb_create, .dumb_map_offset = drm_gem_ttm_dumb_map_offset, + DRM_FBDEV_TTM_DRIVER_OPS, + .name = DRIVER_NAME, .desc = DRIVER_DESC, #ifdef GIT_REVISION -- GitLab From 92c13542e878966bafac28dc19ee8744978e4ca9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:07 +0200 Subject: [PATCH 410/970] drm/qxl: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The qxl driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-70-tzimmermann@suse.de --- drivers/gpu/drm/qxl/Kconfig | 1 + drivers/gpu/drm/qxl/qxl_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/qxl/Kconfig b/drivers/gpu/drm/qxl/Kconfig index ca3f51c2a8fe..1992df4a82d2 100644 --- a/drivers/gpu/drm/qxl/Kconfig +++ b/drivers/gpu/drm/qxl/Kconfig @@ -2,6 +2,7 @@ config DRM_QXL tristate "QXL virtual GPU" depends on DRM && PCI && MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_TTM select DRM_TTM_HELPER diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 5eb3f5719fdf..4ef1c134d6dd 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -36,6 +36,7 @@ #include <drm/drm.h> #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_file.h> @@ -118,7 +119,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto modeset_cleanup; - drm_fbdev_ttm_setup(&qdev->ddev, 32); + drm_client_setup(&qdev->ddev, NULL); return 0; modeset_cleanup: @@ -293,6 +294,7 @@ static struct drm_driver qxl_driver = { .debugfs_init = qxl_debugfs_init, #endif .gem_prime_import_sg_table = qxl_gem_prime_import_sg_table, + DRM_FBDEV_TTM_DRIVER_OPS, .fops = &qxl_fops, .ioctls = qxl_ioctls, .num_ioctls = ARRAY_SIZE(qxl_ioctls), -- GitLab From 13391209a1226226631292316316462afd034540 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:08 +0200 Subject: [PATCH 411/970] drm/vboxvideo: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The vboxvideo driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Hans de Goede <hdegoede@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-71-tzimmermann@suse.de --- drivers/gpu/drm/vboxvideo/Kconfig | 1 + drivers/gpu/drm/vboxvideo/vbox_drv.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vboxvideo/Kconfig b/drivers/gpu/drm/vboxvideo/Kconfig index 45fe135d6e43..180e30b82ab9 100644 --- a/drivers/gpu/drm/vboxvideo/Kconfig +++ b/drivers/gpu/drm/vboxvideo/Kconfig @@ -2,6 +2,7 @@ config DRM_VBOXVIDEO tristate "Virtual Box Graphics Card" depends on DRM && X86 && PCI + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_VRAM_HELPER select DRM_TTM diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index ef36834c8673..49dc337b3e01 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -13,6 +13,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_file.h> @@ -80,7 +81,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_irq_fini; - drm_fbdev_ttm_setup(&vbox->ddev, 32); + drm_client_setup(&vbox->ddev, NULL); return 0; @@ -193,6 +194,7 @@ static const struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, DRM_GEM_VRAM_DRIVER, + DRM_FBDEV_TTM_DRIVER_OPS, }; drm_module_pci_driver_if_modeset(vbox_pci_driver, vbox_modeset); -- GitLab From e87969317a2dc39dbd45014d544697ae6e50e486 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:09 +0200 Subject: [PATCH 412/970] drm/vmwgfx: Run DRM default client setup Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Zack Rusin <zack.rusin@broadcom.com> Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> Reviewed-by: Zack Rusin <zack.rusin@broadcom.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-72-tzimmermann@suse.de --- drivers/gpu/drm/vmwgfx/Kconfig | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 6f1ac940cbae..6c3c2922ae8b 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -3,6 +3,7 @@ config DRM_VMWGFX tristate "DRM driver for VMware Virtual GPU" depends on DRM && PCI && MMU depends on (X86 && HYPERVISOR_GUEST) || ARM64 + select DRM_CLIENT_SELECTION select DRM_TTM select DRM_TTM_HELPER select MAPPING_DIRTY_HELPERS diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 50ad3105c16e..f9009f5a5aef 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -36,6 +36,7 @@ #include "ttm_object.h" #include <drm/drm_aperture.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> #include <drm/drm_gem_ttm_helper.h> @@ -1628,6 +1629,8 @@ static const struct drm_driver driver = { .prime_handle_to_fd = vmw_prime_handle_to_fd, .gem_prime_import_sg_table = vmw_prime_import_sg_table, + DRM_FBDEV_TTM_DRIVER_OPS, + .fops = &vmwgfx_driver_fops, .name = VMWGFX_DRIVER_NAME, .desc = VMWGFX_DRIVER_DESC, @@ -1679,7 +1682,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vmw_fifo_resource_inc(vmw); vmw_svga_enable(vmw); - drm_fbdev_ttm_setup(&vmw->drm, 0); + drm_client_setup(&vmw->drm, NULL); vmw_debugfs_gem_init(vmw); vmw_debugfs_resource_managers_init(vmw); -- GitLab From 1000634477d8d178179b1ad45d92e925fabe3deb Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:10 +0200 Subject: [PATCH 413/970] drm/fbdev-ttm: Remove obsolete setup function The old setup function drm_fbdev_ttm_setup() is unused. Remove it and its internal callbacks. New drivers should call drm_client_setup() instead. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-73-tzimmermann@suse.de --- drivers/gpu/drm/drm_fbdev_ttm.c | 119 -------------------------------- include/drm/drm_fbdev_ttm.h | 6 -- 2 files changed, 125 deletions(-) diff --git a/drivers/gpu/drm/drm_fbdev_ttm.c b/drivers/gpu/drm/drm_fbdev_ttm.c index d799cbe944cd..73d35d59590c 100644 --- a/drivers/gpu/drm/drm_fbdev_ttm.c +++ b/drivers/gpu/drm/drm_fbdev_ttm.c @@ -65,15 +65,6 @@ static const struct fb_ops drm_fbdev_ttm_fb_ops = { .fb_destroy = drm_fbdev_ttm_fb_destroy, }; -/* - * This function uses the client API to create a framebuffer backed by a dumb buffer. - */ -static int drm_fbdev_ttm_helper_fb_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) -{ - return drm_fbdev_ttm_driver_fbdev_probe(fb_helper, sizes); -} - static void drm_fbdev_ttm_damage_blit_real(struct drm_fb_helper *fb_helper, struct drm_clip_rect *clip, struct iosys_map *dst) @@ -172,7 +163,6 @@ static int drm_fbdev_ttm_helper_fb_dirty(struct drm_fb_helper *helper, } static const struct drm_fb_helper_funcs drm_fbdev_ttm_helper_funcs = { - .fb_probe = drm_fbdev_ttm_helper_fb_probe, .fb_dirty = drm_fbdev_ttm_helper_fb_dirty, }; @@ -251,112 +241,3 @@ int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper, return ret; } EXPORT_SYMBOL(drm_fbdev_ttm_driver_fbdev_probe); - -static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_ttm_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs drm_fbdev_ttm_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_ttm_client_unregister, - .restore = drm_fbdev_ttm_client_restore, - .hotplug = drm_fbdev_ttm_client_hotplug, -}; - -/** - * drm_fbdev_ttm_setup() - Setup fbdev emulation for TTM-based drivers - * @dev: DRM device - * @preferred_bpp: Preferred bits per pixel for the device. - * - * This function sets up fbdev emulation for TTM-based drivers that support - * dumb buffers with a virtual address and that can be mmap'ed. - * drm_fbdev_ttm_setup() shall be called after the DRM driver registered - * the new DRM device with drm_dev_register(). - * - * Restore, hotplug events and teardown are all taken care of. Drivers that do - * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. - * Simple drivers might use drm_mode_config_helper_suspend(). - * - * In order to provide fixed mmap-able memory ranges, fbdev emulation - * uses a shadow buffer in system memory. The implementation blits the shadow - * fbdev buffer onto the real buffer in regular intervals. - * - * This function is safe to call even when there are no connectors present. - * Setup will be retried on the next hotplug event. - * - * The fbdev is destroyed by drm_dev_unregister(). - */ -void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ - struct drm_fb_helper *fb_helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_ttm_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_ttm_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_client_init; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - return; -} -EXPORT_SYMBOL(drm_fbdev_ttm_setup); diff --git a/include/drm/drm_fbdev_ttm.h b/include/drm/drm_fbdev_ttm.h index 243685d02eb1..ad4a10bb4c78 100644 --- a/include/drm/drm_fbdev_ttm.h +++ b/include/drm/drm_fbdev_ttm.h @@ -5,7 +5,6 @@ #include <linux/stddef.h> -struct drm_device; struct drm_fb_helper; struct drm_fb_helper_surface_size; @@ -15,14 +14,9 @@ int drm_fbdev_ttm_driver_fbdev_probe(struct drm_fb_helper *fb_helper, #define DRM_FBDEV_TTM_DRIVER_OPS \ .fbdev_probe = drm_fbdev_ttm_driver_fbdev_probe - -void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp); #else #define DRM_FBDEV_TTM_DRIVER_OPS \ .fbdev_probe = NULL - -static inline void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ } #endif #endif -- GitLab From 9f62b01b805df67b9beb1b9e46cb817888452160 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:11 +0200 Subject: [PATCH 414/970] drm/armada: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The armada driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION v4: - revert an unrelated cleanup (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Russell King <linux@armlinux.org.uk> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-74-tzimmermann@suse.de --- drivers/gpu/drm/armada/Kconfig | 1 + drivers/gpu/drm/armada/armada_drm.h | 11 ++- drivers/gpu/drm/armada/armada_drv.c | 4 +- drivers/gpu/drm/armada/armada_fbdev.c | 113 ++------------------------ 4 files changed, 17 insertions(+), 112 deletions(-) diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig index e5597d7c9ae1..b22c891a670b 100644 --- a/drivers/gpu/drm/armada/Kconfig +++ b/drivers/gpu/drm/armada/Kconfig @@ -2,6 +2,7 @@ config DRM_ARMADA tristate "DRM support for Marvell Armada SoCs" depends on DRM && HAVE_CLK && ARM && MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION help diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index c303e8c7ff6c..3c0ff221a43b 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h @@ -16,6 +16,8 @@ struct armada_crtc; struct armada_gem_object; struct clk; struct drm_display_mode; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; static inline void armada_updatel(uint32_t val, uint32_t mask, void __iomem *ptr) @@ -74,10 +76,13 @@ struct armada_private { #define drm_to_armada_dev(dev) container_of(dev, struct armada_private, drm) #if defined(CONFIG_DRM_FBDEV_EMULATION) -void armada_fbdev_setup(struct drm_device *dev); +int armada_fbdev_driver_fbdev_probe(struct drm_fb_helper *fbh, + struct drm_fb_helper_surface_size *sizes); +#define ARMADA_FBDEV_DRIVER_OPS \ + .fbdev_probe = armada_fbdev_driver_fbdev_probe #else -static inline void armada_fbdev_setup(struct drm_device *dev) -{ } +#define ARMADA_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL #endif int armada_overlay_plane_create(struct drm_device *, unsigned long); diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index e51ecc4f7ef4..3dc5f0499e4c 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -12,6 +12,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> @@ -39,6 +40,7 @@ DEFINE_DRM_GEM_FOPS(armada_drm_fops); static const struct drm_driver armada_drm_driver = { .gem_prime_import = armada_gem_prime_import, .dumb_create = armada_gem_dumb_create, + ARMADA_FBDEV_DRIVER_OPS, .major = 1, .minor = 0, .name = "armada-drm", @@ -137,7 +139,7 @@ static int armada_drm_bind(struct device *dev) armada_drm_debugfs_init(priv->drm.primary); #endif - armada_fbdev_setup(&priv->drm); + drm_client_setup(&priv->drm, NULL); return 0; diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index d223176912b6..6ee7ce04ee71 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -39,8 +39,10 @@ static const struct fb_ops armada_fb_ops = { .fb_destroy = armada_fbdev_fb_destroy, }; -static int armada_fbdev_create(struct drm_fb_helper *fbh, - struct drm_fb_helper_surface_size *sizes) +static const struct drm_fb_helper_funcs armada_fbdev_helper_funcs; + +int armada_fbdev_driver_fbdev_probe(struct drm_fb_helper *fbh, + struct drm_fb_helper_surface_size *sizes) { struct drm_device *dev = fbh->dev; struct drm_mode_fb_cmd2 mode; @@ -98,6 +100,7 @@ static int armada_fbdev_create(struct drm_fb_helper *fbh, info->fix.smem_len = obj->obj.size; info->screen_size = obj->obj.size; info->screen_base = ptr; + fbh->funcs = &armada_fbdev_helper_funcs; fbh->fb = &dfb->fb; drm_fb_helper_fill_info(info, fbh, sizes); @@ -112,109 +115,3 @@ static int armada_fbdev_create(struct drm_fb_helper *fbh, dfb->fb.funcs->destroy(&dfb->fb); return ret; } - -static int armada_fb_probe(struct drm_fb_helper *fbh, - struct drm_fb_helper_surface_size *sizes) -{ - int ret = 0; - - if (!fbh->fb) { - ret = armada_fbdev_create(fbh, sizes); - if (ret == 0) - ret = 1; - } - return ret; -} - -static const struct drm_fb_helper_funcs armada_fb_helper_funcs = { - .fb_probe = armada_fb_probe, -}; - -/* - * Fbdev client and struct drm_client_funcs - */ - -static void armada_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fbh = drm_fb_helper_from_client(client); - - if (fbh->info) { - drm_fb_helper_unregister_info(fbh); - } else { - drm_client_release(&fbh->client); - drm_fb_helper_unprepare(fbh); - kfree(fbh); - } -} - -static int armada_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int armada_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fbh = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fbh); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fbh); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fbh); -err_drm_err: - drm_err(dev, "armada: Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs armada_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = armada_fbdev_client_unregister, - .restore = armada_fbdev_client_restore, - .hotplug = armada_fbdev_client_hotplug, -}; - -void armada_fbdev_setup(struct drm_device *dev) -{ - struct drm_fb_helper *fbh; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fbh = kzalloc(sizeof(*fbh), GFP_KERNEL); - if (!fbh) - return; - drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs); - - ret = drm_client_init(dev, &fbh->client, "fbdev", &armada_fbdev_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_client_init; - } - - drm_client_register(&fbh->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fbh); - kfree(fbh); - return; -} -- GitLab From d4016e311765f5e23d2e42d2277fe54e055801f0 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:12 +0200 Subject: [PATCH 415/970] drm/exynos-drm: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The exynos-drm driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION v4: - revert an unrelated cleanup (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Inki Dae <inki.dae@samsung.com> Cc: Seung-Woo Kim <sw0312.kim@samsung.com> Cc: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-75-tzimmermann@suse.de --- drivers/gpu/drm/exynos/Kconfig | 1 + drivers/gpu/drm/exynos/exynos_drm_drv.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 99 ++--------------------- drivers/gpu/drm/exynos/exynos_drm_fbdev.h | 15 ++-- 4 files changed, 20 insertions(+), 99 deletions(-) diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 733b109a5095..0d13828e7d9e 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -4,6 +4,7 @@ config DRM_EXYNOS depends on OF && DRM && COMMON_CLK depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on MMU + select DRM_CLIENT_SELECTION select DRM_DISPLAY_HELPER if DRM_EXYNOS_DP select DRM_KMS_HELPER select VIDEOMODE_HELPERS diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 7c59e1164a48..2a466d8179f4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -15,6 +15,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> #include <drm/drm_fourcc.h> @@ -111,6 +112,7 @@ static const struct drm_driver exynos_drm_driver = { .dumb_create = exynos_drm_gem_dumb_create, .gem_prime_import = exynos_drm_gem_prime_import, .gem_prime_import_sg_table = exynos_drm_gem_prime_import_sg_table, + EXYNOS_DRM_FBDEV_DRIVER_OPS, .ioctls = exynos_ioctls, .num_ioctls = ARRAY_SIZE(exynos_ioctls), .fops = &exynos_drm_driver_fops, @@ -288,7 +290,7 @@ static int exynos_drm_bind(struct device *dev) if (ret < 0) goto err_cleanup_poll; - exynos_drm_fbdev_setup(drm); + drm_client_setup(drm, NULL); return 0; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index a379c8ca435a..9526a25e90ac 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -23,7 +23,6 @@ #include "exynos_drm_fbdev.h" #define MAX_CONNECTOR 4 -#define PREFERRED_BPP 32 static int exynos_drm_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { @@ -87,8 +86,11 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, return 0; } -static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) +static const struct drm_fb_helper_funcs exynos_drm_fbdev_helper_funcs = { +}; + +int exynos_drm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct exynos_drm_gem *exynos_gem; struct drm_device *dev = helper->dev; @@ -120,6 +122,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, ret = PTR_ERR(helper->fb); goto err_destroy_gem; } + helper->funcs = &exynos_drm_fbdev_helper_funcs; ret = exynos_drm_fbdev_update(helper, sizes, exynos_gem); if (ret < 0) @@ -134,93 +137,3 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, exynos_drm_gem_destroy(exynos_gem); return ret; } - -static const struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = { - .fb_probe = exynos_drm_fbdev_create, -}; - -/* - * struct drm_client - */ - -static void exynos_drm_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int exynos_drm_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int exynos_drm_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs exynos_drm_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = exynos_drm_fbdev_client_unregister, - .restore = exynos_drm_fbdev_client_restore, - .hotplug = exynos_drm_fbdev_client_hotplug, -}; - -void exynos_drm_fbdev_setup(struct drm_device *dev) -{ - struct drm_fb_helper *fb_helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, PREFERRED_BPP, &exynos_drm_fb_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &exynos_drm_fbdev_client_funcs); - if (ret) - goto err_drm_client_init; - - drm_client_register(&fb_helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); -} diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h index 1e1dea627cd9..02a9201abea3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h @@ -11,12 +11,17 @@ #ifndef _EXYNOS_DRM_FBDEV_H_ #define _EXYNOS_DRM_FBDEV_H_ -#ifdef CONFIG_DRM_FBDEV_EMULATION -void exynos_drm_fbdev_setup(struct drm_device *dev); +struct drm_fb_helper; +struct drm_fb_helper_surface_size; + +#if defined(CONFIG_DRM_FBDEV_EMULATION) +int exynos_drm_fbdev_driver_fbdev_probe(struct drm_fb_helper *fbh, + struct drm_fb_helper_surface_size *sizes); +#define EXYNOS_DRM_FBDEV_DRIVER_OPS \ + .fbdev_probe = exynos_drm_fbdev_driver_fbdev_probe #else -static inline void exynos_drm_fbdev_setup(struct drm_device *dev) -{ -} +#define EXYNOS_DRM_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL #endif #endif -- GitLab From aecdbfe459a08eb317040bf5cc8a9c60a1d4aaf3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:13 +0200 Subject: [PATCH 416/970] drm/gma500: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-76-tzimmermann@suse.de --- drivers/gpu/drm/gma500/Kconfig | 1 + drivers/gpu/drm/gma500/fbdev.c | 100 +++---------------------------- drivers/gpu/drm/gma500/psb_drv.c | 4 +- drivers/gpu/drm/gma500/psb_drv.h | 12 +++- 4 files changed, 20 insertions(+), 97 deletions(-) diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig index efb4a2dd2f80..c2927c37c40b 100644 --- a/drivers/gpu/drm/gma500/Kconfig +++ b/drivers/gpu/drm/gma500/Kconfig @@ -2,6 +2,7 @@ config DRM_GMA500 tristate "Intel GMA500/600/3600/3650 KMS Framebuffer" depends on DRM && PCI && X86 && MMU + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION select I2C diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c index 98b44974d42d..8edefea2ef59 100644 --- a/drivers/gpu/drm/gma500/fbdev.c +++ b/drivers/gpu/drm/gma500/fbdev.c @@ -143,12 +143,15 @@ static const struct fb_ops psb_fbdev_fb_ops = { .fb_destroy = psb_fbdev_fb_destroy, }; +static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = { +}; + /* - * struct drm_fb_helper_funcs + * struct drm_driver */ -static int psb_fbdev_fb_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) +int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_device *dev = fb_helper->dev; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); @@ -206,6 +209,7 @@ static int psb_fbdev_fb_probe(struct drm_fb_helper *fb_helper, goto err_drm_gem_object_put; } + fb_helper->funcs = &psb_fbdev_fb_helper_funcs; fb_helper->fb = fb; info = drm_fb_helper_alloc_info(fb_helper); @@ -246,93 +250,3 @@ static int psb_fbdev_fb_probe(struct drm_fb_helper *fb_helper, drm_gem_object_put(obj); return ret; } - -static const struct drm_fb_helper_funcs psb_fbdev_fb_helper_funcs = { - .fb_probe = psb_fbdev_fb_probe, -}; - -/* - * struct drm_client_funcs and setup code - */ - -static void psb_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_fb_helper_unprepare(fb_helper); - drm_client_release(&fb_helper->client); - kfree(fb_helper); - } -} - -static int psb_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int psb_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup gma500 fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs psb_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = psb_fbdev_client_unregister, - .restore = psb_fbdev_client_restore, - .hotplug = psb_fbdev_client_hotplug, -}; - -void psb_fbdev_setup(struct drm_psb_private *dev_priv) -{ - struct drm_device *dev = &dev_priv->dev; - struct drm_fb_helper *fb_helper; - int ret; - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fbdev_fb_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "fbdev-gma500", &psb_fbdev_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_fb_helper_unprepare; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_fb_helper_unprepare: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); -} diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 8b64f61ffaf9..43deefef6ad2 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -20,6 +20,7 @@ #include <acpi/video.h> #include <drm/drm.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> @@ -475,7 +476,7 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - psb_fbdev_setup(dev_priv); + drm_client_setup(dev, NULL); return 0; } @@ -506,6 +507,7 @@ static const struct drm_driver driver = { .num_ioctls = ARRAY_SIZE(psb_ioctls), .dumb_create = psb_gem_dumb_create, + PSB_FBDEV_DRIVER_OPS, .ioctls = psb_ioctls, .fops = &psb_gem_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index bddf89b82fec..de62cbfcdc72 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -184,6 +184,9 @@ #define KSEL_BYPASS_25 6 #define KSEL_BYPASS_83_100 7 +struct drm_fb_helper; +struct drm_fb_helper_surface_size; + struct opregion_header; struct opregion_acpi; struct opregion_swsci; @@ -597,10 +600,13 @@ struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev, /* fbdev */ #if defined(CONFIG_DRM_FBDEV_EMULATION) -void psb_fbdev_setup(struct drm_psb_private *dev_priv); +int psb_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes); +#define PSB_FBDEV_DRIVER_OPS \ + .fbdev_probe = psb_fbdev_driver_fbdev_probe #else -static inline void psb_fbdev_setup(struct drm_psb_private *dev_priv) -{ } +#define PSB_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL #endif /* backlight.c */ -- GitLab From fe96a73ae530685365549f6f8a889d45844f9dfb Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:14 +0200 Subject: [PATCH 417/970] drm/msm: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The msm driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Rob Clark <robdclark@gmail.com> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Cc: Sean Paul <sean@poorly.run> Cc: Marijn Suijten <marijn.suijten@somainline.org> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-77-tzimmermann@suse.de --- drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/msm_drv.c | 4 +- drivers/gpu/drm/msm/msm_drv.h | 13 ++- drivers/gpu/drm/msm/msm_fbdev.c | 144 ++++++-------------------------- 4 files changed, 39 insertions(+), 123 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index c8dda0ebd043..f16d7c00e089 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -14,6 +14,7 @@ config DRM_MSM select IOMMU_IO_PGTABLE select QCOM_MDT_LOADER if ARCH_QCOM select REGULATOR + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_AUX_BUS select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9c33f4e3f822..22fe0716d18b 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -10,6 +10,7 @@ #include <linux/of_address.h> #include <linux/uaccess.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> @@ -292,7 +293,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) if (priv->kms_init) { drm_kms_helper_poll_init(ddev); - msm_fbdev_setup(ddev); + drm_client_setup(ddev, NULL); } return 0; @@ -903,6 +904,7 @@ static const struct drm_driver msm_driver = { #ifdef CONFIG_DEBUG_FS .debugfs_init = msm_debugfs_init, #endif + MSM_FBDEV_DRIVER_OPS, .show_fdinfo = msm_show_fdinfo, .ioctls = msm_ioctls, .num_ioctls = ARRAY_SIZE(msm_ioctls), diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 0d3adf398bc1..15de89b3cd3e 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -40,6 +40,9 @@ extern struct fault_attr fail_gem_iova; # define should_fail(attr, size) 0 #endif +struct drm_fb_helper; +struct drm_fb_helper_surface_size; + struct msm_kms; struct msm_gpu; struct msm_mmu; @@ -294,11 +297,13 @@ struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format); #ifdef CONFIG_DRM_FBDEV_EMULATION -void msm_fbdev_setup(struct drm_device *dev); +int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); +#define MSM_FBDEV_DRIVER_OPS \ + .fbdev_probe = msm_fbdev_driver_fbdev_probe #else -static inline void msm_fbdev_setup(struct drm_device *dev) -{ -} +#define MSM_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL #endif struct hdmi; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 030bedac632d..c62249b1ab3d 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -65,8 +65,31 @@ static const struct fb_ops msm_fb_ops = { .fb_destroy = msm_fbdev_fb_destroy, }; -static int msm_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) +static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + +static const struct drm_fb_helper_funcs msm_fbdev_helper_funcs = { + .fb_dirty = msm_fbdev_fb_dirty, +}; + +int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_device *dev = helper->dev; struct msm_drm_private *priv = dev->dev_private; @@ -114,6 +137,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, DBG("fbi=%p, dev=%p", fbi, dev); + helper->funcs = &msm_fbdev_helper_funcs; helper->fb = fb; fbi->fbops = &msm_fb_ops; @@ -138,119 +162,3 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, drm_framebuffer_remove(fb); return ret; } - -static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper, - struct drm_clip_rect *clip) -{ - struct drm_device *dev = helper->dev; - int ret; - - /* Call damage handlers only if necessary */ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->fb->funcs->dirty) { - ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) - return ret; - } - - return 0; -} - -static const struct drm_fb_helper_funcs msm_fb_helper_funcs = { - .fb_probe = msm_fbdev_create, - .fb_dirty = msm_fbdev_fb_dirty, -}; - -/* - * struct drm_client - */ - -static void msm_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int msm_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int msm_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs msm_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = msm_fbdev_client_unregister, - .restore = msm_fbdev_client_restore, - .hotplug = msm_fbdev_client_hotplug, -}; - -/* initialize fbdev helper */ -void msm_fbdev_setup(struct drm_device *dev) -{ - struct drm_fb_helper *helper; - int ret; - - if (!fbdev) - return; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - helper = kzalloc(sizeof(*helper), GFP_KERNEL); - if (!helper) - return; - drm_fb_helper_prepare(dev, helper, 32, &msm_fb_helper_funcs); - - ret = drm_client_init(dev, &helper->client, "fbdev", &msm_fbdev_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_fb_helper_unprepare; - } - - drm_client_register(&helper->client); - - return; - -err_drm_fb_helper_unprepare: - drm_fb_helper_unprepare(helper); - kfree(helper); -} -- GitLab From 41d48e557e01582780eb1426407bd9b26c0bad31 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:15 +0200 Subject: [PATCH 418/970] drm/radeon: Run DRM default client setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The radeon driver specifies a preferred color mode depending on the available video memory, with a default of 32. Adapt this for the new client interface. v5: - select DRM_CLIENT_SELECTION v2: - style changes Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-78-tzimmermann@suse.de --- drivers/gpu/drm/radeon/Kconfig | 1 + drivers/gpu/drm/radeon/radeon_drv.c | 14 +++- drivers/gpu/drm/radeon/radeon_fbdev.c | 114 ++------------------------ drivers/gpu/drm/radeon/radeon_mode.h | 12 ++- 4 files changed, 28 insertions(+), 113 deletions(-) diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig index f98356be0af2..9c6c74a75778 100644 --- a/drivers/gpu/drm/radeon/Kconfig +++ b/drivers/gpu/drm/radeon/Kconfig @@ -5,6 +5,7 @@ config DRM_RADEON depends on DRM && PCI && MMU depends on AGP || !AGP select FW_LOADER + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HELPER select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index f36aa71c57c7..eae79f02d254 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -38,8 +38,10 @@ #include <linux/pci.h> #include <drm/drm_aperture.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem.h> #include <drm/drm_ioctl.h> #include <drm/drm_pciids.h> @@ -261,6 +263,7 @@ static int radeon_pci_probe(struct pci_dev *pdev, unsigned long flags = 0; struct drm_device *ddev; struct radeon_device *rdev; + const struct drm_format_info *format; int ret; if (!ent) @@ -324,7 +327,14 @@ static int radeon_pci_probe(struct pci_dev *pdev, if (ret) goto err_agp; - radeon_fbdev_setup(ddev->dev_private); + if (rdev->mc.real_vram_size <= (8 * 1024 * 1024)) + format = drm_format_info(DRM_FORMAT_C8); + else if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32 * 1024 * 1024)) + format = drm_format_info(DRM_FORMAT_RGB565); + else + format = NULL; + + drm_client_setup(ddev, format); return 0; @@ -590,6 +600,8 @@ static const struct drm_driver kms_driver = { .gem_prime_import_sg_table = radeon_gem_prime_import_sg_table, + RADEON_FBDEV_DRIVER_OPS, + .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c index fb70de29545c..0aa20c8df546 100644 --- a/drivers/gpu/drm/radeon/radeon_fbdev.c +++ b/drivers/gpu/drm/radeon/radeon_fbdev.c @@ -198,12 +198,11 @@ static const struct fb_ops radeon_fbdev_fb_ops = { .fb_destroy = radeon_fbdev_fb_destroy, }; -/* - * Fbdev helpers and struct drm_fb_helper_funcs - */ +static const struct drm_fb_helper_funcs radeon_fbdev_fb_helper_funcs = { +}; -static int radeon_fbdev_fb_helper_fb_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) +int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) { struct radeon_device *rdev = fb_helper->dev->dev_private; struct drm_mode_fb_cmd2 mode_cmd = { }; @@ -243,6 +242,7 @@ static int radeon_fbdev_fb_helper_fb_probe(struct drm_fb_helper *fb_helper, } /* setup helper */ + fb_helper->funcs = &radeon_fbdev_fb_helper_funcs; fb_helper->fb = fb; /* okay we have an object now allocate the framebuffer */ @@ -288,110 +288,6 @@ static int radeon_fbdev_fb_helper_fb_probe(struct drm_fb_helper *fb_helper, return ret; } -static const struct drm_fb_helper_funcs radeon_fbdev_fb_helper_funcs = { - .fb_probe = radeon_fbdev_fb_helper_fb_probe, -}; - -/* - * Fbdev client and struct drm_client_funcs - */ - -static void radeon_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = fb_helper->dev; - struct radeon_device *rdev = dev->dev_private; - - if (fb_helper->info) { - vga_switcheroo_client_fb_set(rdev->pdev, NULL); - drm_helper_force_disable_all(dev); - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int radeon_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - vga_switcheroo_process_delayed_switch(); - - return 0; -} - -static int radeon_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - struct radeon_device *rdev = dev->dev_private; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - vga_switcheroo_client_fb_set(rdev->pdev, fb_helper->info); - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup radeon fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs radeon_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = radeon_fbdev_client_unregister, - .restore = radeon_fbdev_client_restore, - .hotplug = radeon_fbdev_client_hotplug, -}; - -void radeon_fbdev_setup(struct radeon_device *rdev) -{ - struct drm_fb_helper *fb_helper; - int bpp_sel = 32; - int ret; - - if (rdev->mc.real_vram_size <= (8 * 1024 * 1024)) - bpp_sel = 8; - else if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32 * 1024 * 1024)) - bpp_sel = 16; - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(rdev_to_drm(rdev), fb_helper, bpp_sel, &radeon_fbdev_fb_helper_funcs); - - ret = drm_client_init(rdev_to_drm(rdev), &fb_helper->client, "radeon-fbdev", - &radeon_fbdev_client_funcs); - if (ret) { - drm_err(rdev_to_drm(rdev), "Failed to register client: %d\n", ret); - goto err_drm_client_init; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); -} - void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) { if (rdev_to_drm(rdev)->fb_helper) diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 421c83fc70dc..12a1d99a1815 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -38,6 +38,9 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> +struct drm_fb_helper; +struct drm_fb_helper_surface_size; + struct edid; struct drm_edid; struct radeon_bo; @@ -935,12 +938,15 @@ void dce8_program_fmt(struct drm_encoder *encoder); /* fbdev layer */ #if defined(CONFIG_DRM_FBDEV_EMULATION) -void radeon_fbdev_setup(struct radeon_device *rdev); +int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes); +#define RADEON_FBDEV_DRIVER_OPS \ + .fbdev_probe = radeon_fbdev_driver_fbdev_probe void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); #else -static inline void radeon_fbdev_setup(struct radeon_device *rdev) -{ } +#define RADEON_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL static inline void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) { } static inline bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) -- GitLab From 5208989d59f989762578b497aecb1e2b1b0780fd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:16 +0200 Subject: [PATCH 419/970] drm/tegra: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The tegra driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Mikko Perttunen <mperttunen@nvidia.com> Cc: Jonathan Hunter <jonathanh@nvidia.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-79-tzimmermann@suse.de --- drivers/gpu/drm/tegra/Kconfig | 1 + drivers/gpu/drm/tegra/drm.c | 5 +- drivers/gpu/drm/tegra/drm.h | 12 +++-- drivers/gpu/drm/tegra/fbdev.c | 98 +++-------------------------------- 4 files changed, 20 insertions(+), 96 deletions(-) diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index e688d8104652..8a3b16aac5d6 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -5,6 +5,7 @@ config DRM_TEGRA depends on COMMON_CLK depends on DRM depends on OF + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index d9f0728c3afd..6186524cf1a4 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -15,6 +15,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> #include <drm/drm_fourcc.h> @@ -891,6 +892,8 @@ static const struct drm_driver tegra_drm_driver = { .dumb_create = tegra_bo_dumb_create, + TEGRA_FBDEV_DRIVER_OPS, + .ioctls = tegra_drm_ioctls, .num_ioctls = ARRAY_SIZE(tegra_drm_ioctls), .fops = &tegra_drm_fops, @@ -1268,7 +1271,7 @@ static int host1x_drm_probe(struct host1x_device *dev) if (err < 0) goto hub; - tegra_fbdev_setup(drm); + drm_client_setup(drm, NULL); return 0; diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 2f3781e04b0a..0b65e69f3a8a 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -25,6 +25,9 @@ /* XXX move to include/uapi/drm/drm_fourcc.h? */ #define DRM_FORMAT_MOD_NVIDIA_SECTOR_LAYOUT BIT_ULL(22) +struct drm_fb_helper; +struct drm_fb_helper_surface_size; + struct edid; struct reset_control; @@ -190,10 +193,13 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, const struct drm_mode_fb_cmd2 *cmd); #ifdef CONFIG_DRM_FBDEV_EMULATION -void tegra_fbdev_setup(struct drm_device *drm); +int tegra_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); +#define TEGRA_FBDEV_DRIVER_OPS \ + .fbdev_probe = tegra_fbdev_driver_fbdev_probe #else -static inline void tegra_fbdev_setup(struct drm_device *drm) -{ } +#define TEGRA_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL #endif extern struct platform_driver tegra_display_hub_driver; diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c index db6eaac3d30e..cd9d798f8870 100644 --- a/drivers/gpu/drm/tegra/fbdev.c +++ b/drivers/gpu/drm/tegra/fbdev.c @@ -66,8 +66,11 @@ static const struct fb_ops tegra_fb_ops = { .fb_destroy = tegra_fbdev_fb_destroy, }; -static int tegra_fbdev_probe(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) +static const struct drm_fb_helper_funcs tegra_fbdev_helper_funcs = { +}; + +int tegra_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct tegra_drm *tegra = helper->dev->dev_private; struct drm_device *drm = helper->dev; @@ -112,6 +115,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, return PTR_ERR(fb); } + helper->funcs = &tegra_fbdev_helper_funcs; helper->fb = fb; helper->info = info; @@ -144,93 +148,3 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, drm_framebuffer_remove(fb); return err; } - -static const struct drm_fb_helper_funcs tegra_fb_helper_funcs = { - .fb_probe = tegra_fbdev_probe, -}; - -/* - * struct drm_client - */ - -static void tegra_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int tegra_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int tegra_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs tegra_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = tegra_fbdev_client_unregister, - .restore = tegra_fbdev_client_restore, - .hotplug = tegra_fbdev_client_hotplug, -}; - -void tegra_fbdev_setup(struct drm_device *dev) -{ - struct drm_fb_helper *helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - helper = kzalloc(sizeof(*helper), GFP_KERNEL); - if (!helper) - return; - drm_fb_helper_prepare(dev, helper, 32, &tegra_fb_helper_funcs); - - ret = drm_client_init(dev, &helper->client, "fbdev", &tegra_fbdev_client_funcs); - if (ret) - goto err_drm_client_init; - - drm_client_register(&helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(helper); - kfree(helper); -} -- GitLab From eae9b5437ab968e7f26afc5835c3b7384e0f84e0 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:17 +0200 Subject: [PATCH 420/970] drm/omapdrm: Remove struct drm_fb_helper from struct omap_fbdev. Store instances of drm_fb_helper and struct omap_fbdev separately. This will allow omapdrm to use the common fbdev client, which allocates its own instance of struct drm_fb_helper. There is at most one instance of each per DRM device, so both can be referenced directly from the omap and DRM device structures. A later patchset might rework the common fbdev client to allow for storing both, drm_fb_helper and omap_fbdev, together in the same place. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-80-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/omap_drv.h | 3 ++ drivers/gpu/drm/omapdrm/omap_fbdev.c | 42 +++++++++++++++------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 4c7217b35f6b..d903568fd8cc 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -32,6 +32,7 @@ #define MODULE_NAME "omapdrm" struct omap_drm_usergart; +struct omap_fbdev; struct omap_drm_pipeline { struct drm_crtc *crtc; @@ -97,6 +98,8 @@ struct omap_drm_private { /* memory bandwidth limit if it is needed on the platform */ unsigned int max_bandwidth; + + struct omap_fbdev *fbdev; }; diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 523be34682ca..044e80403c3b 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -13,6 +13,7 @@ #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_framebuffer_helper.h> +#include <drm/drm_managed.h> #include <drm/drm_util.h> #include "omap_drv.h" @@ -26,10 +27,8 @@ module_param_named(ywrap, ywrap_enabled, bool, 0644); * fbdev funcs, to implement legacy fbdev interface on top of drm driver */ -#define to_omap_fbdev(x) container_of(x, struct omap_fbdev, base) - struct omap_fbdev { - struct drm_fb_helper base; + struct drm_device *dev; bool ywrap_enabled; /* for deferred dmm roll when getting called in atomic ctx */ @@ -41,7 +40,7 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi); static void pan_worker(struct work_struct *work) { struct omap_fbdev *fbdev = container_of(work, struct omap_fbdev, work); - struct drm_fb_helper *helper = &fbdev->base; + struct drm_fb_helper *helper = fbdev->dev->fb_helper; struct fb_info *fbi = helper->info; struct drm_gem_object *bo = drm_gem_fb_get_obj(helper->fb, 0); int npages; @@ -55,24 +54,25 @@ FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev, drm_fb_helper_damage_range, drm_fb_helper_damage_area) -static int omap_fbdev_pan_display(struct fb_var_screeninfo *var, - struct fb_info *fbi) +static int omap_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { struct drm_fb_helper *helper = get_fb(fbi); - struct omap_fbdev *fbdev = to_omap_fbdev(helper); + struct omap_drm_private *priv; + struct omap_fbdev *fbdev; if (!helper) goto fallback; + priv = helper->dev->dev_private; + fbdev = priv->fbdev; + if (!fbdev->ywrap_enabled) goto fallback; - if (drm_can_sleep()) { + if (drm_can_sleep()) pan_worker(&fbdev->work); - } else { - struct omap_drm_private *priv = helper->dev->dev_private; + else queue_work(priv->wq, &fbdev->work); - } return 0; @@ -92,7 +92,6 @@ static void omap_fbdev_fb_destroy(struct fb_info *info) struct drm_fb_helper *helper = info->par; struct drm_framebuffer *fb = helper->fb; struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0); - struct omap_fbdev *fbdev = to_omap_fbdev(helper); DBG(); @@ -104,7 +103,7 @@ static void omap_fbdev_fb_destroy(struct fb_info *info) drm_client_release(&helper->client); drm_fb_helper_unprepare(helper); - kfree(fbdev); + kfree(helper); } /* @@ -128,9 +127,9 @@ static const struct fb_ops omap_fb_ops = { static int omap_fbdev_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct omap_fbdev *fbdev = to_omap_fbdev(helper); struct drm_device *dev = helper->dev; struct omap_drm_private *priv = dev->dev_private; + struct omap_fbdev *fbdev = priv->fbdev; struct drm_framebuffer *fb = NULL; union omap_gem_size gsize; struct fb_info *fbi = NULL; @@ -338,6 +337,7 @@ static const struct drm_client_funcs omap_fbdev_client_funcs = { void omap_fbdev_setup(struct drm_device *dev) { + struct omap_drm_private *priv = dev->dev_private; struct omap_fbdev *fbdev; struct drm_fb_helper *helper; int ret; @@ -345,24 +345,28 @@ void omap_fbdev_setup(struct drm_device *dev) drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); + fbdev = drmm_kzalloc(dev, sizeof(*fbdev), GFP_KERNEL); if (!fbdev) return; - helper = &fbdev->base; + fbdev->dev = dev; + INIT_WORK(&fbdev->work, pan_worker); + + priv->fbdev = fbdev; + helper = kzalloc(sizeof(*helper), GFP_KERNEL); + if (!helper) + return; drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs); ret = drm_client_init(dev, &helper->client, "fbdev", &omap_fbdev_client_funcs); if (ret) goto err_drm_client_init; - INIT_WORK(&fbdev->work, pan_worker); - drm_client_register(&helper->client); return; err_drm_client_init: drm_fb_helper_unprepare(helper); - kfree(fbdev); + kfree(helper); } -- GitLab From 15499749fbb864cc0737bc8ecaf0e28a6b6d62dd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Tue, 24 Sep 2024 09:13:18 +0200 Subject: [PATCH 421/970] drm/omapdrm: Run DRM default client setup Rework fbdev probing to support fbdev_probe in struct drm_driver and remove the old fb_probe callback. Provide an initializer macro for struct drm_driver that sets the callback according to the kernel configuration. Call drm_client_setup() to run the kernel's default client setup for DRM. Set fbdev_probe in struct drm_driver, so that the client setup can start the common fbdev client. The omapdrm driver specifies a preferred color mode of 32. As this is the default if no format has been given, leave it out entirely. v5: - select DRM_CLIENT_SELECTION Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924071734.98201-81-tzimmermann@suse.de --- drivers/gpu/drm/omapdrm/Kconfig | 1 + drivers/gpu/drm/omapdrm/omap_drv.c | 1 + drivers/gpu/drm/omapdrm/omap_fbdev.c | 131 ++++++--------------------- drivers/gpu/drm/omapdrm/omap_fbdev.h | 8 ++ 4 files changed, 39 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index fbd9af758581..9d4016bd0f44 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig @@ -4,6 +4,7 @@ config DRM_OMAP depends on MMU depends on DRM && OF depends on ARCH_OMAP2PLUS || (COMPILE_TEST && PAGE_SIZE_LESS_THAN_64KB) + select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index a982378aa141..1796cd20a877 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -647,6 +647,7 @@ static const struct drm_driver omap_drm_driver = { .gem_prime_import = omap_gem_prime_import, .dumb_create = omap_gem_dumb_create, .dumb_map_offset = omap_gem_dumb_map_offset, + OMAP_FBDEV_DRIVER_OPS, .ioctls = ioctls, .num_ioctls = DRM_OMAP_NUM_IOCTLS, .fops = &omapdriver_fops, diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 044e80403c3b..f4bd0c6e3f34 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -6,6 +6,7 @@ #include <linux/fb.h> +#include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> @@ -124,8 +125,32 @@ static const struct fb_ops omap_fb_ops = { .fb_destroy = omap_fbdev_fb_destroy, }; -static int omap_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) +static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) + return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + + return 0; +} + +static const struct drm_fb_helper_funcs omap_fbdev_helper_funcs = { + .fb_dirty = omap_fbdev_dirty, +}; + +static struct drm_fb_helper *get_fb(struct fb_info *fbi) +{ + if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) { + /* these are not the fb's you're looking for */ + return NULL; + } + return fbi->par; +} + +int omap_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) { struct drm_device *dev = helper->dev; struct omap_drm_private *priv = dev->dev_private; @@ -207,6 +232,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, DBG("fbi=%p, dev=%p", fbi, dev); + helper->funcs = &omap_fbdev_helper_funcs; helper->fb = fb; fbi->fbops = &omap_fb_ops; @@ -253,94 +279,10 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, return ret; } -static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) -{ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - if (helper->fb->funcs->dirty) - return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - - return 0; -} - -static const struct drm_fb_helper_funcs omap_fb_helper_funcs = { - .fb_probe = omap_fbdev_create, - .fb_dirty = omap_fbdev_dirty, -}; - -static struct drm_fb_helper *get_fb(struct fb_info *fbi) -{ - if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) { - /* these are not the fb's you're looking for */ - return NULL; - } - return fbi->par; -} - -/* - * struct drm_client - */ - -static void omap_fbdev_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int omap_fbdev_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int omap_fbdev_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs omap_fbdev_client_funcs = { - .owner = THIS_MODULE, - .unregister = omap_fbdev_client_unregister, - .restore = omap_fbdev_client_restore, - .hotplug = omap_fbdev_client_hotplug, -}; - void omap_fbdev_setup(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_fbdev *fbdev; - struct drm_fb_helper *helper; - int ret; drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); @@ -353,20 +295,5 @@ void omap_fbdev_setup(struct drm_device *dev) priv->fbdev = fbdev; - helper = kzalloc(sizeof(*helper), GFP_KERNEL); - if (!helper) - return; - drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs); - - ret = drm_client_init(dev, &helper->client, "fbdev", &omap_fbdev_client_funcs); - if (ret) - goto err_drm_client_init; - - drm_client_register(&helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(helper); - kfree(helper); + drm_client_setup(dev, NULL); } diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.h b/drivers/gpu/drm/omapdrm/omap_fbdev.h index 74c691a8d45f..283e35b42ada 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.h +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.h @@ -10,10 +10,18 @@ #define __OMAPDRM_FBDEV_H__ struct drm_device; +struct drm_fb_helper; +struct drm_fb_helper_surface_size; #ifdef CONFIG_DRM_FBDEV_EMULATION +int omap_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); +#define OMAP_FBDEV_DRIVER_OPS \ + .fbdev_probe = omap_fbdev_driver_fbdev_probe void omap_fbdev_setup(struct drm_device *dev); #else +#define OMAP_FBDEV_DRIVER_OPS \ + .fbdev_probe = NULL static inline void omap_fbdev_setup(struct drm_device *dev) { } -- GitLab From 4286cc2c953983d44d248c9de1c81d3a9643345c Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Fri, 13 Sep 2024 17:05:52 +0100 Subject: [PATCH 422/970] drm/sched: Add locking to drm_sched_entity_modify_sched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without the locking amdgpu currently can race between amdgpu_ctx_set_entity_priority() (via drm_sched_entity_modify_sched()) and drm_sched_job_arm(), leading to the latter accesing potentially inconsitent entity->sched_list and entity->num_sched_list pair. v2: * Improve commit message. (Philipp) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Fixes: b37aced31eb0 ("drm/scheduler: implement a function to modify sched list") Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: David Airlie <airlied@gmail.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: dri-devel@lists.freedesktop.org Cc: Philipp Stanner <pstanner@redhat.com> Cc: <stable@vger.kernel.org> # v5.7+ Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240913160559.49054-2-tursulin@igalia.com Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/scheduler/sched_entity.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 567e5ace6d0c..0e002c17fcb6 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -133,8 +133,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, { WARN_ON(!num_sched_list || !sched_list); + spin_lock(&entity->rq_lock); entity->sched_list = sched_list; entity->num_sched_list = num_sched_list; + spin_unlock(&entity->rq_lock); } EXPORT_SYMBOL(drm_sched_entity_modify_sched); -- GitLab From cbc8764e29c2318229261a679b2aafd0f9072885 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Tue, 24 Sep 2024 11:19:08 +0100 Subject: [PATCH 423/970] drm/sched: Always wake up correct scheduler in drm_sched_entity_push_job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since drm_sched_entity_modify_sched() can modify the entities run queue, lets make sure to only dereference the pointer once so both adding and waking up are guaranteed to be consistent. Alternative of moving the spin_unlock to after the wake up would for now be more problematic since the same lock is taken inside drm_sched_rq_update_fifo(). v2: * Improve commit message. (Philipp) * Cache the scheduler pointer directly. (Christian) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Fixes: b37aced31eb0 ("drm/scheduler: implement a function to modify sched list") Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: David Airlie <airlied@gmail.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: Philipp Stanner <pstanner@redhat.com> Cc: dri-devel@lists.freedesktop.org Cc: <stable@vger.kernel.org> # v5.7+ Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924101914.2713-3-tursulin@igalia.com Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/scheduler/sched_entity.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 0e002c17fcb6..a75eede8bf8d 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -599,6 +599,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) /* first job wakes up scheduler */ if (first) { + struct drm_gpu_scheduler *sched; + struct drm_sched_rq *rq; + /* Add the entity to the run queue */ spin_lock(&entity->rq_lock); if (entity->stopped) { @@ -608,13 +611,16 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) return; } - drm_sched_rq_add_entity(entity->rq, entity); + rq = entity->rq; + sched = rq->sched; + + drm_sched_rq_add_entity(rq, entity); spin_unlock(&entity->rq_lock); if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) drm_sched_rq_update_fifo(entity, submit_ts); - drm_sched_wakeup(entity->rq->sched); + drm_sched_wakeup(sched); } } EXPORT_SYMBOL(drm_sched_entity_push_job); -- GitLab From 087913e0ba2b3b9d7ccbafb2acf5dab9e35ae1d5 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Tue, 24 Sep 2024 11:19:09 +0100 Subject: [PATCH 424/970] drm/sched: Always increment correct scheduler score MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Entities run queue can change during drm_sched_entity_push_job() so make sure to update the score consistently. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Fixes: d41a39dda140 ("drm/scheduler: improve job distribution with multiple queues") Cc: Nirmoy Das <nirmoy.das@amd.com> Cc: Christian König <christian.koenig@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: David Airlie <airlied@gmail.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: dri-devel@lists.freedesktop.org Cc: <stable@vger.kernel.org> # v5.9+ Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924101914.2713-4-tursulin@igalia.com Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/scheduler/sched_entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index a75eede8bf8d..b2cf3e0c1838 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -586,7 +586,6 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) ktime_t submit_ts; trace_drm_sched_job(sched_job, entity); - atomic_inc(entity->rq->sched->score); WRITE_ONCE(entity->last_user, current->group_leader); /* @@ -614,6 +613,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) rq = entity->rq; sched = rq->sched; + atomic_inc(sched->score); drm_sched_rq_add_entity(rq, entity); spin_unlock(&entity->rq_lock); -- GitLab From d28af0b6b9580b9f90c265a7da0315b0ad20bbfd Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Tue, 24 Sep 2024 16:09:48 +0100 Subject: [PATCH 425/970] drm/xe/guc_submit: add missing locking in wedged_fini Any non-wedged queue can have a zero refcount here and can be running concurrently with an async queue destroy, therefore dereferencing the queue ptr to check wedge status after the lookup can trigger UAF if queue is not wedged. Fix this by keeping the submission_state lock held around the check to postpone the free and make the check safe, before dropping again around the put() to avoid the deadlock. Fixes: 8ed9aaae39f3 ("drm/xe: Force wedged state and block GT reset upon any GPU hang") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924150947.118433-2-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_guc_submit.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index fbbe6a487bbb..715c761dc7d6 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -290,9 +290,15 @@ static void guc_submit_wedged_fini(void *arg) struct xe_exec_queue *q; unsigned long index; - xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) - if (exec_queue_wedged(q)) + mutex_lock(&guc->submission_state.lock); + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { + if (exec_queue_wedged(q)) { + mutex_unlock(&guc->submission_state.lock); xe_exec_queue_put(q); + mutex_lock(&guc->submission_state.lock); + } + } + mutex_unlock(&guc->submission_state.lock); } static const struct xe_exec_queue_ops guc_exec_queue_ops; -- GitLab From 861108666cc0e999cffeab6aff17b662e68774e3 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Mon, 23 Sep 2024 15:56:48 +0100 Subject: [PATCH 426/970] drm/xe: fix UAF around queue destruction We currently do stuff like queuing the final destruction step on a random system wq, which will outlive the driver instance. With bad timing we can teardown the driver with one or more work workqueue still being alive leading to various UAF splats. Add a fini step to ensure user queues are properly torn down. At this point GuC should already be nuked so queue itself should no longer be referenced from hw pov. v2 (Matt B) - Looks much safer to use a waitqueue and then just wait for the xa_array to become empty before triggering the drain. Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2317 Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923145647.77707-2-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_device.c | 6 +++++- drivers/gpu/drm/xe/xe_device_types.h | 3 +++ drivers/gpu/drm/xe/xe_guc_submit.c | 26 +++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_guc_types.h | 2 ++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 53dcece40fc5..8e9b551c7033 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -295,6 +295,9 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy) if (xe->unordered_wq) destroy_workqueue(xe->unordered_wq); + if (xe->destroy_wq) + destroy_workqueue(xe->destroy_wq); + ttm_device_fini(&xe->ttm); } @@ -358,8 +361,9 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0); xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0); xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0); + xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0); if (!xe->ordered_wq || !xe->unordered_wq || - !xe->preempt_fence_wq) { + !xe->preempt_fence_wq || !xe->destroy_wq) { /* * Cleanup done in xe_device_destroy via * drmm_add_action_or_reset register above diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 484fb34dde98..85bede4dd646 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -422,6 +422,9 @@ struct xe_device { /** @unordered_wq: used to serialize unordered work, mostly display */ struct workqueue_struct *unordered_wq; + /** @destroy_wq: used to serialize user destroy work, like queue */ + struct workqueue_struct *destroy_wq; + /** @tiles: device tiles */ struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE]; diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 715c761dc7d6..98a6a385a796 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -276,10 +276,26 @@ static struct workqueue_struct *get_submit_wq(struct xe_guc *guc) } #endif +static void xe_guc_submit_fini(struct xe_guc *guc) +{ + struct xe_device *xe = guc_to_xe(guc); + struct xe_gt *gt = guc_to_gt(guc); + int ret; + + ret = wait_event_timeout(guc->submission_state.fini_wq, + xa_empty(&guc->submission_state.exec_queue_lookup), + HZ * 5); + + drain_workqueue(xe->destroy_wq); + + xe_gt_assert(gt, ret); +} + static void guc_submit_fini(struct drm_device *drm, void *arg) { struct xe_guc *guc = arg; + xe_guc_submit_fini(guc); xa_destroy(&guc->submission_state.exec_queue_lookup); free_submit_wq(guc); } @@ -351,6 +367,8 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) xa_init(&guc->submission_state.exec_queue_lookup); + init_waitqueue_head(&guc->submission_state.fini_wq); + primelockdep(guc); return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc); @@ -367,6 +385,9 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa xe_guc_id_mgr_release_locked(&guc->submission_state.idm, q->guc->id, q->width); + + if (xa_empty(&guc->submission_state.exec_queue_lookup)) + wake_up(&guc->submission_state.fini_wq); } static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) @@ -1274,13 +1295,16 @@ static void __guc_exec_queue_fini_async(struct work_struct *w) static void guc_exec_queue_fini_async(struct xe_exec_queue *q) { + struct xe_guc *guc = exec_queue_to_guc(q); + struct xe_device *xe = guc_to_xe(guc); + INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async); /* We must block on kernel engines so slabs are empty on driver unload */ if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q)) __guc_exec_queue_fini_async(&q->guc->fini_async); else - queue_work(system_wq, &q->guc->fini_async); + queue_work(xe->destroy_wq, &q->guc->fini_async); } static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q) diff --git a/drivers/gpu/drm/xe/xe_guc_types.h b/drivers/gpu/drm/xe/xe_guc_types.h index 546ac6350a31..69046f698271 100644 --- a/drivers/gpu/drm/xe/xe_guc_types.h +++ b/drivers/gpu/drm/xe/xe_guc_types.h @@ -81,6 +81,8 @@ struct xe_guc { #endif /** @submission_state.enabled: submission is enabled */ bool enabled; + /** @submission_state.fini_wq: submit fini wait queue */ + wait_queue_head_t fini_wq; } submission_state; /** @hwconfig: Hardware config state */ struct { -- GitLab From 76f1ed087b562a469f2153076f179854b749c09a Mon Sep 17 00:00:00 2001 From: Phil Sutter <phil@nwl.cc> Date: Wed, 25 Sep 2024 20:01:20 +0200 Subject: [PATCH 427/970] netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED Fix the comment which incorrectly defines it as NLA_U32. Fixes: 3b49e2e94e6e ("netfilter: nf_tables: add flow table netlink frontend") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/uapi/linux/netfilter/nf_tables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index d6476ca5d7a6..9e9079321380 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -1694,7 +1694,7 @@ enum nft_flowtable_flags { * * @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING) * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING) - * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) + * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration (NLA_NESTED) * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64) * @NFTA_FLOWTABLE_FLAGS: flags (NLA_U32) -- GitLab From ece207a83e464af710d641f29e32b7a144c48e79 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda <ojeda@kernel.org> Date: Thu, 26 Sep 2024 14:47:51 +0200 Subject: [PATCH 428/970] rust: kernel: sort Rust modules Rust modules are intended to be sorted, thus do so. This makes `rustfmtcheck` to pass again. Fixes: 570172569238 ("Merge tag 'rust-6.12' of https://github.com/Rust-for-Linux/linux") Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20240926124751.345471-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- rust/kernel/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 22a3bfa5a9e9..b5f4b3ce6b48 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -44,8 +44,8 @@ pub mod page; pub mod prelude; pub mod print; -pub mod sizes; pub mod rbtree; +pub mod sizes; mod static_assert; #[doc(hidden)] pub mod std_vendor; -- GitLab From a8ee30f45d5d57467ddb7877ed6914d0eba0af7f Mon Sep 17 00:00:00 2001 From: Alice Ryhl <aliceryhl@google.com> Date: Sun, 15 Sep 2024 14:41:28 +0000 Subject: [PATCH 429/970] rust: sync: require `T: Sync` for `LockedBy::access` The `LockedBy::access` method only requires a shared reference to the owner, so if we have shared access to the `LockedBy` from several threads at once, then two threads could call `access` in parallel and both obtain a shared reference to the inner value. Thus, require that `T: Sync` when calling the `access` method. An alternative is to require `T: Sync` in the `impl Sync for LockedBy`. This patch does not choose that approach as it gives up the ability to use `LockedBy` with `!Sync` types, which is okay as long as you only use `access_mut`. Cc: stable@vger.kernel.org Fixes: 7b1f55e3a984 ("rust: sync: introduce `LockedBy`") Signed-off-by: Alice Ryhl <aliceryhl@google.com> Suggested-by: Boqun Feng <boqun.feng@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://lore.kernel.org/r/20240915-locked-by-sync-fix-v2-1-1a8d89710392@google.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- rust/kernel/sync/locked_by.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/rust/kernel/sync/locked_by.rs b/rust/kernel/sync/locked_by.rs index babc731bd5f6..ce2ee8d87865 100644 --- a/rust/kernel/sync/locked_by.rs +++ b/rust/kernel/sync/locked_by.rs @@ -83,8 +83,12 @@ pub struct LockedBy<T: ?Sized, U: ?Sized> { // SAFETY: `LockedBy` can be transferred across thread boundaries iff the data it protects can. unsafe impl<T: ?Sized + Send, U: ?Sized> Send for LockedBy<T, U> {} -// SAFETY: `LockedBy` serialises the interior mutability it provides, so it is `Sync` as long as the -// data it protects is `Send`. +// SAFETY: If `T` is not `Sync`, then parallel shared access to this `LockedBy` allows you to use +// `access_mut` to hand out `&mut T` on one thread at the time. The requirement that `T: Send` is +// sufficient to allow that. +// +// If `T` is `Sync`, then the `access` method also becomes available, which allows you to obtain +// several `&T` from several threads at once. However, this is okay as `T` is `Sync`. unsafe impl<T: ?Sized + Send, U: ?Sized> Sync for LockedBy<T, U> {} impl<T, U> LockedBy<T, U> { @@ -118,7 +122,10 @@ impl<T: ?Sized, U> LockedBy<T, U> { /// /// Panics if `owner` is different from the data protected by the lock used in /// [`new`](LockedBy::new). - pub fn access<'a>(&'a self, owner: &'a U) -> &'a T { + pub fn access<'a>(&'a self, owner: &'a U) -> &'a T + where + T: Sync, + { build_assert!( size_of::<U>() > 0, "`U` cannot be a ZST because `owner` wouldn't be unique" @@ -127,7 +134,10 @@ pub fn access<'a>(&'a self, owner: &'a U) -> &'a T { panic!("mismatched owners"); } - // SAFETY: `owner` is evidence that the owner is locked. + // SAFETY: `owner` is evidence that there are only shared references to the owner for the + // duration of 'a, so it's not possible to use `Self::access_mut` to obtain a mutable + // reference to the inner value that aliases with this shared reference. The type is `Sync` + // so there are no other requirements. unsafe { &*self.data.get() } } -- GitLab From 732cd686cdd60f9d8c36edac2a14d8f5eea57ee1 Mon Sep 17 00:00:00 2001 From: Gary Guo <gary@garyguo.net> Date: Mon, 16 Sep 2024 01:33:46 +0100 Subject: [PATCH 430/970] rust: fix `ARCH_SLAB_MINALIGN` multiple definition error We use const helpers in form of const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; to aid generation of constants by bindgen because it is otherwise a macro definition of an expression and bindgen doesn't expand the constant. The helpers are then have `RUST_CONST_HELPER` prefix stripped and exposed to Rust code as if `ARCH_SLAB_MISALIGN` is generated natively by bindgen. This works well for most constants, but on RISC-V, `ARCH_SLAB_MINALIGN` is defined directly as literal constant if `!CONFIG_MMU`, and bindgen would generate `ARCH_SLAB_MINALIGN` directly, thus conflict with the one generated through the helper. To fix this, we simply need to block bindgen from generating directly without going through helper. Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409160804.eSg9zh1e-lkp@intel.com/ Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com> Link: https://lore.kernel.org/r/20240916003347.1744345-1-gary@garyguo.net Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- rust/bindgen_parameters | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rust/bindgen_parameters b/rust/bindgen_parameters index a721d466bee4..b7c7483123b7 100644 --- a/rust/bindgen_parameters +++ b/rust/bindgen_parameters @@ -24,3 +24,8 @@ # These functions use the `__preserve_most` calling convention, which neither bindgen # nor Rust currently understand, and which Clang currently declares to be unstable. --blocklist-function __list_.*_report + +# These constants are sometimes not recognized by bindgen depending on config. +# We use const helpers to aid bindgen, to avoid conflicts when constants are +# recognized, block generation of the non-helper constants. +--blocklist-item ARCH_SLAB_MINALIGN -- GitLab From ee615c2bac4ce514110876edd3ceff547aaab6b1 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Mon, 23 Sep 2024 14:45:11 -0700 Subject: [PATCH 431/970] drm/xe: Move IRQ-related registers to dedicated header IRQ registers have a well-defined scope and make sense to collect in a dedicated header file. This also reduces confusion about the GT IRQ registers --- even though those registers relate to the GTs, they actually live outside the GT (in the sgunit) and thus do not need to worry about GT-specific register concepts like forcewake, steering, etc. Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923214514.2031410-2-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/display/xe_display.c | 2 +- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 58 ----------------- drivers/gpu/drm/xe/regs/xe_irq_regs.h | 82 +++++++++++++++++++++++++ drivers/gpu/drm/xe/regs/xe_regs.h | 14 ----- drivers/gpu/drm/xe/xe_gsc.c | 1 + drivers/gpu/drm/xe/xe_guc.c | 1 + drivers/gpu/drm/xe/xe_hw_engine.c | 1 + drivers/gpu/drm/xe/xe_irq.c | 3 +- drivers/gpu/drm/xe/xe_memirq.c | 2 +- 9 files changed, 88 insertions(+), 76 deletions(-) create mode 100644 drivers/gpu/drm/xe/regs/xe_irq_regs.h diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 94ac537f2514..26b2cae11d46 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -4,7 +4,7 @@ */ #include "xe_display.h" -#include "regs/xe_regs.h" +#include "regs/xe_irq_regs.h" #include <linux/fb.h> diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 8d8f6a113a86..fb80042cbe0d 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -567,62 +567,4 @@ #define GT_PERF_STATUS XE_REG(0x1381b4) #define VOLTAGE_MASK REG_GENMASK(10, 0) -/* - * Note: Interrupt registers 1900xx are VF accessible only until version 12.50. - * On newer platforms, VFs are using memory-based interrupts instead. - * However, for simplicity we keep this XE_REG_OPTION_VF tag intact. - */ - -#define GT_INTR_DW(x) XE_REG(0x190018 + ((x) * 4), XE_REG_OPTION_VF) -#define INTR_GSC REG_BIT(31) -#define INTR_GUC REG_BIT(25) -#define INTR_MGUC REG_BIT(24) -#define INTR_BCS8 REG_BIT(23) -#define INTR_BCS(x) REG_BIT(15 - (x)) -#define INTR_CCS(x) REG_BIT(4 + (x)) -#define INTR_RCS0 REG_BIT(0) -#define INTR_VECS(x) REG_BIT(31 - (x)) -#define INTR_VCS(x) REG_BIT(x) - -#define RENDER_COPY_INTR_ENABLE XE_REG(0x190030, XE_REG_OPTION_VF) -#define VCS_VECS_INTR_ENABLE XE_REG(0x190034, XE_REG_OPTION_VF) -#define GUC_SG_INTR_ENABLE XE_REG(0x190038, XE_REG_OPTION_VF) -#define ENGINE1_MASK REG_GENMASK(31, 16) -#define ENGINE0_MASK REG_GENMASK(15, 0) -#define GPM_WGBOXPERF_INTR_ENABLE XE_REG(0x19003c, XE_REG_OPTION_VF) -#define GUNIT_GSC_INTR_ENABLE XE_REG(0x190044, XE_REG_OPTION_VF) -#define CCS_RSVD_INTR_ENABLE XE_REG(0x190048, XE_REG_OPTION_VF) - -#define INTR_IDENTITY_REG(x) XE_REG(0x190060 + ((x) * 4), XE_REG_OPTION_VF) -#define INTR_DATA_VALID REG_BIT(31) -#define INTR_ENGINE_INSTANCE(x) REG_FIELD_GET(GENMASK(25, 20), x) -#define INTR_ENGINE_CLASS(x) REG_FIELD_GET(GENMASK(18, 16), x) -#define INTR_ENGINE_INTR(x) REG_FIELD_GET(GENMASK(15, 0), x) -#define OTHER_GUC_INSTANCE 0 -#define OTHER_GSC_HECI2_INSTANCE 3 -#define OTHER_GSC_INSTANCE 6 - -#define IIR_REG_SELECTOR(x) XE_REG(0x190070 + ((x) * 4), XE_REG_OPTION_VF) -#define RCS0_RSVD_INTR_MASK XE_REG(0x190090, XE_REG_OPTION_VF) -#define BCS_RSVD_INTR_MASK XE_REG(0x1900a0, XE_REG_OPTION_VF) -#define VCS0_VCS1_INTR_MASK XE_REG(0x1900a8, XE_REG_OPTION_VF) -#define VCS2_VCS3_INTR_MASK XE_REG(0x1900ac, XE_REG_OPTION_VF) -#define VECS0_VECS1_INTR_MASK XE_REG(0x1900d0, XE_REG_OPTION_VF) -#define HECI2_RSVD_INTR_MASK XE_REG(0x1900e4) -#define GUC_SG_INTR_MASK XE_REG(0x1900e8, XE_REG_OPTION_VF) -#define GPM_WGBOXPERF_INTR_MASK XE_REG(0x1900ec, XE_REG_OPTION_VF) -#define GUNIT_GSC_INTR_MASK XE_REG(0x1900f4, XE_REG_OPTION_VF) -#define CCS0_CCS1_INTR_MASK XE_REG(0x190100) -#define CCS2_CCS3_INTR_MASK XE_REG(0x190104) -#define XEHPC_BCS1_BCS2_INTR_MASK XE_REG(0x190110) -#define XEHPC_BCS3_BCS4_INTR_MASK XE_REG(0x190114) -#define XEHPC_BCS5_BCS6_INTR_MASK XE_REG(0x190118) -#define XEHPC_BCS7_BCS8_INTR_MASK XE_REG(0x19011c) -#define GT_WAIT_SEMAPHORE_INTERRUPT REG_BIT(11) -#define GT_CONTEXT_SWITCH_INTERRUPT REG_BIT(8) -#define GSC_ER_COMPLETE REG_BIT(5) -#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT REG_BIT(4) -#define GT_CS_MASTER_ERROR_INTERRUPT REG_BIT(3) -#define GT_RENDER_USER_INTERRUPT REG_BIT(0) - #endif diff --git a/drivers/gpu/drm/xe/regs/xe_irq_regs.h b/drivers/gpu/drm/xe/regs/xe_irq_regs.h new file mode 100644 index 000000000000..1776b3f78ccb --- /dev/null +++ b/drivers/gpu/drm/xe/regs/xe_irq_regs.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ +#ifndef _XE_IRQ_REGS_H_ +#define _XE_IRQ_REGS_H_ + +#include "regs/xe_reg_defs.h" + +#define PCU_IRQ_OFFSET 0x444e0 +#define GU_MISC_IRQ_OFFSET 0x444f0 +#define GU_MISC_GSE REG_BIT(27) + +#define DG1_MSTR_TILE_INTR XE_REG(0x190008) +#define DG1_MSTR_IRQ REG_BIT(31) +#define DG1_MSTR_TILE(t) REG_BIT(t) + +#define GFX_MSTR_IRQ XE_REG(0x190010, XE_REG_OPTION_VF) +#define MASTER_IRQ REG_BIT(31) +#define GU_MISC_IRQ REG_BIT(29) +#define DISPLAY_IRQ REG_BIT(16) +#define GT_DW_IRQ(x) REG_BIT(x) + +/* + * Note: Interrupt registers 1900xx are VF accessible only until version 12.50. + * On newer platforms, VFs are using memory-based interrupts instead. + * However, for simplicity we keep this XE_REG_OPTION_VF tag intact. + */ + +#define GT_INTR_DW(x) XE_REG(0x190018 + ((x) * 4), XE_REG_OPTION_VF) +#define INTR_GSC REG_BIT(31) +#define INTR_GUC REG_BIT(25) +#define INTR_MGUC REG_BIT(24) +#define INTR_BCS8 REG_BIT(23) +#define INTR_BCS(x) REG_BIT(15 - (x)) +#define INTR_CCS(x) REG_BIT(4 + (x)) +#define INTR_RCS0 REG_BIT(0) +#define INTR_VECS(x) REG_BIT(31 - (x)) +#define INTR_VCS(x) REG_BIT(x) + +#define RENDER_COPY_INTR_ENABLE XE_REG(0x190030, XE_REG_OPTION_VF) +#define VCS_VECS_INTR_ENABLE XE_REG(0x190034, XE_REG_OPTION_VF) +#define GUC_SG_INTR_ENABLE XE_REG(0x190038, XE_REG_OPTION_VF) +#define ENGINE1_MASK REG_GENMASK(31, 16) +#define ENGINE0_MASK REG_GENMASK(15, 0) +#define GPM_WGBOXPERF_INTR_ENABLE XE_REG(0x19003c, XE_REG_OPTION_VF) +#define GUNIT_GSC_INTR_ENABLE XE_REG(0x190044, XE_REG_OPTION_VF) +#define CCS_RSVD_INTR_ENABLE XE_REG(0x190048, XE_REG_OPTION_VF) + +#define INTR_IDENTITY_REG(x) XE_REG(0x190060 + ((x) * 4), XE_REG_OPTION_VF) +#define INTR_DATA_VALID REG_BIT(31) +#define INTR_ENGINE_INSTANCE(x) REG_FIELD_GET(GENMASK(25, 20), x) +#define INTR_ENGINE_CLASS(x) REG_FIELD_GET(GENMASK(18, 16), x) +#define INTR_ENGINE_INTR(x) REG_FIELD_GET(GENMASK(15, 0), x) +#define OTHER_GUC_INSTANCE 0 +#define OTHER_GSC_HECI2_INSTANCE 3 +#define OTHER_GSC_INSTANCE 6 + +#define IIR_REG_SELECTOR(x) XE_REG(0x190070 + ((x) * 4), XE_REG_OPTION_VF) +#define RCS0_RSVD_INTR_MASK XE_REG(0x190090, XE_REG_OPTION_VF) +#define BCS_RSVD_INTR_MASK XE_REG(0x1900a0, XE_REG_OPTION_VF) +#define VCS0_VCS1_INTR_MASK XE_REG(0x1900a8, XE_REG_OPTION_VF) +#define VCS2_VCS3_INTR_MASK XE_REG(0x1900ac, XE_REG_OPTION_VF) +#define VECS0_VECS1_INTR_MASK XE_REG(0x1900d0, XE_REG_OPTION_VF) +#define HECI2_RSVD_INTR_MASK XE_REG(0x1900e4) +#define GUC_SG_INTR_MASK XE_REG(0x1900e8, XE_REG_OPTION_VF) +#define GPM_WGBOXPERF_INTR_MASK XE_REG(0x1900ec, XE_REG_OPTION_VF) +#define GUNIT_GSC_INTR_MASK XE_REG(0x1900f4, XE_REG_OPTION_VF) +#define CCS0_CCS1_INTR_MASK XE_REG(0x190100) +#define CCS2_CCS3_INTR_MASK XE_REG(0x190104) +#define XEHPC_BCS1_BCS2_INTR_MASK XE_REG(0x190110) +#define XEHPC_BCS3_BCS4_INTR_MASK XE_REG(0x190114) +#define XEHPC_BCS5_BCS6_INTR_MASK XE_REG(0x190118) +#define XEHPC_BCS7_BCS8_INTR_MASK XE_REG(0x19011c) +#define GT_WAIT_SEMAPHORE_INTERRUPT REG_BIT(11) +#define GT_CONTEXT_SWITCH_INTERRUPT REG_BIT(8) +#define GSC_ER_COMPLETE REG_BIT(5) +#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT REG_BIT(4) +#define GT_CS_MASTER_ERROR_INTERRUPT REG_BIT(3) +#define GT_RENDER_USER_INTERRUPT REG_BIT(0) + +#endif diff --git a/drivers/gpu/drm/xe/regs/xe_regs.h b/drivers/gpu/drm/xe/regs/xe_regs.h index dfa869f0dddd..3293172b0128 100644 --- a/drivers/gpu/drm/xe/regs/xe_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_regs.h @@ -11,10 +11,6 @@ #define TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK REG_GENMASK(15, 12) #define TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK REG_GENMASK(9, 0) -#define PCU_IRQ_OFFSET 0x444e0 -#define GU_MISC_IRQ_OFFSET 0x444f0 -#define GU_MISC_GSE REG_BIT(27) - #define GU_CNTL_PROTECTED XE_REG(0x10100C) #define DRIVERINT_FLR_DIS REG_BIT(31) @@ -57,16 +53,6 @@ #define MTL_MPE_FREQUENCY XE_REG(0x13802c) #define MTL_RPE_MASK REG_GENMASK(8, 0) -#define DG1_MSTR_TILE_INTR XE_REG(0x190008) -#define DG1_MSTR_IRQ REG_BIT(31) -#define DG1_MSTR_TILE(t) REG_BIT(t) - -#define GFX_MSTR_IRQ XE_REG(0x190010, XE_REG_OPTION_VF) -#define MASTER_IRQ REG_BIT(31) -#define GU_MISC_IRQ REG_BIT(29) -#define DISPLAY_IRQ REG_BIT(16) -#define GT_DW_IRQ(x) REG_BIT(x) - #define VF_CAP_REG XE_REG(0x1901f8, XE_REG_OPTION_VF) #define VF_CAP REG_BIT(0) diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c index 9cb326af5931..783b09bf3681 100644 --- a/drivers/gpu/drm/xe/xe_gsc.c +++ b/drivers/gpu/drm/xe/xe_gsc.c @@ -34,6 +34,7 @@ #include "instructions/xe_gsc_commands.h" #include "regs/xe_gsc_regs.h" #include "regs/xe_gt_regs.h" +#include "regs/xe_irq_regs.h" static struct xe_gt * gsc_to_gt(struct xe_gsc *gsc) diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index b6cd5e941f19..c2ddf883702b 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -14,6 +14,7 @@ #include "regs/xe_gt_regs.h" #include "regs/xe_gtt_defs.h" #include "regs/xe_guc_regs.h" +#include "regs/xe_irq_regs.h" #include "xe_bo.h" #include "xe_device.h" #include "xe_force_wake.h" diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index d7408d06ee20..ea6d9ef7fab6 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -12,6 +12,7 @@ #include "regs/xe_engine_regs.h" #include "regs/xe_gt_regs.h" +#include "regs/xe_irq_regs.h" #include "xe_assert.h" #include "xe_bo.h" #include "xe_device.h" diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 5eb7775c0fd2..b7995ebd54ab 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -10,8 +10,7 @@ #include <drm/drm_managed.h> #include "display/xe_display.h" -#include "regs/xe_gt_regs.h" -#include "regs/xe_regs.h" +#include "regs/xe_irq_regs.h" #include "xe_device.h" #include "xe_drv.h" #include "xe_gsc_proxy.h" diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index 3f8d4ca64302..e3610cb90bb9 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -5,8 +5,8 @@ #include <drm/drm_managed.h> -#include "regs/xe_gt_regs.h" #include "regs/xe_guc_regs.h" +#include "regs/xe_irq_regs.h" #include "regs/xe_regs.h" #include "xe_assert.h" -- GitLab From d065cc76054d21e48a839a2a19ba99dbc51a4d11 Mon Sep 17 00:00:00 2001 From: Dirk Behme <dirk.behme@de.bosch.com> Date: Mon, 16 Sep 2024 09:37:52 +0200 Subject: [PATCH 432/970] rust: mutex: fix __mutex_init() usage in case of PREEMPT_RT In case CONFIG_PREEMPT_RT is enabled __mutex_init() becomes a macro instead of an extern function (simplified from include/linux/mutex.h): #ifndef CONFIG_PREEMPT_RT extern void __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key); #else #define __mutex_init(mutex, name, key) \ do { \ rt_mutex_base_init(&(mutex)->rtmutex); \ __mutex_rt_init((mutex), name, key); \ } while (0) #endif The macro isn't resolved by bindgen, then. What results in a build error: error[E0425]: cannot find function `__mutex_init` in crate `bindings` --> rust/kernel/sync/lock/mutex.rs:104:28 | 104 | unsafe { bindings::__mutex_init(ptr, name, key) } | ^^^^^^^^^^^^ help: a function with a similar name exists: `__mutex_rt_init` | ::: rust/bindings/bindings_generated.rs:23722:5 | 23722 | / pub fn __mutex_rt_init( 23723 | | lock: *mut mutex, 23724 | | name: *const core::ffi::c_char, 23725 | | key: *mut lock_class_key, 23726 | | ); | |_____- similarly named function `__mutex_rt_init` defined here Fix this by adding a helper. As explained by Gary Guo in [1] no #ifdef CONFIG_PREEMPT_RT is needed here as rust/bindings/lib.rs prefers externed function to helpers if an externed function exists. Reported-by: Conor Dooley <conor@kernel.org> Link: https://lore.kernel.org/rust-for-linux/20240913-shack-estate-b376a65921b1@spud/ Link: https://lore.kernel.org/rust-for-linux/20240915123626.1a170103.gary@garyguo.net/ [1] Fixes: 6d20d629c6d8 ("rust: lock: introduce `Mutex`") Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com> Tested-by: Conor Dooley <conor.dooley@microchip.com> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://lore.kernel.org/r/20240916073752.3123484-1-dirk.behme@de.bosch.com [ Reworded to include the proper example by Dirk. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- rust/helpers/mutex.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rust/helpers/mutex.c b/rust/helpers/mutex.c index 200db7e6279f..a17ca8cdb50c 100644 --- a/rust/helpers/mutex.c +++ b/rust/helpers/mutex.c @@ -7,3 +7,9 @@ void rust_helper_mutex_lock(struct mutex *lock) { mutex_lock(lock); } + +void rust_helper___mutex_init(struct mutex *mutex, const char *name, + struct lock_class_key *key) +{ + __mutex_init(mutex, name, key); +} -- GitLab From af6017b6a315e9102582afb92640221d057f84f6 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda <ojeda@kernel.org> Date: Wed, 25 Sep 2024 16:19:44 +0200 Subject: [PATCH 433/970] rust: cfi: fix `patchable-function-entry` starting version The `-Zpatchable-function-entry` flag is available since Rust 1.81.0, not Rust 1.80.0, i.e. commit ac7595fdb1ee ("Support for -Z patchable-function-entry") in upstream Rust. Fixes: ca627e636551 ("rust: cfi: add support for CFI_CLANG with Rust") Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Fiona Behrens <me@kloenk.dev> Link: https://lore.kernel.org/r/20240925141944.277936-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/Kconfig b/init/Kconfig index fbd0cb06a50a..fa734a144589 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1948,7 +1948,7 @@ config RUST depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG - depends on !CALL_PADDING || RUSTC_VERSION >= 108000 + depends on !CALL_PADDING || RUSTC_VERSION >= 108100 depends on !KASAN_SW_TAGS help Enables Rust support in the kernel. -- GitLab From 93e34a0b5c0e79ce765f01fd10f7817863fba23d Mon Sep 17 00:00:00 2001 From: Alice Ryhl <aliceryhl@google.com> Date: Thu, 26 Sep 2024 09:38:49 +0000 Subject: [PATCH 434/970] rust: KASAN+RETHUNK requires rustc 1.83.0 When enabling both KASAN and RETHUNK, objtool emits the following warnings: rust/core.o: warning: objtool: asan.module_ctor+0x13: 'naked' return found in MITIGATION_RETHUNK build rust/core.o: warning: objtool: asan.module_dtor+0x13: 'naked' return found in MITIGATION_RETHUNK build This is caused by the -Zfunction-return=thunk-extern flag in rustc not informing LLVM about the mitigation at the module level (it does so at the function level only currently, which covers most cases, but both are required), which means that the KASAN functions asan.module_ctor and asan.module_dtor are generated without the rethunk mitigation. The other mitigations that we enabled for Rust (SLS, RETPOLINE) do not have the same bug, as they're being applied through the target-feature functionality instead. This is being fixed for rustc 1.83.0, so update Kconfig to reject this configuration on older compilers. Link: https://github.com/rust-lang/rust/pull/130824 Fixes: d7868550d573 ("x86/rust: support MITIGATION_RETHUNK") Reported-by: Miguel Ojeda <ojeda@kernel.org> Closes: https://lore.kernel.org/all/CANiq72myZL4_poCMuNFevtpYYc0V0embjSuKb7y=C+m3vVA_8g@mail.gmail.com/ Signed-off-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20240926093849.1192264-1-aliceryhl@google.com [ Reworded to add the details mentioned in the list. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- init/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/init/Kconfig b/init/Kconfig index fa734a144589..9a2bcba426c5 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1950,6 +1950,7 @@ config RUST select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG depends on !CALL_PADDING || RUSTC_VERSION >= 108100 depends on !KASAN_SW_TAGS + depends on !(MITIGATION_RETHUNK && KASAN) || RUSTC_VERSION >= 108300 help Enables Rust support in the kernel. -- GitLab From 4c66f8307ac099f89038878b7789d72163a74751 Mon Sep 17 00:00:00 2001 From: Alice Ryhl <aliceryhl@google.com> Date: Wed, 25 Sep 2024 08:10:18 +0000 Subject: [PATCH 435/970] cfi: encode cfi normalized integers + kasan/gcov bug in Kconfig There is a bug in the LLVM implementation of KASAN and GCOV that makes these options incompatible with the CFI_ICALL_NORMALIZE_INTEGERS option. The bug has already been fixed in llvm/clang [1] and rustc [2]. However, Kconfig currently has no way to gate features on the LLVM version inside rustc, so we cannot write down a precise `depends on` clause in this case. Instead, a `def_bool` option is defined for whether CFI_ICALL_NORMALIZE_INTEGERS is available, and its default value is set to false when GCOV or KASAN are turned on. End users using a patched clang/rustc can turn on the HAVE_CFI_ICALL_NORMALIZE_INTEGERS option directly to override this. An alternative solution is to inspect a binary created by clang or rustc to see whether the faulty CFI tags are in the binary. This would be a precise check, but it would involve hard-coding the *hashed* version of the CFI tag. This is because there's no way to get clang or rustc to output the unhased version of the CFI tag. Relying on the precise hashing algorithm using by CFI seems too fragile, so I have not pursued this option. Besides, this kind of hack is exactly what lead to the LLVM bug in the first place. If the CFI_ICALL_NORMALIZE_INTEGERS option is used without CONFIG_RUST, then we actually can perform a precise check today: just compare the clang version number. This works since clang and llvm are always updated in lockstep. However, encoding this in Kconfig would give the HAVE_CFI_ICALL_NORMALIZE_INTEGERS option a dependency on CONFIG_RUST, which is not possible as the reverse dependency already exists. HAVE_CFI_ICALL_NORMALIZE_INTEGERS is defined to be a `def_bool` instead of `bool` to avoid asking end users whether they want to turn on the option. Turning it on explicitly is something only experts should do, so making it hard to do so is not an issue. I added a `depends on CFI_CLANG` clause to the new Kconfig option. I'm not sure whether that makes sense or not, but it doesn't seem to make a big difference. In a future kernel release, I would like to add a Kconfig option similar to CLANG_VERSION/RUSTC_VERSION for inspecting the version of the LLVM inside rustc. Once that feature lands, this logic will be replaced with a precise version check. This check is not being introduced here to avoid introducing a new _VERSION constant in a fix. Link: https://github.com/llvm/llvm-project/pull/104826 [1] Link: https://github.com/rust-lang/rust/pull/129373 [2] Fixes: ce4a2620985c ("cfi: add CONFIG_CFI_ICALL_NORMALIZE_INTEGERS") Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202409231044.4f064459-oliver.sang@intel.com Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Link: https://lore.kernel.org/r/20240925-cfi-norm-kasan-fix-v1-1-0328985cdf33@google.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- arch/Kconfig | 18 +++++++++++++++++- init/Kconfig | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 98157b38f5cf..8af374ea1adc 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -838,7 +838,7 @@ config CFI_CLANG config CFI_ICALL_NORMALIZE_INTEGERS bool "Normalize CFI tags for integers" depends on CFI_CLANG - depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS help This option normalizes the CFI tags for integer types so that all integer types of the same size and signedness receive the same CFI @@ -851,6 +851,22 @@ config CFI_ICALL_NORMALIZE_INTEGERS This option is necessary for using CFI with Rust. If unsure, say N. +config HAVE_CFI_ICALL_NORMALIZE_INTEGERS + def_bool !GCOV_KERNEL && !KASAN + depends on CFI_CLANG + depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) + help + Is CFI_ICALL_NORMALIZE_INTEGERS supported with the set of compilers + currently in use? + + This option defaults to false if GCOV or KASAN is enabled, as there is + an LLVM bug that makes normalized integers tags incompatible with + KASAN and GCOV. Kconfig currently does not have the infrastructure to + detect whether your rustc compiler contains the fix for this bug, so + it is assumed that it doesn't. If your compiler has the fix, you can + explicitly enable this option in your config file. The Kconfig logic + needed to detect this will be added in a future kernel release. + config CFI_PERMISSIVE bool "Use CFI in permissive mode" depends on CFI_CLANG diff --git a/init/Kconfig b/init/Kconfig index 9a2bcba426c5..530a382ee0fe 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1946,7 +1946,7 @@ config RUST depends on !GCC_PLUGIN_RANDSTRUCT depends on !RANDSTRUCT depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE - depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) + depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && HAVE_CFI_ICALL_NORMALIZE_INTEGERS select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG depends on !CALL_PADDING || RUSTC_VERSION >= 108100 depends on !KASAN_SW_TAGS -- GitLab From c9c809f4137c3c0f962226c10d245d3ce2fd5b7c Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Thu, 26 Sep 2024 12:56:46 -1000 Subject: [PATCH 436/970] scx_flatcg: Use a user DSQ for fallback instead of SCX_DSQ_GLOBAL scx_flatcg was using SCX_DSQ_GLOBAL for fallback handling. However, it is assuming that SCX_DSQ_GLOBAL isn't automatically consumed, which was true a while ago but is no longer the case. Also, there are further changes planned for SCX_DSQ_GLOBAL which will disallow explicit consumption from it. Switch to a user DSQ for fallback. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: David Vernet <void@manifault.com> --- tools/sched_ext/scx_flatcg.bpf.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/sched_ext/scx_flatcg.bpf.c b/tools/sched_ext/scx_flatcg.bpf.c index e272bc39bbbd..b722baf6da4b 100644 --- a/tools/sched_ext/scx_flatcg.bpf.c +++ b/tools/sched_ext/scx_flatcg.bpf.c @@ -49,7 +49,10 @@ /* * Maximum amount of retries to find a valid cgroup. */ -#define CGROUP_MAX_RETRIES 1024 +enum { + FALLBACK_DSQ = 0, + CGROUP_MAX_RETRIES = 1024, +}; char _license[] SEC("license") = "GPL"; @@ -377,7 +380,7 @@ void BPF_STRUCT_OPS(fcg_enqueue, struct task_struct *p, u64 enq_flags) scx_bpf_dispatch(p, SCX_DSQ_LOCAL, SCX_SLICE_DFL, enq_flags); } else { stat_inc(FCG_STAT_GLOBAL); - scx_bpf_dispatch(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags); + scx_bpf_dispatch(p, FALLBACK_DSQ, SCX_SLICE_DFL, enq_flags); } return; } @@ -780,7 +783,7 @@ void BPF_STRUCT_OPS(fcg_dispatch, s32 cpu, struct task_struct *prev) pick_next_cgroup: cpuc->cur_at = now; - if (scx_bpf_consume(SCX_DSQ_GLOBAL)) { + if (scx_bpf_consume(FALLBACK_DSQ)) { cpuc->cur_cgid = 0; return; } @@ -837,7 +840,7 @@ int BPF_STRUCT_OPS_SLEEPABLE(fcg_cgroup_init, struct cgroup *cgrp, int ret; /* - * Technically incorrect as cgroup ID is full 64bit while dq ID is + * Technically incorrect as cgroup ID is full 64bit while dsq ID is * 63bit. Should not be a problem in practice and easy to spot in the * unlikely case that it breaks. */ @@ -925,6 +928,11 @@ void BPF_STRUCT_OPS(fcg_cgroup_move, struct task_struct *p, p->scx.dsq_vtime = to_cgc->tvtime_now + vtime_delta; } +s32 BPF_STRUCT_OPS_SLEEPABLE(fcg_init) +{ + return scx_bpf_create_dsq(FALLBACK_DSQ, -1); +} + void BPF_STRUCT_OPS(fcg_exit, struct scx_exit_info *ei) { UEI_RECORD(uei, ei); @@ -943,6 +951,7 @@ SCX_OPS_DEFINE(flatcg_ops, .cgroup_init = (void *)fcg_cgroup_init, .cgroup_exit = (void *)fcg_cgroup_exit, .cgroup_move = (void *)fcg_cgroup_move, + .init = (void *)fcg_init, .exit = (void *)fcg_exit, .flags = SCX_OPS_HAS_CGROUP_WEIGHT | SCX_OPS_ENQ_EXITING, .name = "flatcg"); -- GitLab From 63fb3ec80516b256e9fc91de48567f5eda61d135 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Thu, 26 Sep 2024 12:56:46 -1000 Subject: [PATCH 437/970] sched_ext: Allow only user DSQs for scx_bpf_consume(), scx_bpf_dsq_nr_queued() and bpf_iter_scx_dsq_new() SCX_DSQ_GLOBAL is special in that it can't be used as a priority queue and is consumed implicitly, but all BPF DSQ related kfuncs could be used on it. SCX_DSQ_GLOBAL will be split per-node for scalability and those operations won't make sense anymore. Disallow SCX_DSQ_GLOBAL on scx_bpf_consume(), scx_bpf_dsq_nr_queued() and bpf_iter_scx_dsq_new(). This means that SCX_DSQ_GLOBAL can only be used as a dispatch target from BPF schedulers. With scx_flatcg, which was using SCX_DSQ_GLOBAL as the fallback DSQ, updated, this shouldn't affect any schedulers. This leaves find_dsq_for_dispatch() the only user of find_non_local_dsq(). Open code and remove find_non_local_dsq(). Signed-off-by: tejun heo <tj@kernel.org> Acked-by: David Vernet <void@manifault.com> --- kernel/sched/ext.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index d74d1fe06999..ed2b914c42d1 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -1808,16 +1808,6 @@ static struct scx_dispatch_q *find_user_dsq(u64 dsq_id) return rhashtable_lookup_fast(&dsq_hash, &dsq_id, dsq_hash_params); } -static struct scx_dispatch_q *find_non_local_dsq(u64 dsq_id) -{ - lockdep_assert(rcu_read_lock_any_held()); - - if (dsq_id == SCX_DSQ_GLOBAL) - return &scx_dsq_global; - else - return find_user_dsq(dsq_id); -} - static struct scx_dispatch_q *find_dsq_for_dispatch(struct rq *rq, u64 dsq_id, struct task_struct *p) { @@ -1835,7 +1825,11 @@ static struct scx_dispatch_q *find_dsq_for_dispatch(struct rq *rq, u64 dsq_id, return &cpu_rq(cpu)->scx.local_dsq; } - dsq = find_non_local_dsq(dsq_id); + if (dsq_id == SCX_DSQ_GLOBAL) + dsq = &scx_dsq_global; + else + dsq = find_user_dsq(dsq_id); + if (unlikely(!dsq)) { scx_ops_error("non-existent DSQ 0x%llx for %s[%d]", dsq_id, p->comm, p->pid); @@ -6176,7 +6170,7 @@ __bpf_kfunc bool scx_bpf_consume(u64 dsq_id) flush_dispatch_buf(dspc->rq); - dsq = find_non_local_dsq(dsq_id); + dsq = find_user_dsq(dsq_id); if (unlikely(!dsq)) { scx_ops_error("invalid DSQ ID 0x%016llx", dsq_id); return false; @@ -6497,7 +6491,7 @@ __bpf_kfunc s32 scx_bpf_dsq_nr_queued(u64 dsq_id) goto out; } } else { - dsq = find_non_local_dsq(dsq_id); + dsq = find_user_dsq(dsq_id); if (dsq) { ret = READ_ONCE(dsq->nr); goto out; @@ -6546,7 +6540,7 @@ __bpf_kfunc int bpf_iter_scx_dsq_new(struct bpf_iter_scx_dsq *it, u64 dsq_id, if (flags & ~__SCX_DSQ_ITER_USER_FLAGS) return -EINVAL; - kit->dsq = find_non_local_dsq(dsq_id); + kit->dsq = find_user_dsq(dsq_id); if (!kit->dsq) return -ENOENT; -- GitLab From bba26bf356d1c1314a7bb24041c64c5784febbb0 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Thu, 26 Sep 2024 12:56:46 -1000 Subject: [PATCH 438/970] sched_ext: Relocate find_user_dsq() To prepare for the addition of find_global_dsq(). No functional changes. Signed-off-by: tejun heo <tj@kernel.org> Acked-by: David Vernet <void@manifault.com> --- kernel/sched/ext.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index ed2b914c42d1..acb4db7827a4 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -1029,6 +1029,11 @@ static bool u32_before(u32 a, u32 b) return (s32)(a - b) < 0; } +static struct scx_dispatch_q *find_user_dsq(u64 dsq_id) +{ + return rhashtable_lookup_fast(&dsq_hash, &dsq_id, dsq_hash_params); +} + /* * scx_kf_mask enforcement. Some kfuncs can only be called from specific SCX * ops. When invoking SCX ops, SCX_CALL_OP[_RET]() should be used to indicate @@ -1803,11 +1808,6 @@ static void dispatch_dequeue(struct rq *rq, struct task_struct *p) raw_spin_unlock(&dsq->lock); } -static struct scx_dispatch_q *find_user_dsq(u64 dsq_id) -{ - return rhashtable_lookup_fast(&dsq_hash, &dsq_id, dsq_hash_params); -} - static struct scx_dispatch_q *find_dsq_for_dispatch(struct rq *rq, u64 dsq_id, struct task_struct *p) { -- GitLab From b7b3b2dbae73b412c2d24b3d0ebf1110991e4510 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Thu, 26 Sep 2024 12:56:46 -1000 Subject: [PATCH 439/970] sched_ext: Split the global DSQ per NUMA node In the bypass mode, the global DSQ is used to schedule all tasks in simple FIFO order. All tasks are queued into the global DSQ and all CPUs try to execute tasks from it. This creates a lot of cross-node cacheline accesses and scheduling across the node boundaries, and can lead to live-lock conditions where the system takes tens of minutes to disable the BPF scheduler while executing in the bypass mode. Split the global DSQ per NUMA node. Each node has its own global DSQ. When a task is dispatched to SCX_DSQ_GLOBAL, it's put into the global DSQ local to the task's CPU and all CPUs in a node only consume its node-local global DSQ. This resolves a livelock condition which could be reliably triggered on an 2x EPYC 7642 system by running `stress-ng --race-sched 1024` together with `stress-ng --workload 80 --workload-threads 10` while repeatedly enabling and disabling a SCX scheduler. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: David Vernet <void@manifault.com> --- kernel/sched/ext.c | 73 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index acb4db7827a4..949a3c43000a 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -925,8 +925,15 @@ static unsigned long __percpu *scx_kick_cpus_pnt_seqs; */ static DEFINE_PER_CPU(struct task_struct *, direct_dispatch_task); -/* dispatch queues */ -static struct scx_dispatch_q __cacheline_aligned_in_smp scx_dsq_global; +/* + * Dispatch queues. + * + * The global DSQ (%SCX_DSQ_GLOBAL) is split per-node for scalability. This is + * to avoid live-locking in bypass mode where all tasks are dispatched to + * %SCX_DSQ_GLOBAL and all CPUs consume from it. If per-node split isn't + * sufficient, it can be further split. + */ +static struct scx_dispatch_q **global_dsqs; static const struct rhashtable_params dsq_hash_params = { .key_len = 8, @@ -1029,6 +1036,11 @@ static bool u32_before(u32 a, u32 b) return (s32)(a - b) < 0; } +static struct scx_dispatch_q *find_global_dsq(struct task_struct *p) +{ + return global_dsqs[cpu_to_node(task_cpu(p))]; +} + static struct scx_dispatch_q *find_user_dsq(u64 dsq_id) { return rhashtable_lookup_fast(&dsq_hash, &dsq_id, dsq_hash_params); @@ -1642,7 +1654,7 @@ static void dispatch_enqueue(struct scx_dispatch_q *dsq, struct task_struct *p, scx_ops_error("attempting to dispatch to a destroyed dsq"); /* fall back to the global dsq */ raw_spin_unlock(&dsq->lock); - dsq = &scx_dsq_global; + dsq = find_global_dsq(p); raw_spin_lock(&dsq->lock); } } @@ -1820,20 +1832,20 @@ static struct scx_dispatch_q *find_dsq_for_dispatch(struct rq *rq, u64 dsq_id, s32 cpu = dsq_id & SCX_DSQ_LOCAL_CPU_MASK; if (!ops_cpu_valid(cpu, "in SCX_DSQ_LOCAL_ON dispatch verdict")) - return &scx_dsq_global; + return find_global_dsq(p); return &cpu_rq(cpu)->scx.local_dsq; } if (dsq_id == SCX_DSQ_GLOBAL) - dsq = &scx_dsq_global; + dsq = find_global_dsq(p); else dsq = find_user_dsq(dsq_id); if (unlikely(!dsq)) { scx_ops_error("non-existent DSQ 0x%llx for %s[%d]", dsq_id, p->comm, p->pid); - return &scx_dsq_global; + return find_global_dsq(p); } return dsq; @@ -2005,7 +2017,7 @@ static void do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, global: touch_core_sched(rq, p); /* see the comment in local: */ p->scx.slice = SCX_SLICE_DFL; - dispatch_enqueue(&scx_dsq_global, p, enq_flags); + dispatch_enqueue(find_global_dsq(p), p, enq_flags); } static bool task_runnable(const struct task_struct *p) @@ -2391,6 +2403,13 @@ static bool consume_dispatch_q(struct rq *rq, struct scx_dispatch_q *dsq) return false; } +static bool consume_global_dsq(struct rq *rq) +{ + int node = cpu_to_node(cpu_of(rq)); + + return consume_dispatch_q(rq, global_dsqs[node]); +} + /** * dispatch_to_local_dsq - Dispatch a task to a local dsq * @rq: current rq which is locked @@ -2424,7 +2443,8 @@ static void dispatch_to_local_dsq(struct rq *rq, struct scx_dispatch_q *dst_dsq, #ifdef CONFIG_SMP if (unlikely(!task_can_run_on_remote_rq(p, dst_rq, true))) { - dispatch_enqueue(&scx_dsq_global, p, enq_flags | SCX_ENQ_CLEAR_OPSS); + dispatch_enqueue(find_global_dsq(p), p, + enq_flags | SCX_ENQ_CLEAR_OPSS); return; } @@ -2624,7 +2644,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev) if (rq->scx.local_dsq.nr) goto has_tasks; - if (consume_dispatch_q(rq, &scx_dsq_global)) + if (consume_global_dsq(rq)) goto has_tasks; if (!SCX_HAS_OP(dispatch) || scx_rq_bypassing(rq) || !scx_rq_online(rq)) @@ -2649,7 +2669,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev) if (rq->scx.local_dsq.nr) goto has_tasks; - if (consume_dispatch_q(rq, &scx_dsq_global)) + if (consume_global_dsq(rq)) goto has_tasks; /* @@ -4924,7 +4944,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) struct scx_task_iter sti; struct task_struct *p; unsigned long timeout; - int i, cpu, ret; + int i, cpu, node, ret; if (!cpumask_equal(housekeeping_cpumask(HK_TYPE_DOMAIN), cpu_possible_mask)) { @@ -4943,6 +4963,34 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) } } + if (!global_dsqs) { + struct scx_dispatch_q **dsqs; + + dsqs = kcalloc(nr_node_ids, sizeof(dsqs[0]), GFP_KERNEL); + if (!dsqs) { + ret = -ENOMEM; + goto err_unlock; + } + + for_each_node_state(node, N_POSSIBLE) { + struct scx_dispatch_q *dsq; + + dsq = kzalloc_node(sizeof(*dsq), GFP_KERNEL, node); + if (!dsq) { + for_each_node_state(node, N_POSSIBLE) + kfree(dsqs[node]); + kfree(dsqs); + ret = -ENOMEM; + goto err_unlock; + } + + init_dsq(dsq, SCX_DSQ_GLOBAL); + dsqs[node] = dsq; + } + + global_dsqs = dsqs; + } + if (scx_ops_enable_state() != SCX_OPS_DISABLED) { ret = -EBUSY; goto err_unlock; @@ -5777,7 +5825,6 @@ void __init init_sched_ext_class(void) SCX_TG_ONLINE); BUG_ON(rhashtable_init(&dsq_hash, &dsq_hash_params)); - init_dsq(&scx_dsq_global, SCX_DSQ_GLOBAL); #ifdef CONFIG_SMP BUG_ON(!alloc_cpumask_var(&idle_masks.cpu, GFP_KERNEL)); BUG_ON(!alloc_cpumask_var(&idle_masks.smt, GFP_KERNEL)); @@ -6053,7 +6100,7 @@ static bool scx_dispatch_from_dsq(struct bpf_iter_scx_dsq_kern *kit, if (dst_dsq->id == SCX_DSQ_LOCAL) { dst_rq = container_of(dst_dsq, struct rq, scx.local_dsq); if (!task_can_run_on_remote_rq(p, dst_rq, true)) { - dst_dsq = &scx_dsq_global; + dst_dsq = find_global_dsq(p); dst_rq = src_rq; } } else { -- GitLab From 6f34d8d382d64e7d8e77f5a9ddfd06f4c04937b0 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Thu, 26 Sep 2024 12:56:46 -1000 Subject: [PATCH 440/970] sched_ext: Use shorter slice while bypassing While bypassing, tasks are scheduled in FIFO order which favors tasks that hog CPUs. This can slow down e.g. unloading of the BPF scheduler. While bypassing, guaranteeing timely forward progress is the main goal. There's no point in giving long slices. Shorten the time slice used while bypassing from 20ms to 5ms. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: David Vernet <void@manifault.com> --- kernel/sched/ext.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index 949a3c43000a..d6f6bf6caecc 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -9,6 +9,7 @@ #define SCX_OP_IDX(op) (offsetof(struct sched_ext_ops, op) / sizeof(void (*)(void))) enum scx_consts { + SCX_SLICE_BYPASS = SCX_SLICE_DFL / 4, SCX_DSP_DFL_MAX_BATCH = 32, SCX_DSP_MAX_LOOPS = 32, SCX_WATCHDOG_MAX_TIMEOUT = 30 * HZ, @@ -1944,6 +1945,7 @@ static bool scx_rq_online(struct rq *rq) static void do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, int sticky_cpu) { + bool bypassing = scx_rq_bypassing(rq); struct task_struct **ddsp_taskp; unsigned long qseq; @@ -1961,7 +1963,7 @@ static void do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, if (!scx_rq_online(rq)) goto local; - if (scx_rq_bypassing(rq)) + if (bypassing) goto global; if (p->scx.ddsp_dsq_id != SCX_DSQ_INVALID) @@ -2016,7 +2018,7 @@ static void do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, global: touch_core_sched(rq, p); /* see the comment in local: */ - p->scx.slice = SCX_SLICE_DFL; + p->scx.slice = bypassing ? SCX_SLICE_BYPASS : SCX_SLICE_DFL; dispatch_enqueue(find_global_dsq(p), p, enq_flags); } -- GitLab From 8ec5a4e5ce97d6ee9f5eb5b4ce4cfc831976fdec Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Wed, 24 Jul 2024 16:59:19 -0700 Subject: [PATCH 441/970] drm/xe: Resume TDR after GT reset Not starting the TDR after GT reset on exec queue which have been restarted can lead to jobs being able to be run forever. Fix this by restarting the TDR. Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240724235919.1917216-1-matthew.brost@intel.com --- drivers/gpu/drm/xe/xe_gpu_scheduler.c | 5 +++++ drivers/gpu/drm/xe/xe_gpu_scheduler.h | 2 ++ drivers/gpu/drm/xe/xe_guc_submit.c | 1 + 3 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.c b/drivers/gpu/drm/xe/xe_gpu_scheduler.c index c518d1d16d82..50361b4638f9 100644 --- a/drivers/gpu/drm/xe/xe_gpu_scheduler.c +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.c @@ -90,6 +90,11 @@ void xe_sched_submission_stop(struct xe_gpu_scheduler *sched) cancel_work_sync(&sched->work_process_msg); } +void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched) +{ + drm_sched_resume_timeout(&sched->base, sched->base.timeout); +} + void xe_sched_add_msg(struct xe_gpu_scheduler *sched, struct xe_sched_msg *msg) { diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.h b/drivers/gpu/drm/xe/xe_gpu_scheduler.h index cee9c6809fc0..5ad5629a6c60 100644 --- a/drivers/gpu/drm/xe/xe_gpu_scheduler.h +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.h @@ -22,6 +22,8 @@ void xe_sched_fini(struct xe_gpu_scheduler *sched); void xe_sched_submission_start(struct xe_gpu_scheduler *sched); void xe_sched_submission_stop(struct xe_gpu_scheduler *sched); +void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched); + void xe_sched_add_msg(struct xe_gpu_scheduler *sched, struct xe_sched_msg *msg); void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched, diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 98a6a385a796..80062e1d3f66 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1826,6 +1826,7 @@ static void guc_exec_queue_start(struct xe_exec_queue *q) } xe_sched_submission_start(sched); + xe_sched_submission_resume_tdr(sched); } int xe_guc_submit_start(struct xe_guc *guc) -- GitLab From dcfd3971327f3ee92765154baebbaece833d3ca9 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 25 Sep 2024 08:14:27 +0100 Subject: [PATCH 442/970] drm/xe/vm: move xa_alloc to prevent UAF Evil user can guess the next id of the vm before the ioctl completes and then call vm destroy ioctl to trigger UAF since create ioctl is still referencing the same vm. Move the xa_alloc all the way to the end to prevent this. v2: - Rebase Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925071426.144015-3-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_vm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 31fe31db3fdc..ce9dca4d4e87 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1765,10 +1765,6 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, if (IS_ERR(vm)) return PTR_ERR(vm); - err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); - if (err) - goto err_close_and_put; - if (xe->info.has_asid) { down_write(&xe->usm.lock); err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, @@ -1776,12 +1772,11 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, &xe->usm.next_asid, GFP_KERNEL); up_write(&xe->usm.lock); if (err < 0) - goto err_free_id; + goto err_close_and_put; vm->usm.asid = asid; } - args->vm_id = id; vm->xef = xe_file_get(xef); /* Record BO memory for VM pagetable created against client */ @@ -1794,10 +1789,15 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); #endif + /* user id alloc must always be last in ioctl to prevent UAF */ + err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); + if (err) + goto err_close_and_put; + + args->vm_id = id; + return 0; -err_free_id: - xa_erase(&xef->vm.xa, id); err_close_and_put: xe_vm_close_and_put(vm); -- GitLab From 16536582ddbebdbdf9e1d7af321bbba2bf955a87 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 25 Sep 2024 08:14:28 +0100 Subject: [PATCH 443/970] drm/xe/queue: move xa_alloc to prevent UAF Evil user can guess the next id of the queue before the ioctl completes and then call queue destroy ioctl to trigger UAF since create ioctl is still referencing the same queue. Move the xa_alloc all the way to the end to prevent this. v2: - Rebase Fixes: 2149ded63079 ("drm/xe: Fix use after free when client stats are captured") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925071426.144015-4-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_exec_queue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 7743ebdcbf4b..d098d2dd1b2d 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -635,12 +635,14 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data, } } + q->xef = xe_file_get(xef); + + /* user id alloc must always be last in ioctl to prevent UAF */ err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); if (err) goto kill_exec_queue; args->exec_queue_id = id; - q->xef = xe_file_get(xef); return 0; -- GitLab From 09573b1cc76e7ff8f056ab29ea1cdc152ec8c653 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Wed, 11 Sep 2024 17:42:34 +0800 Subject: [PATCH 444/970] net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: 8c6ad9cc5157 ("ieee802154: Add NXP MCR20A IEEE 802.15.4 transceiver driver") Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Link: https://lore.kernel.org/20240911094234.1922418-1-ruanjinjie@huawei.com Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org> --- drivers/net/ieee802154/mcr20a.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index 433fb5839203..020d392a98b6 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c @@ -1302,16 +1302,13 @@ mcr20a_probe(struct spi_device *spi) irq_type = IRQF_TRIGGER_FALLING; ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr, - irq_type, dev_name(&spi->dev), lp); + irq_type | IRQF_NO_AUTOEN, dev_name(&spi->dev), lp); if (ret) { dev_err(&spi->dev, "could not request_irq for mcr20a\n"); ret = -ENODEV; goto free_dev; } - /* disable_irq by default and wait for starting hardware */ - disable_irq(spi->irq); - ret = ieee802154_register_hw(hw); if (ret) { dev_crit(&spi->dev, "ieee802154_register_hw failed\n"); -- GitLab From d505d3593b52b6c43507f119572409087416ba28 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 23 Sep 2024 19:57:43 +0800 Subject: [PATCH 445/970] net: wwan: qcom_bam_dmux: Fix missing pm_runtime_disable() It's important to undo pm_runtime_use_autosuspend() with pm_runtime_dont_use_autosuspend() at driver exit time. But the pm_runtime_disable() and pm_runtime_dont_use_autosuspend() is missing in the error path for bam_dmux_probe(). So add it. Found by code review. Compile-tested only. Fixes: 21a0ffd9b38c ("net: wwan: Add Qualcomm BAM-DMUX WWAN network driver") Suggested-by: Stephan Gerhold <stephan.gerhold@linaro.org> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Reviewed-by: Stephan Gerhold <stephan.gerhold@linaro.org> Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> --- drivers/net/wwan/qcom_bam_dmux.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c index 26ca719fa0de..5dcb9a84a12e 100644 --- a/drivers/net/wwan/qcom_bam_dmux.c +++ b/drivers/net/wwan/qcom_bam_dmux.c @@ -823,17 +823,17 @@ static int bam_dmux_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, pc_ack_irq, NULL, bam_dmux_pc_ack_irq, IRQF_ONESHOT, NULL, dmux); if (ret) - return ret; + goto err_disable_pm; ret = devm_request_threaded_irq(dev, dmux->pc_irq, NULL, bam_dmux_pc_irq, IRQF_ONESHOT, NULL, dmux); if (ret) - return ret; + goto err_disable_pm; ret = irq_get_irqchip_state(dmux->pc_irq, IRQCHIP_STATE_LINE_LEVEL, &dmux->pc_state); if (ret) - return ret; + goto err_disable_pm; /* Check if remote finished initialization before us */ if (dmux->pc_state) { @@ -844,6 +844,11 @@ static int bam_dmux_probe(struct platform_device *pdev) } return 0; + +err_disable_pm: + pm_runtime_disable(dev); + pm_runtime_dont_use_autosuspend(dev); + return ret; } static void bam_dmux_remove(struct platform_device *pdev) -- GitLab From 8a89015644513ef69193a037eb966f2d55fe385a Mon Sep 17 00:00:00 2001 From: Phil Sutter <phil@nwl.cc> Date: Thu, 26 Sep 2024 18:56:31 +0200 Subject: [PATCH 446/970] selftests: netfilter: Fix nft_audit.sh for newer nft binaries As a side-effect of nftables' commit dbff26bfba833 ("cache: consolidate reset command"), audit logs changed when more objects were reset than fit into a single netlink message. Since the objects' distribution in netlink messages is not relevant, implement a summarizing function which combines repeated audit logs into a single one with summed up 'entries=' value. Fixes: 203bb9d39866 ("selftests: netfilter: Extend nft_audit.sh") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- .../selftests/net/netfilter/nft_audit.sh | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/tools/testing/selftests/net/netfilter/nft_audit.sh b/tools/testing/selftests/net/netfilter/nft_audit.sh index 902f8114bc80..87f2b4c725aa 100755 --- a/tools/testing/selftests/net/netfilter/nft_audit.sh +++ b/tools/testing/selftests/net/netfilter/nft_audit.sh @@ -48,12 +48,31 @@ logread_pid=$! trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT exec 3<"$logfile" +lsplit='s/^\(.*\) entries=\([^ ]*\) \(.*\)$/pfx="\1"\nval="\2"\nsfx="\3"/' +summarize_logs() { + sum=0 + while read line; do + eval $(sed "$lsplit" <<< "$line") + [[ $sum -gt 0 ]] && { + [[ "$pfx $sfx" == "$tpfx $tsfx" ]] && { + let "sum += val" + continue + } + echo "$tpfx entries=$sum $tsfx" + } + tpfx="$pfx" + tsfx="$sfx" + sum=$val + done + echo "$tpfx entries=$sum $tsfx" +} + do_test() { # (cmd, log) echo -n "testing for cmd: $1 ... " cat <&3 >/dev/null $1 >/dev/null || exit 1 sleep 0.1 - res=$(diff -a -u <(echo "$2") - <&3) + res=$(diff -a -u <(echo "$2") <(summarize_logs <&3)) [ $? -eq 0 ] && { echo "OK"; return; } echo "FAIL" grep -v '^\(---\|+++\|@@\)' <<< "$res" @@ -152,31 +171,17 @@ do_test 'nft reset rules t1 c2' \ 'table=t1 family=2 entries=3 op=nft_reset_rule' do_test 'nft reset rules table t1' \ -'table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule' +'table=t1 family=2 entries=9 op=nft_reset_rule' do_test 'nft reset rules t2 c3' \ -'table=t2 family=2 entries=189 op=nft_reset_rule -table=t2 family=2 entries=188 op=nft_reset_rule -table=t2 family=2 entries=126 op=nft_reset_rule' +'table=t2 family=2 entries=503 op=nft_reset_rule' do_test 'nft reset rules t2' \ -'table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=186 op=nft_reset_rule -table=t2 family=2 entries=188 op=nft_reset_rule -table=t2 family=2 entries=129 op=nft_reset_rule' +'table=t2 family=2 entries=509 op=nft_reset_rule' do_test 'nft reset rules' \ -'table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule -table=t1 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=3 op=nft_reset_rule -table=t2 family=2 entries=180 op=nft_reset_rule -table=t2 family=2 entries=188 op=nft_reset_rule -table=t2 family=2 entries=135 op=nft_reset_rule' +'table=t1 family=2 entries=9 op=nft_reset_rule +table=t2 family=2 entries=509 op=nft_reset_rule' # resetting sets and elements @@ -200,13 +205,11 @@ do_test 'nft reset counters t1' \ 'table=t1 family=2 entries=1 op=nft_reset_obj' do_test 'nft reset counters t2' \ -'table=t2 family=2 entries=342 op=nft_reset_obj -table=t2 family=2 entries=158 op=nft_reset_obj' +'table=t2 family=2 entries=500 op=nft_reset_obj' do_test 'nft reset counters' \ 'table=t1 family=2 entries=1 op=nft_reset_obj -table=t2 family=2 entries=341 op=nft_reset_obj -table=t2 family=2 entries=159 op=nft_reset_obj' +table=t2 family=2 entries=500 op=nft_reset_obj' # resetting quotas @@ -217,13 +220,11 @@ do_test 'nft reset quotas t1' \ 'table=t1 family=2 entries=1 op=nft_reset_obj' do_test 'nft reset quotas t2' \ -'table=t2 family=2 entries=315 op=nft_reset_obj -table=t2 family=2 entries=185 op=nft_reset_obj' +'table=t2 family=2 entries=500 op=nft_reset_obj' do_test 'nft reset quotas' \ 'table=t1 family=2 entries=1 op=nft_reset_obj -table=t2 family=2 entries=314 op=nft_reset_obj -table=t2 family=2 entries=186 op=nft_reset_obj' +table=t2 family=2 entries=500 op=nft_reset_obj' # deleting rules -- GitLab From 92ceba94de6fb4cee2bf40b485979c342f44a492 Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@google.com> Date: Thu, 26 Sep 2024 18:56:11 +0000 Subject: [PATCH 447/970] netfilter: nf_tables: prevent nf_skb_duplicated corruption syzbot found that nf_dup_ipv4() or nf_dup_ipv6() could write per-cpu variable nf_skb_duplicated in an unsafe way [1]. Disabling preemption as hinted by the splat is not enough, we have to disable soft interrupts as well. [1] BUG: using __this_cpu_write() in preemptible [00000000] code: syz.4.282/6316 caller is nf_dup_ipv4+0x651/0x8f0 net/ipv4/netfilter/nf_dup_ipv4.c:87 CPU: 0 UID: 0 PID: 6316 Comm: syz.4.282 Not tainted 6.11.0-rc7-syzkaller-00104-g7052622fccb1 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 Call Trace: <TASK> __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119 check_preemption_disabled+0x10e/0x120 lib/smp_processor_id.c:49 nf_dup_ipv4+0x651/0x8f0 net/ipv4/netfilter/nf_dup_ipv4.c:87 nft_dup_ipv4_eval+0x1db/0x300 net/ipv4/netfilter/nft_dup_ipv4.c:30 expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] nft_do_chain+0x4ad/0x1da0 net/netfilter/nf_tables_core.c:288 nft_do_chain_ipv4+0x202/0x320 net/netfilter/nft_chain_filter.c:23 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xc3/0x220 net/netfilter/core.c:626 nf_hook+0x2c4/0x450 include/linux/netfilter.h:269 NF_HOOK_COND include/linux/netfilter.h:302 [inline] ip_output+0x185/0x230 net/ipv4/ip_output.c:433 ip_local_out net/ipv4/ip_output.c:129 [inline] ip_send_skb+0x74/0x100 net/ipv4/ip_output.c:1495 udp_send_skb+0xacf/0x1650 net/ipv4/udp.c:981 udp_sendmsg+0x1c21/0x2a60 net/ipv4/udp.c:1269 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg+0x1a6/0x270 net/socket.c:745 ____sys_sendmsg+0x525/0x7d0 net/socket.c:2597 ___sys_sendmsg net/socket.c:2651 [inline] __sys_sendmmsg+0x3b2/0x740 net/socket.c:2737 __do_sys_sendmmsg net/socket.c:2766 [inline] __se_sys_sendmmsg net/socket.c:2763 [inline] __x64_sys_sendmmsg+0xa0/0xb0 net/socket.c:2763 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f4ce4f7def9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f4ce5d4a038 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 00007f4ce5135f80 RCX: 00007f4ce4f7def9 RDX: 0000000000000001 RSI: 0000000020005d40 RDI: 0000000000000006 RBP: 00007f4ce4ff0b76 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f4ce5135f80 R15: 00007ffd4cbc6d68 </TASK> Fixes: d877f07112f1 ("netfilter: nf_tables: add nft_dup expression") Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/ipv4/netfilter/nf_dup_ipv4.c | 7 +++++-- net/ipv6/netfilter/nf_dup_ipv6.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/net/ipv4/netfilter/nf_dup_ipv4.c b/net/ipv4/netfilter/nf_dup_ipv4.c index f4aed0789d69..ec94ee1051c7 100644 --- a/net/ipv4/netfilter/nf_dup_ipv4.c +++ b/net/ipv4/netfilter/nf_dup_ipv4.c @@ -53,8 +53,9 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum, { struct iphdr *iph; + local_bh_disable(); if (this_cpu_read(nf_skb_duplicated)) - return; + goto out; /* * Copy the skb, and route the copy. Will later return %XT_CONTINUE for * the original skb, which should continue on its way as if nothing has @@ -62,7 +63,7 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum, */ skb = pskb_copy(skb, GFP_ATOMIC); if (skb == NULL) - return; + goto out; #if IS_ENABLED(CONFIG_NF_CONNTRACK) /* Avoid counting cloned packets towards the original connection. */ @@ -91,6 +92,8 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum, } else { kfree_skb(skb); } +out: + local_bh_enable(); } EXPORT_SYMBOL_GPL(nf_dup_ipv4); diff --git a/net/ipv6/netfilter/nf_dup_ipv6.c b/net/ipv6/netfilter/nf_dup_ipv6.c index a0a2de30be3e..0c39c77fe8a8 100644 --- a/net/ipv6/netfilter/nf_dup_ipv6.c +++ b/net/ipv6/netfilter/nf_dup_ipv6.c @@ -47,11 +47,12 @@ static bool nf_dup_ipv6_route(struct net *net, struct sk_buff *skb, void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum, const struct in6_addr *gw, int oif) { + local_bh_disable(); if (this_cpu_read(nf_skb_duplicated)) - return; + goto out; skb = pskb_copy(skb, GFP_ATOMIC); if (skb == NULL) - return; + goto out; #if IS_ENABLED(CONFIG_NF_CONNTRACK) nf_reset_ct(skb); @@ -69,6 +70,8 @@ void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum, } else { kfree_skb(skb); } +out: + local_bh_enable(); } EXPORT_SYMBOL_GPL(nf_dup_ipv6); -- GitLab From 10dbd23633f0433f8d13c2803d687b36a675ef60 Mon Sep 17 00:00:00 2001 From: zhang jiao <zhangjiao2@cmss.chinamobile.com> Date: Fri, 27 Sep 2024 11:22:05 +0800 Subject: [PATCH 448/970] selftests: netfilter: Add missing return value There is no return value in count_entries, just add it. Fixes: eff3c558bb7e ("netfilter: ctnetlink: support filtering by zone") Signed-off-by: zhang jiao <zhangjiao2@cmss.chinamobile.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- tools/testing/selftests/net/netfilter/conntrack_dump_flush.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c b/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c index bd9317bf5ada..dc056fec993b 100644 --- a/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c +++ b/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c @@ -207,6 +207,7 @@ static int conntrack_data_generate_v6(struct mnl_socket *sock, static int count_entries(const struct nlmsghdr *nlh, void *data) { reply_counter++; + return MNL_CB_OK; } static int conntracK_count_zone(struct mnl_socket *sock, uint16_t zone) -- GitLab From f53e1c9c726d83092167f2226f32bd3b73f26c21 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Thu, 12 Sep 2024 12:34:42 -0400 Subject: [PATCH 449/970] Bluetooth: MGMT: Fix possible crash on mgmt_index_removed If mgmt_index_removed is called while there are commands queued on cmd_sync it could lead to crashes like the bellow trace: 0x0000053D: __list_del_entry_valid_or_report+0x98/0xdc 0x0000053D: mgmt_pending_remove+0x18/0x58 [bluetooth] 0x0000053E: mgmt_remove_adv_monitor_complete+0x80/0x108 [bluetooth] 0x0000053E: hci_cmd_sync_work+0xbc/0x164 [bluetooth] So while handling mgmt_index_removed this attempts to dequeue commands passed as user_data to cmd_sync. Fixes: 7cf5c2978f23 ("Bluetooth: hci_sync: Refactor remove Adv Monitor") Reported-by: jiaymao <quic_jiaymao@quicinc.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> --- net/bluetooth/mgmt.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index e4f564d6f6fb..4157d9f23f46 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1453,10 +1453,15 @@ static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) { - if (cmd->cmd_complete) { - u8 *status = data; + struct cmd_lookup *match = data; + + /* dequeue cmd_sync entries using cmd as data as that is about to be + * removed/freed. + */ + hci_cmd_sync_dequeue(match->hdev, NULL, cmd, NULL); - cmd->cmd_complete(cmd, *status); + if (cmd->cmd_complete) { + cmd->cmd_complete(cmd, match->mgmt_status); mgmt_pending_remove(cmd); return; @@ -9394,12 +9399,12 @@ void mgmt_index_added(struct hci_dev *hdev) void mgmt_index_removed(struct hci_dev *hdev) { struct mgmt_ev_ext_index ev; - u8 status = MGMT_STATUS_INVALID_INDEX; + struct cmd_lookup match = { NULL, hdev, MGMT_STATUS_INVALID_INDEX }; if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) return; - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); + mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, @@ -9450,7 +9455,7 @@ void mgmt_power_on(struct hci_dev *hdev, int err) void __mgmt_power_off(struct hci_dev *hdev) { struct cmd_lookup match = { NULL, hdev }; - u8 status, zero_cod[] = { 0, 0, 0 }; + u8 zero_cod[] = { 0, 0, 0 }; mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); @@ -9462,11 +9467,11 @@ void __mgmt_power_off(struct hci_dev *hdev) * status responses. */ if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) - status = MGMT_STATUS_INVALID_INDEX; + match.mgmt_status = MGMT_STATUS_INVALID_INDEX; else - status = MGMT_STATUS_NOT_POWERED; + match.mgmt_status = MGMT_STATUS_NOT_POWERED; - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status); + mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, -- GitLab From 333b4fd11e89b29c84c269123f871883a30be586 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Mon, 23 Sep 2024 12:47:39 -0400 Subject: [PATCH 450/970] Bluetooth: L2CAP: Fix uaf in l2cap_connect [Syzbot reported] BUG: KASAN: slab-use-after-free in l2cap_connect.constprop.0+0x10d8/0x1270 net/bluetooth/l2cap_core.c:3949 Read of size 8 at addr ffff8880241e9800 by task kworker/u9:0/54 CPU: 0 UID: 0 PID: 54 Comm: kworker/u9:0 Not tainted 6.11.0-rc6-syzkaller-00268-g788220eee30d #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 Workqueue: hci2 hci_rx_work Call Trace: <TASK> __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:119 print_address_description mm/kasan/report.c:377 [inline] print_report+0xc3/0x620 mm/kasan/report.c:488 kasan_report+0xd9/0x110 mm/kasan/report.c:601 l2cap_connect.constprop.0+0x10d8/0x1270 net/bluetooth/l2cap_core.c:3949 l2cap_connect_req net/bluetooth/l2cap_core.c:4080 [inline] l2cap_bredr_sig_cmd net/bluetooth/l2cap_core.c:4772 [inline] l2cap_sig_channel net/bluetooth/l2cap_core.c:5543 [inline] l2cap_recv_frame+0xf0b/0x8eb0 net/bluetooth/l2cap_core.c:6825 l2cap_recv_acldata+0x9b4/0xb70 net/bluetooth/l2cap_core.c:7514 hci_acldata_packet net/bluetooth/hci_core.c:3791 [inline] hci_rx_work+0xaab/0x1610 net/bluetooth/hci_core.c:4028 process_one_work+0x9c5/0x1b40 kernel/workqueue.c:3231 process_scheduled_works kernel/workqueue.c:3312 [inline] worker_thread+0x6c8/0xed0 kernel/workqueue.c:3389 kthread+0x2c1/0x3a0 kernel/kthread.c:389 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 ... Freed by task 5245: kasan_save_stack+0x33/0x60 mm/kasan/common.c:47 kasan_save_track+0x14/0x30 mm/kasan/common.c:68 kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:579 poison_slab_object+0xf7/0x160 mm/kasan/common.c:240 __kasan_slab_free+0x32/0x50 mm/kasan/common.c:256 kasan_slab_free include/linux/kasan.h:184 [inline] slab_free_hook mm/slub.c:2256 [inline] slab_free mm/slub.c:4477 [inline] kfree+0x12a/0x3b0 mm/slub.c:4598 l2cap_conn_free net/bluetooth/l2cap_core.c:1810 [inline] kref_put include/linux/kref.h:65 [inline] l2cap_conn_put net/bluetooth/l2cap_core.c:1822 [inline] l2cap_conn_del+0x59d/0x730 net/bluetooth/l2cap_core.c:1802 l2cap_connect_cfm+0x9e6/0xf80 net/bluetooth/l2cap_core.c:7241 hci_connect_cfm include/net/bluetooth/hci_core.h:1960 [inline] hci_conn_failed+0x1c3/0x370 net/bluetooth/hci_conn.c:1265 hci_abort_conn_sync+0x75a/0xb50 net/bluetooth/hci_sync.c:5583 abort_conn_sync+0x197/0x360 net/bluetooth/hci_conn.c:2917 hci_cmd_sync_work+0x1a4/0x410 net/bluetooth/hci_sync.c:328 process_one_work+0x9c5/0x1b40 kernel/workqueue.c:3231 process_scheduled_works kernel/workqueue.c:3312 [inline] worker_thread+0x6c8/0xed0 kernel/workqueue.c:3389 kthread+0x2c1/0x3a0 kernel/kthread.c:389 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 Reported-by: syzbot+c12e2f941af1feb5632c@syzkaller.appspotmail.com Tested-by: syzbot+c12e2f941af1feb5632c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c12e2f941af1feb5632c Fixes: 7b064edae38d ("Bluetooth: Fix authentication if acl data comes before remote feature evt") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> --- net/bluetooth/hci_core.c | 2 ++ net/bluetooth/hci_event.c | 2 +- net/bluetooth/l2cap_core.c | 8 -------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d6976db02c06..b2f8f9c5b610 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3782,6 +3782,8 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, handle); + if (conn && hci_dev_test_flag(hdev, HCI_MGMT)) + mgmt_device_connected(hdev, conn, NULL, 0); hci_dev_unlock(hdev); if (conn) { diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 1c82dcdf6e8f..b87c0f1dab9e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3706,7 +3706,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data, goto unlock; } - if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) { + if (!ev->status) { struct hci_cp_remote_name_req cp; memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, &conn->dst); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9988ba382b68..6544c1ed7143 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4066,17 +4066,9 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, static int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { - struct hci_dev *hdev = conn->hcon->hdev; - struct hci_conn *hcon = conn->hcon; - if (cmd_len < sizeof(struct l2cap_conn_req)) return -EPROTO; - hci_dev_lock(hdev); - if (hci_dev_test_flag(hdev, HCI_MGMT)) - mgmt_device_connected(hdev, hcon, NULL, 0); - hci_dev_unlock(hdev); - l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP); return 0; } -- GitLab From 7b1ab460592ca818e7b52f27cd3ec86af79220d1 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Thu, 12 Sep 2024 11:12:04 +0800 Subject: [PATCH 451/970] Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq() disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ. Fixes: bb7f4f0bcee6 ("btmrvl: add platform specific wakeup interrupt support") Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> --- drivers/bluetooth/btmrvl_sdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 85b7f2bb4259..07cd308f7abf 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -92,7 +92,7 @@ static int btmrvl_sdio_probe_of(struct device *dev, } else { ret = devm_request_irq(dev, cfg->irq_bt, btmrvl_wake_irq_bt, - 0, "bt_wake", card); + IRQF_NO_AUTOEN, "bt_wake", card); if (ret) { dev_err(dev, "Failed to request irq_bt %d (%d)\n", @@ -101,7 +101,6 @@ static int btmrvl_sdio_probe_of(struct device *dev, /* Configure wakeup (enabled by default) */ device_init_wakeup(dev, true); - disable_irq(cfg->irq_bt); } } -- GitLab From b25e11f978b63cb7857890edb3a698599cddb10e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Thu, 12 Sep 2024 12:17:00 -0400 Subject: [PATCH 452/970] Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE This aligned BR/EDR JUST_WORKS method with LE which since 92516cd97fd4 ("Bluetooth: Always request for user confirmation for Just Works") always request user confirmation with confirm_hint set since the likes of bluetoothd have dedicated policy around JUST_WORKS method (e.g. main.conf:JustWorksRepairing). CVE: CVE-2024-8805 Cc: stable@vger.kernel.org Fixes: ba15a58b179e ("Bluetooth: Fix SSP acceptor just-works confirmation without MITM") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Tested-by: Kiran K <kiran.k@intel.com> --- net/bluetooth/hci_event.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b87c0f1dab9e..561c8cb87473 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5324,19 +5324,16 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data, goto unlock; } - /* If no side requires MITM protection; auto-accept */ + /* If no side requires MITM protection; use JUST_CFM method */ if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) && (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) { - /* If we're not the initiators request authorization to - * proceed from user space (mgmt_user_confirm with - * confirm_hint set to 1). The exception is if neither - * side had MITM or if the local IO capability is - * NoInputNoOutput, in which case we do auto-accept + /* If we're not the initiator of request authorization and the + * local IO capability is not NoInputNoOutput, use JUST_WORKS + * method (mgmt_user_confirm with confirm_hint set to 1). */ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && - conn->io_capability != HCI_IO_NO_INPUT_OUTPUT && - (loc_mitm || rem_mitm)) { + conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) { bt_dev_dbg(hdev, "Confirming auto-accept as acceptor"); confirm_hint = 1; goto confirm; -- GitLab From da6ef2dffe6056aad3435e6cf7c6471c2a62187c Mon Sep 17 00:00:00 2001 From: Baokun Li <libaokun1@huawei.com> Date: Thu, 29 Aug 2024 16:34:09 +0800 Subject: [PATCH 453/970] cachefiles: fix dentry leak in cachefiles_open_file() A dentry leak may be caused when a lookup cookie and a cull are concurrent: P1 | P2 ----------------------------------------------------------- cachefiles_lookup_cookie cachefiles_look_up_object lookup_one_positive_unlocked // get dentry cachefiles_cull inode->i_flags |= S_KERNEL_FILE; cachefiles_open_file cachefiles_mark_inode_in_use __cachefiles_mark_inode_in_use can_use = false if (!(inode->i_flags & S_KERNEL_FILE)) can_use = true return false return false // Returns an error but doesn't put dentry After that the following WARNING will be triggered when the backend folder is umounted: ================================================================== BUG: Dentry 000000008ad87947{i=7a,n=Dx_1_1.img} still in use (1) [unmount of ext4 sda] WARNING: CPU: 4 PID: 359261 at fs/dcache.c:1767 umount_check+0x5d/0x70 CPU: 4 PID: 359261 Comm: umount Not tainted 6.6.0-dirty #25 RIP: 0010:umount_check+0x5d/0x70 Call Trace: <TASK> d_walk+0xda/0x2b0 do_one_tree+0x20/0x40 shrink_dcache_for_umount+0x2c/0x90 generic_shutdown_super+0x20/0x160 kill_block_super+0x1a/0x40 ext4_kill_sb+0x22/0x40 deactivate_locked_super+0x35/0x80 cleanup_mnt+0x104/0x160 ================================================================== Whether cachefiles_open_file() returns true or false, the reference count obtained by lookup_positive_unlocked() in cachefiles_look_up_object() should be released. Therefore release that reference count in cachefiles_look_up_object() to fix the above issue and simplify the code. Fixes: 1f08c925e7a3 ("cachefiles: Implement backing file wrangling") Cc: stable@kernel.org Signed-off-by: Baokun Li <libaokun1@huawei.com> Link: https://lore.kernel.org/r/20240829083409.3788142-1-libaokun@huaweicloud.com Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/cachefiles/namei.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index f53977169db4..2b3f9935dbb4 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -595,14 +595,12 @@ static bool cachefiles_open_file(struct cachefiles_object *object, * write and readdir but not lookup or open). */ touch_atime(&file->f_path); - dput(dentry); return true; check_failed: fscache_cookie_lookup_negative(object->cookie); cachefiles_unmark_inode_in_use(object, file); fput(file); - dput(dentry); if (ret == -ESTALE) return cachefiles_create_file(object); return false; @@ -611,7 +609,6 @@ static bool cachefiles_open_file(struct cachefiles_object *object, fput(file); error: cachefiles_do_unmark_inode_in_use(object, d_inode(dentry)); - dput(dentry); return false; } @@ -654,7 +651,9 @@ bool cachefiles_look_up_object(struct cachefiles_object *object) goto new_file; } - if (!cachefiles_open_file(object, dentry)) + ret = cachefiles_open_file(object, dentry); + dput(dentry); + if (!ret) return false; _leave(" = t [%lu]", file_inode(object->file)->i_ino); -- GitLab From 2cf36327ee1e47733aba96092d7bd082a4056ff5 Mon Sep 17 00:00:00 2001 From: David Howells <dhowells@redhat.com> Date: Sat, 14 Sep 2024 21:40:02 +0100 Subject: [PATCH 454/970] afs: Fix missing wire-up of afs_retry_request() afs_retry_request() is supposed to be pointed to by the afs_req_ops netfs operations table, but the pointer got lost somewhere. The function is used during writeback to rotate through the authentication keys that were in force when the file was modified locally. Fix this by adding the pointer to the function. Fixes: 1ecb146f7cd8 ("netfs, afs: Use writeback retry to deal with alternate keys") Reported-by: Dr. David Alan Gilbert <linux@treblig.org> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/1690847.1726346402@warthog.procyon.org.uk cc: Marc Dionne <marc.dionne@auristor.com> cc: Jeff Layton <jlayton@kernel.org> cc: linux-afs@lists.infradead.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/afs/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/afs/file.c b/fs/afs/file.c index 492d857a3fa0..6762eff97517 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -420,6 +420,7 @@ const struct netfs_request_ops afs_req_ops = { .begin_writeback = afs_begin_writeback, .prepare_write = afs_prepare_write, .issue_write = afs_issue_write, + .retry_request = afs_retry_request, }; static void afs_add_open_mmap(struct afs_vnode *vnode) -- GitLab From 8a46067783bdff222d1fb8f8c20e3b7b711e3ce5 Mon Sep 17 00:00:00 2001 From: Christian Brauner <brauner@kernel.org> Date: Thu, 26 Sep 2024 18:51:46 +0200 Subject: [PATCH 455/970] pidfs: check for valid pid namespace When we access a no-current task's pid namespace we need check that the task hasn't been reaped in the meantime and it's pid namespace isn't accessible anymore. The user namespace is fine because it is only released when the last reference to struct task_struct is put and exit_creds() is called. Link: https://lore.kernel.org/r/20240926-klebt-altgedienten-0415ad4d273c@brauner Fixes: 5b08bd408534 ("pidfs: allow retrieval of namespace file descriptors") CC: stable@vger.kernel.org # v6.11 Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/pidfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/pidfs.c b/fs/pidfs.c index 7ffdc88dfb52..80675b6bf884 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -120,6 +120,7 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct nsproxy *nsp __free(put_nsproxy) = NULL; struct pid *pid = pidfd_pid(file); struct ns_common *ns_common = NULL; + struct pid_namespace *pid_ns; if (arg) return -EINVAL; @@ -202,7 +203,9 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case PIDFD_GET_PID_NAMESPACE: if (IS_ENABLED(CONFIG_PID_NS)) { rcu_read_lock(); - ns_common = to_ns_common( get_pid_ns(task_active_pid_ns(task))); + pid_ns = task_active_pid_ns(task); + if (pid_ns) + ns_common = to_ns_common(get_pid_ns(pid_ns)); rcu_read_unlock(); } break; -- GitLab From f94d54208f25dc93f3bcae9e725a582380a503b1 Mon Sep 17 00:00:00 2001 From: Marc Dionne <marc.dionne@auristor.com> Date: Mon, 23 Sep 2024 16:07:49 +0100 Subject: [PATCH 456/970] afs: Fix possible infinite loop with unresponsive servers A return code of 0 from afs_wait_for_one_fs_probe is an indication that the endpoint state attached to the operation is stale and has been superseded. In that case the iteration needs to be restarted so that the newer probe result state gets used. Failure to do so can result in an tight infinite loop around the iterate_address label, where all addresses are thought to be responsive and have been tried, with nothing to refresh the endpoint state. Fixes: 495f2ae9e355 ("afs: Fix fileserver rotation") Reported-by: Markus Suvanto <markus.suvanto@gmail.com> Link: https://lists.infradead.org/pipermail/linux-afs/2024-July/008628.html cc: linux-afs@lists.infradead.org Signed-off-by: Marc Dionne <marc.dionne@auristor.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/20240906134019.131553-1-marc.dionne@auristor.com/ Link: https://lore.kernel.org/r/20240923150756.902363-6-dhowells@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/afs/fs_probe.c | 4 ++-- fs/afs/rotate.c | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c index 580de4adaaf6..b516d05b0fef 100644 --- a/fs/afs/fs_probe.c +++ b/fs/afs/fs_probe.c @@ -506,10 +506,10 @@ int afs_wait_for_one_fs_probe(struct afs_server *server, struct afs_endpoint_sta finish_wait(&server->probe_wq, &wait); dont_wait: - if (estate->responsive_set & ~exclude) - return 1; if (test_bit(AFS_ESTATE_SUPERSEDED, &estate->flags)) return 0; + if (estate->responsive_set & ~exclude) + return 1; if (is_intr && signal_pending(current)) return -ERESTARTSYS; if (timo == 0) diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c index ed09d4d4c211..d612983d6f38 100644 --- a/fs/afs/rotate.c +++ b/fs/afs/rotate.c @@ -632,8 +632,10 @@ bool afs_select_fileserver(struct afs_operation *op) wait_for_more_probe_results: error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried, !(op->flags & AFS_OPERATION_UNINTR)); - if (!error) + if (error == 1) goto iterate_address; + if (!error) + goto restart_from_beginning; /* We've now had a failure to respond on all of a server's addresses - * immediately probe them again and consider retrying the server. @@ -644,10 +646,13 @@ bool afs_select_fileserver(struct afs_operation *op) error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried, !(op->flags & AFS_OPERATION_UNINTR)); switch (error) { - case 0: + case 1: op->flags &= ~AFS_OPERATION_RETRY_SERVER; - trace_afs_rotate(op, afs_rotate_trace_retry_server, 0); + trace_afs_rotate(op, afs_rotate_trace_retry_server, 1); goto retry_server; + case 0: + trace_afs_rotate(op, afs_rotate_trace_retry_server, 0); + goto restart_from_beginning; case -ERESTARTSYS: afs_op_set_error(op, error); goto failed; -- GitLab From 19dcfb9c1685d45ba96852e021415134865b0a95 Mon Sep 17 00:00:00 2001 From: Thorsten Blum <thorsten.blum@toblux.com> Date: Mon, 23 Sep 2024 16:07:48 +0100 Subject: [PATCH 457/970] afs: Remove unused struct and function prototype The struct afs_address_list and the function prototype afs_put_address_list() are not used anymore and can be removed. Remove them. Signed-off-by: Thorsten Blum <thorsten.blum@toblux.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/20240911095046.3749-2-thorsten.blum@toblux.com/ Link: https://lore.kernel.org/r/20240923150756.902363-5-dhowells@redhat.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/afs/afs_vl.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/afs/afs_vl.h b/fs/afs/afs_vl.h index 9c65ffb8a523..a06296c8827d 100644 --- a/fs/afs/afs_vl.h +++ b/fs/afs/afs_vl.h @@ -134,13 +134,4 @@ struct afs_uvldbentry__xdr { __be32 spares9; }; -struct afs_address_list { - refcount_t usage; - unsigned int version; - unsigned int nr_addrs; - struct sockaddr_rxrpc addrs[]; -}; - -extern void afs_put_address_list(struct afs_address_list *alist); - #endif /* AFS_VL_H */ -- GitLab From ff98751bae40faed1ba9c6a7287e84430f7dec64 Mon Sep 17 00:00:00 2001 From: David Howells <dhowells@redhat.com> Date: Mon, 23 Sep 2024 16:07:50 +0100 Subject: [PATCH 458/970] afs: Fix the setting of the server responding flag In afs_wait_for_operation(), we set transcribe the call responded flag to the server record that we used after doing the fileserver iteration loop - but it's possible to exit the loop having had a response from the server that we've discarded (e.g. it returned an abort or we started receiving data, but the call didn't complete). This means that op->server might be NULL, but we don't check that before attempting to set the server flag. Fixes: 98f9fda2057b ("afs: Fold the afs_addr_cursor struct in") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/20240923150756.902363-7-dhowells@redhat.com cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/afs/fs_operation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c index 3546b087e791..428721bbe4f6 100644 --- a/fs/afs/fs_operation.c +++ b/fs/afs/fs_operation.c @@ -201,7 +201,7 @@ void afs_wait_for_operation(struct afs_operation *op) } } - if (op->call_responded) + if (op->call_responded && op->server) set_bit(AFS_SERVER_FL_RESPONDING, &op->server->flags); if (!afs_op_error(op)) { -- GitLab From 9fffa4e9b3b158f63334e603e610da7d529a0f9a Mon Sep 17 00:00:00 2001 From: David Howells <dhowells@redhat.com> Date: Fri, 27 Sep 2024 09:08:42 +0100 Subject: [PATCH 459/970] netfs: Advance iterator correctly rather than jumping it In netfs_write_folio(), use iov_iter_advance() to advance the folio as we split bits of it off to subrequests rather than manually jumping the ->iov_offset value around. This becomes more problematic when we use a bounce buffer made out of single-page folios to cover a multipage pagecache folio. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/2238548.1727424522@warthog.procyon.org.uk cc: Jeff Layton <jlayton@kernel.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/netfs/write_issue.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c index 04e66d587f77..f9761d11791d 100644 --- a/fs/netfs/write_issue.c +++ b/fs/netfs/write_issue.c @@ -307,6 +307,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq, struct netfs_io_stream *stream; struct netfs_group *fgroup; /* TODO: Use this with ceph */ struct netfs_folio *finfo; + size_t iter_off = 0; size_t fsize = folio_size(folio), flen = fsize, foff = 0; loff_t fpos = folio_pos(folio), i_size; bool to_eof = false, streamw = false; @@ -462,7 +463,12 @@ static int netfs_write_folio(struct netfs_io_request *wreq, if (choose_s < 0) break; stream = &wreq->io_streams[choose_s]; - wreq->io_iter.iov_offset = stream->submit_off; + + /* Advance the iterator(s). */ + if (stream->submit_off > iter_off) { + iov_iter_advance(&wreq->io_iter, stream->submit_off - iter_off); + iter_off = stream->submit_off; + } atomic64_set(&wreq->issued_to, fpos + stream->submit_off); stream->submit_extendable_to = fsize - stream->submit_off; @@ -477,8 +483,8 @@ static int netfs_write_folio(struct netfs_io_request *wreq, debug = true; } - wreq->io_iter.iov_offset = 0; - iov_iter_advance(&wreq->io_iter, fsize); + if (fsize > iter_off) + iov_iter_advance(&wreq->io_iter, fsize - iter_off); atomic64_set(&wreq->issued_to, fpos + fsize); if (!debug) -- GitLab From 0c8650b09a365f4a31fca1d1d1e9d99c56071128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= <jose.souza@intel.com> Date: Tue, 24 Sep 2024 14:37:13 -0700 Subject: [PATCH 460/970] drm/xe/oa: Don't reset OAC_CONTEXT_ENABLE on OA stream close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesa testing on Xe2+ revealed that when OA metrics are collected for an exec_queue, after the OA stream is closed, future batch buffers submitted on that exec_queue do not complete. Not resetting OAC_CONTEXT_ENABLE on OA stream close resolves these hangs and should not have any adverse effects. v2: Make the change that we don't reset the bit clearer (Ashutosh) Also make the same fix for OAC as OAR (Ashutosh) Bspec: 60314 Fixes: 2f4a730fcd2d ("drm/xe/oa: Add OAR support") Fixes: 14e077f8006d ("drm/xe/oa: Add OAC support") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2821 Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Cc: stable@vger.kernel.org Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924213713.3497992-1-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/xe_oa.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 354ee9045efc..4c7b677115a8 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -712,8 +712,7 @@ static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable) { RING_CONTEXT_CONTROL(stream->hwe->mmio_base), regs_offset + CTX_CONTEXT_CONTROL, - _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, - enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE), }, }; struct xe_oa_reg reg_lri = { OAR_OACONTROL, oacontrol }; @@ -745,10 +744,8 @@ static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable) { RING_CONTEXT_CONTROL(stream->hwe->mmio_base), regs_offset + CTX_CONTEXT_CONTROL, - _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, - enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) | - _MASKED_FIELD(CTX_CTRL_RUN_ALONE, - enable ? CTX_CTRL_RUN_ALONE : 0), + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) | + _MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0), }, }; struct xe_oa_reg reg_lri = { OAC_OACONTROL, oacontrol }; -- GitLab From acd5f76fd5292c91628e04da83e8b78c986cfa2b Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires <bentiss@kernel.org> Date: Fri, 27 Sep 2024 16:17:41 +0200 Subject: [PATCH 461/970] HID: bpf: fix cfi stubs for hid_bpf_ops With the introduction of commit e42ac1418055 ("bpf: Check unsupported ops from the bpf_struct_ops's cfi_stubs"), a HID-BPF struct_ops containing a .hid_hw_request() or a .hid_hw_output_report() was failing to load as the cfi stubs were not defined. Fix that by defining those simple static functions and restore HID-BPF functionality. This was detected with the HID selftests suddenly failing on Linus' tree. Cc: stable@vger.kernel.org # v6.11+ Fixes: 9286675a2aed ("HID: bpf: add HID-BPF hooks for hid_hw_output_report") Fixes: 8bd0488b5ea5 ("HID: bpf: add HID-BPF hooks for hid_hw_raw_requests") Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Jiri Kosina <jkosina@suse.com> --- drivers/hid/bpf/hid_bpf_struct_ops.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c index cd696c59ba0f..702c22fae136 100644 --- a/drivers/hid/bpf/hid_bpf_struct_ops.c +++ b/drivers/hid/bpf/hid_bpf_struct_ops.c @@ -276,9 +276,23 @@ static int __hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx) return 0; } +static int __hid_bpf_hw_request(struct hid_bpf_ctx *ctx, unsigned char reportnum, + enum hid_report_type rtype, enum hid_class_request reqtype, + u64 source) +{ + return 0; +} + +static int __hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, u64 source) +{ + return 0; +} + static struct hid_bpf_ops __bpf_hid_bpf_ops = { .hid_device_event = __hid_bpf_device_event, .hid_rdesc_fixup = __hid_bpf_rdesc_fixup, + .hid_hw_request = __hid_bpf_hw_request, + .hid_hw_output_report = __hid_bpf_hw_output_report, }; static struct bpf_struct_ops bpf_hid_bpf_ops = { -- GitLab From 1bbcfe620e03aafc542b1c649dea0a9499a4490f Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:39 -1000 Subject: [PATCH 462/970] sched_ext: Relocate check_hotplug_seq() call in scx_ops_enable() check_hotplug_seq() is used to detect CPU hotplug event which occurred while the BPF scheduler is being loaded so that initialization can be retried if CPU hotplug events take place before the CPU hotplug callbacks are online. As such, the best place to call it is in the same cpu_read_lock() section that enables the CPU hotplug ops. Currently, it is called in the next cpus_read_lock() block in scx_ops_enable(). The side effect of this placement is a small window in which hotplug sequence detection can trigger unnecessarily, which isn't critical. Move check_hotplug_seq() invocation to the same cpus_read_lock() block as the hotplug operation enablement to close the window and get the invocation out of the way for planned locking updates. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: David Vernet <void@manifault.com> --- kernel/sched/ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index d6f6bf6caecc..e8ab7e5ee2dd 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -5050,6 +5050,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) if (((void (**)(void))ops)[i]) static_branch_enable_cpuslocked(&scx_has_op[i]); + check_hotplug_seq(ops); cpus_read_unlock(); ret = validate_ops(ops); @@ -5098,8 +5099,6 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) cpus_read_lock(); scx_cgroup_lock(); - check_hotplug_seq(ops); - for (i = SCX_OPI_NORMAL_BEGIN; i < SCX_OPI_NORMAL_END; i++) if (((void (**)(void))ops)[i]) static_branch_enable_cpuslocked(&scx_has_op[i]); -- GitLab From fc1fcebead344360979ea9407029f9c8a99d718f Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:39 -1000 Subject: [PATCH 463/970] sched_ext: Remove SCX_OPS_PREPPING The distinction between SCX_OPS_PREPPING and SCX_OPS_ENABLING is not used anywhere and only adds confusion. Drop SCX_OPS_PREPPING. Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/sched/ext.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index e8ab7e5ee2dd..daeb8446ff32 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -779,7 +779,6 @@ enum scx_tg_flags { }; enum scx_ops_enable_state { - SCX_OPS_PREPPING, SCX_OPS_ENABLING, SCX_OPS_ENABLED, SCX_OPS_DISABLING, @@ -787,7 +786,6 @@ enum scx_ops_enable_state { }; static const char *scx_ops_enable_state_str[] = { - [SCX_OPS_PREPPING] = "prepping", [SCX_OPS_ENABLING] = "enabling", [SCX_OPS_ENABLED] = "enabled", [SCX_OPS_DISABLING] = "disabling", @@ -5016,12 +5014,12 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) } /* - * Set scx_ops, transition to PREPPING and clear exit info to arm the + * Set scx_ops, transition to ENABLING and clear exit info to arm the * disable path. Failure triggers full disabling from here on. */ scx_ops = *ops; - WARN_ON_ONCE(scx_ops_set_enable_state(SCX_OPS_PREPPING) != + WARN_ON_ONCE(scx_ops_set_enable_state(SCX_OPS_ENABLING) != SCX_OPS_DISABLED); atomic_set(&scx_exit_kind, SCX_EXIT_NONE); @@ -5174,23 +5172,6 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) */ preempt_disable(); - /* - * From here on, the disable path must assume that tasks have ops - * enabled and need to be recovered. - * - * Transition to ENABLING fails iff the BPF scheduler has already - * triggered scx_bpf_error(). Returning an error code here would lose - * the recorded error information. Exit indicating success so that the - * error is notified through ops.exit() with all the details. - */ - if (!scx_ops_tryset_enable_state(SCX_OPS_ENABLING, SCX_OPS_PREPPING)) { - preempt_enable(); - spin_unlock_irq(&scx_tasks_lock); - WARN_ON_ONCE(atomic_read(&scx_exit_kind) == SCX_EXIT_NONE); - ret = 0; - goto err_disable_unlock_all; - } - /* * We're fully committed and can't fail. The PREPPED -> ENABLED * transitions here are synchronized against sched_ext_free() through @@ -5221,7 +5202,11 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) cpus_read_unlock(); percpu_up_write(&scx_fork_rwsem); - /* see above ENABLING transition for the explanation on exiting with 0 */ + /* + * Returning an error code here would lose the recorded error + * information. Exit indicating success so that the error is notified + * through ops.exit() with all the details. + */ if (!scx_ops_tryset_enable_state(SCX_OPS_ENABLED, SCX_OPS_ENABLING)) { WARN_ON_ONCE(atomic_read(&scx_exit_kind) == SCX_EXIT_NONE); ret = 0; -- GitLab From 8c2090c504e998c8f34ec870bae71dafcc96a6e0 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:40 -1000 Subject: [PATCH 464/970] sched_ext: Initialize in bypass mode scx_ops_enable() used preempt_disable() around the task iteration loop to switch tasks into SCX to guarantee forward progress of the task which is running scx_ops_enable(). However, in the gap between setting __scx_ops_enabled and preeempt_disable(), an external entity can put tasks including the enabling one into SCX prematurely, which can lead to malfunctions including stalls. The bypass mode can wrap the entire enabling operation and guarantee forward progress no matter what the BPF scheduler does. Use the bypass mode instead to guarantee forward progress while enabling. While at it, release and regrab scx_tasks_lock between the two task iteration locks in scx_ops_enable() for clarity as there is no reason to keep holding the lock between them. Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/sched/ext.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index daeb8446ff32..00883f3ef647 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -5075,6 +5075,14 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) queue_delayed_work(system_unbound_wq, &scx_watchdog_work, scx_watchdog_timeout / 2); + /* + * Once __scx_ops_enabled is set, %current can be switched to SCX + * anytime. This can lead to stalls as some BPF schedulers (e.g. + * userspace scheduling) may not function correctly before all tasks are + * switched. Init in bypass mode to guarantee forward progress. + */ + scx_ops_bypass(true); + /* * Lock out forks, cgroup on/offlining and moves before opening the * floodgate so that they don't wander into the operations prematurely. @@ -5134,7 +5142,6 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) * disabled. */ spin_lock_irq(&scx_tasks_lock); - scx_task_iter_init(&sti); while ((p = scx_task_iter_next_locked(&sti))) { /* @@ -5163,22 +5170,19 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) spin_lock_irq(&scx_tasks_lock); } scx_task_iter_exit(&sti); + spin_unlock_irq(&scx_tasks_lock); /* - * All tasks are prepped but are still ops-disabled. Ensure that - * %current can't be scheduled out and switch everyone. - * preempt_disable() is necessary because we can't guarantee that - * %current won't be starved if scheduled out while switching. + * All tasks are prepped but the tasks are not enabled. Switch everyone. */ - preempt_disable(); + WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL)); /* * We're fully committed and can't fail. The PREPPED -> ENABLED * transitions here are synchronized against sched_ext_free() through * scx_tasks_lock. */ - WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL)); - + spin_lock_irq(&scx_tasks_lock); scx_task_iter_init(&sti); while ((p = scx_task_iter_next_locked(&sti))) { const struct sched_class *old_class = p->sched_class; @@ -5195,12 +5199,12 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) check_class_changed(task_rq(p), p, old_class, p->prio); } scx_task_iter_exit(&sti); - spin_unlock_irq(&scx_tasks_lock); - preempt_enable(); + scx_cgroup_unlock(); cpus_read_unlock(); percpu_up_write(&scx_fork_rwsem); + scx_ops_bypass(false); /* * Returning an error code here would lose the recorded error @@ -5241,6 +5245,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) err_disable_unlock_all: scx_cgroup_unlock(); percpu_up_write(&scx_fork_rwsem); + scx_ops_bypass(false); err_disable_unlock_cpus: cpus_read_unlock(); err_disable: -- GitLab From 9753358a6a2b011478e8efdabbb489216252426f Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:40 -1000 Subject: [PATCH 465/970] sched_ext: Fix SCX_TASK_INIT -> SCX_TASK_READY transitions in scx_ops_enable() scx_ops_enable() has two task iteration loops. The first one calls scx_ops_init_task() on every task and the latter switches the eligible ones into SCX. The first loop left the tasks in SCX_TASK_INIT state and then the second loop switched it into READY before switching the task into SCX. The distinction between INIT and READY is only meaningful in the fork path where it's used to tell whether the task finished forking so that we can tell ops.exit_task() accordingly. Leaving task in INIT state between the two loops is incosistent with the fork path and incorrect. The following can be triggered by running a program which keeps toggling a task between SCHED_OTHER and SCHED_SCX while enabling a task: sched_ext: Invalid task state transition 1 -> 3 for fish[1526] WARNING: CPU: 2 PID: 1615 at kernel/sched/ext.c:3393 scx_ops_enable_task+0x1a1/0x200 ... Sched_ext: qmap (enabling+all) RIP: 0010:scx_ops_enable_task+0x1a1/0x200 ... switching_to_scx+0x13/0xa0 __sched_setscheduler+0x850/0xa50 do_sched_setscheduler+0x104/0x1c0 __x64_sys_sched_setscheduler+0x18/0x30 do_syscall_64+0x7b/0x140 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fix it by transitioning to READY in the first loop right after scx_ops_init_task() succeeds. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: David Vernet <void@manifault.com> --- kernel/sched/ext.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index 00883f3ef647..e83af19de59d 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -5166,6 +5166,8 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) goto err_disable_unlock_all; } + scx_set_task_state(p, SCX_TASK_READY); + put_task_struct(p); spin_lock_irq(&scx_tasks_lock); } @@ -5178,7 +5180,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL)); /* - * We're fully committed and can't fail. The PREPPED -> ENABLED + * We're fully committed and can't fail. The task READY -> ENABLED * transitions here are synchronized against sched_ext_free() through * scx_tasks_lock. */ @@ -5190,7 +5192,6 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx); - scx_set_task_state(p, SCX_TASK_READY); __setscheduler_prio(p, p->prio); check_class_changing(task_rq(p), p, old_class); -- GitLab From 4269c603cc26df154e0db303a9347e6ec3cc805e Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:40 -1000 Subject: [PATCH 466/970] sched_ext: Enable scx_ops_init_task() separately scx_ops_init_task() and the follow-up scx_ops_enable_task() in the fork path were gated by scx_enabled() test and thus __scx_ops_enabled had to be turned on before the first scx_ops_init_task() loop in scx_ops_enable(). However, if an external entity causes sched_class switch before the loop is complete, tasks which are not initialized could be switched to SCX. The following can be reproduced by running a program which keeps toggling a process between SCHED_OTHER and SCHED_EXT using sched_setscheduler(2). sched_ext: Invalid task state transition 0 -> 3 for fish[1623] WARNING: CPU: 1 PID: 1650 at kernel/sched/ext.c:3392 scx_ops_enable_task+0x1a1/0x200 ... Sched_ext: simple (enabling) RIP: 0010:scx_ops_enable_task+0x1a1/0x200 ... switching_to_scx+0x13/0xa0 __sched_setscheduler+0x850/0xa50 do_sched_setscheduler+0x104/0x1c0 __x64_sys_sched_setscheduler+0x18/0x30 do_syscall_64+0x7b/0x140 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fix it by gating scx_ops_init_task() separately using scx_ops_init_task_enabled. __scx_ops_enabled is now set after all tasks are finished with scx_ops_init_task(). Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/sched/ext.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index e83af19de59d..7729594882d9 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -853,6 +853,7 @@ DEFINE_STATIC_KEY_FALSE(__scx_ops_enabled); DEFINE_STATIC_PERCPU_RWSEM(scx_fork_rwsem); static atomic_t scx_ops_enable_state_var = ATOMIC_INIT(SCX_OPS_DISABLED); static atomic_t scx_ops_bypass_depth = ATOMIC_INIT(0); +static bool scx_ops_init_task_enabled; static bool scx_switching_all; DEFINE_STATIC_KEY_FALSE(__scx_switched_all); @@ -3565,7 +3566,7 @@ int scx_fork(struct task_struct *p) { percpu_rwsem_assert_held(&scx_fork_rwsem); - if (scx_enabled()) + if (scx_ops_init_task_enabled) return scx_ops_init_task(p, task_group(p), true); else return 0; @@ -3573,7 +3574,7 @@ int scx_fork(struct task_struct *p) void scx_post_fork(struct task_struct *p) { - if (scx_enabled()) { + if (scx_ops_init_task_enabled) { scx_set_task_state(p, SCX_TASK_READY); /* @@ -4453,6 +4454,8 @@ static void scx_ops_disable_workfn(struct kthread_work *work) cpus_read_lock(); scx_cgroup_lock(); + scx_ops_init_task_enabled = false; + spin_lock_irq(&scx_tasks_lock); scx_task_iter_init(&sti); /* @@ -5132,7 +5135,8 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) if (ret) goto err_disable_unlock_all; - static_branch_enable_cpuslocked(&__scx_ops_enabled); + WARN_ON_ONCE(scx_ops_init_task_enabled); + scx_ops_init_task_enabled = true; /* * Enable ops for every task. Fork is excluded by scx_fork_rwsem @@ -5175,9 +5179,11 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) spin_unlock_irq(&scx_tasks_lock); /* - * All tasks are prepped but the tasks are not enabled. Switch everyone. + * All tasks are READY. It's safe to turn on scx_enabled() and switch + * all eligible tasks. */ WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL)); + static_branch_enable_cpuslocked(&__scx_ops_enabled); /* * We're fully committed and can't fail. The task READY -> ENABLED -- GitLab From 568894edbe48f0878f787ed533dc9dbfd09c0fbe Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:40 -1000 Subject: [PATCH 467/970] sched_ext: Add scx_cgroup_enabled to gate cgroup operations and fix scx_tg_online() If the BPF scheduler does not implement ops.cgroup_init(), scx_tg_online() didn't set SCX_TG_INITED which meant that ops.cgroup_exit(), even if implemented, won't be called from scx_tg_offline(). This is because SCX_HAS_OP(cgroupt_init) is used to test both whether SCX cgroup operations are enabled and ops.cgroup_init() exists. Fix it by introducing a separate bool scx_cgroup_enabled to gate cgroup operations and use SCX_HAS_OP(cgroup_init) only to test whether ops.cgroup_init() exists. Make all cgroup operations consistently use scx_cgroup_enabled to test whether cgroup operations are enabled. scx_cgroup_enabled is added instead of using scx_enabled() to ease planned locking updates. Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/sched/ext.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index 7729594882d9..f9675ced75e8 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -3706,6 +3706,7 @@ bool scx_can_stop_tick(struct rq *rq) #ifdef CONFIG_EXT_GROUP_SCHED DEFINE_STATIC_PERCPU_RWSEM(scx_cgroup_rwsem); +static bool scx_cgroup_enabled; static bool cgroup_warned_missing_weight; static bool cgroup_warned_missing_idle; @@ -3725,8 +3726,7 @@ static void scx_cgroup_warn_missing_weight(struct task_group *tg) static void scx_cgroup_warn_missing_idle(struct task_group *tg) { - if (scx_ops_enable_state() == SCX_OPS_DISABLED || - cgroup_warned_missing_idle) + if (!scx_cgroup_enabled || cgroup_warned_missing_idle) return; if (!tg->idle) @@ -3747,15 +3747,18 @@ int scx_tg_online(struct task_group *tg) scx_cgroup_warn_missing_weight(tg); - if (SCX_HAS_OP(cgroup_init)) { - struct scx_cgroup_init_args args = { .weight = tg->scx_weight }; + if (scx_cgroup_enabled) { + if (SCX_HAS_OP(cgroup_init)) { + struct scx_cgroup_init_args args = + { .weight = tg->scx_weight }; - ret = SCX_CALL_OP_RET(SCX_KF_UNLOCKED, cgroup_init, - tg->css.cgroup, &args); - if (!ret) + ret = SCX_CALL_OP_RET(SCX_KF_UNLOCKED, cgroup_init, + tg->css.cgroup, &args); + if (ret) + ret = ops_sanitize_err("cgroup_init", ret); + } + if (ret == 0) tg->scx_flags |= SCX_TG_ONLINE | SCX_TG_INITED; - else - ret = ops_sanitize_err("cgroup_init", ret); } else { tg->scx_flags |= SCX_TG_ONLINE; } @@ -3786,7 +3789,7 @@ int scx_cgroup_can_attach(struct cgroup_taskset *tset) /* released in scx_finish/cancel_attach() */ percpu_down_read(&scx_cgroup_rwsem); - if (!scx_enabled()) + if (!scx_cgroup_enabled) return 0; cgroup_taskset_for_each(p, css, tset) { @@ -3829,7 +3832,7 @@ int scx_cgroup_can_attach(struct cgroup_taskset *tset) void scx_move_task(struct task_struct *p) { - if (!scx_enabled()) + if (!scx_cgroup_enabled) return; /* @@ -3865,7 +3868,7 @@ void scx_cgroup_cancel_attach(struct cgroup_taskset *tset) struct cgroup_subsys_state *css; struct task_struct *p; - if (!scx_enabled()) + if (!scx_cgroup_enabled) goto out_unlock; cgroup_taskset_for_each(p, css, tset) { @@ -3882,7 +3885,7 @@ void scx_group_set_weight(struct task_group *tg, unsigned long weight) { percpu_down_read(&scx_cgroup_rwsem); - if (tg->scx_weight != weight) { + if (scx_cgroup_enabled && tg->scx_weight != weight) { if (SCX_HAS_OP(cgroup_set_weight)) SCX_CALL_OP(SCX_KF_UNLOCKED, cgroup_set_weight, tg_cgrp(tg), weight); @@ -4054,6 +4057,9 @@ static void scx_cgroup_exit(void) percpu_rwsem_assert_held(&scx_cgroup_rwsem); + WARN_ON_ONCE(!scx_cgroup_enabled); + scx_cgroup_enabled = false; + /* * scx_tg_on/offline() are excluded through scx_cgroup_rwsem. If we walk * cgroups and exit all the inited ones, all online cgroups are exited. @@ -4129,6 +4135,9 @@ static int scx_cgroup_init(void) } rcu_read_unlock(); + WARN_ON_ONCE(scx_cgroup_enabled); + scx_cgroup_enabled = true; + return 0; } -- GitLab From 160216568cddc9d6e7f36133ba41d25459d90de4 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:40 -1000 Subject: [PATCH 468/970] sched_ext: Decouple locks in scx_ops_disable_workfn() The disable path uses three big locks - scx_fork_rwsem, scx_cgroup_rwsem and cpus_read_lock. Currently, the locks are grabbed together which is prone to locking order problems. With the preceding scx_cgroup_enabled change, we can decouple them: - As cgroup disabling no longer requires modifying a static_key which requires cpus_read_lock(), no need to grab cpus_read_lock() before grabbing scx_cgroup_rwsem. - cgroup can now be independently disabled before tasks are moved back to the fair class. Relocate scx_cgroup_exit() invocation before scx_fork_rwsem is grabbed, drop now unnecessary cpus_read_lock() and move static_key operations out of scx_fork_rwsem. This decouples all three locks in the disable path. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-and-tested-by: Aboorva Devarajan <aboorvad@linux.ibm.com> Link: http://lkml.kernel.org/r/8cd0ec0c4c7c1bc0119e61fbef0bee9d5e24022d.camel@linux.ibm.com --- kernel/sched/ext.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index f9675ced75e8..7d0ce7e6ea1f 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -4456,21 +4456,23 @@ static void scx_ops_disable_workfn(struct kthread_work *work) WRITE_ONCE(scx_switching_all, false); /* - * Avoid racing against fork and cgroup changes. See scx_ops_enable() - * for explanation on the locking order. + * Shut down cgroup support before tasks so that the cgroup attach path + * doesn't race against scx_ops_exit_task(). */ - percpu_down_write(&scx_fork_rwsem); - cpus_read_lock(); scx_cgroup_lock(); + scx_cgroup_exit(); + scx_cgroup_unlock(); - scx_ops_init_task_enabled = false; - - spin_lock_irq(&scx_tasks_lock); - scx_task_iter_init(&sti); /* * The BPF scheduler is going away. All tasks including %TASK_DEAD ones * must be switched out and exited synchronously. */ + percpu_down_write(&scx_fork_rwsem); + + scx_ops_init_task_enabled = false; + + spin_lock_irq(&scx_tasks_lock); + scx_task_iter_init(&sti); while ((p = scx_task_iter_next_locked(&sti))) { const struct sched_class *old_class = p->sched_class; struct sched_enq_and_set_ctx ctx; @@ -4488,23 +4490,18 @@ static void scx_ops_disable_workfn(struct kthread_work *work) } scx_task_iter_exit(&sti); spin_unlock_irq(&scx_tasks_lock); + percpu_up_write(&scx_fork_rwsem); /* no task is on scx, turn off all the switches and flush in-progress calls */ - static_branch_disable_cpuslocked(&__scx_ops_enabled); + static_branch_disable(&__scx_ops_enabled); for (i = SCX_OPI_BEGIN; i < SCX_OPI_END; i++) - static_branch_disable_cpuslocked(&scx_has_op[i]); - static_branch_disable_cpuslocked(&scx_ops_enq_last); - static_branch_disable_cpuslocked(&scx_ops_enq_exiting); - static_branch_disable_cpuslocked(&scx_ops_cpu_preempt); - static_branch_disable_cpuslocked(&scx_builtin_idle_enabled); + static_branch_disable(&scx_has_op[i]); + static_branch_disable(&scx_ops_enq_last); + static_branch_disable(&scx_ops_enq_exiting); + static_branch_disable(&scx_ops_cpu_preempt); + static_branch_disable(&scx_builtin_idle_enabled); synchronize_rcu(); - scx_cgroup_exit(); - - scx_cgroup_unlock(); - cpus_read_unlock(); - percpu_up_write(&scx_fork_rwsem); - if (ei->kind >= SCX_EXIT_ERROR) { pr_err("sched_ext: BPF scheduler \"%s\" disabled (%s)\n", scx_ops.name, ei->reason); -- GitLab From efe231d9debf6db812bebb262407c95b21cdb8a2 Mon Sep 17 00:00:00 2001 From: Tejun Heo <tj@kernel.org> Date: Fri, 27 Sep 2024 10:02:40 -1000 Subject: [PATCH 469/970] sched_ext: Decouple locks in scx_ops_enable() The enable path uses three big locks - scx_fork_rwsem, scx_cgroup_rwsem and cpus_read_lock. Currently, the locks are grabbed together which is prone to locking order problems. For example, currently, there is a possible deadlock involving scx_fork_rwsem and cpus_read_lock. cpus_read_lock has to nest inside scx_fork_rwsem due to locking order existing in other subsystems. However, there exists a dependency in the other direction during hotplug if hotplug needs to fork a new task, which happens in some cases. This leads to the following deadlock: scx_ops_enable() hotplug percpu_down_write(&cpu_hotplug_lock) percpu_down_write(&scx_fork_rwsem) block on cpu_hotplug_lock kthread_create() waits for kthreadd kthreadd blocks on scx_fork_rwsem Note that this doesn't trigger lockdep because the hotplug side dependency bounces through kthreadd. With the preceding scx_cgroup_enabled change, this can be solved by decoupling cpus_read_lock, which is needed for static_key manipulations, from the other two locks. - Move the first block of static_key manipulations outside of scx_fork_rwsem and scx_cgroup_rwsem. This is now safe with the preceding scx_cgroup_enabled change. - Drop scx_cgroup_rwsem and scx_fork_rwsem between the two task iteration blocks so that __scx_ops_enabled static_key enabling is outside the two rwsems. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-and-tested-by: Aboorva Devarajan <aboorvad@linux.ibm.com> Link: http://lkml.kernel.org/r/8cd0ec0c4c7c1bc0119e61fbef0bee9d5e24022d.camel@linux.ibm.com --- kernel/sched/ext.c | 67 +++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index 7d0ce7e6ea1f..0c398ecdb938 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -5049,7 +5049,8 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) ret = SCX_CALL_OP_RET(SCX_KF_UNLOCKED, init); if (ret) { ret = ops_sanitize_err("init", ret); - goto err_disable_unlock_cpus; + cpus_read_unlock(); + goto err_disable; } } @@ -5092,54 +5093,30 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) */ scx_ops_bypass(true); - /* - * Lock out forks, cgroup on/offlining and moves before opening the - * floodgate so that they don't wander into the operations prematurely. - * - * We don't need to keep the CPUs stable but static_branch_*() requires - * cpus_read_lock() and scx_cgroup_rwsem must nest inside - * cpu_hotplug_lock because of the following dependency chain: - * - * cpu_hotplug_lock --> cgroup_threadgroup_rwsem --> scx_cgroup_rwsem - * - * So, we need to do cpus_read_lock() before scx_cgroup_lock() and use - * static_branch_*_cpuslocked(). - * - * Note that cpu_hotplug_lock must nest inside scx_fork_rwsem due to the - * following dependency chain: - * - * scx_fork_rwsem --> pernet_ops_rwsem --> cpu_hotplug_lock - */ - percpu_down_write(&scx_fork_rwsem); - cpus_read_lock(); - scx_cgroup_lock(); - for (i = SCX_OPI_NORMAL_BEGIN; i < SCX_OPI_NORMAL_END; i++) if (((void (**)(void))ops)[i]) - static_branch_enable_cpuslocked(&scx_has_op[i]); + static_branch_enable(&scx_has_op[i]); if (ops->flags & SCX_OPS_ENQ_LAST) - static_branch_enable_cpuslocked(&scx_ops_enq_last); + static_branch_enable(&scx_ops_enq_last); if (ops->flags & SCX_OPS_ENQ_EXITING) - static_branch_enable_cpuslocked(&scx_ops_enq_exiting); + static_branch_enable(&scx_ops_enq_exiting); if (scx_ops.cpu_acquire || scx_ops.cpu_release) - static_branch_enable_cpuslocked(&scx_ops_cpu_preempt); + static_branch_enable(&scx_ops_cpu_preempt); if (!ops->update_idle || (ops->flags & SCX_OPS_KEEP_BUILTIN_IDLE)) { reset_idle_masks(); - static_branch_enable_cpuslocked(&scx_builtin_idle_enabled); + static_branch_enable(&scx_builtin_idle_enabled); } else { - static_branch_disable_cpuslocked(&scx_builtin_idle_enabled); + static_branch_disable(&scx_builtin_idle_enabled); } /* - * All cgroups should be initialized before letting in tasks. cgroup - * on/offlining and task migrations are already locked out. + * Lock out forks, cgroup on/offlining and moves before opening the + * floodgate so that they don't wander into the operations prematurely. */ - ret = scx_cgroup_init(); - if (ret) - goto err_disable_unlock_all; + percpu_down_write(&scx_fork_rwsem); WARN_ON_ONCE(scx_ops_init_task_enabled); scx_ops_init_task_enabled = true; @@ -5150,7 +5127,18 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) * leaving as sched_ext_free() can handle both prepped and enabled * tasks. Prep all tasks first and then enable them with preemption * disabled. + * + * All cgroups should be initialized before scx_ops_init_task() so that + * the BPF scheduler can reliably track each task's cgroup membership + * from scx_ops_init_task(). Lock out cgroup on/offlining and task + * migrations while tasks are being initialized so that + * scx_cgroup_can_attach() never sees uninitialized tasks. */ + scx_cgroup_lock(); + ret = scx_cgroup_init(); + if (ret) + goto err_disable_unlock_all; + spin_lock_irq(&scx_tasks_lock); scx_task_iter_init(&sti); while ((p = scx_task_iter_next_locked(&sti))) { @@ -5183,19 +5171,22 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) } scx_task_iter_exit(&sti); spin_unlock_irq(&scx_tasks_lock); + scx_cgroup_unlock(); + percpu_up_write(&scx_fork_rwsem); /* * All tasks are READY. It's safe to turn on scx_enabled() and switch * all eligible tasks. */ WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL)); - static_branch_enable_cpuslocked(&__scx_ops_enabled); + static_branch_enable(&__scx_ops_enabled); /* * We're fully committed and can't fail. The task READY -> ENABLED * transitions here are synchronized against sched_ext_free() through * scx_tasks_lock. */ + percpu_down_write(&scx_fork_rwsem); spin_lock_irq(&scx_tasks_lock); scx_task_iter_init(&sti); while ((p = scx_task_iter_next_locked(&sti))) { @@ -5213,10 +5204,8 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) } scx_task_iter_exit(&sti); spin_unlock_irq(&scx_tasks_lock); - - scx_cgroup_unlock(); - cpus_read_unlock(); percpu_up_write(&scx_fork_rwsem); + scx_ops_bypass(false); /* @@ -5259,8 +5248,6 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link) scx_cgroup_unlock(); percpu_up_write(&scx_fork_rwsem); scx_ops_bypass(false); -err_disable_unlock_cpus: - cpus_read_unlock(); err_disable: mutex_unlock(&scx_ops_enable_mutex); /* must be fully disabled before returning */ -- GitLab From 95b873693a0841e02b812e693296a884362fdd51 Mon Sep 17 00:00:00 2001 From: Zhang Qiao <zhangqiao22@huawei.com> Date: Thu, 26 Sep 2024 18:39:49 +0800 Subject: [PATCH 470/970] sched_ext: Remove redundant p->nr_cpus_allowed checker select_rq_task() already checked that 'p->nr_cpus_allowed > 1', 'p->nr_cpus_allowed == 1' checker in scx_select_cpu_dfl() is redundant. Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com> Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/sched/ext.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index 0c398ecdb938..3cd7c50a51c5 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -3074,22 +3074,13 @@ static s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, * there is an idle core elsewhere on the system. */ cpu = smp_processor_id(); - if ((wake_flags & SCX_WAKE_SYNC) && p->nr_cpus_allowed > 1 && + if ((wake_flags & SCX_WAKE_SYNC) && !cpumask_empty(idle_masks.cpu) && !(current->flags & PF_EXITING) && cpu_rq(cpu)->scx.local_dsq.nr == 0) { if (cpumask_test_cpu(cpu, p->cpus_ptr)) goto cpu_found; } - if (p->nr_cpus_allowed == 1) { - if (test_and_clear_cpu_idle(prev_cpu)) { - cpu = prev_cpu; - goto cpu_found; - } else { - return prev_cpu; - } - } - /* * If CPU has SMT, any wholly idle CPU is likely a better pick than * partially idle @prev_cpu. -- GitLab From dd3a7ee91e0ce0b03d22e974a79e8247cc99959b Mon Sep 17 00:00:00 2001 From: Nathan Chancellor <nathan@kernel.org> Date: Sat, 28 Sep 2024 11:13:13 -0700 Subject: [PATCH 471/970] hardening: Adjust dependencies in selection of MODVERSIONS MODVERSIONS recently grew a dependency on !COMPILE_TEST so that Rust could be more easily tested. However, this introduces a Kconfig warning when building allmodconfig with a clang version that supports RANDSTRUCT natively because RANDSTRUCT_FULL and RANDSTRUCT_PERFORMANCE select MODVERSIONS when MODULES is enabled, bypassing the !COMPILE_TEST dependency: WARNING: unmet direct dependencies detected for MODVERSIONS Depends on [n]: MODULES [=y] && !COMPILE_TEST [=y] Selected by [y]: - RANDSTRUCT_FULL [=y] && (CC_HAS_RANDSTRUCT [=y] || GCC_PLUGINS [=n]) && MODULES [=y] Add the !COMPILE_TEST dependency to the selections to clear up the warning. Fixes: 1f9c4a996756 ("Kbuild: make MODVERSIONS support depend on not being a compile test build") Signed-off-by: Nathan Chancellor <nathan@kernel.org> Link: https://lore.kernel.org/r/20240928-fix-randstruct-modversions-kconfig-warning-v1-1-27d3edc8571e@kernel.org Signed-off-by: Kees Cook <kees@kernel.org> --- security/Kconfig.hardening | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index 2cff851ebfd7..c9d5ca3d8d08 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -340,7 +340,7 @@ choice config RANDSTRUCT_FULL bool "Fully randomize structure layout" depends on CC_HAS_RANDSTRUCT || GCC_PLUGINS - select MODVERSIONS if MODULES + select MODVERSIONS if MODULES && !COMPILE_TEST help Fully randomize the member layout of sensitive structures as much as possible, which may have both a @@ -356,7 +356,7 @@ choice config RANDSTRUCT_PERFORMANCE bool "Limit randomization of structure layout to cache-lines" depends on GCC_PLUGINS - select MODVERSIONS if MODULES + select MODVERSIONS if MODULES && !COMPILE_TEST help Randomization of sensitive kernel structures will make a best effort at restricting randomization to cacheline-sized -- GitLab From 045244dd5d75c61ae37b7b96fe0a95805bd1842d Mon Sep 17 00:00:00 2001 From: Nathan Chancellor <nathan@kernel.org> Date: Sat, 28 Sep 2024 11:26:09 -0700 Subject: [PATCH 472/970] MAINTAINERS: Add security/Kconfig.hardening to hardening section When running get_maintainer.pl on security/Kconfig.hardening, only the security subsystem folks show up, even though they have never taken patches to this file: $ scripts/get_maintainer.pl security/Kconfig.hardening Paul Moore <...> (supporter:SECURITY SUBSYSTEM) James Morris <...> (supporter:SECURITY SUBSYSTEM) "Serge E. Hallyn" <...> (supporter:SECURITY SUBSYSTEM) linux-security-module@vger.kernel.org (open list:SECURITY SUBSYSTEM) linux-kernel@vger.kernel.org (open list) $ git log --format=%cn --no-merges security/Kconfig.hardening | sort | uniq -c 3 Andrew Morton 1 Greg Kroah-Hartman 18 Kees Cook 2 Linus Torvald Add it to the hardening section so that the KSPP folks are also shown, which matches reality over who should comment on and take said patches if necessary. Signed-off-by: Nathan Chancellor <nathan@kernel.org> Link: https://lore.kernel.org/r/20240928-maintainers-security-kconfig-hardening-v1-1-c8c64071cc02@kernel.org Signed-off-by: Kees Cook <kees@kernel.org> --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3a29f123e1be..fecc7c696737 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12152,6 +12152,7 @@ F: include/linux/randomize_kstack.h F: kernel/configs/hardening.config F: lib/usercopy_kunit.c F: mm/usercopy.c +F: security/Kconfig.hardening K: \b(add|choose)_random_kstack_offset\b K: \b__check_(object_size|heap_object)\b K: \b__counted_by\b -- GitLab From a9023656bcd28aaf184974a121d3c2f2ec1ded46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> Date: Fri, 27 Sep 2024 20:20:39 +0200 Subject: [PATCH 473/970] cifs: Check for UTF-16 null codepoint in SFU symlink target location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check that read buffer of SFU symlink target location does not contain UTF-16 null codepoint (via UniStrnlen() call) because Linux cannot process symlink with null byte, it truncates everything in buffer after null byte. Fixes: cf2ce67345d6 ("cifs: Add support for reading SFU symlink location") Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/inode.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 647f9bedd9fc..eff3f57235ee 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -629,10 +629,16 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, &symlink_len_utf16, &symlink_buf_utf16, &buf_type); + /* + * Check that read buffer has valid length and does not + * contain UTF-16 null codepoint (via UniStrnlen() call) + * because Linux cannot process symlink with null byte. + */ if ((rc == 0) && (symlink_len_utf16 > 0) && (symlink_len_utf16 < fattr->cf_eof-8 + 1) && - (symlink_len_utf16 % 2 == 0)) { + (symlink_len_utf16 % 2 == 0) && + (UniStrnlen((wchar_t *)symlink_buf_utf16, symlink_len_utf16/2) == symlink_len_utf16/2)) { fattr->cf_symlink_target = cifs_strndup_from_utf16(symlink_buf_utf16, symlink_len_utf16, -- GitLab From dd0d7edb866db2b9d23dc50553cbdd3f6a159fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> Date: Sat, 28 Sep 2024 23:59:41 +0200 Subject: [PATCH 474/970] smb: Update comments about some reparse point tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NFS-style reparse points are recognized only by the Windows NFS server 2012 and new. Windows 8 does not contain Windows NFS server, so these reparse points are not used on Windows 8. Reparse points with IO_REPARSE_TAG_AF_UNIX tag were primarily introduced for native Win32 AF_UNIX sockets and later were re-used by also by WSL: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ https://devblogs.microsoft.com/commandline/windowswsl-interop-with-af_unix/ Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/common/smbfsctl.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/smb/common/smbfsctl.h b/fs/smb/common/smbfsctl.h index a94d658b88e8..4b379e84c46b 100644 --- a/fs/smb/common/smbfsctl.h +++ b/fs/smb/common/smbfsctl.h @@ -140,20 +140,21 @@ /* Used by the DFS filter See MS-DFSC */ #define IO_REPARSE_TAG_DFSR 0x80000012 #define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B -/* See section MS-FSCC 2.1.2.4 */ +/* Native SMB symlinks since Windows Vista, see MS-FSCC 2.1.2.4 */ #define IO_REPARSE_TAG_SYMLINK 0xA000000C #define IO_REPARSE_TAG_DEDUP 0x80000013 #define IO_REPARSE_APPXSTREAM 0xC0000014 -/* NFS symlinks, Win 8/SMB3 and later */ +/* NFS special files used by Windows NFS server since Windows Server 2012, see MS-FSCC 2.1.2.6 */ #define IO_REPARSE_TAG_NFS 0x80000014 /* * AzureFileSync - see * https://docs.microsoft.com/en-us/azure/storage/files/storage-sync-cloud-tiering */ #define IO_REPARSE_TAG_AZ_FILE_SYNC 0x8000001e +/* Native Win32 AF_UNIX sockets since Windows 10 April 2018 Update, used also by WSL */ +#define IO_REPARSE_TAG_AF_UNIX 0x80000023 /* WSL reparse tags */ #define IO_REPARSE_TAG_LX_SYMLINK 0xA000001D -#define IO_REPARSE_TAG_AF_UNIX 0x80000023 #define IO_REPARSE_TAG_LX_FIFO 0x80000024 #define IO_REPARSE_TAG_LX_CHR 0x80000025 #define IO_REPARSE_TAG_LX_BLK 0x80000026 -- GitLab From 34820304cc2cd1804ee1f8f3504ec77813d29c8e Mon Sep 17 00:00:00 2001 From: Oleg Nesterov <oleg@redhat.com> Date: Sun, 29 Sep 2024 18:20:47 +0200 Subject: [PATCH 475/970] uprobes: fix kernel info leak via "[uprobes]" vma xol_add_vma() maps the uninitialized page allocated by __create_xol_area() into userspace. On some architectures (x86) this memory is readable even without VM_READ, VM_EXEC results in the same pgprot_t as VM_EXEC|VM_READ, although this doesn't really matter, debugger can read this memory anyway. Link: https://lore.kernel.org/all/20240929162047.GA12611@redhat.com/ Reported-by: Will Deacon <will@kernel.org> Fixes: d4b3b6384f98 ("uprobes/core: Allocate XOL slots for uprobes use") Cc: stable@vger.kernel.org Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> --- kernel/events/uprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 2ec796e2f055..4b52cb2ae6d6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1545,7 +1545,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) if (!area->bitmap) goto free_area; - area->page = alloc_page(GFP_HIGHUSER); + area->page = alloc_page(GFP_HIGHUSER | __GFP_ZERO); if (!area->page) goto free_bitmap; -- GitLab From 678379e1d4f7443b170939525d3312cfc37bf86b Mon Sep 17 00:00:00 2001 From: Al Viro <viro@zeniv.linux.org.uk> Date: Fri, 16 Aug 2024 15:17:00 -0400 Subject: [PATCH 476/970] close_range(): fix the logics in descriptor table trimming Cloning a descriptor table picks the size that would cover all currently opened files. That's fine for clone() and unshare(), but for close_range() there's an additional twist - we clone before we close, and it would be a shame to have close_range(3, ~0U, CLOSE_RANGE_UNSHARE) leave us with a huge descriptor table when we are not going to keep anything past stderr, just because some large file descriptor used to be open before our call has taken it out. Unfortunately, it had been dealt with in an inherently racy way - sane_fdtable_size() gets a "don't copy anything past that" argument (passed via unshare_fd() and dup_fd()), close_range() decides how much should be trimmed and passes that to unshare_fd(). The problem is, a range that used to extend to the end of descriptor table back when close_range() had looked at it might very well have stuff grown after it by the time dup_fd() has allocated a new files_struct and started to figure out the capacity of fdtable to be attached to that. That leads to interesting pathological cases; at the very least it's a QoI issue, since unshare(CLONE_FILES) is atomic in a sense that it takes a snapshot of descriptor table one might have observed at some point. Since CLOSE_RANGE_UNSHARE close_range() is supposed to be a combination of unshare(CLONE_FILES) with plain close_range(), ending up with a weird state that would never occur with unshare(2) is confusing, to put it mildly. It's not hard to get rid of - all it takes is passing both ends of the range down to sane_fdtable_size(). There we are under ->files_lock, so the race is trivially avoided. So we do the following: * switch close_files() from calling unshare_fd() to calling dup_fd(). * undo the calling convention change done to unshare_fd() in 60997c3d45d9 "close_range: add CLOSE_RANGE_UNSHARE" * introduce struct fd_range, pass a pointer to that to dup_fd() and sane_fdtable_size() instead of "trim everything past that point" they are currently getting. NULL means "we are not going to be punching any holes"; NR_OPEN_MAX is gone. * make sane_fdtable_size() use find_last_bit() instead of open-coding it; it's easier to follow that way. * while we are at it, have dup_fd() report errors by returning ERR_PTR(), no need to use a separate int *errorp argument. Fixes: 60997c3d45d9 "close_range: add CLOSE_RANGE_UNSHARE" Cc: stable@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- fs/file.c | 95 +++++++++++++++-------------------------- include/linux/fdtable.h | 8 ++-- kernel/fork.c | 32 ++++++-------- 3 files changed, 52 insertions(+), 83 deletions(-) diff --git a/fs/file.c b/fs/file.c index 5125607d040a..eb093e736972 100644 --- a/fs/file.c +++ b/fs/file.c @@ -272,59 +272,45 @@ static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt) return test_bit(fd, fdt->open_fds); } -static unsigned int count_open_files(struct fdtable *fdt) -{ - unsigned int size = fdt->max_fds; - unsigned int i; - - /* Find the last open fd */ - for (i = size / BITS_PER_LONG; i > 0; ) { - if (fdt->open_fds[--i]) - break; - } - i = (i + 1) * BITS_PER_LONG; - return i; -} - /* * Note that a sane fdtable size always has to be a multiple of * BITS_PER_LONG, since we have bitmaps that are sized by this. * - * 'max_fds' will normally already be properly aligned, but it - * turns out that in the close_range() -> __close_range() -> - * unshare_fd() -> dup_fd() -> sane_fdtable_size() we can end - * up having a 'max_fds' value that isn't already aligned. - * - * Rather than make close_range() have to worry about this, - * just make that BITS_PER_LONG alignment be part of a sane - * fdtable size. Becuase that's really what it is. + * punch_hole is optional - when close_range() is asked to unshare + * and close, we don't need to copy descriptors in that range, so + * a smaller cloned descriptor table might suffice if the last + * currently opened descriptor falls into that range. */ -static unsigned int sane_fdtable_size(struct fdtable *fdt, unsigned int max_fds) +static unsigned int sane_fdtable_size(struct fdtable *fdt, struct fd_range *punch_hole) { - unsigned int count; - - count = count_open_files(fdt); - if (max_fds < NR_OPEN_DEFAULT) - max_fds = NR_OPEN_DEFAULT; - return ALIGN(min(count, max_fds), BITS_PER_LONG); + unsigned int last = find_last_bit(fdt->open_fds, fdt->max_fds); + + if (last == fdt->max_fds) + return NR_OPEN_DEFAULT; + if (punch_hole && punch_hole->to >= last && punch_hole->from <= last) { + last = find_last_bit(fdt->open_fds, punch_hole->from); + if (last == punch_hole->from) + return NR_OPEN_DEFAULT; + } + return ALIGN(last + 1, BITS_PER_LONG); } /* - * Allocate a new files structure and copy contents from the - * passed in files structure. - * errorp will be valid only when the returned files_struct is NULL. + * Allocate a new descriptor table and copy contents from the passed in + * instance. Returns a pointer to cloned table on success, ERR_PTR() + * on failure. For 'punch_hole' see sane_fdtable_size(). */ -struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int *errorp) +struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_hole) { struct files_struct *newf; struct file **old_fds, **new_fds; unsigned int open_files, i; struct fdtable *old_fdt, *new_fdt; + int error; - *errorp = -ENOMEM; newf = kmem_cache_alloc(files_cachep, GFP_KERNEL); if (!newf) - goto out; + return ERR_PTR(-ENOMEM); atomic_set(&newf->count, 1); @@ -341,7 +327,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int spin_lock(&oldf->file_lock); old_fdt = files_fdtable(oldf); - open_files = sane_fdtable_size(old_fdt, max_fds); + open_files = sane_fdtable_size(old_fdt, punch_hole); /* * Check whether we need to allocate a larger fd array and fd set. @@ -354,14 +340,14 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int new_fdt = alloc_fdtable(open_files - 1); if (!new_fdt) { - *errorp = -ENOMEM; + error = -ENOMEM; goto out_release; } /* beyond sysctl_nr_open; nothing to do */ if (unlikely(new_fdt->max_fds < open_files)) { __free_fdtable(new_fdt); - *errorp = -EMFILE; + error = -EMFILE; goto out_release; } @@ -372,7 +358,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int */ spin_lock(&oldf->file_lock); old_fdt = files_fdtable(oldf); - open_files = sane_fdtable_size(old_fdt, max_fds); + open_files = sane_fdtable_size(old_fdt, punch_hole); } copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG); @@ -406,8 +392,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int out_release: kmem_cache_free(files_cachep, newf); -out: - return NULL; + return ERR_PTR(error); } static struct fdtable *close_files(struct files_struct * files) @@ -748,37 +733,25 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags) if (fd > max_fd) return -EINVAL; - if (flags & CLOSE_RANGE_UNSHARE) { - int ret; - unsigned int max_unshare_fds = NR_OPEN_MAX; + if ((flags & CLOSE_RANGE_UNSHARE) && atomic_read(&cur_fds->count) > 1) { + struct fd_range range = {fd, max_fd}, *punch_hole = ⦥ /* * If the caller requested all fds to be made cloexec we always * copy all of the file descriptors since they still want to * use them. */ - if (!(flags & CLOSE_RANGE_CLOEXEC)) { - /* - * If the requested range is greater than the current - * maximum, we're closing everything so only copy all - * file descriptors beneath the lowest file descriptor. - */ - rcu_read_lock(); - if (max_fd >= last_fd(files_fdtable(cur_fds))) - max_unshare_fds = fd; - rcu_read_unlock(); - } - - ret = unshare_fd(CLONE_FILES, max_unshare_fds, &fds); - if (ret) - return ret; + if (flags & CLOSE_RANGE_CLOEXEC) + punch_hole = NULL; + fds = dup_fd(cur_fds, punch_hole); + if (IS_ERR(fds)) + return PTR_ERR(fds); /* * We used to share our file descriptor table, and have now * created a private one, make sure we're using it below. */ - if (fds) - swap(cur_fds, fds); + swap(cur_fds, fds); } if (flags & CLOSE_RANGE_CLOEXEC) diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 2944d4aa413b..b1c5722f2b3c 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -22,7 +22,6 @@ * as this is the granularity returned by copy_fdset(). */ #define NR_OPEN_DEFAULT BITS_PER_LONG -#define NR_OPEN_MAX ~0U struct fdtable { unsigned int max_fds; @@ -106,7 +105,10 @@ struct task_struct; void put_files_struct(struct files_struct *fs); int unshare_files(void); -struct files_struct *dup_fd(struct files_struct *, unsigned, int *) __latent_entropy; +struct fd_range { + unsigned int from, to; +}; +struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy; void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), @@ -115,8 +117,6 @@ int iterate_fd(struct files_struct *, unsigned, extern int close_fd(unsigned int fd); extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags); extern struct file *file_close_fd(unsigned int fd); -extern int unshare_fd(unsigned long unshare_flags, unsigned int max_fds, - struct files_struct **new_fdp); extern struct kmem_cache *files_cachep; diff --git a/kernel/fork.c b/kernel/fork.c index 60c0b4868fd4..89ceb4a68af2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1756,33 +1756,30 @@ static int copy_files(unsigned long clone_flags, struct task_struct *tsk, int no_files) { struct files_struct *oldf, *newf; - int error = 0; /* * A background process may not have any files ... */ oldf = current->files; if (!oldf) - goto out; + return 0; if (no_files) { tsk->files = NULL; - goto out; + return 0; } if (clone_flags & CLONE_FILES) { atomic_inc(&oldf->count); - goto out; + return 0; } - newf = dup_fd(oldf, NR_OPEN_MAX, &error); - if (!newf) - goto out; + newf = dup_fd(oldf, NULL); + if (IS_ERR(newf)) + return PTR_ERR(newf); tsk->files = newf; - error = 0; -out: - return error; + return 0; } static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) @@ -3238,17 +3235,16 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) /* * Unshare file descriptor table if it is being shared */ -int unshare_fd(unsigned long unshare_flags, unsigned int max_fds, - struct files_struct **new_fdp) +static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp) { struct files_struct *fd = current->files; - int error = 0; if ((unshare_flags & CLONE_FILES) && (fd && atomic_read(&fd->count) > 1)) { - *new_fdp = dup_fd(fd, max_fds, &error); - if (!*new_fdp) - return error; + fd = dup_fd(fd, NULL); + if (IS_ERR(fd)) + return PTR_ERR(fd); + *new_fdp = fd; } return 0; @@ -3306,7 +3302,7 @@ int ksys_unshare(unsigned long unshare_flags) err = unshare_fs(unshare_flags, &new_fs); if (err) goto bad_unshare_out; - err = unshare_fd(unshare_flags, NR_OPEN_MAX, &new_fd); + err = unshare_fd(unshare_flags, &new_fd); if (err) goto bad_unshare_cleanup_fs; err = unshare_userns(unshare_flags, &new_cred); @@ -3398,7 +3394,7 @@ int unshare_files(void) struct files_struct *old, *copy = NULL; int error; - error = unshare_fd(CLONE_FILES, NR_OPEN_MAX, ©); + error = unshare_fd(CLONE_FILES, ©); if (error || !copy) return error; -- GitLab From 2007d28ec0095c6db0a24fd8bb8fe280c65446cd Mon Sep 17 00:00:00 2001 From: Guenter Roeck <linux@roeck-us.net> Date: Sun, 29 Sep 2024 17:39:02 -0700 Subject: [PATCH 477/970] bcachefs: rename version -> bversion for big endian builds Builds on big endian systems fail as follows. fs/bcachefs/bkey.h: In function 'bch2_bkey_format_add_key': fs/bcachefs/bkey.h:557:41: error: 'const struct bkey' has no member named 'bversion' The original commit only renamed the variable for little endian builds. Rename it for big endian builds as well to fix the problem. Fixes: cf49f8a8c277 ("bcachefs: rename version -> bversion") Cc: Kent Overstreet <kent.overstreet@linux.dev> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/bcachefs_format.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h index 203ee627cab5..84832c2d4df9 100644 --- a/fs/bcachefs/bcachefs_format.h +++ b/fs/bcachefs/bcachefs_format.h @@ -223,7 +223,7 @@ struct bkey { #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ struct bpos p; __u32 size; /* extent size, in sectors */ - struct bversion version; + struct bversion bversion; __u8 pad[1]; #endif -- GitLab From 2a94a0898b14f2d5dee10bf36d00ab5e766af94b Mon Sep 17 00:00:00 2001 From: Abdul Rahim <abdul.rahim@myyahoo.com> Date: Mon, 23 Sep 2024 04:28:18 +0530 Subject: [PATCH 478/970] selftest: alsa: check if user has alsa installed Currently, if alsa development package is not installed on the user's system then the make command would print a `pagefull` of errors. In particular one error message is repeated 3 times. This error is returned by `pkg-config` and since it is not being handeled appropriately, repeated calls to `pkg-config` prints the same message again. This patch adds check for alsa package installation. If alsa is not installed, a short and consize error is returned. Also, it does not affect the compilation of other tests. Signed-off-by: Abdul Rahim <abdul.rahim@myyahoo.com> Reviewed-by: Shuah Khan <skhan@linuxfoundation.org> Link: https://patch.msgid.link/20240922225824.18918-1-abdul.rahim@myyahoo.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- tools/testing/selftests/alsa/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/testing/selftests/alsa/Makefile b/tools/testing/selftests/alsa/Makefile index 25be68025290..944279160fed 100644 --- a/tools/testing/selftests/alsa/Makefile +++ b/tools/testing/selftests/alsa/Makefile @@ -1,5 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 # +ifneq ($(shell pkg-config --exists alsa && echo 0 || echo 1),0) +$(error Package alsa not found, please install alsa development package or \ + add directory containing `alsa.pc` in PKG_CONFIG_PATH) +endif CFLAGS += $(shell pkg-config --cflags alsa) $(KHDR_INCLUDES) LDLIBS += $(shell pkg-config --libs alsa) -- GitLab From 73c6e9e16f5bd8709c8cf3861d4b97f6ee23e2b7 Mon Sep 17 00:00:00 2001 From: Yu Jiaoliang <yujiaoliang@vivo.com> Date: Tue, 24 Sep 2024 12:17:45 +0800 Subject: [PATCH 479/970] ALSA: Fix typos in comments across various files This patch fixes typos in comments within the ALSA subsystem. These changes improve code readability without affecting functionality. Signed-off-by: Yu Jiaoliang <yujiaoliang@vivo.com> Link: https://patch.msgid.link/20240924041749.3125507-1-yujiaoliang@vivo.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/core/compress_offload.c | 2 +- sound/core/oss/rate.c | 2 +- sound/core/pcm_native.c | 2 +- sound/core/sound.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index b8c0d6edbdd1..bdf1d78de833 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -288,7 +288,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, stream = &data->stream; guard(mutex)(&stream->device->lock); - /* write is allowed when stream is running or has been steup */ + /* write is allowed when stream is running or has been setup */ switch (stream->runtime->state) { case SNDRV_PCM_STATE_SETUP: case SNDRV_PCM_STATE_PREPARED: diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 98269119347f..b56eeda5e30e 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -294,7 +294,7 @@ static int rate_action(struct snd_pcm_plugin *plugin, default: break; } - return 0; /* silenty ignore other actions */ + return 0; /* silently ignore other actions */ } int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 5e1e6006707b..be50d8e83a08 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3115,7 +3115,7 @@ struct snd_pcm_sync_ptr32 { } c; } __packed; -/* recalcuate the boundary within 32bit */ +/* recalculate the boundary within 32bit */ static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime) { snd_pcm_uframes_t boundary; diff --git a/sound/core/sound.c b/sound/core/sound.c index b9db9aa0bfcb..6531a67f13b3 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -133,7 +133,7 @@ static struct snd_minor *autoload_device(unsigned int minor) /* /dev/aloadSEQ */ snd_request_other(minor); } - mutex_lock(&sound_mutex); /* reacuire lock */ + mutex_lock(&sound_mutex); /* reacquire lock */ return snd_minors[minor]; } #else /* !CONFIG_MODULES */ -- GitLab From 73385f3e0d8088b715ae8f3f66d533c482a376ab Mon Sep 17 00:00:00 2001 From: Lianqin Hu <hulianqin@vivo.com> Date: Wed, 25 Sep 2024 03:16:29 +0000 Subject: [PATCH 480/970] ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET Audio control requests that sets sampling frequency sometimes fail on this card. Adding delay between control messages eliminates that problem. Signed-off-by: Lianqin Hu <hulianqin@vivo.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/TYUPR06MB62177E629E9DEF2401333BF7D2692@TYUPR06MB6217.apcprd06.prod.outlook.com --- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index f62631b54e10..c7a9c50a65bb 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2279,6 +2279,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x2d95, 0x8011, /* VIVO USB-C HEADSET */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */ QUIRK_FLAG_CTL_MSG_DELAY_1M), DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ -- GitLab From dee476950cbd83125655a3f49e00d63b79f6114e Mon Sep 17 00:00:00 2001 From: Ai Chao <aichao@kylinos.cn> Date: Thu, 26 Sep 2024 14:02:52 +0800 Subject: [PATCH 481/970] ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9 The headset mic requires a fixup to be properly detected/used. Signed-off-by: Ai Chao <aichao@kylinos.cn> Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20240926060252.25630-1-aichao@kylinos.cn Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f787ff4182d4..7681200e84e8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10880,6 +10880,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1854, 0x048a, "LG gram 17 (17ZD90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x19e5, 0x3212, "Huawei KLV-WX9 ", ALC256_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI), SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101), -- GitLab From 368e4663c557de4a33f321b44e7eeec0a21b2e4e Mon Sep 17 00:00:00 2001 From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Date: Thu, 26 Sep 2024 20:17:36 +0200 Subject: [PATCH 482/970] ALSA: mixer_oss: Remove some incorrect kfree_const() usages "assigned" and "assigned->name" are allocated in snd_mixer_oss_proc_write() using kmalloc() and kstrdup(), so there is no point in using kfree_const() to free these resources. Switch to the more standard kfree() to free these resources. This could avoid a memory leak. Fixes: 454f5ec1d2b7 ("ALSA: mixer: oss: Constify snd_mixer_oss_assign_table definition") Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Link: https://patch.msgid.link/63ac20f64234b7c9ea87a7fa9baf41e8255852f7.1727374631.git.christophe.jaillet@wanadoo.fr Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/core/oss/mixer_oss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 33bf9a220ada..89b317c728b4 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -901,8 +901,8 @@ static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn) struct slot *p = chn->private_data; if (p) { if (p->allocated && p->assigned) { - kfree_const(p->assigned->name); - kfree_const(p->assigned); + kfree(p->assigned->name); + kfree(p->assigned); } kfree(p); } -- GitLab From 4b058c9f281f5b100efbf665dd5a1a05e1654d6d Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" <Jason@zx2c4.com> Date: Wed, 25 Sep 2024 19:50:22 +0200 Subject: [PATCH 483/970] powerpc/vdso: allow r30 in vDSO code generation of getrandom For gettimeofday, -ffixed-r30 was passed to work around a bug in Go code, where the vDSO trampoline forgot to save and restore this register across function calls. But Go requires a different trampoline for every call, and there's no reason that new Go code needs to be broken and add more bugs. So remove -ffixed-r30 for getrandom. Fixes: 8072b39c3a75 ("powerpc/vdso: Wire up getrandom() vDSO implementation on VDSO64") Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20240925175021.1526936-2-Jason@zx2c4.com --- arch/powerpc/kernel/vdso/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile index 56fb1633529a..31ca5a547004 100644 --- a/arch/powerpc/kernel/vdso/Makefile +++ b/arch/powerpc/kernel/vdso/Makefile @@ -22,7 +22,7 @@ endif ifneq ($(c-getrandom-y),) CFLAGS_vgetrandom-32.o += -include $(c-getrandom-y) - CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y) $(call cc-option, -ffixed-r30) + CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y) endif # Build rules -- GitLab From 7fb1d1e0382c2841906fbc1bad7d902b21fe67de Mon Sep 17 00:00:00 2001 From: Masahiro Yamada <masahiroy@kernel.org> Date: Mon, 23 Sep 2024 16:56:02 +0900 Subject: [PATCH 484/970] kbuild: move non-boot built-in DTBs to .rodata section Commit aab94339cd85 ("of: Add support for linking device tree blobs into vmlinux") introduced a mechanism to embed DTBs into vmlinux. Initially, it was used for wrapping boot DTBs in arch/*/boot/dts/, but it is now reused for more generic purposes, such as testing. Built-in DTBs are discarded because KERNEL_DTB() is part of INIT_DATA, as defined in include/asm-generic/vmlinux.lds.h. This has not been an issue so far because OF unittests are triggered during boot, as defined by late_initcall(of_unittest). However, the recent clk KUnit test additions have caused problems because KUnit can execute test suites after boot. For example: # echo > /sys/kernel/debug/kunit/clk_register_clk_parent_data_device/run This command triggers a stack trace because built-in DTBs have already been freed. While it is possible to move such test suites from kunit_test_suites to kunit_test_init_section_suites, it would be preferable to avoid usage limitations. This commit moves non-boot built-in DTBs to the .rodata section. Since these generic DTBs are looked up by name, they do not need to be placed in the special .dtb.init.rodata section. Boot DTBs should remain in .dtb.init.rodata because the arch boot code generally does not know the DT name, thus it uses the __dtb_start symbol to locate it. This separation also ensures that the __dtb_start symbol references the boot DTB. Currently, the .dtb.init.rodata is a mixture of both boot and non-boot DTBs. The __dtb_start symbol must be followed by the boot DTB, but we currently rely on the link order (i.e., the order in Makefiles), which is very fragile. The implementation is kind of cheesy; the section is .dtb.init.rodata when $(obj) starts with arch/$(SRCARCH)/boot/dts, and .rodata section otherwise. This will be refactored later. Fixes: 5c9dd72d8385 ("of: Add a KUnit test for overlays and test managed APIs") Fixes: 5776526beb95 ("clk: Add KUnit tests for clk fixed rate basic type") Fixes: 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Rob Herring (Arm) <robh@kernel.org> --- scripts/Makefile.dtbs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs index 46009d5f1486..8d56c0815f33 100644 --- a/scripts/Makefile.dtbs +++ b/scripts/Makefile.dtbs @@ -34,12 +34,14 @@ $(obj)/dtbs-list: $(dtb-y) FORCE # Assembly file to wrap dtb(o) # --------------------------------------------------------------------------- +builtin-dtb-section = $(if $(filter arch/$(SRCARCH)/boot/dts%, $(obj)),.dtb.init.rodata,.rodata) + # Generate an assembly file to wrap the output of the device tree compiler quiet_cmd_wrap_S_dtb = WRAP $@ cmd_wrap_S_dtb = { \ symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*)); \ echo '\#include <asm-generic/vmlinux.lds.h>'; \ - echo '.section .dtb.init.rodata,"a"'; \ + echo '.section $(builtin-dtb-section),"a"'; \ echo '.balign STRUCT_ALIGNMENT'; \ echo ".global $${symbase}_begin"; \ echo "$${symbase}_begin:"; \ -- GitLab From 4d46b5b623e0adee1153b1d80689211e5094ae44 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada <masahiroy@kernel.org> Date: Wed, 25 Sep 2024 20:25:31 +0900 Subject: [PATCH 485/970] kconfig: fix infinite loop in sym_calc_choice() Since commit f79dc03fe68c ("kconfig: refactor choice value calculation"), Kconfig for ARCH=powerpc may result in an infinite loop. This occurs because there are two entries for POWERPC64_CPU in a choice block. If the same symbol appears twice in a choice block, the ->choice_link node is added twice to ->choice_members, resulting a corrupted linked list. A simple test case is: choice prompt "choice" config A bool "A" config B bool "B 1" config B bool "B 2" endchoice Running 'make defconfig' results in an infinite loop. One solution is to replace the current two entries: config POWERPC64_CPU bool "Generic (POWER5 and PowerPC 970 and above)" depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN select PPC_64S_HASH_MMU config POWERPC64_CPU bool "Generic (POWER8 and above)" depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN select ARCH_HAS_FAST_MULTIPLIER select PPC_64S_HASH_MMU select PPC_HAS_LBARX_LHARX with the following single entry: config POWERPC64_CPU bool "Generic 64 bit powerpc" depends on PPC_BOOK3S_64 select ARCH_HAS_FAST_MULTIPLIER if CPU_LITTLE_ENDIAN select PPC_64S_HASH_MMU select PPC_HAS_LBARX_LHARX if CPU_LITTLE_ENDIAN In my opinion, the latter looks cleaner, but PowerPC maintainers may prefer to display different prompts depending on CPU_LITTLE_ENDIAN. For now, this commit fixes the issue in Kconfig, restoring the original behavior. I will reconsider whether such a use case is worth supporting. Fixes: f79dc03fe68c ("kconfig: refactor choice value calculation") Reported-by: Marco Bonelli <marco@mebeim.net> Closes: https://lore.kernel.org/all/1763151587.3581913.1727224126288@privateemail.com/ Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/kconfig/parser.y | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 1ad60f9e164e..bc43fb67c7c4 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -159,8 +159,14 @@ config_stmt: config_entry_start config_option_list yynerrs++; } - list_add_tail(¤t_entry->sym->choice_link, - ¤t_choice->choice_members); + /* + * If the same symbol appears twice in a choice block, the list + * node would be added twice, leading to a broken linked list. + * list_empty() ensures that this symbol has not yet added. + */ + if (list_empty(¤t_entry->sym->choice_link)) + list_add_tail(¤t_entry->sym->choice_link, + ¤t_choice->choice_members); } printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); -- GitLab From 3360d41f4ac490282fddc3ccc0b58679aa5c065d Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli <emanuele.ghidoli@toradex.com> Date: Wed, 28 Aug 2024 15:32:07 +0200 Subject: [PATCH 486/970] gpio: davinci: fix lazy disable On a few platforms such as TI's AM69 device, disable_irq() fails to keep track of the interrupts that happen between disable_irq() and enable_irq() and those interrupts are missed. Use the ->irq_unmask() and ->irq_mask() methods instead of ->irq_enable() and ->irq_disable() to correctly keep track of edges when disable_irq is called. This solves the issue of disable_irq() not working as expected on such platforms. Fixes: 23265442b02b ("ARM: davinci: irq_data conversion.") Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com> Signed-off-by: Parth Pancholi <parth.pancholi@toradex.com> Acked-by: Keerthy <j-keerthy@ti.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240828133207.493961-1-parth105105@gmail.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> --- drivers/gpio/gpio-davinci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index b54fef6b1e12..790595f3b949 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -253,7 +253,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) * serve as EDMA event triggers. */ -static void gpio_irq_disable(struct irq_data *d) +static void gpio_irq_mask(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d); uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); @@ -262,7 +262,7 @@ static void gpio_irq_disable(struct irq_data *d) writel_relaxed(mask, &g->clr_rising); } -static void gpio_irq_enable(struct irq_data *d) +static void gpio_irq_unmask(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d); uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); @@ -288,8 +288,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger) static struct irq_chip gpio_irqchip = { .name = "GPIO", - .irq_enable = gpio_irq_enable, - .irq_disable = gpio_irq_disable, + .irq_unmask = gpio_irq_unmask, + .irq_mask = gpio_irq_mask, .irq_set_type = gpio_irq_type, .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, }; -- GitLab From 28e8c5c095ec28edeedab5e976e62e0419a89fc1 Mon Sep 17 00:00:00 2001 From: David Howells <dhowells@redhat.com> Date: Mon, 30 Sep 2024 11:14:41 +0100 Subject: [PATCH 487/970] netfs: Add folio_queue API documentation Add API documentation for folio_queue. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/2912369.1727691281@warthog.procyon.org.uk cc: Jeff Layton <jlayton@kernel.org> cc: netfs@lists.linux.dev cc: linux-doc@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- Documentation/core-api/folio_queue.rst | 212 +++++++++++++++++++++++++ include/linux/folio_queue.h | 168 ++++++++++++++++++++ 2 files changed, 380 insertions(+) create mode 100644 Documentation/core-api/folio_queue.rst diff --git a/Documentation/core-api/folio_queue.rst b/Documentation/core-api/folio_queue.rst new file mode 100644 index 000000000000..1fe7a9bc4b8d --- /dev/null +++ b/Documentation/core-api/folio_queue.rst @@ -0,0 +1,212 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +=========== +Folio Queue +=========== + +:Author: David Howells <dhowells@redhat.com> + +.. Contents: + + * Overview + * Initialisation + * Adding and removing folios + * Querying information about a folio + * Querying information about a folio_queue + * Folio queue iteration + * Folio marks + * Lockless simultaneous production/consumption issues + + +Overview +======== + +The folio_queue struct forms a single segment in a segmented list of folios +that can be used to form an I/O buffer. As such, the list can be iterated over +using the ITER_FOLIOQ iov_iter type. + +The publicly accessible members of the structure are:: + + struct folio_queue { + struct folio_queue *next; + struct folio_queue *prev; + ... + }; + +A pair of pointers are provided, ``next`` and ``prev``, that point to the +segments on either side of the segment being accessed. Whilst this is a +doubly-linked list, it is intentionally not a circular list; the outward +sibling pointers in terminal segments should be NULL. + +Each segment in the list also stores: + + * an ordered sequence of folio pointers, + * the size of each folio and + * three 1-bit marks per folio, + +but hese should not be accessed directly as the underlying data structure may +change, but rather the access functions outlined below should be used. + +The facility can be made accessible by:: + + #include <linux/folio_queue.h> + +and to use the iterator:: + + #include <linux/uio.h> + + +Initialisation +============== + +A segment should be initialised by calling:: + + void folioq_init(struct folio_queue *folioq); + +with a pointer to the segment to be initialised. Note that this will not +necessarily initialise all the folio pointers, so care must be taken to check +the number of folios added. + + +Adding and removing folios +========================== + +Folios can be set in the next unused slot in a segment struct by calling one +of:: + + unsigned int folioq_append(struct folio_queue *folioq, + struct folio *folio); + + unsigned int folioq_append_mark(struct folio_queue *folioq, + struct folio *folio); + +Both functions update the stored folio count, store the folio and note its +size. The second function also sets the first mark for the folio added. Both +functions return the number of the slot used. [!] Note that no attempt is made +to check that the capacity wasn't overrun and the list will not be extended +automatically. + +A folio can be excised by calling:: + + void folioq_clear(struct folio_queue *folioq, unsigned int slot); + +This clears the slot in the array and also clears all the marks for that folio, +but doesn't change the folio count - so future accesses of that slot must check +if the slot is occupied. + + +Querying information about a folio +================================== + +Information about the folio in a particular slot may be queried by the +following function:: + + struct folio *folioq_folio(const struct folio_queue *folioq, + unsigned int slot); + +If a folio has not yet been set in that slot, this may yield an undefined +pointer. The size of the folio in a slot may be queried with either of:: + + unsigned int folioq_folio_order(const struct folio_queue *folioq, + unsigned int slot); + + size_t folioq_folio_size(const struct folio_queue *folioq, + unsigned int slot); + +The first function returns the size as an order and the second as a number of +bytes. + + +Querying information about a folio_queue +======================================== + +Information may be retrieved about a particular segment with the following +functions:: + + unsigned int folioq_nr_slots(const struct folio_queue *folioq); + + unsigned int folioq_count(struct folio_queue *folioq); + + bool folioq_full(struct folio_queue *folioq); + +The first function returns the maximum capacity of a segment. It must not be +assumed that this won't vary between segments. The second returns the number +of folios added to a segments and the third is a shorthand to indicate if the +segment has been filled to capacity. + +Not that the count and fullness are not affected by clearing folios from the +segment. These are more about indicating how many slots in the array have been +initialised, and it assumed that slots won't get reused, but rather the segment +will get discarded as the queue is consumed. + + +Folio marks +=========== + +Folios within a queue can also have marks assigned to them. These marks can be +used to note information such as if a folio needs folio_put() calling upon it. +There are three marks available to be set for each folio. + +The marks can be set by:: + + void folioq_mark(struct folio_queue *folioq, unsigned int slot); + void folioq_mark2(struct folio_queue *folioq, unsigned int slot); + void folioq_mark3(struct folio_queue *folioq, unsigned int slot); + +Cleared by:: + + void folioq_unmark(struct folio_queue *folioq, unsigned int slot); + void folioq_unmark2(struct folio_queue *folioq, unsigned int slot); + void folioq_unmark3(struct folio_queue *folioq, unsigned int slot); + +And the marks can be queried by:: + + bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot); + bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot); + bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot); + +The marks can be used for any purpose and are not interpreted by this API. + + +Folio queue iteration +===================== + +A list of segments may be iterated over using the I/O iterator facility using +an ``iov_iter`` iterator of ``ITER_FOLIOQ`` type. The iterator may be +initialised with:: + + void iov_iter_folio_queue(struct iov_iter *i, unsigned int direction, + const struct folio_queue *folioq, + unsigned int first_slot, unsigned int offset, + size_t count); + +This may be told to start at a particular segment, slot and offset within a +queue. The iov iterator functions will follow the next pointers when advancing +and prev pointers when reverting when needed. + + +Lockless simultaneous production/consumption issues +=================================================== + +If properly managed, the list can be extended by the producer at the head end +and shortened by the consumer at the tail end simultaneously without the need +to take locks. The ITER_FOLIOQ iterator inserts appropriate barriers to aid +with this. + +Care must be taken when simultaneously producing and consuming a list. If the +last segment is reached and the folios it refers to are entirely consumed by +the IOV iterators, an iov_iter struct will be left pointing to the last segment +with a slot number equal to the capacity of that segment. The iterator will +try to continue on from this if there's another segment available when it is +used again, but care must be taken lest the segment got removed and freed by +the consumer before the iterator was advanced. + +It is recommended that the queue always contain at least one segment, even if +that segment has never been filled or is entirely spent. This prevents the +head and tail pointers from collapsing. + + +API Function Reference +====================== + +.. kernel-doc:: include/linux/folio_queue.h diff --git a/include/linux/folio_queue.h b/include/linux/folio_queue.h index 955680c3bb5f..af871405ae55 100644 --- a/include/linux/folio_queue.h +++ b/include/linux/folio_queue.h @@ -3,6 +3,12 @@ * * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) + * + * See: + * + * Documentation/core-api/folio_queue.rst + * + * for a description of the API. */ #ifndef _LINUX_FOLIO_QUEUE_H @@ -33,6 +39,13 @@ struct folio_queue { #endif }; +/** + * folioq_init - Initialise a folio queue segment + * @folioq: The segment to initialise + * + * Initialise a folio queue segment. Note that the folio pointers are + * left uninitialised. + */ static inline void folioq_init(struct folio_queue *folioq) { folio_batch_init(&folioq->vec); @@ -43,62 +56,155 @@ static inline void folioq_init(struct folio_queue *folioq) folioq->marks3 = 0; } +/** + * folioq_nr_slots: Query the capacity of a folio queue segment + * @folioq: The segment to query + * + * Query the number of folios that a particular folio queue segment might hold. + * [!] NOTE: This must not be assumed to be the same for every segment! + */ static inline unsigned int folioq_nr_slots(const struct folio_queue *folioq) { return PAGEVEC_SIZE; } +/** + * folioq_count: Query the occupancy of a folio queue segment + * @folioq: The segment to query + * + * Query the number of folios that have been added to a folio queue segment. + * Note that this is not decreased as folios are removed from a segment. + */ static inline unsigned int folioq_count(struct folio_queue *folioq) { return folio_batch_count(&folioq->vec); } +/** + * folioq_count: Query if a folio queue segment is full + * @folioq: The segment to query + * + * Query if a folio queue segment is fully occupied. Note that this does not + * change if folios are removed from a segment. + */ static inline bool folioq_full(struct folio_queue *folioq) { //return !folio_batch_space(&folioq->vec); return folioq_count(folioq) >= folioq_nr_slots(folioq); } +/** + * folioq_is_marked: Check first folio mark in a folio queue segment + * @folioq: The segment to query + * @slot: The slot number of the folio to query + * + * Determine if the first mark is set for the folio in the specified slot in a + * folio queue segment. + */ static inline bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot) { return test_bit(slot, &folioq->marks); } +/** + * folioq_mark: Set the first mark on a folio in a folio queue segment + * @folioq: The segment to modify + * @slot: The slot number of the folio to modify + * + * Set the first mark for the folio in the specified slot in a folio queue + * segment. + */ static inline void folioq_mark(struct folio_queue *folioq, unsigned int slot) { set_bit(slot, &folioq->marks); } +/** + * folioq_unmark: Clear the first mark on a folio in a folio queue segment + * @folioq: The segment to modify + * @slot: The slot number of the folio to modify + * + * Clear the first mark for the folio in the specified slot in a folio queue + * segment. + */ static inline void folioq_unmark(struct folio_queue *folioq, unsigned int slot) { clear_bit(slot, &folioq->marks); } +/** + * folioq_is_marked2: Check second folio mark in a folio queue segment + * @folioq: The segment to query + * @slot: The slot number of the folio to query + * + * Determine if the second mark is set for the folio in the specified slot in a + * folio queue segment. + */ static inline bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot) { return test_bit(slot, &folioq->marks2); } +/** + * folioq_mark2: Set the second mark on a folio in a folio queue segment + * @folioq: The segment to modify + * @slot: The slot number of the folio to modify + * + * Set the second mark for the folio in the specified slot in a folio queue + * segment. + */ static inline void folioq_mark2(struct folio_queue *folioq, unsigned int slot) { set_bit(slot, &folioq->marks2); } +/** + * folioq_unmark2: Clear the second mark on a folio in a folio queue segment + * @folioq: The segment to modify + * @slot: The slot number of the folio to modify + * + * Clear the second mark for the folio in the specified slot in a folio queue + * segment. + */ static inline void folioq_unmark2(struct folio_queue *folioq, unsigned int slot) { clear_bit(slot, &folioq->marks2); } +/** + * folioq_is_marked3: Check third folio mark in a folio queue segment + * @folioq: The segment to query + * @slot: The slot number of the folio to query + * + * Determine if the third mark is set for the folio in the specified slot in a + * folio queue segment. + */ static inline bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot) { return test_bit(slot, &folioq->marks3); } +/** + * folioq_mark3: Set the third mark on a folio in a folio queue segment + * @folioq: The segment to modify + * @slot: The slot number of the folio to modify + * + * Set the third mark for the folio in the specified slot in a folio queue + * segment. + */ static inline void folioq_mark3(struct folio_queue *folioq, unsigned int slot) { set_bit(slot, &folioq->marks3); } +/** + * folioq_unmark3: Clear the third mark on a folio in a folio queue segment + * @folioq: The segment to modify + * @slot: The slot number of the folio to modify + * + * Clear the third mark for the folio in the specified slot in a folio queue + * segment. + */ static inline void folioq_unmark3(struct folio_queue *folioq, unsigned int slot) { clear_bit(slot, &folioq->marks3); @@ -111,6 +217,19 @@ static inline unsigned int __folio_order(struct folio *folio) return folio->_flags_1 & 0xff; } +/** + * folioq_append: Add a folio to a folio queue segment + * @folioq: The segment to add to + * @folio: The folio to add + * + * Add a folio to the tail of the sequence in a folio queue segment, increasing + * the occupancy count and returning the slot number for the folio just added. + * The folio size is extracted and stored in the queue and the marks are left + * unmodified. + * + * Note that it's left up to the caller to check that the segment capacity will + * not be exceeded and to extend the queue. + */ static inline unsigned int folioq_append(struct folio_queue *folioq, struct folio *folio) { unsigned int slot = folioq->vec.nr++; @@ -120,6 +239,19 @@ static inline unsigned int folioq_append(struct folio_queue *folioq, struct foli return slot; } +/** + * folioq_append_mark: Add a folio to a folio queue segment + * @folioq: The segment to add to + * @folio: The folio to add + * + * Add a folio to the tail of the sequence in a folio queue segment, increasing + * the occupancy count and returning the slot number for the folio just added. + * The folio size is extracted and stored in the queue, the first mark is set + * and and the second and third marks are left unmodified. + * + * Note that it's left up to the caller to check that the segment capacity will + * not be exceeded and to extend the queue. + */ static inline unsigned int folioq_append_mark(struct folio_queue *folioq, struct folio *folio) { unsigned int slot = folioq->vec.nr++; @@ -130,21 +262,57 @@ static inline unsigned int folioq_append_mark(struct folio_queue *folioq, struct return slot; } +/** + * folioq_folio: Get a folio from a folio queue segment + * @folioq: The segment to access + * @slot: The folio slot to access + * + * Retrieve the folio in the specified slot from a folio queue segment. Note + * that no bounds check is made and if the slot hasn't been added into yet, the + * pointer will be undefined. If the slot has been cleared, NULL will be + * returned. + */ static inline struct folio *folioq_folio(const struct folio_queue *folioq, unsigned int slot) { return folioq->vec.folios[slot]; } +/** + * folioq_folio_order: Get the order of a folio from a folio queue segment + * @folioq: The segment to access + * @slot: The folio slot to access + * + * Retrieve the order of the folio in the specified slot from a folio queue + * segment. Note that no bounds check is made and if the slot hasn't been + * added into yet, the order returned will be 0. + */ static inline unsigned int folioq_folio_order(const struct folio_queue *folioq, unsigned int slot) { return folioq->orders[slot]; } +/** + * folioq_folio_size: Get the size of a folio from a folio queue segment + * @folioq: The segment to access + * @slot: The folio slot to access + * + * Retrieve the size of the folio in the specified slot from a folio queue + * segment. Note that no bounds check is made and if the slot hasn't been + * added into yet, the size returned will be PAGE_SIZE. + */ static inline size_t folioq_folio_size(const struct folio_queue *folioq, unsigned int slot) { return PAGE_SIZE << folioq_folio_order(folioq, slot); } +/** + * folioq_clear: Clear a folio from a folio queue segment + * @folioq: The segment to clear + * @slot: The folio slot to clear + * + * Clear a folio from a sequence in a folio queue segment and clear its marks. + * The occupancy count is left unchanged. + */ static inline void folioq_clear(struct folio_queue *folioq, unsigned int slot) { folioq->vec.folios[slot] = NULL; -- GitLab From f801850bc263d7fa0a4e6d9a36cddf4966c79c14 Mon Sep 17 00:00:00 2001 From: David Howells <dhowells@redhat.com> Date: Mon, 30 Sep 2024 12:59:16 +0100 Subject: [PATCH 488/970] netfs: Fix the netfs_folio tracepoint to handle NULL mapping Fix the netfs_folio tracepoint to handle folios that have a NULL mapping pointer. In such a case, just substitute a zero inode number. Fixes: c38f4e96e605 ("netfs: Provide func to copy data to pagecache for buffered write") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/2917423.1727697556@warthog.procyon.org.uk cc: Jeff Layton <jlayton@kernel.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- include/trace/events/netfs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h index 76bd42a96815..1d7c52821e55 100644 --- a/include/trace/events/netfs.h +++ b/include/trace/events/netfs.h @@ -448,7 +448,8 @@ TRACE_EVENT(netfs_folio, ), TP_fast_assign( - __entry->ino = folio->mapping->host->i_ino; + struct address_space *__m = READ_ONCE(folio->mapping); + __entry->ino = __m ? __m->host->i_ino : 0; __entry->why = why; __entry->index = folio_index(folio); __entry->nr = folio_nr_pages(folio); -- GitLab From ee1e3c46ed19c096be22472c728fa7f68b1352c4 Mon Sep 17 00:00:00 2001 From: Ben Cheatham <Benjamin.Cheatham@amd.com> Date: Fri, 27 Sep 2024 11:34:28 -0500 Subject: [PATCH 489/970] EINJ, CXL: Fix CXL device SBDF calculation The SBDF of the target CXL 2.0 compliant root port is required to inject a CXL protocol error as per ACPI 6.5. The SBDF given has to be in the following format: 31 24 23 16 15 11 10 8 7 0 +-------------------------------------------------+ | segment | bus | device | function | reserved | +-------------------------------------------------+ The SBDF calculated in cxl_dport_get_sbdf() doesn't account for the reserved bits currently, causing the wrong SBDF to be used. Fix said calculation to properly shift the SBDF. Without this fix, error injection into CXL 2.0 root ports through the CXL debugfs interface (<debugfs>/cxl) is broken. Injection through the legacy interface (<debugfs>/apei/einj/) will still work because the SBDF is manually provided by the user. Fixes: 12fb28ea6b1cf ("EINJ: Add CXL error type support") Signed-off-by: Ben Cheatham <Benjamin.Cheatham@amd.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Tested-by: Srinivasulu Thanneeru <sthanneeru.opensrc@micron.com> Reviewed-by: Srinivasulu Thanneeru <sthanneeru.opensrc@micron.com> Link: https://patch.msgid.link/20240927163428.366557-1-Benjamin.Cheatham@amd.com Signed-off-by: Ira Weiny <ira.weiny@intel.com> --- drivers/acpi/apei/einj-cxl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/apei/einj-cxl.c b/drivers/acpi/apei/einj-cxl.c index 4f81a119ec08..a4e709937236 100644 --- a/drivers/acpi/apei/einj-cxl.c +++ b/drivers/acpi/apei/einj-cxl.c @@ -63,7 +63,7 @@ static int cxl_dport_get_sbdf(struct pci_dev *dport_dev, u64 *sbdf) seg = bridge->domain_nr; bus = pbus->number; - *sbdf = (seg << 24) | (bus << 16) | dport_dev->devfn; + *sbdf = (seg << 24) | (bus << 16) | (dport_dev->devfn << 8); return 0; } -- GitLab From abf201f6ce14c4ceeccde5471bdf59614b83a3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> Date: Mon, 30 Sep 2024 15:07:49 +0200 Subject: [PATCH 490/970] drm/sched: revert "Always increment correct scheduler score" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 087913e0ba2b3b9d7ccbafb2acf5dab9e35ae1d5. It turned out that the original code was correct since the rq can only change when there is no armed job for an entity. This change here broke the logic since we only incremented the counter for the first job, so revert it. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930131451.536150-1-christian.koenig@amd.com --- drivers/gpu/drm/scheduler/sched_entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index b2cf3e0c1838..a75eede8bf8d 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -586,6 +586,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) ktime_t submit_ts; trace_drm_sched_job(sched_job, entity); + atomic_inc(entity->rq->sched->score); WRITE_ONCE(entity->last_user, current->group_leader); /* @@ -613,7 +614,6 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) rq = entity->rq; sched = rq->sched; - atomic_inc(sched->score); drm_sched_rq_add_entity(rq, entity); spin_unlock(&entity->rq_lock); -- GitLab From 73253f2fd1d0a44708735c842e37163712e3f03b Mon Sep 17 00:00:00 2001 From: Oldherl Oh <me@oldherl.one> Date: Mon, 30 Sep 2024 16:41:32 +0800 Subject: [PATCH 491/970] ALSA: hda/conexant: fix some typos Fix some typos in patch_conexant.c Signed-off-by: Oldherl Oh <me@oldherl.one> Link: https://patch.msgid.link/20240930084132.3373750-1-me@oldherl.one Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_conexant.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e851785ff058..ade42a8209c2 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -166,18 +166,18 @@ static void cxt_init_gpio_led(struct hda_codec *codec) static void cx_fixup_headset_recog(struct hda_codec *codec) { - unsigned int mic_persent; + unsigned int mic_present; /* fix some headset type recognize fail issue, such as EDIFIER headset */ - /* set micbiasd output current comparator threshold from 66% to 55%. */ + /* set micbias output current comparator threshold from 66% to 55%. */ snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010); - /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias registor + /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias register * value adjustment trim from 2.2K ohms to 2.0K ohms. */ snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10); /* fix reboot headset type recognize fail issue */ - mic_persent = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); - if (mic_persent & AC_PINSENSE_PRESENCE) + mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); + if (mic_present & AC_PINSENSE_PRESENCE) /* enable headset mic VREF */ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24); else @@ -249,9 +249,9 @@ static void cx_update_headset_mic_vref(struct hda_codec *codec, struct hda_jack_ { unsigned int mic_present; - /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled, - * the node 19 can only be config to microphone or disabled. - * Check hp&mic tag to process headset pulgin&plugout. + /* In cx8070 and sn6140, the node 16 can only be configured to headphone or disabled, + * the node 19 can only be configured to microphone or disabled. + * Check hp&mic tag to process headset plugin & plugout. */ mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); if (!(mic_present & AC_PINSENSE_PRESENCE)) /* mic plugout */ -- GitLab From 05df9732a0894846c46d0062d4af535c5002799d Mon Sep 17 00:00:00 2001 From: Oder Chiou <oder_chiou@realtek.com> Date: Mon, 30 Sep 2024 18:50:39 +0800 Subject: [PATCH 492/970] ALSA: hda/realtek: Fix the push button function for the ALC257 The headset push button cannot work properly in case of the ALC257. This patch reverted the previous commit to correct the side effect. Fixes: ef9718b3d54e ("ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7") Signed-off-by: Oder Chiou <oder_chiou@realtek.com> Link: https://patch.msgid.link/20240930105039.3473266-1-oder_chiou@realtek.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7681200e84e8..b42257e03344 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -587,6 +587,7 @@ static void alc_shutup_pins(struct hda_codec *codec) switch (codec->core.vendor_id) { case 0x10ec0236: case 0x10ec0256: + case 0x10ec0257: case 0x19e58326: case 0x10ec0283: case 0x10ec0285: -- GitLab From 8a193d8e351d185d75186bf0bdfa979e19d8fba8 Mon Sep 17 00:00:00 2001 From: Julia Lawall <Julia.Lawall@inria.fr> Date: Mon, 30 Sep 2024 13:20:50 +0200 Subject: [PATCH 493/970] ALSA: Reorganize kerneldoc parameter names Reorganize kerneldoc parameter names to match the parameter order in the function header. Problems identified using Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr> Link: https://patch.msgid.link/20240930112121.95324-5-Julia.Lawall@inria.fr Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3dd1bda0c5c6..14763c0f31ad 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1734,9 +1734,9 @@ EXPORT_SYMBOL_GPL(snd_hda_ctl_add); /** * snd_hda_add_nid - Assign a NID to a control element * @codec: HD-audio codec - * @nid: corresponding NID (optional) * @kctl: the control element to assign * @index: index to kctl + * @nid: corresponding NID (optional) * * Add the given control element to an array inside the codec instance. * This function is used when #snd_hda_ctl_add cannot be used for 1:1 -- GitLab From c314094cb4cfa6fc5a17f4881ead2dfebfa717a7 Mon Sep 17 00:00:00 2001 From: Jens Axboe <axboe@kernel.dk> Date: Thu, 26 Sep 2024 07:08:10 -0600 Subject: [PATCH 494/970] io_uring/net: harden multishot termination case for recv If the recv returns zero, or an error, then it doesn't matter if more data has already been received for this buffer. A condition like that should terminate the multishot receive. Rather than pass in the collected return value, pass in whether to terminate or keep the recv going separately. Note that this isn't a bug right now, as the only way to get there is via setting MSG_WAITALL with multishot receive. And if an application does that, then -EINVAL is returned anyway. But it seems like an easy bug to introduce, so let's make it a bit more explicit. Link: https://github.com/axboe/liburing/issues/1246 Cc: stable@vger.kernel.org Fixes: b3fdea6ecb55 ("io_uring: multishot recv") Signed-off-by: Jens Axboe <axboe@kernel.dk> --- io_uring/net.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/io_uring/net.c b/io_uring/net.c index f10f5a22d66a..18507658a921 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -1133,6 +1133,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags) int ret, min_ret = 0; bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; size_t len = sr->len; + bool mshot_finished; if (!(req->flags & REQ_F_POLLED) && (sr->flags & IORING_RECVSEND_POLL_FIRST)) @@ -1187,6 +1188,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags) req_set_fail(req); } + mshot_finished = ret <= 0; if (ret > 0) ret += sr->done_io; else if (sr->done_io) @@ -1194,7 +1196,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags) else io_kbuf_recycle(req, issue_flags); - if (!io_recv_finish(req, &ret, kmsg, ret <= 0, issue_flags)) + if (!io_recv_finish(req, &ret, kmsg, mshot_finished, issue_flags)) goto retry_multishot; return ret; -- GitLab From 852836bc704463740e0d4076cea671b41f37ff78 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:42 +0200 Subject: [PATCH 495/970] fbdev: atmel_lcdfb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Nicolas Ferre <nicolas.ferre@microchip.com> Cc: Helge Deller <deller@gmx.de> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-2-tzimmermann@suse.de --- drivers/video/fbdev/atmel_lcdfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 5574fb0361ee..4da233fb02a8 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -152,7 +152,7 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) } sinfo->backlight = bl; - bl->props.power = FB_BLANK_UNBLANK; + bl->props.power = BACKLIGHT_POWER_ON; bl->props.brightness = atmel_bl_get_brightness(bl); } @@ -162,7 +162,7 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo) return; if (sinfo->backlight->ops) { - sinfo->backlight->props.power = FB_BLANK_POWERDOWN; + sinfo->backlight->props.power = BACKLIGHT_POWER_OFF; sinfo->backlight->ops->update_status(sinfo->backlight); } backlight_device_unregister(sinfo->backlight); -- GitLab From 005d1869cf5eff33907daf3370a119acd4a770fe Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:43 +0200 Subject: [PATCH 496/970] fbdev: aty128fb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-3-tzimmermann@suse.de --- drivers/video/fbdev/aty/aty128fb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index f4de11f19235..f55b4c7609a8 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -1299,11 +1299,11 @@ static void aty128_set_lcd_enable(struct aty128fb_par *par, int on) reg &= ~LVDS_DISPLAY_DIS; aty_st_le32(LVDS_GEN_CNTL, reg); #ifdef CONFIG_FB_ATY128_BACKLIGHT - aty128_bl_set_power(info, FB_BLANK_UNBLANK); + aty128_bl_set_power(info, BACKLIGHT_POWER_ON); #endif } else { #ifdef CONFIG_FB_ATY128_BACKLIGHT - aty128_bl_set_power(info, FB_BLANK_POWERDOWN); + aty128_bl_set_power(info, BACKLIGHT_POWER_OFF); #endif reg = aty_ld_le32(LVDS_GEN_CNTL); reg |= LVDS_DISPLAY_DIS; @@ -1858,7 +1858,7 @@ static void aty128_bl_init(struct aty128fb_par *par) 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); bd->props.brightness = bd->props.max_brightness; - bd->props.power = FB_BLANK_UNBLANK; + bd->props.power = BACKLIGHT_POWER_ON; backlight_update_status(bd); printk("aty128: Backlight initialized (%s)\n", name); -- GitLab From ac7a07da591b7ba6c46e83eca79746517726d508 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:44 +0200 Subject: [PATCH 497/970] fbdev: atyfb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-4-tzimmermann@suse.de --- drivers/video/fbdev/aty/atyfb_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index a6dd1cd27125..210fd3ac18a4 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2272,7 +2272,7 @@ static void aty_bl_init(struct atyfb_par *par) 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); bd->props.brightness = bd->props.max_brightness; - bd->props.power = FB_BLANK_UNBLANK; + bd->props.power = BACKLIGHT_POWER_ON; backlight_update_status(bd); printk("aty: Backlight initialized (%s)\n", name); -- GitLab From 35f7f68272903aead8e62be53112ad59977b50af Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:45 +0200 Subject: [PATCH 498/970] fbdev: chipsfb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-5-tzimmermann@suse.de --- drivers/video/fbdev/chipsfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index b16a905588fe..33caf0b99a45 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c @@ -399,7 +399,7 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) /* turn on the backlight */ mutex_lock(&pmac_backlight_mutex); if (pmac_backlight) { - pmac_backlight->props.power = FB_BLANK_UNBLANK; + pmac_backlight->props.power = BACKLIGHT_POWER_ON; backlight_update_status(pmac_backlight); } mutex_unlock(&pmac_backlight_mutex); -- GitLab From d408dcfa731fc536714d2527d850a7693dabd1ae Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:46 +0200 Subject: [PATCH 499/970] fbdev: nvidiafb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Antonino Daplas <adaplas@gmail.com> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-6-tzimmermann@suse.de --- drivers/video/fbdev/nvidia/nv_backlight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c index 160da9c50a52..7edd47ab16e9 100644 --- a/drivers/video/fbdev/nvidia/nv_backlight.c +++ b/drivers/video/fbdev/nvidia/nv_backlight.c @@ -112,7 +112,7 @@ void nvidia_bl_init(struct nvidia_par *par) 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); bd->props.brightness = bd->props.max_brightness; - bd->props.power = FB_BLANK_UNBLANK; + bd->props.power = BACKLIGHT_POWER_ON; backlight_update_status(bd); printk("nvidia: Backlight initialized (%s)\n", name); -- GitLab From ce27a76a53606eaa87c5e7b76c6d9ae63d5c1adc Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:47 +0200 Subject: [PATCH 500/970] fbdev: omapfb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-7-tzimmermann@suse.de --- drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c | 4 ++-- .../video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c index 274bdf7b3b45..35ed1b2db993 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c @@ -1215,7 +1215,7 @@ static int dsicm_probe(struct platform_device *pdev) ddata->bldev = bldev; - bldev->props.power = FB_BLANK_UNBLANK; + bldev->props.power = BACKLIGHT_POWER_ON; bldev->props.brightness = 255; dsicm_bl_update_status(bldev); @@ -1253,7 +1253,7 @@ static void dsicm_remove(struct platform_device *pdev) bldev = ddata->bldev; if (bldev != NULL) { - bldev->props.power = FB_BLANK_POWERDOWN; + bldev->props.power = BACKLIGHT_POWER_OFF; dsicm_bl_update_status(bldev); backlight_device_unregister(bldev); } diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c index fc975615d5c9..8f430d9e8054 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-sony-acx565akm.c @@ -754,7 +754,7 @@ static int acx565akm_probe(struct spi_device *spi) } memset(&props, 0, sizeof(props)); - props.power = FB_BLANK_UNBLANK; + props.power = BACKLIGHT_POWER_ON; props.type = BACKLIGHT_RAW; bldev = backlight_device_register("acx565akm", &ddata->spi->dev, -- GitLab From 9d353834a867b3e1e93d62a3017dcbd699dcd9bd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:48 +0200 Subject: [PATCH 501/970] fbdev: radeonfb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-8-tzimmermann@suse.de --- drivers/video/fbdev/aty/radeon_backlight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c index 23a38c3f3977..9e41d2a18649 100644 --- a/drivers/video/fbdev/aty/radeon_backlight.c +++ b/drivers/video/fbdev/aty/radeon_backlight.c @@ -179,7 +179,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); bd->props.brightness = bd->props.max_brightness; - bd->props.power = FB_BLANK_UNBLANK; + bd->props.power = BACKLIGHT_POWER_ON; backlight_update_status(bd); printk("radeonfb: Backlight initialized (%s)\n", name); -- GitLab From 1af45064d6b55ed4332ad6dbc0383a008e0248af Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:49 +0200 Subject: [PATCH 502/970] fbdev: rivafb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Antonino Daplas <adaplas@gmail.com> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-9-tzimmermann@suse.de --- drivers/video/fbdev/riva/fbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 237db738af13..1e377b2ec089 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -347,7 +347,7 @@ static void riva_bl_init(struct riva_par *par) FB_BACKLIGHT_MAX); bd->props.brightness = bd->props.max_brightness; - bd->props.power = FB_BLANK_UNBLANK; + bd->props.power = BACKLIGHT_POWER_ON; backlight_update_status(bd); printk("riva: Backlight initialized (%s)\n", name); -- GitLab From 86fdd6b9b1e98cfd26249505e8ce72f4fc0de37f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Wed, 31 Jul 2024 14:33:50 +0200 Subject: [PATCH 503/970] fbdev: sh_mobile_lcdc_fb: Use backlight power constants Replace FB_BLANK_ constants with their counterparts from the backlight subsystem. The values are identical, so there's no change in functionality or semantics. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Helge Deller <deller@gmx.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240731123502.1145082-10-tzimmermann@suse.de --- drivers/video/fbdev/sh_mobile_lcdcfb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 73c69e39a68d..fcc1446ae746 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -1049,7 +1049,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) sh_mobile_lcdc_display_on(ch); if (ch->bl) { - ch->bl->props.power = FB_BLANK_UNBLANK; + ch->bl->props.power = BACKLIGHT_POWER_ON; backlight_update_status(ch->bl); } } @@ -1082,7 +1082,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) } if (ch->bl) { - ch->bl->props.power = FB_BLANK_POWERDOWN; + ch->bl->props.power = BACKLIGHT_POWER_OFF; backlight_update_status(ch->bl); } @@ -2125,7 +2125,7 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev) struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); int brightness = bdev->props.brightness; - if (bdev->props.power != FB_BLANK_UNBLANK || + if (bdev->props.power != BACKLIGHT_POWER_ON || bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) brightness = 0; -- GitLab From 1ad999870a86d58246b6a614a435d055a9edf269 Mon Sep 17 00:00:00 2001 From: Joseph Jang <jjang@nvidia.com> Date: Thu, 23 May 2024 18:38:07 -0700 Subject: [PATCH 504/970] selftest: rtc: Check if could access /dev/rtc0 before testing The rtctest requires the read permission on /dev/rtc0. The rtctest will be skipped if the /dev/rtc0 is not readable. Reviewed-by: Koba Ko <kobak@nvidia.com> Reviewed-by: Matthew R. Ochs <mochs@nvidia.com> Signed-off-by: Joseph Jang <jjang@nvidia.com> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/rtc/rtctest.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c index 9647b14b47c5..38a8e67de77d 100644 --- a/tools/testing/selftests/rtc/rtctest.c +++ b/tools/testing/selftests/rtc/rtctest.c @@ -412,6 +412,8 @@ TEST_F_TIMEOUT(rtc, alarm_wkalm_set_minute, 65) { int main(int argc, char **argv) { + int ret = -1; + switch (argc) { case 2: rtc_file = argv[1]; @@ -423,5 +425,12 @@ int main(int argc, char **argv) return 1; } - return test_harness_run(argc, argv); + /* Run the test if rtc_file is accessible */ + if (access(rtc_file, R_OK) == 0) + ret = test_harness_run(argc, argv); + else + ksft_exit_skip("[SKIP]: Cannot access rtc file %s - Exiting\n", + rtc_file); + + return ret; } -- GitLab From ba872972002bd1e9ae89c397307a079e04ee289a Mon Sep 17 00:00:00 2001 From: Shuah Khan <skhan@linuxfoundation.org> Date: Tue, 24 Sep 2024 09:56:46 -0600 Subject: [PATCH 505/970] selftests:timers: posix_timers: Fix warn_unused_result in __fatal_error() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __fatal_error routine doesn't check strerror_r() return value, which results in the following compile time warning: posix_timers.c: In function ‘__fatal_error’: posix_timers.c:31:9: warning: ignoring return value of ‘strerror_r’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 31 | strerror_r(errno, buf, sizeof(buf)); Fix this by adding a check for return value and error handling appropriate for the GNU-specific strerror_r() in use in __fatal_error(). Check if return string is null and handle accordingly. From Linux strerror_r() manual page: "The GNU-specific strerror_r() returns a pointer to a string containing the error message. This may be either a pointer to a string that the function stores in buf, or a pointer to some (immutable) static string (in which case buf is unused). If the function stores a string in buf, then at most buflen bytes are stored (the string may be truncated if buflen is too small and errnum is unknown). The string always includes a terminating null byte." Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> Acked-by: John Stultz <jstultz@google.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/timers/posix_timers.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index 16bd49492efa..ddb1cebc844e 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -26,13 +26,17 @@ static void __fatal_error(const char *test, const char *name, const char *what) { char buf[64]; + char *ret_str = NULL; - strerror_r(errno, buf, sizeof(buf)); + ret_str = strerror_r(errno, buf, sizeof(buf)); - if (name && strlen(name)) - ksft_exit_fail_msg("%s %s %s %s\n", test, name, what, buf); + if (name && strlen(name) && ret_str) + ksft_exit_fail_msg("%s %s %s %s\n", test, name, what, ret_str); + else if (ret_str) + ksft_exit_fail_msg("%s %s %s\n", test, what, ret_str); else - ksft_exit_fail_msg("%s %s %s\n", test, what, buf); + ksft_exit_fail_msg("%s %s\n", test, what); + } #define fatal_error(name, what) __fatal_error(__func__, name, what) -- GitLab From 74923546a0f5affe867a15e83e21c2f043f9298a Mon Sep 17 00:00:00 2001 From: Ba Jing <bajing@cmss.chinamobile.com> Date: Tue, 3 Sep 2024 11:36:28 +0800 Subject: [PATCH 506/970] clone3: clone3_cap_checkpoint_restore: remove unused MAX_PID_NS_LEVEL macro The macro MAX_PID_NS_LEVEL is never referenced in the code, so remove it. Signed-off-by: Ba Jing <bajing@cmss.chinamobile.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c b/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c index 31b56d625655..3c196fa86c99 100644 --- a/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c +++ b/tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c @@ -27,8 +27,6 @@ #include "../kselftest_harness.h" #include "clone3_selftests.h" -#define MAX_PID_NS_LEVEL 32 - static void child_exit(int ret) { fflush(stdout); -- GitLab From b79a038de6a6e826fc832223d5fea435c2a0fa17 Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 23:55:11 +0200 Subject: [PATCH 507/970] selftests: core: add unshare_test to gitignore This executable is missing from the corresponding gitignore file. Add unshare_test to the core gitignore list. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/core/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/core/.gitignore b/tools/testing/selftests/core/.gitignore index 6e6712ce5817..7999361992aa 100644 --- a/tools/testing/selftests/core/.gitignore +++ b/tools/testing/selftests/core/.gitignore @@ -1 +1,2 @@ close_range_test +unshare_test -- GitLab From 45a8897db67d43aad3a17a792fe06a6306f483d6 Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 23:55:15 +0200 Subject: [PATCH 508/970] selftests: exec: update gitignore for load_address The name of the "load_address" objects has been modified, but the corresponding entry in the gitignore file must be updated. Update the load_address entry in the gitignore file to account for the new names, adding an exception to keep on tracking load_address.c. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/exec/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/exec/.gitignore b/tools/testing/selftests/exec/.gitignore index 90c238ba6a4b..a0dc5d4bf733 100644 --- a/tools/testing/selftests/exec/.gitignore +++ b/tools/testing/selftests/exec/.gitignore @@ -9,7 +9,8 @@ execveat.ephemeral execveat.denatured non-regular null-argv -/load_address_* +/load_address.* +!load_address.c /recursion-depth xxxxxxxx* pipe -- GitLab From 65bdebf38e5fac7c56a9e05d3479a707e6dc783c Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Fri, 27 Sep 2024 16:16:03 +0200 Subject: [PATCH 509/970] ACPI: resource: Remove duplicate Asus E1504GAB IRQ override Commit d2aaf1996504 ("ACPI: resource: Add DMI quirks for ASUS Vivobook E1504GA and E1504GAB") does exactly what the subject says, adding DMI matches for both the E1504GA and E1504GAB. But DMI_MATCH() does a substring match, so checking for E1504GA will also match E1504GAB. Drop the unnecessary E1504GAB entry since that is covered already by the E1504GA entry. Fixes: d2aaf1996504 ("ACPI: resource: Add DMI quirks for ASUS Vivobook E1504GA and E1504GAB") Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://patch.msgid.link/20240927141606.66826-1-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/resource.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 8a4726e2eb69..1ff251fd1901 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -511,19 +511,12 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { }, }, { - /* Asus Vivobook E1504GA */ + /* Asus Vivobook E1504GA* */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_BOARD_NAME, "E1504GA"), }, }, - { - /* Asus Vivobook E1504GAB */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"), - }, - }, { /* Asus Vivobook Pro N6506MV */ .matches = { -- GitLab From 63539defee17bf0cbd8e24078cf103efee9c6633 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Fri, 27 Sep 2024 16:16:04 +0200 Subject: [PATCH 510/970] ACPI: resource: Loosen the Asus E1404GAB DMI match to also cover the E1404GA Like other Asus Vivobooks, the Asus Vivobook Go E1404GA has a DSDT describing IRQ 1 as ActiveLow, while the kernel overrides to Edge_High. $ sudo dmesg | grep DMI:.*BIOS [ 0.000000] DMI: ASUSTeK COMPUTER INC. Vivobook Go E1404GA_E1404GA/E1404GA, BIOS E1404GA.302 08/23/2023 $ sudo cp /sys/firmware/acpi/tables/DSDT dsdt.dat $ iasl -d dsdt.dat $ grep -A 30 PS2K dsdt.dsl | grep IRQ -A 1 IRQ (Level, ActiveLow, Exclusive, ) {1} There already is an entry in the irq1_level_low_skip_override[] DMI match table for the "E1404GAB", change this to match on "E1404GA" to cover the E1404GA model as well (DMI_MATCH() does a substring match). Reported-by: Paul Menzel <pmenzel@molgen.mpg.de> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219224 Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://patch.msgid.link/20240927141606.66826-2-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/resource.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 1ff251fd1901..dfe108e2ccde 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -504,10 +504,10 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { }, }, { - /* Asus Vivobook Go E1404GAB */ + /* Asus Vivobook Go E1404GA* */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_BOARD_NAME, "E1404GAB"), + DMI_MATCH(DMI_BOARD_NAME, "E1404GA"), }, }, { -- GitLab From 2f80ce0b78c340e332f04a5801dee5e4ac8cfaeb Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Fri, 27 Sep 2024 16:16:05 +0200 Subject: [PATCH 511/970] ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[] Like other Asus Vivobook models the X1704VAP has its keybopard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard. Add the X1704VAP to the irq1_level_low_skip_override[] quirk table to fix this. Reported-by: Lamome Julien <julien.lamome@wanadoo.fr> Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1078696 Closes: https://lore.kernel.org/all/1226760b-4699-4529-bf57-6423938157a3@wanadoo.fr/ Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://patch.msgid.link/20240927141606.66826-3-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index dfe108e2ccde..8e672790ac51 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -440,6 +440,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), }, }, + { + /* Asus Vivobook X1704VAP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"), + }, + }, { /* Asus ExpertBook B1402CBA */ .matches = { -- GitLab From 056301e7c7c886f96d799edd36f3406cc30e1822 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Fri, 27 Sep 2024 16:16:06 +0200 Subject: [PATCH 512/970] ACPI: resource: Add Asus ExpertBook B2502CVA to irq1_level_low_skip_override[] Like other Asus ExpertBook models the B2502CVA has its keybopard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard. Add the B2502CVA to the irq1_level_low_skip_override[] quirk table to fix this. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217760 Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://patch.msgid.link/20240927141606.66826-4-hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 8e672790ac51..3d74ebe9dbd8 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -510,6 +510,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { DMI_MATCH(DMI_BOARD_NAME, "B2502FBA"), }, }, + { + /* Asus ExpertBook B2502CVA */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"), + }, + }, { /* Asus Vivobook Go E1404GA* */ .matches = { -- GitLab From a36614bf88cd4b43984f24fd960c7aa0e43b5fb7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang <wsa+renesas@sang-engineering.com> Date: Thu, 26 Sep 2024 13:32:41 +0200 Subject: [PATCH 513/970] ASoC: dt-bindings: renesas,rsnd: correct reg-names for R-Car Gen1 The device at 0xffd90000 is named SRU, both in the datasheet and SoC DTSI. Fix the typo in the bindings to avoid the false positive report: sound@ffd90000: reg-names:0: 'sru' is not one of ['scu', 'ssi', 'adg'] Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Rob Herring (Arm) <robh@kernel.org> Link: https://patch.msgid.link/20240926113241.24060-2-wsa+renesas@sang-engineering.com Signed-off-by: Mark Brown <broonie@kernel.org> --- Documentation/devicetree/bindings/sound/renesas,rsnd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml index 3bc93c59535e..6d0d1514cd42 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml @@ -302,7 +302,7 @@ allOf: reg-names: items: enum: - - scu + - sru - ssi - adg # for Gen2/Gen3 -- GitLab From b6e05ba0844139dde138625906015c974c86aa93 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 23 Sep 2024 12:00:13 +0800 Subject: [PATCH 514/970] spi: spi-imx: Fix pm_runtime_set_suspended() with runtime pm enabled It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it. Fixes: 43b6bf406cd0 ("spi: imx: fix runtime pm support for !CONFIG_PM") Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Link: https://patch.msgid.link/20240923040015.3009329-2-ruanjinjie@huawei.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/spi/spi-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 85bd1a82a34e..4c31d36f3130 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1865,8 +1865,8 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx_sdma_exit(spi_imx); out_runtime_pm_put: pm_runtime_dont_use_autosuspend(spi_imx->dev); - pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(spi_imx->dev); + pm_runtime_set_suspended(&pdev->dev); clk_disable_unprepare(spi_imx->clk_ipg); out_put_per: -- GitLab From 67d4a70faa662df07451e83db1546d3ca0695e08 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 23 Sep 2024 12:00:14 +0800 Subject: [PATCH 515/970] spi: spi-cadence: Fix pm_runtime_set_suspended() with runtime pm enabled It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it. Fixes: d36ccd9f7ea4 ("spi: cadence: Runtime pm adaptation") Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Link: https://patch.msgid.link/20240923040015.3009329-3-ruanjinjie@huawei.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/spi/spi-cadence.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index e07e081de5ea..087e748d9cc9 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -678,8 +678,8 @@ static int cdns_spi_probe(struct platform_device *pdev) clk_dis_all: if (!spi_controller_is_target(ctlr)) { - pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); } remove_ctlr: spi_controller_put(ctlr); @@ -701,8 +701,8 @@ static void cdns_spi_remove(struct platform_device *pdev) cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); - pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); spi_unregister_controller(ctlr); } -- GitLab From 3eae4a916fc0eb6f85b5d399e10335dbd24dd765 Mon Sep 17 00:00:00 2001 From: Jinjie Ruan <ruanjinjie@huawei.com> Date: Mon, 23 Sep 2024 12:00:15 +0800 Subject: [PATCH 516/970] spi: spi-cadence: Fix missing spi_controller_is_target() check The spi_controller_is_target() check is missing for pm_runtime_disable() in cdns_spi_remove(), add it. Fixes: b1b90514eaa3 ("spi: spi-cadence: Add support for Slave mode") Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> Link: https://patch.msgid.link/20240923040015.3009329-4-ruanjinjie@huawei.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/spi/spi-cadence.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 087e748d9cc9..3c87d2bf786a 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -701,8 +701,10 @@ static void cdns_spi_remove(struct platform_device *pdev) cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE); - pm_runtime_disable(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); + if (!spi_controller_is_target(ctlr)) { + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + } spi_unregister_controller(ctlr); } -- GitLab From 72455e33173c1a00c0ce93d2b0198eb45d5f4195 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang <shengjiu.wang@nxp.com> Date: Mon, 30 Sep 2024 14:08:28 +0800 Subject: [PATCH 517/970] ASoC: fsl_sai: Enable 'FIFO continue on error' FCONT bit FCONT=1 means On FIFO error, the SAI will continue from the same word that caused the FIFO error to set after the FIFO warning flag has been cleared. Set FCONT bit in control register to avoid the channel swap issue after SAI xrun. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Link: https://patch.msgid.link/1727676508-22830-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/fsl/fsl_sai.c | 5 ++++- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index ab58a4461073..634168d2bb6e 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -613,6 +613,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, val_cr4 |= FSL_SAI_CR4_FRSZ(slots); + /* Set to avoid channel swap */ + val_cr4 |= FSL_SAI_CR4_FCONT; + /* Set to output mode to avoid tri-stated data pins */ if (tx) val_cr4 |= FSL_SAI_CR4_CHMOD; @@ -699,7 +702,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | - FSL_SAI_CR4_CHMOD_MASK, + FSL_SAI_CR4_CHMOD_MASK | FSL_SAI_CR4_FCONT_MASK, val_cr4); regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index dadbd16ee394..9c4d19fe22c6 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -137,6 +137,7 @@ /* SAI Transmit and Receive Configuration 4 Register */ +#define FSL_SAI_CR4_FCONT_MASK BIT(28) #define FSL_SAI_CR4_FCONT BIT(28) #define FSL_SAI_CR4_FCOMB_SHIFT BIT(26) #define FSL_SAI_CR4_FCOMB_SOFT BIT(27) -- GitLab From 1eecd880a3ffb42e8cfbc4895998bdb178449b8b Mon Sep 17 00:00:00 2001 From: Steve French <stfrench@microsoft.com> Date: Mon, 30 Sep 2024 20:03:44 -0500 Subject: [PATCH 518/970] Revert "smb: client: make SHA-512 TFM ephemeral" The original patch causes a crash with signed mounts when using the SMB2.1 dialect RIP: 0010:smb2_calc_signature+0x10e/0x460 [cifs] Code: 46 30 00 00 00 00 49 c7 46 38 00 00 00 00 0f 85 3e 01 00 00 48 8b 83 a8 02 00 00 48 89 85 68 ff ff ff 49 8b b4 24 58 01 00 00 <48> 8b 38 ba 10 00 00 00 e8 55 0f 0c e0 41 89 c7 85 c0 0f 85 44 01 RSP: 0018:ffffb349422fb5c8 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff98028765b800 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff980200f2b100 RDI: 0000000000000000 RBP: ffffb349422fb680 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff980235e37800 R13: ffffb349422fb900 R14: ffff98027c160700 R15: ffff98028765b820 FS: 000074139b98f780(0000) GS:ffff98097b980000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000011cb78006 CR4: 00000000003726f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? show_regs+0x6c/0x80 ? __die+0x24/0x80 ? page_fault_oops+0x175/0x5c0 ? hrtimer_try_to_cancel.part.0+0x55/0xf0 ? do_user_addr_fault+0x4b2/0x870 ? exc_page_fault+0x85/0x1c0 ? asm_exc_page_fault+0x27/0x30 ? smb2_calc_signature+0x10e/0x460 [cifs] ? smb2_calc_signature+0xa7/0x460 [cifs] ? kmem_cache_alloc_noprof+0x101/0x300 smb2_sign_rqst+0xa2/0xe0 [cifs] smb2_setup_request+0x12d/0x240 [cifs] compound_send_recv+0x304/0x1220 [cifs] cifs_send_recv+0x22/0x40 [cifs] SMB2_tcon+0x2d9/0x8c0 [cifs] cifs_get_smb_ses+0x910/0xef0 [cifs] ? cifs_get_smb_ses+0x910/0xef0 [cifs] cifs_mount_get_session+0x6a/0x250 [cifs] Reported-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Suggested-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com> This reverts commit 220d83b52c7d16ec3c168b82f4e6ce59c645f7ab. --- fs/smb/client/cifsencrypt.c | 1 + fs/smb/client/cifsglob.h | 1 + fs/smb/client/sess.c | 2 +- fs/smb/client/smb2misc.c | 28 ++++++++++++++-------------- fs/smb/client/smb2proto.h | 2 +- fs/smb/client/smb2transport.c | 30 +++++++++++++++++++++++++++++- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index 2d851f596a72..464e6ccdfa5f 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -700,6 +700,7 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) cifs_free_hash(&server->secmech.aes_cmac); cifs_free_hash(&server->secmech.hmacsha256); cifs_free_hash(&server->secmech.md5); + cifs_free_hash(&server->secmech.sha512); if (!SERVER_IS_CHAN(server)) { if (server->secmech.enc) { diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 315aac5dec05..da35c160e7dd 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -180,6 +180,7 @@ struct session_key { struct cifs_secmech { struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */ struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */ + struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */ struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */ struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */ diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index 03c0b484a4b5..3216f786908f 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -624,7 +624,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, * to sign packets before we generate the channel signing key * (we sign with the session key) */ - rc = smb3_crypto_shash_allocate(chan->server); + rc = smb311_crypto_shash_allocate(chan->server); if (rc) { cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); mutex_unlock(&ses->session_mutex); diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c index bdeb12ff53e3..f3c4b70b77b9 100644 --- a/fs/smb/client/smb2misc.c +++ b/fs/smb/client/smb2misc.c @@ -906,41 +906,41 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server, || (hdr->Status != cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)))) return 0; + ok: - rc = cifs_alloc_hash("sha512", &sha512); - if (rc) { - cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc); + rc = smb311_crypto_shash_allocate(server); + if (rc) return rc; - } + sha512 = server->secmech.sha512; rc = crypto_shash_init(sha512); if (rc) { - cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc); - goto err_free; + cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); + return rc; } rc = crypto_shash_update(sha512, ses->preauth_sha_hash, SMB2_PREAUTH_HASH_SIZE); if (rc) { - cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc); - goto err_free; + cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); + return rc; } for (i = 0; i < nvec; i++) { rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len); if (rc) { - cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc); - goto err_free; + cifs_dbg(VFS, "%s: Could not update sha512 shash\n", + __func__); + return rc; } } rc = crypto_shash_final(sha512, ses->preauth_sha_hash); if (rc) { - cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc); - goto err_free; + cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n", + __func__); + return rc; } -err_free: - cifs_free_hash(&sha512); return 0; } diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 56a896ff7cd9..c7e1b149877a 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -291,7 +291,7 @@ extern int smb2_validate_and_copy_iov(unsigned int offset, extern void smb2_copy_fs_info_to_kstatfs( struct smb2_fs_full_size_info *pfs_inf, struct kstatfs *kst); -extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server); +extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); extern int smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server, struct kvec *iov, int nvec); diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index f7e04c40d22e..c8bf0000f73b 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -26,7 +26,8 @@ #include "../common/smb2status.h" #include "smb2glob.h" -int smb3_crypto_shash_allocate(struct TCP_Server_Info *server) +static int +smb3_crypto_shash_allocate(struct TCP_Server_Info *server) { struct cifs_secmech *p = &server->secmech; int rc; @@ -45,6 +46,33 @@ int smb3_crypto_shash_allocate(struct TCP_Server_Info *server) return rc; } +int +smb311_crypto_shash_allocate(struct TCP_Server_Info *server) +{ + struct cifs_secmech *p = &server->secmech; + int rc = 0; + + rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256); + if (rc) + return rc; + + rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac); + if (rc) + goto err; + + rc = cifs_alloc_hash("sha512", &p->sha512); + if (rc) + goto err; + + return 0; + +err: + cifs_free_hash(&p->aes_cmac); + cifs_free_hash(&p->hmacsha256); + return rc; +} + + static int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) { -- GitLab From c9432ad5e32f066875b1bf95939c363bc46d6a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> Date: Mon, 30 Sep 2024 22:25:10 +0200 Subject: [PATCH 519/970] cifs: Remove intermediate object of failed create reparse call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CREATE was successful but SMB2_OP_SET_REPARSE failed then remove the intermediate object created by CREATE. Otherwise empty object stay on the server when reparse call failed. This ensures that if the creating of special files is unsupported by the server then no empty file stay on the server as a result of unsupported operation. Fixes: 102466f303ff ("smb: client: allow creating special files via reparse points") Signed-off-by: Pali Rohár <pali@kernel.org> Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/smb2inode.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index b992117377e9..4e9e225520a6 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -1205,9 +1205,12 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data, struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifsFileInfo *cfile; struct inode *new = NULL; + int out_buftype[4] = {}; + struct kvec out_iov[4] = {}; struct kvec in_iov[2]; int cmds[2]; int rc; + int i; oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, SYNCHRONIZE | DELETE | @@ -1228,7 +1231,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data, cmds[1] = SMB2_OP_POSIX_QUERY_INFO; cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, - in_iov, cmds, 2, cfile, NULL, NULL, NULL); + in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); if (!rc) { rc = smb311_posix_get_inode_info(&new, full_path, data, sb, xid); @@ -1237,12 +1240,29 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data, cmds[1] = SMB2_OP_QUERY_INFO; cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, - in_iov, cmds, 2, cfile, NULL, NULL, NULL); + in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); if (!rc) { rc = cifs_get_inode_info(&new, full_path, data, sb, xid, NULL); } } + + + /* + * If CREATE was successful but SMB2_OP_SET_REPARSE failed then + * remove the intermediate object created by CREATE. Otherwise + * empty object stay on the server when reparse call failed. + */ + if (rc && + out_iov[0].iov_base != NULL && out_buftype[0] != CIFS_NO_BUFFER && + ((struct smb2_hdr *)out_iov[0].iov_base)->Status == STATUS_SUCCESS && + (out_iov[1].iov_base == NULL || out_buftype[1] == CIFS_NO_BUFFER || + ((struct smb2_hdr *)out_iov[1].iov_base)->Status != STATUS_SUCCESS)) + smb2_unlink(xid, tcon, full_path, cifs_sb, NULL); + + for (i = 0; i < ARRAY_SIZE(out_buftype); i++) + free_rsp_buf(out_buftype[i], out_iov[i].iov_base); + return rc ? ERR_PTR(rc) : new; } -- GitLab From 394b52462020b6cceff1f7f47fdebd03589574f3 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 18 Sep 2024 20:35:43 +0300 Subject: [PATCH 520/970] drm/i915/gem: fix bitwise and logical AND mixup CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND is an int, defaulting to 250. When the wakeref is non-zero, it's either -1 or a dynamically allocated pointer, depending on CONFIG_DRM_I915_DEBUG_RUNTIME_PM. It's likely that the code works by coincidence with the bitwise AND, but with CONFIG_DRM_I915_DEBUG_RUNTIME_PM=y, there's the off chance that the condition evaluates to false, and intel_wakeref_auto() doesn't get called. Switch to the intended logical AND. v2: Use != to avoid clang -Wconstant-logical-operand (Nathan) Fixes: ad74457a6b5a ("drm/i915/dgfx: Release mmap on rpm suspend") Cc: Matthew Auld <matthew.auld@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Anshuman Gupta <anshuman.gupta@intel.com> Cc: Andi Shyti <andi.shyti@linux.intel.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: stable@vger.kernel.org # v6.1+ Reviewed-by: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> # v1 Link: https://patchwork.freedesktop.org/patch/msgid/643cc0a4d12f47fd8403d42581e83b1e9c4543c7.1726680898.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> (cherry picked from commit 4c1bfe259ed1d2ade826f95d437e1c41b274df04) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 5c72462d1f57..b22e2019768f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -1131,7 +1131,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) GEM_WARN_ON(!i915_ttm_cpu_maps_iomem(bo->resource)); } - if (wakeref & CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND) + if (wakeref && CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND != 0) intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref, msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)); -- GitLab From 6c24a03a61a245fe34d47582898331fa034b6ccd Mon Sep 17 00:00:00 2001 From: Vladimir Oltean <vladimir.oltean@nxp.com> Date: Fri, 13 Sep 2024 23:35:49 +0300 Subject: [PATCH 521/970] net: dsa: improve shutdown sequence Alexander Sverdlin presents 2 problems during shutdown with the lan9303 driver. One is specific to lan9303 and the other just happens to reproduce there. The first problem is that lan9303 is unique among DSA drivers in that it calls dev_get_drvdata() at "arbitrary runtime" (not probe, not shutdown, not remove): phy_state_machine() -> ... -> dsa_user_phy_read() -> ds->ops->phy_read() -> lan9303_phy_read() -> chip->ops->phy_read() -> lan9303_mdio_phy_read() -> dev_get_drvdata() But we never stop the phy_state_machine(), so it may continue to run after dsa_switch_shutdown(). Our common pattern in all DSA drivers is to set drvdata to NULL to suppress the remove() method that may come afterwards. But in this case it will result in an NPD. The second problem is that the way in which we set dp->conduit->dsa_ptr = NULL; is concurrent with receive packet processing. dsa_switch_rcv() checks once whether dev->dsa_ptr is NULL, but afterwards, rather than continuing to use that non-NULL value, dev->dsa_ptr is dereferenced again and again without NULL checks: dsa_conduit_find_user() and many other places. In between dereferences, there is no locking to ensure that what was valid once continues to be valid. Both problems have the common aspect that closing the conduit interface solves them. In the first case, dev_close(conduit) triggers the NETDEV_GOING_DOWN event in dsa_user_netdevice_event() which closes user ports as well. dsa_port_disable_rt() calls phylink_stop(), which synchronously stops the phylink state machine, and ds->ops->phy_read() will thus no longer call into the driver after this point. In the second case, dev_close(conduit) should do this, as per Documentation/networking/driver.rst: | Quiescence | ---------- | | After the ndo_stop routine has been called, the hardware must | not receive or transmit any data. All in flight packets must | be aborted. If necessary, poll or wait for completion of | any reset commands. So it should be sufficient to ensure that later, when we zeroize conduit->dsa_ptr, there will be no concurrent dsa_switch_rcv() call on this conduit. The addition of the netif_device_detach() function is to ensure that ioctls, rtnetlinks and ethtool requests on the user ports no longer propagate down to the driver - we're no longer prepared to handle them. The race condition actually did not exist when commit 0650bf52b31f ("net: dsa: be compatible with masters which unregister on shutdown") first introduced dsa_switch_shutdown(). It was created later, when we stopped unregistering the user interfaces from a bad spot, and we just replaced that sequence with a racy zeroization of conduit->dsa_ptr (one which doesn't ensure that the interfaces aren't up). Reported-by: Alexander Sverdlin <alexander.sverdlin@siemens.com> Closes: https://lore.kernel.org/netdev/2d2e3bba17203c14a5ffdabc174e3b6bbb9ad438.camel@siemens.com/ Closes: https://lore.kernel.org/netdev/c1bf4de54e829111e0e4a70e7bd1cf523c9550ff.camel@siemens.com/ Fixes: ee534378f005 ("net: dsa: fix panic when DSA master device unbinds on shutdown") Reviewed-by: Alexander Sverdlin <alexander.sverdlin@siemens.com> Tested-by: Alexander Sverdlin <alexander.sverdlin@siemens.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://patch.msgid.link/20240913203549.3081071-1-vladimir.oltean@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/dsa/dsa.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 668c729946ea..1664547deffd 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -1577,6 +1577,7 @@ EXPORT_SYMBOL_GPL(dsa_unregister_switch); void dsa_switch_shutdown(struct dsa_switch *ds) { struct net_device *conduit, *user_dev; + LIST_HEAD(close_list); struct dsa_port *dp; mutex_lock(&dsa2_mutex); @@ -1586,10 +1587,16 @@ void dsa_switch_shutdown(struct dsa_switch *ds) rtnl_lock(); + dsa_switch_for_each_cpu_port(dp, ds) + list_add(&dp->conduit->close_list, &close_list); + + dev_close_many(&close_list, true); + dsa_switch_for_each_user_port(dp, ds) { conduit = dsa_port_to_conduit(dp); user_dev = dp->user; + netif_device_detach(user_dev); netdev_upper_dev_unlink(conduit, user_dev); } -- GitLab From 8d095547debdd26583171a6b589acbc9fd76aa9f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada <masahiroy@kernel.org> Date: Tue, 1 Oct 2024 02:02:22 +0900 Subject: [PATCH 522/970] kconfig: clear expr::val_is_valid when allocated Since commit 95573cac25c6 ("kconfig: cache expression values"), xconfig emits a lot of false-positive "unmet direct dependencies" warnings. While conf_read() clears val_is_valid flags, 'make xconfig' calculates symbol values even before the conf_read() call. This is another issue that should be addressed separately, but it has revealed that the val_is_valid field is not initialized. Fixes: 95573cac25c6 ("kconfig: cache expression values") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/kconfig/expr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 78738ef412de..16f92c4a775a 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -47,6 +47,7 @@ static struct expr *expr_lookup(enum expr_type type, void *l, void *r) e->type = type; e->left._initdata = l; e->right._initdata = r; + e->val_is_valid = false; hash_add(expr_hashtable, &e->node, hash); -- GitLab From da724c33b685463720b1c625ac440e894dc57ec0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada <masahiroy@kernel.org> Date: Tue, 1 Oct 2024 02:02:23 +0900 Subject: [PATCH 523/970] kconfig: qconf: move conf_read() before drawing tree pain The constructor of ConfigMainWindow() calls show*View(), which needs to calculate symbol values. conf_read() must be called before that. Fixes: 060e05c3b422 ("kconfig: qconf: remove initial call to conf_changed()") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/kconfig/qconf.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 97fce13e551e..7dba8014ead4 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1505,6 +1505,8 @@ ConfigMainWindow::ConfigMainWindow(void) connect(helpText, &ConfigInfoView::menuSelected, this, &ConfigMainWindow::setMenuLink); + conf_read(NULL); + QString listMode = configSettings->value("/listMode", "symbol").toString(); if (listMode == "single") showSingleView(); @@ -1906,8 +1908,6 @@ int main(int ac, char** av) configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); - conf_read(NULL); - v->show(); configApp->exec(); -- GitLab From e8d4d34df715133c319fabcf63fdec684be75ff8 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann <daniel@iogearbox.net> Date: Mon, 23 Sep 2024 23:22:41 +0200 Subject: [PATCH 524/970] net: Add netif_get_gro_max_size helper for GRO Add a small netif_get_gro_max_size() helper which returns the maximum IPv4 or IPv6 GRO size of the netdevice. We later add a netif_get_gso_max_size() equivalent as well for GSO, so that these helpers can be used consistently instead of open-coded checks. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20240923212242.15669-1-daniel@iogearbox.net Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- include/linux/netdevice.h | 9 +++++++++ net/core/gro.c | 9 ++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e87b5e488325..d571451638de 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -5029,6 +5029,15 @@ void netif_set_tso_max_segs(struct net_device *dev, unsigned int segs); void netif_inherit_tso_max(struct net_device *to, const struct net_device *from); +static inline unsigned int +netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb) +{ + /* pairs with WRITE_ONCE() in netif_set_gro(_ipv4)_max_size() */ + return skb->protocol == htons(ETH_P_IPV6) ? + READ_ONCE(dev->gro_max_size) : + READ_ONCE(dev->gro_ipv4_max_size); +} + static inline bool netif_is_macsec(const struct net_device *dev) { return dev->priv_flags & IFF_MACSEC; diff --git a/net/core/gro.c b/net/core/gro.c index 802b4a062400..d1f44084e978 100644 --- a/net/core/gro.c +++ b/net/core/gro.c @@ -98,7 +98,6 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb) unsigned int headlen = skb_headlen(skb); unsigned int len = skb_gro_len(skb); unsigned int delta_truesize; - unsigned int gro_max_size; unsigned int new_truesize; struct sk_buff *lp; int segs; @@ -112,12 +111,8 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb) if (p->pp_recycle != skb->pp_recycle) return -ETOOMANYREFS; - /* pairs with WRITE_ONCE() in netif_set_gro(_ipv4)_max_size() */ - gro_max_size = p->protocol == htons(ETH_P_IPV6) ? - READ_ONCE(p->dev->gro_max_size) : - READ_ONCE(p->dev->gro_ipv4_max_size); - - if (unlikely(p->len + len >= gro_max_size || NAPI_GRO_CB(skb)->flush)) + if (unlikely(p->len + len >= netif_get_gro_max_size(p->dev, p) || + NAPI_GRO_CB(skb)->flush)) return -E2BIG; if (unlikely(p->len + len >= GRO_LEGACY_MAX_SIZE)) { -- GitLab From e609c959a939660c7519895f853dfa5624c6827a Mon Sep 17 00:00:00 2001 From: Daniel Borkmann <daniel@iogearbox.net> Date: Mon, 23 Sep 2024 23:22:42 +0200 Subject: [PATCH 525/970] net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size Commit 24ab059d2ebd ("net: check dev->gso_max_size in gso_features_check()") added a dev->gso_max_size test to gso_features_check() in order to fall back to GSO when needed. This was added as it was noticed that some drivers could misbehave if TSO packets get too big. However, the check doesn't respect dev->gso_ipv4_max_size limit. For instance, a device could be configured with BIG TCP for IPv4, but not IPv6. Therefore, add a netif_get_gso_max_size() equivalent to netif_get_gro_max_size() and use the helper to respect both limits before falling back to GSO engine. Fixes: 24ab059d2ebd ("net: check dev->gso_max_size in gso_features_check()") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20240923212242.15669-2-daniel@iogearbox.net Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- include/linux/netdevice.h | 9 +++++++++ net/core/dev.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d571451638de..4d20c776a4ff 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -5038,6 +5038,15 @@ netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb) READ_ONCE(dev->gro_ipv4_max_size); } +static inline unsigned int +netif_get_gso_max_size(const struct net_device *dev, const struct sk_buff *skb) +{ + /* pairs with WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */ + return skb->protocol == htons(ETH_P_IPV6) ? + READ_ONCE(dev->gso_max_size) : + READ_ONCE(dev->gso_ipv4_max_size); +} + static inline bool netif_is_macsec(const struct net_device *dev) { return dev->priv_flags & IFF_MACSEC; diff --git a/net/core/dev.c b/net/core/dev.c index cd479f5f22f6..74cf78a6b512 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3512,7 +3512,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb, if (gso_segs > READ_ONCE(dev->gso_max_segs)) return features & ~NETIF_F_GSO_MASK; - if (unlikely(skb->len >= READ_ONCE(dev->gso_max_size))) + if (unlikely(skb->len >= netif_get_gso_max_size(dev, skb))) return features & ~NETIF_F_GSO_MASK; if (!skb_shinfo(skb)->gso_type) { -- GitLab From 45c0de18ff2dc9af01236380404bbd6a46502c69 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski <olek2@wp.pl> Date: Mon, 23 Sep 2024 23:49:49 +0200 Subject: [PATCH 526/970] net: ethernet: lantiq_etop: fix memory disclosure When applying padding, the buffer is not zeroed, which results in memory disclosure. The mentioned data is observed on the wire. This patch uses skb_put_padto() to pad Ethernet frames properly. The mentioned function zeroes the expanded buffer. In case the packet cannot be padded it is silently dropped. Statistics are also not incremented. This driver does not support statistics in the old 32-bit format or the new 64-bit format. These will be added in the future. In its current form, the patch should be easily backported to stable versions. Ethernet MACs on Amazon-SE and Danube cannot do padding of the packets in hardware, so software padding must be applied. Fixes: 504d4721ee8e ("MIPS: Lantiq: Add ethernet driver") Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Link: https://patch.msgid.link/20240923214949.231511-2-olek2@wp.pl Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- drivers/net/ethernet/lantiq_etop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 3c289bfe0a09..7179271f63b6 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -481,7 +481,9 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev) unsigned long flags; u32 byte_offset; - len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + if (skb_put_padto(skb, ETH_ZLEN)) + return NETDEV_TX_OK; + len = skb->len; if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { netdev_err(dev, "tx ring full\n"); -- GitLab From 93ef6ee5c20e9330477930ec6347672c9e0cf5a6 Mon Sep 17 00:00:00 2001 From: Jiawen Wu <jiawenwu@trustnetic.com> Date: Tue, 24 Sep 2024 10:28:57 +0800 Subject: [PATCH 527/970] net: pcs: xpcs: fix the wrong register that was written back The value is read from the register TXGBE_RX_GEN_CTL3, and it should be written back to TXGBE_RX_GEN_CTL3 when it changes some fields. Cc: stable@vger.kernel.org Fixes: f629acc6f210 ("net: pcs: xpcs: support to switch mode for Wangxun NICs") Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Reported-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Link: https://patch.msgid.link/20240924022857.865422-1-jiawenwu@trustnetic.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- drivers/net/pcs/pcs-xpcs-wx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pcs/pcs-xpcs-wx.c b/drivers/net/pcs/pcs-xpcs-wx.c index 19c75886f070..5f5cd3596cb8 100644 --- a/drivers/net/pcs/pcs-xpcs-wx.c +++ b/drivers/net/pcs/pcs-xpcs-wx.c @@ -109,7 +109,7 @@ static void txgbe_pma_config_1g(struct dw_xpcs *xpcs) txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0); val = txgbe_read_pma(xpcs, TXGBE_RX_GEN_CTL3); val = u16_replace_bits(val, 0x4, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0); - txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val); + txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL3, val); txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20); txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46); -- GitLab From a1477dc87dc4996dcf65a4893d4e2c3a6b593002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= <csokas.bence@prolan.hu> Date: Tue, 24 Sep 2024 11:37:04 +0200 Subject: [PATCH 528/970] net: fec: Restart PPS after link state change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On link state change, the controller gets reset, causing PPS to drop out. Re-enable PPS if it was enabled before the controller reset. Fixes: 6605b730c061 ("FEC: Add time stamping code and a PTP hardware clock") Signed-off-by: Csókás, Bence <csokas.bence@prolan.hu> Link: https://patch.msgid.link/20240924093705.2897329-1-csokas.bence@prolan.hu Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- drivers/net/ethernet/freescale/fec.h | 6 +++++ drivers/net/ethernet/freescale/fec_main.c | 11 ++++++++- drivers/net/ethernet/freescale/fec_ptp.c | 30 +++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index a19cb2a786fd..0552317a2554 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -691,10 +691,16 @@ struct fec_enet_private { /* XDP BPF Program */ struct bpf_prog *xdp_prog; + struct { + int pps_enable; + } ptp_saved_state; + u64 ethtool_stats[]; }; void fec_ptp_init(struct platform_device *pdev, int irq_idx); +void fec_ptp_restore_state(struct fec_enet_private *fep); +void fec_ptp_save_state(struct fec_enet_private *fep); void fec_ptp_stop(struct platform_device *pdev); void fec_ptp_start_cyclecounter(struct net_device *ndev); int fec_ptp_set(struct net_device *ndev, struct kernel_hwtstamp_config *config, diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index acbb627d51bf..31ebf6a4f973 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1077,6 +1077,8 @@ fec_restart(struct net_device *ndev) u32 rcntl = OPT_FRAME_SIZE | 0x04; u32 ecntl = FEC_ECR_ETHEREN; + fec_ptp_save_state(fep); + /* Whack a reset. We should wait for this. * For i.MX6SX SOC, enet use AXI bus, we use disable MAC * instead of reset MAC itself. @@ -1244,8 +1246,10 @@ fec_restart(struct net_device *ndev) writel(ecntl, fep->hwp + FEC_ECNTRL); fec_enet_active_rxring(ndev); - if (fep->bufdesc_ex) + if (fep->bufdesc_ex) { fec_ptp_start_cyclecounter(ndev); + fec_ptp_restore_state(fep); + } /* Enable interrupts we wish to service */ if (fep->link) @@ -1336,6 +1340,8 @@ fec_stop(struct net_device *ndev) netdev_err(ndev, "Graceful transmit stop did not complete!\n"); } + fec_ptp_save_state(fep); + /* Whack a reset. We should wait for this. * For i.MX6SX SOC, enet use AXI bus, we use disable MAC * instead of reset MAC itself. @@ -1366,6 +1372,9 @@ fec_stop(struct net_device *ndev) val = readl(fep->hwp + FEC_ECNTRL); val |= FEC_ECR_EN1588; writel(val, fep->hwp + FEC_ECNTRL); + + fec_ptp_start_cyclecounter(ndev); + fec_ptp_restore_state(fep); } } diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 4cffda363a14..df1ef023493b 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -764,6 +764,36 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx) schedule_delayed_work(&fep->time_keep, HZ); } +void fec_ptp_save_state(struct fec_enet_private *fep) +{ + unsigned long flags; + + spin_lock_irqsave(&fep->tmreg_lock, flags); + + fep->ptp_saved_state.pps_enable = fep->pps_enable; + + spin_unlock_irqrestore(&fep->tmreg_lock, flags); +} + +/* Restore PTP functionality after a reset */ +void fec_ptp_restore_state(struct fec_enet_private *fep) +{ + unsigned long flags; + + spin_lock_irqsave(&fep->tmreg_lock, flags); + + /* Reset turned it off, so adjust our status flag */ + fep->pps_enable = 0; + + spin_unlock_irqrestore(&fep->tmreg_lock, flags); + + /* Restart PPS if needed */ + if (fep->ptp_saved_state.pps_enable) { + /* Re-enable PPS */ + fec_ptp_enable_pps(fep, 1); + } +} + void fec_ptp_stop(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); -- GitLab From d9335d0232d2da605585eea1518ac6733518f938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cs=C3=B3k=C3=A1s=2C=20Bence?= <csokas.bence@prolan.hu> Date: Tue, 24 Sep 2024 11:37:06 +0200 Subject: [PATCH 529/970] net: fec: Reload PTP registers after link-state change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On link-state change, the controller gets reset, which clears all PTP registers, including PHC time, calibrated clock correction values etc. For correct IEEE 1588 operation we need to restore these after the reset. Fixes: 6605b730c061 ("FEC: Add time stamping code and a PTP hardware clock") Signed-off-by: Csókás, Bence <csokas.bence@prolan.hu> Reviewed-by: Wei Fang <wei.fang@nxp.com> Link: https://patch.msgid.link/20240924093705.2897329-2-csokas.bence@prolan.hu Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- drivers/net/ethernet/freescale/fec.h | 3 +++ drivers/net/ethernet/freescale/fec_ptp.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 0552317a2554..1cca0425d493 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -693,6 +693,9 @@ struct fec_enet_private { struct { int pps_enable; + u64 ns_sys, ns_phc; + u32 at_corr; + u8 at_inc_corr; } ptp_saved_state; u64 ethtool_stats[]; diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index df1ef023493b..a4eb6edb850a 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -767,24 +767,44 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx) void fec_ptp_save_state(struct fec_enet_private *fep) { unsigned long flags; + u32 atime_inc_corr; spin_lock_irqsave(&fep->tmreg_lock, flags); fep->ptp_saved_state.pps_enable = fep->pps_enable; + fep->ptp_saved_state.ns_phc = timecounter_read(&fep->tc); + fep->ptp_saved_state.ns_sys = ktime_get_ns(); + + fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR); + atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK; + fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET); + spin_unlock_irqrestore(&fep->tmreg_lock, flags); } /* Restore PTP functionality after a reset */ void fec_ptp_restore_state(struct fec_enet_private *fep) { + u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK; unsigned long flags; + u32 counter; + u64 ns; spin_lock_irqsave(&fep->tmreg_lock, flags); /* Reset turned it off, so adjust our status flag */ fep->pps_enable = 0; + writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR); + atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET; + writel(atime_inc, fep->hwp + FEC_ATIME_INC); + + ns = ktime_get_ns() - fep->ptp_saved_state.ns_sys + fep->ptp_saved_state.ns_phc; + counter = ns & fep->cc.mask; + writel(counter, fep->hwp + FEC_ATIME); + timecounter_init(&fep->tc, &fep->cc, ns); + spin_unlock_irqrestore(&fep->tmreg_lock, flags); /* Restart PPS if needed */ -- GitLab From ff35237de5f00a8dd777cddb7ca433a41f503872 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Mon, 30 Sep 2024 19:40:52 +0300 Subject: [PATCH 530/970] drm/xe/compat: remove unused i915_gpu_error.h The last user of the compat header was removed in commit d6b933912df0 ("drm/i915/dmc: convert intel_dmc_print_error_state() to drm_printer"). Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930164052.3862911-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- .../drm/xe/compat-i915-headers/i915_gpu_error.h | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 drivers/gpu/drm/xe/compat-i915-headers/i915_gpu_error.h diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_gpu_error.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_gpu_error.h deleted file mode 100644 index 98e9dd78f670..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_gpu_error.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef _I915_GPU_ERROR_H_ -#define _I915_GPU_ERROR_H_ - -struct drm_i915_error_state_buf; - -__printf(2, 3) -static inline void -i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...) -{ -} - -#endif -- GitLab From 1910bd470a0acea01b88722be61f0dfa29089730 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven <geert+renesas@glider.be> Date: Tue, 24 Sep 2024 11:59:09 +0200 Subject: [PATCH 531/970] net: microchip: Make FDMA config symbol invisible There is no need to ask the user about enabling Microchip FDMA functionality, as all drivers that use it select the FDMA symbol. Hence make the symbol invisible, unless when compile-testing. Fixes: 30e48a75df9c6ead ("net: microchip: add FDMA library") Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Daniel Machon <daniel.machon@microchip.com> Link: https://patch.msgid.link/8e2bcd8899c417a962b7ee3f75b29f35b25d7933.1727171879.git.geert+renesas@glider.be Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- drivers/net/ethernet/microchip/fdma/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/fdma/Kconfig b/drivers/net/ethernet/microchip/fdma/Kconfig index 59159ad6701a..ec228c061351 100644 --- a/drivers/net/ethernet/microchip/fdma/Kconfig +++ b/drivers/net/ethernet/microchip/fdma/Kconfig @@ -6,7 +6,7 @@ if NET_VENDOR_MICROCHIP config FDMA - bool "FDMA API" + bool "FDMA API" if COMPILE_TEST help Provides the basic FDMA functionality for multiple Microchip switchcores. -- GitLab From e9d591b16c0ed8489aedc86cac237145815d14dc Mon Sep 17 00:00:00 2001 From: Roger Quadros <rogerq@kernel.org> Date: Tue, 24 Sep 2024 15:28:48 +0300 Subject: [PATCH 532/970] net: ethernet: ti: cpsw_ale: Fix warning on some platforms The number of register fields cannot be assumed to be ALE_FIELDS_MAX as some platforms can have lesser fields. Solve this by embedding the actual number of fields available in platform data and use that instead of ALE_FIELDS_MAX. Gets rid of the below warning on BeagleBone Black [ 1.007735] WARNING: CPU: 0 PID: 33 at drivers/base/regmap/regmap.c:1208 regmap_field_init+0x88/0x9c [ 1.007802] invalid empty mask defined [ 1.007812] Modules linked in: [ 1.007842] CPU: 0 UID: 0 PID: 33 Comm: kworker/u4:3 Not tainted 6.11.0-01459-g508403ab7b74-dirty #840 [ 1.007867] Hardware name: Generic AM33XX (Flattened Device Tree) [ 1.007890] Workqueue: events_unbound deferred_probe_work_func [ 1.007935] Call trace: [ 1.007957] unwind_backtrace from show_stack+0x10/0x14 [ 1.007999] show_stack from dump_stack_lvl+0x50/0x64 [ 1.008033] dump_stack_lvl from __warn+0x70/0x124 [ 1.008077] __warn from warn_slowpath_fmt+0x194/0x1a8 [ 1.008113] warn_slowpath_fmt from regmap_field_init+0x88/0x9c [ 1.008154] regmap_field_init from devm_regmap_field_alloc+0x48/0x64 [ 1.008193] devm_regmap_field_alloc from cpsw_ale_create+0xfc/0x320 [ 1.008251] cpsw_ale_create from cpsw_init_common+0x214/0x354 [ 1.008286] cpsw_init_common from cpsw_probe+0x4ac/0xb88 Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Closes: https://lore.kernel.org/netdev/CAMuHMdUf-tKRDzkz2_m8qdFTFutefddU0NTratVrEjRTzA3yQQ@mail.gmail.com/ Fixes: 11cbcfeaa79e ("net: ethernet: ti: cpsw_ale: use regfields for number of Entries and Policers") Signed-off-by: Roger Quadros <rogerq@kernel.org> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20240924-am65-cpsw-multi-rx-fix-v1-1-0ca3fa9a1398@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- drivers/net/ethernet/ti/cpsw_ale.c | 12 +++++++++++- drivers/net/ethernet/ti/cpsw_ale.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 0d5d8917c70b..8d02d2b21429 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -96,6 +96,7 @@ enum { * @features: features supported by ALE * @tbl_entries: number of ALE entries * @reg_fields: pointer to array of register field configuration + * @num_fields: number of fields in the reg_fields array * @nu_switch_ale: NU Switch ALE * @vlan_entry_tbl: ALE vlan entry fields description tbl */ @@ -104,6 +105,7 @@ struct cpsw_ale_dev_id { u32 features; u32 tbl_entries; const struct reg_field *reg_fields; + int num_fields; bool nu_switch_ale; const struct ale_entry_fld *vlan_entry_tbl; }; @@ -1400,6 +1402,7 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = { .dev_id = "cpsw", .tbl_entries = 1024, .reg_fields = ale_fields_cpsw, + .num_fields = ARRAY_SIZE(ale_fields_cpsw), .vlan_entry_tbl = vlan_entry_cpsw, }, { @@ -1407,12 +1410,14 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = { .dev_id = "66ak2h-xgbe", .tbl_entries = 2048, .reg_fields = ale_fields_cpsw, + .num_fields = ARRAY_SIZE(ale_fields_cpsw), .vlan_entry_tbl = vlan_entry_cpsw, }, { .dev_id = "66ak2el", .features = CPSW_ALE_F_STATUS_REG, .reg_fields = ale_fields_cpsw_nu, + .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu), .nu_switch_ale = true, .vlan_entry_tbl = vlan_entry_nu, }, @@ -1421,6 +1426,7 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = { .features = CPSW_ALE_F_STATUS_REG, .tbl_entries = 64, .reg_fields = ale_fields_cpsw_nu, + .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu), .nu_switch_ale = true, .vlan_entry_tbl = vlan_entry_nu, }, @@ -1429,6 +1435,7 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = { .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING, .tbl_entries = 64, .reg_fields = ale_fields_cpsw_nu, + .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu), .nu_switch_ale = true, .vlan_entry_tbl = vlan_entry_nu, }, @@ -1436,12 +1443,14 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = { .dev_id = "j721e-cpswxg", .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING, .reg_fields = ale_fields_cpsw_nu, + .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu), .vlan_entry_tbl = vlan_entry_k3_cpswxg, }, { .dev_id = "am64-cpswxg", .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING, .reg_fields = ale_fields_cpsw_nu, + .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu), .vlan_entry_tbl = vlan_entry_k3_cpswxg, .tbl_entries = 512, }, @@ -1477,7 +1486,7 @@ static int cpsw_ale_regfield_init(struct cpsw_ale *ale) struct regmap *regmap = ale->regmap; int i; - for (i = 0; i < ALE_FIELDS_MAX; i++) { + for (i = 0; i < ale->params.num_fields; i++) { ale->fields[i] = devm_regmap_field_alloc(dev, regmap, reg_fields[i]); if (IS_ERR(ale->fields[i])) { @@ -1503,6 +1512,7 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params) params->ale_entries = ale_dev_id->tbl_entries; params->nu_switch_ale = ale_dev_id->nu_switch_ale; params->reg_fields = ale_dev_id->reg_fields; + params->num_fields = ale_dev_id->num_fields; ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL); if (!ale) diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index 1e4e9a3dd234..87b7d1b3a34a 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h @@ -24,6 +24,7 @@ struct cpsw_ale_params { */ bool nu_switch_ale; const struct reg_field *reg_fields; + int num_fields; const char *dev_id; unsigned long bus_freq; }; -- GitLab From c20029db28399ecc50e556964eaba75c43b1e2f1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@google.com> Date: Tue, 24 Sep 2024 15:02:56 +0000 Subject: [PATCH 533/970] net: avoid potential underflow in qdisc_pkt_len_init() with UFO After commit 7c6d2ecbda83 ("net: be more gentle about silly gso requests coming from user") virtio_net_hdr_to_skb() had sanity check to detect malicious attempts from user space to cook a bad GSO packet. Then commit cf9acc90c80ec ("net: virtio_net_hdr_to_skb: count transport header in UFO") while fixing one issue, allowed user space to cook a GSO packet with the following characteristic : IPv4 SKB_GSO_UDP, gso_size=3, skb->len = 28. When this packet arrives in qdisc_pkt_len_init(), we end up with hdr_len = 28 (IPv4 header + UDP header), matching skb->len Then the following sets gso_segs to 0 : gso_segs = DIV_ROUND_UP(skb->len - hdr_len, shinfo->gso_size); Then later we set qdisc_skb_cb(skb)->pkt_len to back to zero :/ qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len; This leads to the following crash in fq_codel [1] qdisc_pkt_len_init() is best effort, we only want an estimation of the bytes sent on the wire, not crashing the kernel. This patch is fixing this particular issue, a following one adds more sanity checks for another potential bug. [1] [ 70.724101] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 70.724561] #PF: supervisor read access in kernel mode [ 70.724561] #PF: error_code(0x0000) - not-present page [ 70.724561] PGD 10ac61067 P4D 10ac61067 PUD 107ee2067 PMD 0 [ 70.724561] Oops: Oops: 0000 [#1] SMP NOPTI [ 70.724561] CPU: 11 UID: 0 PID: 2163 Comm: b358537762 Not tainted 6.11.0-virtme #991 [ 70.724561] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 70.724561] RIP: 0010:fq_codel_enqueue (net/sched/sch_fq_codel.c:120 net/sched/sch_fq_codel.c:168 net/sched/sch_fq_codel.c:230) sch_fq_codel [ 70.724561] Code: 24 08 49 c1 e1 06 44 89 7c 24 18 45 31 ed 45 31 c0 31 ff 89 44 24 14 4c 03 8b 90 01 00 00 eb 04 39 ca 73 37 4d 8b 39 83 c7 01 <49> 8b 17 49 89 11 41 8b 57 28 45 8b 5f 34 49 c7 07 00 00 00 00 49 All code ======== 0: 24 08 and $0x8,%al 2: 49 c1 e1 06 shl $0x6,%r9 6: 44 89 7c 24 18 mov %r15d,0x18(%rsp) b: 45 31 ed xor %r13d,%r13d e: 45 31 c0 xor %r8d,%r8d 11: 31 ff xor %edi,%edi 13: 89 44 24 14 mov %eax,0x14(%rsp) 17: 4c 03 8b 90 01 00 00 add 0x190(%rbx),%r9 1e: eb 04 jmp 0x24 20: 39 ca cmp %ecx,%edx 22: 73 37 jae 0x5b 24: 4d 8b 39 mov (%r9),%r15 27: 83 c7 01 add $0x1,%edi 2a:* 49 8b 17 mov (%r15),%rdx <-- trapping instruction 2d: 49 89 11 mov %rdx,(%r9) 30: 41 8b 57 28 mov 0x28(%r15),%edx 34: 45 8b 5f 34 mov 0x34(%r15),%r11d 38: 49 c7 07 00 00 00 00 movq $0x0,(%r15) 3f: 49 rex.WB Code starting with the faulting instruction =========================================== 0: 49 8b 17 mov (%r15),%rdx 3: 49 89 11 mov %rdx,(%r9) 6: 41 8b 57 28 mov 0x28(%r15),%edx a: 45 8b 5f 34 mov 0x34(%r15),%r11d e: 49 c7 07 00 00 00 00 movq $0x0,(%r15) 15: 49 rex.WB [ 70.724561] RSP: 0018:ffff95ae85e6fb90 EFLAGS: 00000202 [ 70.724561] RAX: 0000000002000000 RBX: ffff95ae841de000 RCX: 0000000000000000 [ 70.724561] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001 [ 70.724561] RBP: ffff95ae85e6fbf8 R08: 0000000000000000 R09: ffff95b710a30000 [ 70.724561] R10: 0000000000000000 R11: bdf289445ce31881 R12: ffff95ae85e6fc58 [ 70.724561] R13: 0000000000000000 R14: 0000000000000040 R15: 0000000000000000 [ 70.724561] FS: 000000002c5c1380(0000) GS:ffff95bd7fcc0000(0000) knlGS:0000000000000000 [ 70.724561] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 70.724561] CR2: 0000000000000000 CR3: 000000010c568000 CR4: 00000000000006f0 [ 70.724561] Call Trace: [ 70.724561] <TASK> [ 70.724561] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434) [ 70.724561] ? page_fault_oops (arch/x86/mm/fault.c:715) [ 70.724561] ? exc_page_fault (./arch/x86/include/asm/irqflags.h:26 ./arch/x86/include/asm/irqflags.h:87 ./arch/x86/include/asm/irqflags.h:147 arch/x86/mm/fault.c:1489 arch/x86/mm/fault.c:1539) [ 70.724561] ? asm_exc_page_fault (./arch/x86/include/asm/idtentry.h:623) [ 70.724561] ? fq_codel_enqueue (net/sched/sch_fq_codel.c:120 net/sched/sch_fq_codel.c:168 net/sched/sch_fq_codel.c:230) sch_fq_codel [ 70.724561] dev_qdisc_enqueue (net/core/dev.c:3784) [ 70.724561] __dev_queue_xmit (net/core/dev.c:3880 (discriminator 2) net/core/dev.c:4390 (discriminator 2)) [ 70.724561] ? irqentry_enter (kernel/entry/common.c:237) [ 70.724561] ? sysvec_apic_timer_interrupt (./arch/x86/include/asm/hardirq.h:74 (discriminator 2) arch/x86/kernel/apic/apic.c:1043 (discriminator 2) arch/x86/kernel/apic/apic.c:1043 (discriminator 2)) [ 70.724561] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:58 (discriminator 4)) [ 70.724561] ? asm_sysvec_apic_timer_interrupt (./arch/x86/include/asm/idtentry.h:702) [ 70.724561] ? virtio_net_hdr_to_skb.constprop.0 (./include/linux/virtio_net.h:129 (discriminator 1)) [ 70.724561] packet_sendmsg (net/packet/af_packet.c:3145 (discriminator 1) net/packet/af_packet.c:3177 (discriminator 1)) [ 70.724561] ? _raw_spin_lock_bh (./arch/x86/include/asm/atomic.h:107 (discriminator 4) ./include/linux/atomic/atomic-arch-fallback.h:2170 (discriminator 4) ./include/linux/atomic/atomic-instrumented.h:1302 (discriminator 4) ./include/asm-generic/qspinlock.h:111 (discriminator 4) ./include/linux/spinlock.h:187 (discriminator 4) ./include/linux/spinlock_api_smp.h:127 (discriminator 4) kernel/locking/spinlock.c:178 (discriminator 4)) [ 70.724561] ? netdev_name_node_lookup_rcu (net/core/dev.c:325 (discriminator 1)) [ 70.724561] __sys_sendto (net/socket.c:730 (discriminator 1) net/socket.c:745 (discriminator 1) net/socket.c:2210 (discriminator 1)) [ 70.724561] ? __sys_setsockopt (./include/linux/file.h:34 net/socket.c:2355) [ 70.724561] __x64_sys_sendto (net/socket.c:2222 (discriminator 1) net/socket.c:2218 (discriminator 1) net/socket.c:2218 (discriminator 1)) [ 70.724561] do_syscall_64 (arch/x86/entry/common.c:52 (discriminator 1) arch/x86/entry/common.c:83 (discriminator 1)) [ 70.724561] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) [ 70.724561] RIP: 0033:0x41ae09 Fixes: cf9acc90c80ec ("net: virtio_net_hdr_to_skb: count transport header in UFO") Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Jonathan Davies <jonathan.davies@nutanix.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Reviewed-by: Jonathan Davies <jonathan.davies@nutanix.com> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 74cf78a6b512..7d3d34a3bdf5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3758,7 +3758,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) sizeof(_tcphdr), &_tcphdr); if (likely(th)) hdr_len += __tcp_hdrlen(th); - } else { + } else if (shinfo->gso_type & SKB_GSO_UDP_L4) { struct udphdr _udphdr; if (skb_header_pointer(skb, hdr_len, -- GitLab From ab9a9a9e9647392a19e7a885b08000e89c86b535 Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@google.com> Date: Tue, 24 Sep 2024 15:02:57 +0000 Subject: [PATCH 534/970] net: add more sanity checks to qdisc_pkt_len_init() One path takes care of SKB_GSO_DODGY, assuming skb->len is bigger than hdr_len. virtio_net_hdr_to_skb() does not fully dissect TCP headers, it only make sure it is at least 20 bytes. It is possible for an user to provide a malicious 'GSO' packet, total length of 80 bytes. - 20 bytes of IPv4 header - 60 bytes TCP header - a small gso_size like 8 virtio_net_hdr_to_skb() would declare this packet as a normal GSO packet, because it would see 40 bytes of payload, bigger than gso_size. We need to make detect this case to not underflow qdisc_skb_cb(skb)->pkt_len. Fixes: 1def9238d4aa ("net_sched: more precise pkt_len computation") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/core/dev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 7d3d34a3bdf5..ea5fbcd133ae 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3766,10 +3766,14 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) hdr_len += sizeof(struct udphdr); } - if (shinfo->gso_type & SKB_GSO_DODGY) - gso_segs = DIV_ROUND_UP(skb->len - hdr_len, - shinfo->gso_size); + if (unlikely(shinfo->gso_type & SKB_GSO_DODGY)) { + int payload = skb->len - hdr_len; + /* Malicious packet. */ + if (payload <= 0) + return; + gso_segs = DIV_ROUND_UP(payload, shinfo->gso_size); + } qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len; } } -- GitLab From c625154993d0d24a962b1830cd5ed92adda2cf86 Mon Sep 17 00:00:00 2001 From: Pu Lehui <pulehui@huawei.com> Date: Sat, 31 Aug 2024 07:15:20 +0000 Subject: [PATCH 535/970] drivers/perf: riscv: Align errno for unsupported perf event RISC-V perf driver does not yet support PERF_TYPE_BREAKPOINT. It would be more appropriate to return -EOPNOTSUPP or -ENOENT for this type in pmu_sbi_event_map. Considering that other implementations return -ENOENT for unsupported perf types, let's synchronize this behavior. Due to this reason, a riscv bpf testcases perf_skip fail. Meanwhile, align that behavior to the rest of proper place. Signed-off-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Atish Patra <atishp@rivosinc.com> Fixes: 9b3e150e310e ("RISC-V: Add a simple platform driver for RISC-V legacy perf") Fixes: 16d3b1af0944 ("perf: RISC-V: Check standard event availability") Fixes: e9991434596f ("RISC-V: Add perf platform driver based on SBI PMU extension") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240831071520.1630360-1-pulehui@huaweicloud.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> --- drivers/perf/riscv_pmu_legacy.c | 4 ++-- drivers/perf/riscv_pmu_sbi.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/perf/riscv_pmu_legacy.c b/drivers/perf/riscv_pmu_legacy.c index 04487ad7fba0..93c8e0fdb589 100644 --- a/drivers/perf/riscv_pmu_legacy.c +++ b/drivers/perf/riscv_pmu_legacy.c @@ -22,13 +22,13 @@ static int pmu_legacy_ctr_get_idx(struct perf_event *event) struct perf_event_attr *attr = &event->attr; if (event->attr.type != PERF_TYPE_HARDWARE) - return -EOPNOTSUPP; + return -ENOENT; if (attr->config == PERF_COUNT_HW_CPU_CYCLES) return RISCV_PMU_LEGACY_CYCLE; else if (attr->config == PERF_COUNT_HW_INSTRUCTIONS) return RISCV_PMU_LEGACY_INSTRET; else - return -EOPNOTSUPP; + return -ENOENT; } /* For legacy config & counter index are same */ diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 5c39fbd8ed04..391ca1422cae 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -309,7 +309,7 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata) ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); } else if (ret.error == SBI_ERR_NOT_SUPPORTED) { /* This event cannot be monitored by any counter */ - edata->event_idx = -EINVAL; + edata->event_idx = -ENOENT; } } @@ -556,7 +556,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig) } break; default: - ret = -EINVAL; + ret = -ENOENT; break; } -- GitLab From 0d24852bd71ec85ca0016b6d6fc997e6a3381552 Mon Sep 17 00:00:00 2001 From: Omar Sandoval <osandov@fb.com> Date: Mon, 30 Sep 2024 11:55:00 -0700 Subject: [PATCH 536/970] iov_iter: fix advancing slot in iter_folioq_get_pages() iter_folioq_get_pages() decides to advance to the next folioq slot when it has reached the end of the current folio. However, it is checking offset, which is the beginning of the current part, instead of iov_offset, which is adjusted to the end of the current part, so it doesn't advance the slot when it's supposed to. As a result, on the next iteration, we'll use the same folio with an out-of-bounds offset and return an unrelated page. This manifested as various crashes and other failures in 9pfs in drgn's VM testing setup and BPF CI. Fixes: db0aa2e9566f ("mm: Define struct folio_queue and ITER_FOLIOQ to handle a sequence of folios") Link: https://lore.kernel.org/linux-fsdevel/20240923183432.1876750-1-chantr4@gmail.com/ Tested-by: Manu Bretelle <chantr4@gmail.com> Signed-off-by: Omar Sandoval <osandov@fb.com> Link: https://lore.kernel.org/r/cbaf141ba6c0e2e209717d02746584072844841a.1727722269.git.osandov@fb.com Tested-by: Eduard Zingerman <eddyz87@gmail.com> Tested-by: Leon Romanovsky <leon@kernel.org> Tested-by: Joey Gouly <joey.gouly@arm.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Christian Brauner <brauner@kernel.org> --- lib/iov_iter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 97003155bfac..1abb32c0da50 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1033,7 +1033,7 @@ static ssize_t iter_folioq_get_pages(struct iov_iter *iter, if (maxpages == 0 || extracted >= maxsize) break; - if (offset >= fsize) { + if (iov_offset >= fsize) { iov_offset = 0; slot++; if (slot == folioq_nr_slots(folioq) && folioq->next) { -- GitLab From 4c1b56671b68ffcbe6b78308bfdda6bcce6491ae Mon Sep 17 00:00:00 2001 From: Shenwei Wang <shenwei.wang@nxp.com> Date: Tue, 24 Sep 2024 15:54:24 -0500 Subject: [PATCH 537/970] net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increase the timeout for checking the busy bit of the VLAN Tag register from 10µs to 500ms. This change is necessary to accommodate scenarios where Energy Efficient Ethernet (EEE) is enabled. Overnight testing revealed that when EEE is active, the busy bit can remain set for up to approximately 300ms. The new 500ms timeout provides a safety margin. Fixes: ed64639bc1e0 ("net: stmmac: Add support for VLAN Rx filtering") Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com> Link: https://patch.msgid.link/20240924205424.573913-1-shenwei.wang@nxp.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index a1858f083eef..e65a65666cc1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/ethtool.h> #include <linux/io.h> +#include <linux/iopoll.h> #include "stmmac.h" #include "stmmac_pcs.h" #include "dwmac4.h" @@ -471,7 +472,7 @@ static int dwmac4_write_vlan_filter(struct net_device *dev, u8 index, u32 data) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; - int i, timeout = 10; + int ret; u32 val; if (index >= hw->num_vlan) @@ -487,16 +488,15 @@ static int dwmac4_write_vlan_filter(struct net_device *dev, writel(val, ioaddr + GMAC_VLAN_TAG); - for (i = 0; i < timeout; i++) { - val = readl(ioaddr + GMAC_VLAN_TAG); - if (!(val & GMAC_VLAN_TAG_CTRL_OB)) - return 0; - udelay(1); + ret = readl_poll_timeout(ioaddr + GMAC_VLAN_TAG, val, + !(val & GMAC_VLAN_TAG_CTRL_OB), + 1000, 500000); + if (ret) { + netdev_err(dev, "Timeout accessing MAC_VLAN_Tag_Filter\n"); + return -EBUSY; } - netdev_err(dev, "Timeout accessing MAC_VLAN_Tag_Filter\n"); - - return -EBUSY; + return 0; } static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev, -- GitLab From a3f9a74d210bf5b80046a840d3e9949b5fe0a67c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov <dmitry.torokhov@gmail.com> Date: Tue, 1 Oct 2024 03:54:05 -0700 Subject: [PATCH 538/970] Revert "Input: Add driver for PixArt PS/2 touchpad" This reverts commit 740ff03d7238214a318cdcfd96dec51832b053d2 because current PixArt detection is too greedy and claims devices that are not PixArt. Reported-by: Benjamin Tissoires <bentiss@kernel.org> Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2314756 Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/mouse/Kconfig | 12 -- drivers/input/mouse/Makefile | 1 - drivers/input/mouse/pixart_ps2.c | 300 ----------------------------- drivers/input/mouse/pixart_ps2.h | 36 ---- drivers/input/mouse/psmouse-base.c | 17 -- drivers/input/mouse/psmouse.h | 3 +- 6 files changed, 1 insertion(+), 368 deletions(-) delete mode 100644 drivers/input/mouse/pixart_ps2.c delete mode 100644 drivers/input/mouse/pixart_ps2.h diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 8a27a20d04b0..833b643f0616 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -69,18 +69,6 @@ config MOUSE_PS2_LOGIPS2PP If unsure, say Y. -config MOUSE_PS2_PIXART - bool "PixArt PS/2 touchpad protocol extension" if EXPERT - default y - depends on MOUSE_PS2 - help - This driver supports the PixArt PS/2 touchpad found in some - laptops. - Say Y here if you have a PixArt PS/2 TouchPad connected to - your system. - - If unsure, say Y. - config MOUSE_PS2_SYNAPTICS bool "Synaptics PS/2 mouse protocol extension" if EXPERT default y diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 563029551529..a1336d5bee6f 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -32,7 +32,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o -psmouse-$(CONFIG_MOUSE_PS2_PIXART) += pixart_ps2.o psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o diff --git a/drivers/input/mouse/pixart_ps2.c b/drivers/input/mouse/pixart_ps2.c deleted file mode 100644 index 1993fc760d7b..000000000000 --- a/drivers/input/mouse/pixart_ps2.c +++ /dev/null @@ -1,300 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Pixart Touchpad Controller 1336U PS2 driver - * - * Author: Jon Xie <jon_xie@pixart.com> - * Jay Lee <jay_lee@pixart.com> - * Further cleanup and restructuring by: - * Binbin Zhou <zhoubinbin@loongson.cn> - * - * Copyright (C) 2021-2024 Pixart Imaging. - * Copyright (C) 2024 Loongson Technology Corporation Limited. - * - */ - -#include <linux/bitfield.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/input.h> -#include <linux/input/mt.h> -#include <linux/libps2.h> -#include <linux/serio.h> -#include <linux/slab.h> - -#include "pixart_ps2.h" - -static int pixart_read_tp_mode(struct ps2dev *ps2dev, u8 *mode) -{ - int error; - u8 param[1] = { 0 }; - - error = ps2_command(ps2dev, param, PIXART_CMD_REPORT_FORMAT); - if (error) - return error; - - *mode = param[0] == 1 ? PIXART_MODE_ABS : PIXART_MODE_REL; - - return 0; -} - -static int pixart_read_tp_type(struct ps2dev *ps2dev, u8 *type) -{ - int error; - u8 param[3] = { 0 }; - - param[0] = 0x0a; - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - if (error) - return error; - - param[0] = 0x0; - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - if (error) - return error; - - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - if (error) - return error; - - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - if (error) - return error; - - param[0] = 0x03; - error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - if (error) - return error; - - error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); - if (error) - return error; - - *type = param[0] == 0x0e ? PIXART_TYPE_TOUCHPAD : PIXART_TYPE_CLICKPAD; - - return 0; -} - -static void pixart_reset(struct psmouse *psmouse) -{ - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); - - /* according to PixArt, 100ms is required for the upcoming reset */ - msleep(100); - psmouse_reset(psmouse); -} - -static void pixart_process_packet(struct psmouse *psmouse) -{ - struct pixart_data *priv = psmouse->private; - struct input_dev *dev = psmouse->dev; - const u8 *pkt = psmouse->packet; - unsigned int contact_cnt = FIELD_GET(CONTACT_CNT_MASK, pkt[0]); - unsigned int i, id, abs_x, abs_y; - bool tip; - - for (i = 0; i < contact_cnt; i++) { - const u8 *p = &pkt[i * 3]; - - id = FIELD_GET(SLOT_ID_MASK, p[3]); - abs_y = FIELD_GET(ABS_Y_MASK, p[3]) << 8 | p[1]; - abs_x = FIELD_GET(ABS_X_MASK, p[3]) << 8 | p[2]; - - if (i == PIXART_MAX_FINGERS - 1) - tip = pkt[14] & BIT(1); - else - tip = pkt[3 * contact_cnt + 1] & BIT(2 * i + 1); - - input_mt_slot(dev, id); - if (input_mt_report_slot_state(dev, MT_TOOL_FINGER, tip)) { - input_report_abs(dev, ABS_MT_POSITION_Y, abs_y); - input_report_abs(dev, ABS_MT_POSITION_X, abs_x); - } - } - - input_mt_sync_frame(dev); - - if (priv->type == PIXART_TYPE_CLICKPAD) { - input_report_key(dev, BTN_LEFT, pkt[0] & 0x03); - } else { - input_report_key(dev, BTN_LEFT, pkt[0] & BIT(0)); - input_report_key(dev, BTN_RIGHT, pkt[0] & BIT(1)); - } - - input_sync(dev); -} - -static psmouse_ret_t pixart_protocol_handler(struct psmouse *psmouse) -{ - u8 *pkt = psmouse->packet; - u8 contact_cnt; - - if ((pkt[0] & 0x8c) != 0x80) - return PSMOUSE_BAD_DATA; - - contact_cnt = FIELD_GET(CONTACT_CNT_MASK, pkt[0]); - if (contact_cnt > PIXART_MAX_FINGERS) - return PSMOUSE_BAD_DATA; - - if (contact_cnt == PIXART_MAX_FINGERS && - psmouse->pktcnt < psmouse->pktsize) { - return PSMOUSE_GOOD_DATA; - } - - if (contact_cnt == 0 && psmouse->pktcnt < 5) - return PSMOUSE_GOOD_DATA; - - if (psmouse->pktcnt < 3 * contact_cnt + 2) - return PSMOUSE_GOOD_DATA; - - pixart_process_packet(psmouse); - - return PSMOUSE_FULL_PACKET; -} - -static void pixart_disconnect(struct psmouse *psmouse) -{ - pixart_reset(psmouse); - kfree(psmouse->private); - psmouse->private = NULL; -} - -static int pixart_reconnect(struct psmouse *psmouse) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - u8 mode; - int error; - - pixart_reset(psmouse); - - error = pixart_read_tp_mode(ps2dev, &mode); - if (error) - return error; - - if (mode != PIXART_MODE_ABS) - return -EIO; - - error = ps2_command(ps2dev, NULL, PIXART_CMD_SWITCH_PROTO); - if (error) - return error; - - return 0; -} - -static int pixart_set_input_params(struct input_dev *dev, - struct pixart_data *priv) -{ - /* No relative support */ - __clear_bit(EV_REL, dev->evbit); - __clear_bit(REL_X, dev->relbit); - __clear_bit(REL_Y, dev->relbit); - __clear_bit(BTN_MIDDLE, dev->keybit); - - /* Buttons */ - __set_bit(EV_KEY, dev->evbit); - __set_bit(BTN_LEFT, dev->keybit); - if (priv->type == PIXART_TYPE_CLICKPAD) - __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); - else - __set_bit(BTN_RIGHT, dev->keybit); - - /* Absolute position */ - input_set_abs_params(dev, ABS_X, 0, PIXART_PAD_WIDTH, 0, 0); - input_set_abs_params(dev, ABS_Y, 0, PIXART_PAD_HEIGHT, 0, 0); - - input_set_abs_params(dev, ABS_MT_POSITION_X, - 0, PIXART_PAD_WIDTH, 0, 0); - input_set_abs_params(dev, ABS_MT_POSITION_Y, - 0, PIXART_PAD_HEIGHT, 0, 0); - - return input_mt_init_slots(dev, PIXART_MAX_FINGERS, INPUT_MT_POINTER); -} - -static int pixart_query_hardware(struct ps2dev *ps2dev, u8 *mode, u8 *type) -{ - int error; - - error = pixart_read_tp_type(ps2dev, type); - if (error) - return error; - - error = pixart_read_tp_mode(ps2dev, mode); - if (error) - return error; - - return 0; -} - -int pixart_detect(struct psmouse *psmouse, bool set_properties) -{ - u8 type; - int error; - - pixart_reset(psmouse); - - error = pixart_read_tp_type(&psmouse->ps2dev, &type); - if (error) - return error; - - if (set_properties) { - psmouse->vendor = "PixArt"; - psmouse->name = (type == PIXART_TYPE_TOUCHPAD) ? - "touchpad" : "clickpad"; - } - - return 0; -} - -int pixart_init(struct psmouse *psmouse) -{ - int error; - struct pixart_data *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - psmouse->private = priv; - pixart_reset(psmouse); - - error = pixart_query_hardware(&psmouse->ps2dev, - &priv->mode, &priv->type); - if (error) { - psmouse_err(psmouse, "init: Unable to query PixArt touchpad hardware.\n"); - goto err_exit; - } - - /* Relative mode follows standard PS/2 mouse protocol */ - if (priv->mode != PIXART_MODE_ABS) { - error = -EIO; - goto err_exit; - } - - /* Set absolute mode */ - error = ps2_command(&psmouse->ps2dev, NULL, PIXART_CMD_SWITCH_PROTO); - if (error) { - psmouse_err(psmouse, "init: Unable to initialize PixArt absolute mode.\n"); - goto err_exit; - } - - error = pixart_set_input_params(psmouse->dev, priv); - if (error) { - psmouse_err(psmouse, "init: Unable to set input params.\n"); - goto err_exit; - } - - psmouse->pktsize = 15; - psmouse->protocol_handler = pixart_protocol_handler; - psmouse->disconnect = pixart_disconnect; - psmouse->reconnect = pixart_reconnect; - psmouse->cleanup = pixart_reset; - /* resync is not supported yet */ - psmouse->resync_time = 0; - - return 0; - -err_exit: - pixart_reset(psmouse); - kfree(priv); - psmouse->private = NULL; - return error; -} diff --git a/drivers/input/mouse/pixart_ps2.h b/drivers/input/mouse/pixart_ps2.h deleted file mode 100644 index 47a1d040f2d1..000000000000 --- a/drivers/input/mouse/pixart_ps2.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _PIXART_PS2_H -#define _PIXART_PS2_H - -#include "psmouse.h" - -#define PIXART_PAD_WIDTH 1023 -#define PIXART_PAD_HEIGHT 579 -#define PIXART_MAX_FINGERS 4 - -#define PIXART_CMD_REPORT_FORMAT 0x01d8 -#define PIXART_CMD_SWITCH_PROTO 0x00de - -#define PIXART_MODE_REL 0 -#define PIXART_MODE_ABS 1 - -#define PIXART_TYPE_CLICKPAD 0 -#define PIXART_TYPE_TOUCHPAD 1 - -#define CONTACT_CNT_MASK GENMASK(6, 4) - -#define SLOT_ID_MASK GENMASK(2, 0) -#define ABS_Y_MASK GENMASK(5, 4) -#define ABS_X_MASK GENMASK(7, 6) - -struct pixart_data { - u8 mode; - u8 type; - int x_max; - int y_max; -}; - -int pixart_detect(struct psmouse *psmouse, bool set_properties); -int pixart_init(struct psmouse *psmouse); - -#endif /* _PIXART_PS2_H */ diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 5a4defe9cf32..a2c9f7144864 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -36,7 +36,6 @@ #include "focaltech.h" #include "vmmouse.h" #include "byd.h" -#include "pixart_ps2.h" #define DRIVER_DESC "PS/2 mouse driver" @@ -906,15 +905,6 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = byd_detect, .init = byd_init, }, -#endif -#ifdef CONFIG_MOUSE_PS2_PIXART - { - .type = PSMOUSE_PIXART, - .name = "PixArtPS/2", - .alias = "pixart", - .detect = pixart_detect, - .init = pixart_init, - }, #endif { .type = PSMOUSE_AUTO, @@ -1182,13 +1172,6 @@ static int psmouse_extensions(struct psmouse *psmouse, return ret; } - /* Try PixArt touchpad */ - if (max_proto > PSMOUSE_IMEX && - psmouse_try_protocol(psmouse, PSMOUSE_PIXART, &max_proto, - set_properties, true)) { - return PSMOUSE_PIXART; - } - if (max_proto > PSMOUSE_IMEX) { if (psmouse_try_protocol(psmouse, PSMOUSE_GENPS, &max_proto, set_properties, true)) diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 23f7fa7243cb..4d8acfe0d82a 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -69,7 +69,6 @@ enum psmouse_type { PSMOUSE_BYD, PSMOUSE_SYNAPTICS_SMBUS, PSMOUSE_ELANTECH_SMBUS, - PSMOUSE_PIXART, PSMOUSE_AUTO /* This one should always be last */ }; @@ -95,7 +94,7 @@ struct psmouse { const char *vendor; const char *name; const struct psmouse_protocol *protocol; - unsigned char packet[16]; + unsigned char packet[8]; unsigned char badbyte; unsigned char pktcnt; unsigned char pktsize; -- GitLab From c4a14f6d9d17ad1e41a36182dd3b8a5fd91efbd7 Mon Sep 17 00:00:00 2001 From: Anton Danilov <littlesmilingcloud@gmail.com> Date: Wed, 25 Sep 2024 02:51:59 +0300 Subject: [PATCH 539/970] ipv4: ip_gre: Fix drops of small packets in ipgre_xmit Regression Description: Depending on the options specified for the GRE tunnel device, small packets may be dropped. This occurs because the pskb_network_may_pull function fails due to the packet's insufficient length. For example, if only the okey option is specified for the tunnel device, original (before encapsulation) packets smaller than 28 bytes (including the IPv4 header) will be dropped. This happens because the required length is calculated relative to the network header, not the skb->head. Here is how the required length is computed and checked: * The pull_len variable is set to 28 bytes, consisting of: * IPv4 header: 20 bytes * GRE header with Key field: 8 bytes * The pskb_network_may_pull function adds the network offset, shifting the checkable space further to the beginning of the network header and extending it to the beginning of the packet. As a result, the end of the checkable space occurs beyond the actual end of the packet. Instead of ensuring that 28 bytes are present in skb->head, the function is requesting these 28 bytes starting from the network header. For small packets, this requested length exceeds the actual packet size, causing the check to fail and the packets to be dropped. This issue affects both locally originated and forwarded packets in DMVPN-like setups. How to reproduce (for local originated packets): ip link add dev gre1 type gre ikey 1.9.8.4 okey 1.9.8.4 \ local <your-ip> remote 0.0.0.0 ip link set mtu 1400 dev gre1 ip link set up dev gre1 ip address add 192.168.13.1/24 dev gre1 ip neighbor add 192.168.13.2 lladdr <remote-ip> dev gre1 ping -s 1374 -c 10 192.168.13.2 tcpdump -vni gre1 tcpdump -vni <your-ext-iface> 'ip proto 47' ip -s -s -d link show dev gre1 Solution: Use the pskb_may_pull function instead the pskb_network_may_pull. Fixes: 80d875cfc9d3 ("ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit()") Signed-off-by: Anton Danilov <littlesmilingcloud@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20240924235158.106062-1-littlesmilingcloud@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/ipv4/ip_gre.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5f6fd382af38..f1f31ebfc793 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -662,11 +662,11 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, if (skb_cow_head(skb, 0)) goto free_skb; - tnl_params = (const struct iphdr *)skb->data; - - if (!pskb_network_may_pull(skb, pull_len)) + if (!pskb_may_pull(skb, pull_len)) goto free_skb; + tnl_params = (const struct iphdr *)skb->data; + /* ip_tunnel_xmit() needs skb->data pointing to gre header. */ skb_pull(skb, pull_len); skb_reset_mac_header(skb); -- GitLab From 5afc29ba44fdd1bcbad4e07246c395d946301580 Mon Sep 17 00:00:00 2001 From: Bard Liao <yung-chuan.liao@linux.intel.com> Date: Tue, 1 Oct 2024 14:17:37 +0800 Subject: [PATCH 540/970] ASoC: Intel: soc-acpi-intel-rpl-match: add missing empty item MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no links_num in struct snd_soc_acpi_mach {}, and we test !link->num_adr as a condition to end the loop in hda_sdw_machine_select(). So an empty item in struct snd_soc_acpi_link_adr array is required. Fixes: 65ab45b90656 ("ASoC: Intel: soc-acpi: Add match entries for some cs42l43 laptops") Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20241001061738.34854-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index bc8817633b81..b83ac2e6337c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -198,6 +198,7 @@ static const struct snd_soc_acpi_link_adr rpl_cs42l43_l0[] = { .num_adr = ARRAY_SIZE(cs42l43_0_adr), .adr_d = cs42l43_0_adr, }, + {} }; static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { -- GitLab From cccb586f513cd999b9dade82e5a25b711d90a76f Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@opensource.cirrus.com> Date: Tue, 1 Oct 2024 14:17:38 +0800 Subject: [PATCH 541/970] ASoC: Intel: soc-acpi: arl: Fix some missing empty terminators Fixes: c0524067653d ("ASoC: Intel: soc-acpi: arl: Add match entries for new cs42l43 laptops") Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://patch.msgid.link/20241001061738.34854-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/intel/common/soc-acpi-intel-arl-match.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-arl-match.c b/sound/soc/intel/common/soc-acpi-intel-arl-match.c index c97c961187dd..072b8486d072 100644 --- a/sound/soc/intel/common/soc-acpi-intel-arl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-arl-match.c @@ -191,6 +191,7 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = { .num_adr = ARRAY_SIZE(cs42l43_0_adr), .adr_d = cs42l43_0_adr, }, + {} }; static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = { @@ -199,6 +200,7 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = { .num_adr = ARRAY_SIZE(cs42l43_2_adr), .adr_d = cs42l43_2_adr, }, + {} }; static const struct snd_soc_acpi_link_adr arl_cs42l43_l2_cs35l56_l3[] = { -- GitLab From 162d9b5d2308c7e48efbc97d36babbf4d73b2c61 Mon Sep 17 00:00:00 2001 From: Alexander Dahl <ada@thorsis.com> Date: Thu, 26 Sep 2024 11:03:56 +0200 Subject: [PATCH 542/970] spi: atmel-quadspi: Fix wrong register value written to MR aq->mr should go to MR, nothing else. Fixes: 329ca3eed4a9 ("spi: atmel-quadspi: Avoid overwriting delay register settings") Signed-off-by: Alexander Dahl <ada@thorsis.com> Link: https://lore.kernel.org/linux-spi/20240926-macarena-wincing-7c4995487a29@thorsis.com/T/#u Link: https://patch.msgid.link/20240926090356.105789-1-ada@thorsis.com Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/spi/atmel-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index 4f288f07e38f..95cdfc28361e 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -377,7 +377,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, */ if (!(aq->mr & QSPI_MR_SMM)) { aq->mr |= QSPI_MR_SMM; - atmel_qspi_write(aq->scr, aq, QSPI_MR); + atmel_qspi_write(aq->mr, aq, QSPI_MR); } /* Clear pending interrupts */ -- GitLab From 9abe390e689f4f5c23c5f507754f8678431b4f72 Mon Sep 17 00:00:00 2001 From: Mark Rutland <mark.rutland@arm.com> Date: Fri, 27 Sep 2024 11:18:38 +0100 Subject: [PATCH 543/970] arm64: Force position-independent veneers Certain portions of code always need to be position-independent regardless of CONFIG_RELOCATABLE, including code which is executed in an idmap or which is executed before relocations are applied. In some kernel configurations the LLD linker generates position-dependent veneers for such code, and when executed these result in early boot-time failures. Marc Zyngier encountered a boot failure resulting from this when building a (particularly cursed) configuration with LLVM, as he reported to the list: https://lore.kernel.org/linux-arm-kernel/86wmjwvatn.wl-maz@kernel.org/ In Marc's kernel configuration, the .head.text and .rodata.text sections end up more than 128MiB apart, requiring a veneer to branch between the two: | [mark@lakrids:~/src/linux]% usekorg 14.1.0 aarch64-linux-objdump -t vmlinux | grep -w _text | ffff800080000000 g .head.text 0000000000000000 _text | [mark@lakrids:~/src/linux]% usekorg 14.1.0 aarch64-linux-objdump -t vmlinux | grep -w primary_entry | ffff8000889df0e0 g .rodata.text 000000000000006c primary_entry, ... consequently, LLD inserts a position-dependent veneer for the branch from _stext (in .head.text) to primary_entry (in .rodata.text): | ffff800080000000 <_text>: | ffff800080000000: fa405a4d ccmp x18, #0x0, #0xd, pl // pl = nfrst | ffff800080000004: 14003fff b ffff800080010000 <__AArch64AbsLongThunk_primary_entry> ... | ffff800080010000 <__AArch64AbsLongThunk_primary_entry>: | ffff800080010000: 58000050 ldr x16, ffff800080010008 <__AArch64AbsLongThunk_primary_entry+0x8> | ffff800080010004: d61f0200 br x16 | ffff800080010008: 889df0e0 .word 0x889df0e0 | ffff80008001000c: ffff8000 .word 0xffff8000 ... and as this is executed early in boot before the kernel is mapped in TTBR1 this results in a silent boot failure. Fix this by passing '--pic-veneer' to the linker, which will cause the linker to use position-independent veneers, e.g. | ffff800080000000 <_text>: | ffff800080000000: fa405a4d ccmp x18, #0x0, #0xd, pl // pl = nfrst | ffff800080000004: 14003fff b ffff800080010000 <__AArch64ADRPThunk_primary_entry> ... | ffff800080010000 <__AArch64ADRPThunk_primary_entry>: | ffff800080010000: f004e3f0 adrp x16, ffff800089c8f000 <__idmap_text_start> | ffff800080010004: 91038210 add x16, x16, #0xe0 | ffff800080010008: d61f0200 br x16 I've opted to pass '--pic-veneer' unconditionally, as: * In addition to solving the boot failure, these sequences are generally nicer as they require fewer instructions and don't need to perform data accesses. * While the position-independent veneer sequences have a limited +/-2GiB range, this is not a new restriction. Even kernels built with CONFIG_RELOCATABLE=n are limited to 2GiB in size as we have several structues using 32-bit relative offsets and PPREL32 relocations, which are similarly limited to +/-2GiB in range. These include extable entries, jump table entries, and alt_instr entries. * GNU LD defaults to using position-independent veneers, and supports the same '--pic-veneer' option, so this change is not expected to adversely affect GNU LD. I've tested with GNU LD 2.30 to 2.42 inclusive and LLVM 13.0.1 to 19.1.0 inclusive, using the kernel.org binaries from: * https://mirrors.edge.kernel.org/pub/tools/crosstool/ * https://mirrors.edge.kernel.org/pub/tools/llvm/ Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reported-by: Marc Zyngier <maz@kernel.org> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Will Deacon <will@kernel.org> Acked-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Nathan Chancellor <nathan@kernel.org> Link: https://lore.kernel.org/r/20240927101838.3061054-1-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- arch/arm64/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index b058c4803efb..9efd3f37c2fd 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -10,7 +10,7 @@ # # Copyright (C) 1995-2001 by Russell King -LDFLAGS_vmlinux :=--no-undefined -X +LDFLAGS_vmlinux :=--no-undefined -X --pic-veneer ifeq ($(CONFIG_RELOCATABLE), y) # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour -- GitLab From 924725707d80bc2588cefafef76ff3f164d299bc Mon Sep 17 00:00:00 2001 From: Mark Rutland <mark.rutland@arm.com> Date: Mon, 30 Sep 2024 12:17:04 +0100 Subject: [PATCH 544/970] arm64: cputype: Add Neoverse-N3 definitions Add cputype definitions for Neoverse-N3. These will be used for errata detection in subsequent patches. These values can be found in Table A-261 ("MIDR_EL1 bit descriptions") in issue 02 of the Neoverse-N3 TRM, which can be found at: https://developer.arm.com/documentation/107997/0000/?lang=en Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: James Morse <james.morse@arm.com> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20240930111705.3352047-2-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 5a7dfeb8e8eb..488f8e751349 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -94,6 +94,7 @@ #define ARM_CPU_PART_NEOVERSE_V3 0xD84 #define ARM_CPU_PART_CORTEX_X925 0xD85 #define ARM_CPU_PART_CORTEX_A725 0xD87 +#define ARM_CPU_PART_NEOVERSE_N3 0xD8E #define APM_CPU_PART_XGENE 0x000 #define APM_CPU_VAR_POTENZA 0x00 @@ -176,6 +177,7 @@ #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) +#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) -- GitLab From 081eb7932c2b244f63317a982c5e3990e2c7fbdd Mon Sep 17 00:00:00 2001 From: Mark Rutland <mark.rutland@arm.com> Date: Mon, 30 Sep 2024 12:17:05 +0100 Subject: [PATCH 545/970] arm64: errata: Expand speculative SSBS workaround once more A number of Arm Ltd CPUs suffer from errata whereby an MSR to the SSBS special-purpose register does not affect subsequent speculative instructions, permitting speculative store bypassing for a window of time. We worked around this for a number of CPUs in commits: * 7187bb7d0b5c7dfa ("arm64: errata: Add workaround for Arm errata 3194386 and 3312417") * 75b3c43eab594bfb ("arm64: errata: Expand speculative SSBS workaround") * 145502cac7ea70b5 ("arm64: errata: Expand speculative SSBS workaround (again)") Since then, a (hopefully final) batch of updates have been published, with two more affected CPUs. For the affected CPUs the existing mitigation is sufficient, as described in their respective Software Developer Errata Notice (SDEN) documents: * Cortex-A715 (MP148) SDEN v15.0, erratum 3456084 https://developer.arm.com/documentation/SDEN-2148827/1500/ * Neoverse-N3 (MP195) SDEN v5.0, erratum 3456111 https://developer.arm.com/documentation/SDEN-3050973/0500/ Enable the existing mitigation by adding the relevant MIDRs to erratum_spec_ssbs_list, and update silicon-errata.rst and the Kconfig text accordingly. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: James Morse <james.morse@arm.com> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20240930111705.3352047-3-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- Documentation/arch/arm64/silicon-errata.rst | 4 ++++ arch/arm64/Kconfig | 2 ++ arch/arm64/kernel/cpu_errata.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 9eb5e70b4888..ae45a409f76f 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -146,6 +146,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | @@ -186,6 +188,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V1 | #1619801 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3e29b44d2d7b..ae495cc848c5 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1097,6 +1097,7 @@ config ARM64_ERRATUM_3194386 * ARM Cortex-A78C erratum 3324346 * ARM Cortex-A78C erratum 3324347 * ARM Cortex-A710 erratam 3324338 + * ARM Cortex-A715 errartum 3456084 * ARM Cortex-A720 erratum 3456091 * ARM Cortex-A725 erratum 3456106 * ARM Cortex-X1 erratum 3324344 @@ -1107,6 +1108,7 @@ config ARM64_ERRATUM_3194386 * ARM Cortex-X925 erratum 3324334 * ARM Neoverse-N1 erratum 3324349 * ARM Neoverse N2 erratum 3324339 + * ARM Neoverse-N3 erratum 3456111 * ARM Neoverse-V1 erratum 3324341 * ARM Neoverse V2 erratum 3324336 * ARM Neoverse-V3 erratum 3312417 diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index dfefbdf4073a..d9b9ec2bd6ff 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -439,6 +439,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), @@ -449,6 +450,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), -- GitLab From b3d6121eaeb22aee8a02f46706745b1968cc0292 Mon Sep 17 00:00:00 2001 From: Mark Rutland <mark.rutland@arm.com> Date: Mon, 30 Sep 2024 13:04:48 +0100 Subject: [PATCH 546/970] arm64: fix selection of HAVE_DYNAMIC_FTRACE_WITH_ARGS The Kconfig logic to select HAVE_DYNAMIC_FTRACE_WITH_ARGS is incorrect, and HAVE_DYNAMIC_FTRACE_WITH_ARGS may be selected when it is not supported by the combination of clang and GNU LD, resulting in link-time errors: aarch64-linux-gnu-ld: .init.data has both ordered [`__patchable_function_entries' in init/main.o] and unordered [`.meminit.data' in mm/sparse.o] sections aarch64-linux-gnu-ld: final link failed: bad value ... which can be seen when building with CC=clang using a binutils version older than 2.36. We originally fixed that in commit: 45bd8951806eb5e8 ("arm64: Improve HAVE_DYNAMIC_FTRACE_WITH_REGS selection for clang") ... by splitting the "select HAVE_DYNAMIC_FTRACE_WITH_ARGS" statement into separete CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS and GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS options which individually select HAVE_DYNAMIC_FTRACE_WITH_ARGS. Subsequently we accidentally re-introduced the common "select HAVE_DYNAMIC_FTRACE_WITH_ARGS" statement in commit: 26299b3f6ba26bfc ("ftrace: arm64: move from REGS to ARGS") ... then we removed it again in commit: 68a63a412d18bd2e ("arm64: Fix build with CC=clang, CONFIG_FTRACE=y and CONFIG_STACK_TRACER=y") ... then we accidentally re-introduced it again in commit: 2aa6ac03516d078c ("arm64: ftrace: Add direct call support") Fix this for the third time by keeping the unified select statement and making this depend onf either GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS or CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS. This is more consistent with usual style and less likely to go wrong in future. Fixes: 2aa6ac03516d ("arm64: ftrace: Add direct call support") Cc: <stable@vger.kernel.org> # 6.4.x Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20240930120448.3352564-1-mark.rutland@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- arch/arm64/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index ae495cc848c5..fd9df6dcc593 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -200,7 +200,8 @@ config ARM64 select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_ARGS \ - if $(cc-option,-fpatchable-function-entry=2) + if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \ + CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS) select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \ if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ @@ -286,12 +287,10 @@ config CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS def_bool CC_IS_CLANG # https://github.com/ClangBuiltLinux/linux/issues/1507 depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600)) - select HAVE_DYNAMIC_FTRACE_WITH_ARGS config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS def_bool CC_IS_GCC depends on $(cc-option,-fpatchable-function-entry=2) - select HAVE_DYNAMIC_FTRACE_WITH_ARGS config 64BIT def_bool y -- GitLab From a04dae6fa4fc56c6a29cd40e133ef6a77f2c7e4e Mon Sep 17 00:00:00 2001 From: Dan Carpenter <dan.carpenter@linaro.org> Date: Mon, 30 Sep 2024 10:19:58 +0300 Subject: [PATCH 547/970] ALSA: silence integer wrapping warning This patch doesn't change runtime at all, it's just for kernel hardening. The "count" here comes from the user and on 32bit systems, it leads to integer wrapping when we pass it to compute_user_elem_size(): alloc_size = compute_user_elem_size(private_size, count); However, the integer over is harmless because later "count" is checked when we pass it to snd_ctl_new(): err = snd_ctl_new(&kctl, count, access, file); These days as part of kernel hardening we're trying to avoid integer overflows when they affect size_t type. So to avoid the integer overflow copy the check from snd_ctl_new() and do it at the start of the snd_ctl_elem_add() function as well. Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> Reviewed-by: Jaroslav Kysela <perex@perex.cz> Link: https://patch.msgid.link/5457e8c1-01ff-4dd9-b49c-15b817f65ee7@stanley.mountain Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/core/control.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/control.c b/sound/core/control.c index 4f55f64c42e1..82b9d14f4ee3 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1641,6 +1641,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, count = info->owner; if (count == 0) count = 1; + if (count > MAX_CONTROL_COUNT) + return -EINVAL; /* Arrange access permissions if needed. */ access = info->access; -- GitLab From f6023535b52f5a066fa52fcfd0dc51c7f7894ce6 Mon Sep 17 00:00:00 2001 From: Chang Yu <marcus.yu.56@gmail.com> Date: Mon, 30 Sep 2024 23:31:52 -0700 Subject: [PATCH 548/970] netfs: Fix a KMSAN uninit-value error in netfs_clear_buffer Use folioq_count instead of folioq_nr_slots to fix a KMSAN uninit-value error in netfs_clear_buffer Signed-off-by: Chang Yu <marcus.yu.56@gmail.com> Link: https://lore.kernel.org/r/ZvuXWC2bYpvQsWgS@gmail.com Fixes: cd0277ed0c18 ("netfs: Use new folio_queue data type and iterator instead of xarray iter") Acked-by: David Howells <dhowells@redhat.com> Reported-by: syzbot+921873345a95f4dae7e9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=921873345a95f4dae7e9 Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/netfs/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/netfs/misc.c b/fs/netfs/misc.c index 63280791de3b..78fe5796b2b2 100644 --- a/fs/netfs/misc.c +++ b/fs/netfs/misc.c @@ -102,7 +102,7 @@ void netfs_clear_buffer(struct netfs_io_request *rreq) while ((p = rreq->buffer)) { rreq->buffer = p->next; - for (int slot = 0; slot < folioq_nr_slots(p); slot++) { + for (int slot = 0; slot < folioq_count(p); slot++) { struct folio *folio = folioq_folio(p, slot); if (!folio) continue; -- GitLab From 78fee4198bb4d29cf82c457086d07e009955a682 Mon Sep 17 00:00:00 2001 From: Vincent Donnefort <vdonnefort@google.com> Date: Thu, 19 Sep 2024 12:05:00 +0100 Subject: [PATCH 549/970] KVM: arm64: Fix __pkvm_init_vcpu cptr_el2 error path On an error, hyp_vcpu will be accessed while this memory has already been relinquished to the host and unmapped from the hypervisor. Protect the CPTR assignment with an early return. Fixes: b5b9955617bc ("KVM: arm64: Eagerly restore host fpsimd/sve state in pKVM") Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Vincent Donnefort <vdonnefort@google.com> Link: https://lore.kernel.org/r/20240919110500.2345927-1-vdonnefort@google.com Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/kvm/hyp/nvhe/pkvm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 187a5f4d56c0..077d4098548d 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -574,12 +574,14 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, unlock: hyp_spin_unlock(&vm_table_lock); - if (ret) + if (ret) { unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu)); + return ret; + } hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu); - return ret; + return 0; } static void -- GitLab From a9f41588a902f386b48f021f56a4c14735cd9371 Mon Sep 17 00:00:00 2001 From: Mark Brown <broonie@kernel.org> Date: Thu, 12 Sep 2024 12:39:35 +0100 Subject: [PATCH 550/970] KVM: arm64: Constrain the host to the maximum shared SVE VL with pKVM When pKVM saves and restores the host floating point state on a SVE system, it programs the vector length in ZCR_EL2.LEN to be whatever the maximum VL for the PE is. But it uses a buffer allocated with kvm_host_sve_max_vl, the maximum VL shared by all PEs in the system. This means that if we run on a system where the maximum VLs are not consistent, we will overflow the buffer on PEs which support larger VLs. Since the host will not currently attempt to make use of non-shared VLs, fix this by explicitly setting the EL2 VL to be the maximum shared VL when we save and restore. This will enforce the limit on host VL usage. Should we wish to support asymmetric VLs, this code will need to be updated along with the required changes for the host: https://lore.kernel.org/r/20240730-kvm-arm64-fix-pkvm-sve-vl-v6-0-cae8a2e0bd66@kernel.org Fixes: b5b9955617bc ("KVM: arm64: Eagerly restore host fpsimd/sve state in pKVM") Signed-off-by: Mark Brown <broonie@kernel.org> Tested-by: Fuad Tabba <tabba@google.com> Reviewed-by: Fuad Tabba <tabba@google.com> Link: https://lore.kernel.org/r/20240912-kvm-arm64-limit-guest-vl-v2-1-dd2c29cb2ac9@kernel.org [maz: added punctuation to the commit message] Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index 46d52e8a3df3..5310fe1da616 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -338,7 +338,7 @@ static inline void __hyp_sve_save_host(void) struct cpu_sve_state *sve_state = *host_data_ptr(sve_state); sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR); - write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); + write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), &sve_state->fpsr, true); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 87692b566d90..fefc89209f9e 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -33,7 +33,7 @@ static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu) */ sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true); - write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); + write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); } static void __hyp_sve_restore_host(void) @@ -45,10 +45,11 @@ static void __hyp_sve_restore_host(void) * the host. The layout of the data when saving the sve state depends * on the VL, so use a consistent (i.e., the maximum) host VL. * - * Setting ZCR_EL2 to ZCR_ELx_LEN_MASK sets the effective length - * supported by the system (or limited at EL3). + * Note that this constrains the PE to the maximum shared VL + * that was discovered, if we wish to use larger VLs this will + * need to be revisited. */ - write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); + write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), &sve_state->fpsr, true); @@ -488,7 +489,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) case ESR_ELx_EC_SVE: cpacr_clear_set(0, CPACR_ELx_ZEN); isb(); - sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); + sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, + SYS_ZCR_EL2); break; case ESR_ELx_EC_IABT_LOW: case ESR_ELx_EC_DABT_LOW: -- GitLab From 64a1d716615ee234a743b2528e95d8c3a9bef95f Mon Sep 17 00:00:00 2001 From: Marc Zyngier <maz@kernel.org> Date: Fri, 27 Sep 2024 11:49:56 +0100 Subject: [PATCH 551/970] KVM: arm64: Another reviewer reshuffle It has been a while since James had any significant bandwidth to review KVM/arm64 patches. But in the meantime, Joey has stepped up and did a really good job reviewing some terrifying patch series. Having talked with the interested parties, it appears that James is unlikely to have time for KVM in the near future, and that Joey is willing to take more responsibilities. So let's appoint Joey as an official reviewer, and give James some breathing space, as well as my personal thanks. I'm sure he will be back one way or another! Cc: Suzuki K Poulose <suzuki.poulose@arm.com> Cc: Zenghui Yu <yuzenghui@huawei.com> Cc: Will Deacon <will@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Oliver Upton <oliver.upton@linux.dev> Acked-by: Joey Gouly <joey.gouly@arm.com> Acked-by: Zenghui Yu <yuzenghui@huawei.com> Link: https://lore.kernel.org/r/20240927104956.1223658-1-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org> --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c27f3190737f..391fe4b106f8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12459,7 +12459,7 @@ F: virt/kvm/* KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) M: Marc Zyngier <maz@kernel.org> M: Oliver Upton <oliver.upton@linux.dev> -R: James Morse <james.morse@arm.com> +R: Joey Gouly <joey.gouly@arm.com> R: Suzuki K Poulose <suzuki.poulose@arm.com> R: Zenghui Yu <yuzenghui@huawei.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- GitLab From a18c835779e1a2ecf8e83c18f5af6a3b05699aaa Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" <Jason@zx2c4.com> Date: Sun, 29 Sep 2024 04:55:49 +0200 Subject: [PATCH 552/970] selftests: vDSO: align getrandom states to cache line This prevents false sharing, which makes a large difference on machines with several NUMA nodes, such as on a dual socket Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz, where the "bench-multi" test goes from 2.7s down to 1.9s. While this is just test code, it also forms the basis of how folks will wind up implementing this in libraries, so we should implement this simple cache alignment improvement here. Suggested-by: Florian Weimer <fweimer@redhat.com> Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/vDSO/vdso_test_getrandom.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/vDSO/vdso_test_getrandom.c b/tools/testing/selftests/vDSO/vdso_test_getrandom.c index 72a1d9b43a84..e5e83dbec589 100644 --- a/tools/testing/selftests/vDSO/vdso_test_getrandom.c +++ b/tools/testing/selftests/vDSO/vdso_test_getrandom.c @@ -59,10 +59,12 @@ static void *vgetrandom_get_state(void) size_t page_size = getpagesize(); size_t new_cap; size_t alloc_size, num = sysconf(_SC_NPROCESSORS_ONLN); /* Just a decent heuristic. */ + size_t state_size_aligned, cache_line_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ?: 1; void *new_block, *new_states; - alloc_size = (num * vgrnd.params.size_of_opaque_state + page_size - 1) & (~(page_size - 1)); - num = (page_size / vgrnd.params.size_of_opaque_state) * (alloc_size / page_size); + state_size_aligned = (vgrnd.params.size_of_opaque_state + cache_line_size - 1) & (~(cache_line_size - 1)); + alloc_size = (num * state_size_aligned + page_size - 1) & (~(page_size - 1)); + num = (page_size / state_size_aligned) * (alloc_size / page_size); new_block = mmap(0, alloc_size, vgrnd.params.mmap_prot, vgrnd.params.mmap_flags, -1, 0); if (new_block == MAP_FAILED) goto out; @@ -78,7 +80,7 @@ static void *vgetrandom_get_state(void) if (((uintptr_t)new_block & (page_size - 1)) + vgrnd.params.size_of_opaque_state > page_size) new_block = (void *)(((uintptr_t)new_block + page_size - 1) & (~(page_size - 1))); vgrnd.states[i] = new_block; - new_block += vgrnd.params.size_of_opaque_state; + new_block += state_size_aligned; } vgrnd.len = num; goto success; -- GitLab From 048bbbdbf85e5e00258dfb12f5e368f908801d7b Mon Sep 17 00:00:00 2001 From: Marek Vasut <marex@denx.de> Date: Mon, 30 Sep 2024 21:27:41 +0200 Subject: [PATCH 553/970] i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume In case there is any sort of clock controller attached to this I2C bus controller, for example Versaclock or even an AIC32x4 I2C codec, then an I2C transfer triggered from the clock controller clk_ops .prepare callback may trigger a deadlock on drivers/clk/clk.c prepare_lock mutex. This is because the clock controller first grabs the prepare_lock mutex and then performs the prepare operation, including its I2C access. The I2C access resumes this I2C bus controller via .runtime_resume callback, which calls clk_prepare_enable(), which attempts to grab the prepare_lock mutex again and deadlocks. Since the clock are already prepared since probe() and unprepared in remove(), use simple clk_enable()/clk_disable() calls to enable and disable the clock on runtime suspend and resume, to avoid hitting the prepare_lock mutex. Acked-by: Alain Volmat <alain.volmat@foss.st.com> Signed-off-by: Marek Vasut <marex@denx.de> Fixes: 4e7bca6fc07b ("i2c: i2c-stm32f7: add PM Runtime support") Cc: <stable@vger.kernel.org> # v5.0+ Signed-off-by: Andi Shyti <andi.shyti@kernel.org> --- drivers/i2c/busses/i2c-stm32f7.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index cfee2d9c09de..0174ead99de6 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -2395,7 +2395,7 @@ static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev) struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); if (!stm32f7_i2c_is_slave_registered(i2c_dev)) - clk_disable_unprepare(i2c_dev->clk); + clk_disable(i2c_dev->clk); return 0; } @@ -2406,9 +2406,9 @@ static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev) int ret; if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { - ret = clk_prepare_enable(i2c_dev->clk); + ret = clk_enable(i2c_dev->clk); if (ret) { - dev_err(dev, "failed to prepare_enable clock\n"); + dev_err(dev, "failed to enable clock\n"); return ret; } } -- GitLab From 160c826b4dd0d570f0f51cf002cb49bda807e9f5 Mon Sep 17 00:00:00 2001 From: Yun Lu <luyun@kylinos.cn> Date: Sun, 29 Sep 2024 16:55:49 +0800 Subject: [PATCH 554/970] selftest: hid: add missing run-hid-tools-tests.sh HID test cases run tests using the run-hid-tools-tests.sh script. When installed with "make install", the run-hid-tools-tests.sh script will not be copied over, resulting in the following error message. make -C tools/testing/selftests/ TARGETS=hid install \ INSTALL_PATH=$KSFT_INSTALL_PATH cd $KSFT_INSTALL_PATH ./run_kselftest.sh -c hid selftests: hid: hid-core.sh bash: ./run-hid-tools-tests.sh: No such file or directory Add the run-hid-tools-tests.sh script to the TEST_FILES in the Makefile for it to be installed. Fixes: ffb85d5c9e80 ("selftests: hid: import hid-tools hid-core tests") Signed-off-by: Yun Lu <luyun@kylinos.cn> Acked-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- tools/testing/selftests/hid/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile index 72be55ac4bdf..38ae31bb07b5 100644 --- a/tools/testing/selftests/hid/Makefile +++ b/tools/testing/selftests/hid/Makefile @@ -17,6 +17,8 @@ TEST_PROGS += hid-tablet.sh TEST_PROGS += hid-usb_crash.sh TEST_PROGS += hid-wacom.sh +TEST_FILES := run-hid-tools-tests.sh + CXX ?= $(CROSS_COMPILE)g++ HOSTPKG_CONFIG := pkg-config -- GitLab From fb5cc65f973661241e4a2b7390b429aa7b330c69 Mon Sep 17 00:00:00 2001 From: Nuno Sa <nuno.sa@analog.com> Date: Tue, 1 Oct 2024 07:46:44 -0700 Subject: [PATCH 555/970] Input: adp5589-keys - fix NULL pointer dereference We register a devm action to call adp5589_clear_config() and then pass the i2c client as argument so that we can call i2c_get_clientdata() in order to get our device object. However, i2c_set_clientdata() is only being set at the end of the probe function which means that we'll get a NULL pointer dereference in case the probe function fails early. Fixes: 30df385e35a4 ("Input: adp5589-keys - use devm_add_action_or_reset() for register clear") Signed-off-by: Nuno Sa <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20241001-b4-dev-adp5589-fw-conversion-v1-1-fca0149dfc47@analog.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/keyboard/adp5589-keys.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 8996e00cd63a..68a29d67be57 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -936,10 +936,9 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid) static void adp5589_clear_config(void *data) { - struct i2c_client *client = data; - struct adp5589_kpad *kpad = i2c_get_clientdata(client); + struct adp5589_kpad *kpad = data; - adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); + adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); } static int adp5589_probe(struct i2c_client *client) @@ -983,7 +982,7 @@ static int adp5589_probe(struct i2c_client *client) } error = devm_add_action_or_reset(&client->dev, adp5589_clear_config, - client); + kpad); if (error) return error; @@ -1010,8 +1009,6 @@ static int adp5589_probe(struct i2c_client *client) if (error) return error; - i2c_set_clientdata(client, kpad); - dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); return 0; } -- GitLab From c684771630e64bc39bddffeb65dd8a6612a6b249 Mon Sep 17 00:00:00 2001 From: Nuno Sa <nuno.sa@analog.com> Date: Tue, 1 Oct 2024 07:47:23 -0700 Subject: [PATCH 556/970] Input: adp5589-keys - fix adp5589_gpio_get_value() The adp5589 seems to have the same behavior as similar devices as explained in commit 910a9f5636f5 ("Input: adp5588-keys - get value from data out when dir is out"). Basically, when the gpio is set as output we need to get the value from ADP5589_GPO_DATA_OUT_A register instead of ADP5589_GPI_STATUS_A. Fixes: 9d2e173644bb ("Input: ADP5589 - new driver for I2C Keypad Decoder and I/O Expander") Signed-off-by: Nuno Sa <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20241001-b4-dev-adp5589-fw-conversion-v1-2-fca0149dfc47@analog.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/keyboard/adp5589-keys.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 68a29d67be57..922d3ab998f3 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -391,10 +391,17 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) struct adp5589_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); + int val; - return !!(adp5589_read(kpad->client, - kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) & - bit); + mutex_lock(&kpad->gpio_lock); + if (kpad->dir[bank] & bit) + val = kpad->dat_out[bank]; + else + val = adp5589_read(kpad->client, + kpad->var->reg(ADP5589_GPI_STATUS_A) + bank); + mutex_unlock(&kpad->gpio_lock); + + return !!(val & bit); } static void adp5589_gpio_set_value(struct gpio_chip *chip, -- GitLab From f5c82730bedbc4a424cb94d2653bcb8be9dbd2ec Mon Sep 17 00:00:00 2001 From: Christian Brauner <brauner@kernel.org> Date: Tue, 1 Oct 2024 17:01:40 +0200 Subject: [PATCH 557/970] folio_queue: fix documentation s/folioq_count/folioq_full/ Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Link: https://lore.kernel.org/r/20241001134729.3f65ae78@canb.auug.org.au Signed-off-by: Christian Brauner <brauner@kernel.org> --- include/linux/folio_queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/folio_queue.h b/include/linux/folio_queue.h index af871405ae55..3abe614ef5f0 100644 --- a/include/linux/folio_queue.h +++ b/include/linux/folio_queue.h @@ -81,7 +81,7 @@ static inline unsigned int folioq_count(struct folio_queue *folioq) } /** - * folioq_count: Query if a folio queue segment is full + * folioq_full: Query if a folio queue segment is full * @folioq: The segment to query * * Query if a folio queue segment is fully occupied. Note that this does not -- GitLab From 59d39b9259e4d15b6e4c6da758ab318a76a10ca4 Mon Sep 17 00:00:00 2001 From: Christian Brauner <brauner@kernel.org> Date: Tue, 1 Oct 2024 17:04:32 +0200 Subject: [PATCH 558/970] Documentation: add missing folio_queue entry Add missing folio_queue entry. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Link: https://lore.kernel.org/r/20241001133920.6e28637b@canb.auug.org.au Signed-off-by: Christian Brauner <brauner@kernel.org> --- Documentation/core-api/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index a331d2c814f5..6a875743dd4b 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -37,6 +37,7 @@ Library functionality that is used throughout the kernel. kref cleanup assoc_array + folio_queue xarray maple_tree idr -- GitLab From 76f972c2cfdf4beba8221c94b983e10a0de797c5 Mon Sep 17 00:00:00 2001 From: Mark Brown <broonie@kernel.org> Date: Mon, 30 Sep 2024 19:10:33 +0100 Subject: [PATCH 559/970] KVM: selftests: Fix build on architectures other than x86_64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent addition of support for testing with the x86 specific quirk KVM_X86_QUIRK_SLOT_ZAP_ALL disabled in the generic memslot tests broke the build of the KVM selftests for all other architectures: In file included from include/kvm_util.h:8, from include/memstress.h:13, from memslot_modification_stress_test.c:21: memslot_modification_stress_test.c: In function ‘main’: memslot_modification_stress_test.c:176:38: error: ‘KVM_X86_QUIRK_SLOT_ZAP_ALL’ undeclared (first use in this function) 176 | KVM_X86_QUIRK_SLOT_ZAP_ALL); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ Add __x86_64__ guard defines to avoid building the relevant code on other architectures. Fixes: 61de4c34b51c ("KVM: selftests: Test memslot move in memslot_perf_test with quirk disabled") Fixes: 218f6415004a ("KVM: selftests: Allow slot modification stress test with quirk disabled") Reported-by: Aishwarya TCV <aishwarya.tcv@arm.com> Signed-off-by: Mark Brown <broonie@kernel.org> Message-ID: <20240930-kvm-build-breakage-v1-1-866fad3cc164@kernel.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- .../selftests/kvm/memslot_modification_stress_test.c | 2 ++ tools/testing/selftests/kvm/memslot_perf_test.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c b/tools/testing/selftests/kvm/memslot_modification_stress_test.c index e3343f0df9e1..c81a84990eab 100644 --- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c +++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c @@ -169,12 +169,14 @@ int main(int argc, char *argv[]) case 'i': p.nr_iterations = atoi_positive("Number of iterations", optarg); break; +#ifdef __x86_64__ case 'q': p.disable_slot_zap_quirk = true; TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & KVM_X86_QUIRK_SLOT_ZAP_ALL); break; +#endif case 'h': default: help(argv[0]); diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testing/selftests/kvm/memslot_perf_test.c index 893366982f77..989ffe0d047f 100644 --- a/tools/testing/selftests/kvm/memslot_perf_test.c +++ b/tools/testing/selftests/kvm/memslot_perf_test.c @@ -113,7 +113,9 @@ static_assert(ATOMIC_BOOL_LOCK_FREE == 2, "atomic bool is not lockless"); static sem_t vcpu_ready; static bool map_unmap_verify; +#ifdef __x86_64__ static bool disable_slot_zap_quirk; +#endif static bool verbose; #define pr_info_v(...) \ @@ -579,8 +581,10 @@ static bool test_memslot_move_prepare(struct vm_data *data, uint32_t guest_page_size = data->vm->page_size; uint64_t movesrcgpa, movetestgpa; +#ifdef __x86_64__ if (disable_slot_zap_quirk) vm_enable_cap(data->vm, KVM_CAP_DISABLE_QUIRKS2, KVM_X86_QUIRK_SLOT_ZAP_ALL); +#endif movesrcgpa = vm_slot2gpa(data, data->nslots - 1); @@ -971,11 +975,13 @@ static bool parse_args(int argc, char *argv[], case 'd': map_unmap_verify = true; break; +#ifdef __x86_64__ case 'q': disable_slot_zap_quirk = true; TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & KVM_X86_QUIRK_SLOT_ZAP_ALL); break; +#endif case 's': targs->nslots = atoi_paranoid(optarg); if (targs->nslots <= 1 && targs->nslots != -1) { -- GitLab From 77ced98f0f03fdc196561d1afbe652899c318073 Mon Sep 17 00:00:00 2001 From: Nilay Shroff <nilay@linux.ibm.com> Date: Tue, 1 Oct 2024 19:32:35 +0530 Subject: [PATCH 560/970] mm, slab: fix use of SLAB_SUPPORTS_SYSFS in kmem_cache_release() The fix implemented in commit 4ec10268ed98 ("mm, slab: unlink slabinfo, sysfs and debugfs immediately") caused a subtle side effect due to which while destroying the kmem cache, the code path would never get into sysfs_slab_release() function even though SLAB_SUPPORTS_SYSFS is defined and slab state is FULL. Due to this side effect, we would never release kobject defined for kmem cache and leak the associated memory. The issue here's with the use of __is_defined() macro in kmem_cache_ release(). The __is_defined() macro expands to __take_second_arg( arg1_or_junk 1, 0). If "arg1_or_junk" is defined to 1 then it expands to __take_second_arg(0, 1, 0) and returns 1. If "arg1_or_junk" is NOT defined to any value then it expands to __take_second_arg(... 1, 0) and returns 0. In this particular issue, SLAB_SUPPORTS_SYSFS is defined without any associated value and that causes __is_defined(SLAB_SUPPORTS_SYSFS) to always evaluate to 0 and hence it would never invoke sysfs_slab_release(). This patch helps fix this issue by defining SLAB_SUPPORTS_SYSFS to 1. Fixes: 4ec10268ed98 ("mm, slab: unlink slabinfo, sysfs and debugfs immediately") Reported-by: Yi Zhang <yi.zhang@redhat.com> Closes: https://lore.kernel.org/all/CAHj4cs9YCCcfmdxN43-9H3HnTYQsRtTYw1Kzq-L468GfLKAENA@mail.gmail.com/ Signed-off-by: Nilay Shroff <nilay@linux.ibm.com> Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Tested-by: Yi Zhang <yi.zhang@redhat.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> --- mm/slab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/slab.h b/mm/slab.h index f22fb760b286..3e0a08ea4c42 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -310,7 +310,7 @@ struct kmem_cache { }; #if defined(CONFIG_SYSFS) && !defined(CONFIG_SLUB_TINY) -#define SLAB_SUPPORTS_SYSFS +#define SLAB_SUPPORTS_SYSFS 1 void sysfs_slab_unlink(struct kmem_cache *s); void sysfs_slab_release(struct kmem_cache *s); #else -- GitLab From 3c5d61ae919cc377c71118ccc76fa6e8518023f8 Mon Sep 17 00:00:00 2001 From: "Uladzislau Rezki (Sony)" <urezki@gmail.com> Date: Mon, 30 Sep 2024 13:37:10 +0200 Subject: [PATCH 561/970] rcu/kvfree: Refactor kvfree_rcu_queue_batch() Improve readability of kvfree_rcu_queue_batch() function in away that, after a first batch queuing, the loop is break and success value is returned to a caller. There is no reason to loop and check batches further as all outstanding objects have already been picked and attached to a certain batch to complete an offloading. Fixes: 2b55d6a42d14 ("rcu/kvfree: Add kvfree_rcu_barrier() API") Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Closes: https://lore.kernel.org/lkml/ZvWUt2oyXRsvJRNc@pc636/T/ Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> --- kernel/rcu/tree.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index a60616e69b66..b1f883fcd918 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3607,11 +3607,12 @@ kvfree_rcu_queue_batch(struct kfree_rcu_cpu *krcp) } // One work is per one batch, so there are three - // "free channels", the batch can handle. It can - // be that the work is in the pending state when - // channels have been detached following by each - // other. + // "free channels", the batch can handle. Break + // the loop since it is done with this CPU thus + // queuing an RCU work is _always_ success here. queued = queue_rcu_work(system_unbound_wq, &krwp->rcu_work); + WARN_ON_ONCE(!queued); + break; } } -- GitLab From 2b55639a4e25ff02ee496368b03456bd28ebdc0b Mon Sep 17 00:00:00 2001 From: Liviu Dudau <liviu.dudau@arm.com> Date: Fri, 20 Sep 2024 11:28:02 +0100 Subject: [PATCH 562/970] drm/panthor: Add FOP_UNSIGNED_OFFSET to fop_flags Since commit 641bb4394f40 ("fs: move FMODE_UNSIGNED_OFFSET to fop_flags") the FMODE_UNSIGNED_OFFSET flag has been moved to fop_flags and renamed, but the patch failed to make the changes for the panthor driver. When user space opens the render node the WARN() added by the patch gets triggered. Fixes: 641bb4394f40 ("fs: move FMODE_UNSIGNED_OFFSET to fop_flags") Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920102802.2483367-1-liviu.dudau@arm.com --- drivers/gpu/drm/panthor/panthor_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 34182f67136c..c520f156e2d7 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -1383,6 +1383,7 @@ static const struct file_operations panthor_drm_driver_fops = { .read = drm_read, .llseek = noop_llseek, .mmap = panthor_mmap, + .fop_flags = FOP_UNSIGNED_OFFSET, }; #ifdef CONFIG_DEBUG_FS -- GitLab From fa998a9eac8809da4f219aad49836fcad2a9bf5c Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Fri, 13 Sep 2024 13:27:22 +0200 Subject: [PATCH 563/970] drm/panthor: Lock the VM resv before calling drm_gpuvm_bo_obtain_prealloc() drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our pre-allocated BO if the <BO,VM> association exists. Given we only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will be called immediately, and we have to hold the VM resv lock when calling this function. Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Steven Price <steven.price@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240913112722.492144-1-boris.brezillon@collabora.com --- drivers/gpu/drm/panthor/panthor_mmu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index bbc12728437f..3cd2bce59edc 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -1251,9 +1251,17 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, goto err_cleanup; } + /* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our + * pre-allocated BO if the <BO,VM> association exists. Given we + * only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will + * be called immediately, and we have to hold the VM resv lock when + * calling this function. + */ + dma_resv_lock(panthor_vm_resv(vm), NULL); mutex_lock(&bo->gpuva_list_lock); op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); mutex_unlock(&bo->gpuva_list_lock); + dma_resv_unlock(panthor_vm_resv(vm)); /* If the a vm_bo for this <VM,BO> combination exists, it already * retains a pin ref, and we can release the one we took earlier. -- GitLab From 282864cc5d3f144af0cdea1868ee2dc2c5110f0d Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Mon, 30 Sep 2024 18:37:42 +0200 Subject: [PATCH 564/970] drm/panthor: Fix access to uninitialized variable in tick_ctx_cleanup() The group variable can't be used to retrieve ptdev in our second loop, because it points to the previously iterated list_head, not a valid group. Get the ptdev object from the scheduler instead. Cc: <stable@vger.kernel.org> Fixes: d72f049087d4 ("drm/panthor: Allow driver compilation") Reported-by: kernel test robot <lkp@intel.com> Reported-by: Julia Lawall <julia.lawall@inria.fr> Closes: https://lore.kernel.org/r/202409302306.UDikqa03-lkp@intel.com/ Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930163742.87036-1-boris.brezillon@collabora.com --- drivers/gpu/drm/panthor/panthor_sched.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index a8a939a9fb51..145d983bb129 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -2046,6 +2046,7 @@ static void tick_ctx_cleanup(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *ctx) { + struct panthor_device *ptdev = sched->ptdev; struct panthor_group *group, *tmp; u32 i; @@ -2054,7 +2055,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched, /* If everything went fine, we should only have groups * to be terminated in the old_groups lists. */ - drm_WARN_ON(&group->ptdev->base, !ctx->csg_upd_failed_mask && + drm_WARN_ON(&ptdev->base, !ctx->csg_upd_failed_mask && group_can_run(group)); if (!group_can_run(group)) { @@ -2077,7 +2078,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched, /* If everything went fine, the groups to schedule lists should * be empty. */ - drm_WARN_ON(&group->ptdev->base, + drm_WARN_ON(&ptdev->base, !ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i])); list_for_each_entry_safe(group, tmp, &ctx->groups[i], run_node) { -- GitLab From 7a1f30afe97294281a2ba05977688385744f9844 Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Thu, 5 Sep 2024 09:19:14 +0200 Subject: [PATCH 565/970] drm/panthor: Don't declare a queue blocked if deferred operations are pending If deferred operations are pending, we want to wait for those to land before declaring the queue blocked on a SYNC_WAIT. We need this to deal with the case where the sync object is signalled through a deferred SYNC_{ADD,SET} from the same queue. If we don't do that and the group gets scheduled out before the deferred SYNC_{SET,ADD} is executed, we'll end up with a timeout, because no external SYNC_{SET,ADD} will make the scheduler reconsider the group for execution. Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block") Cc: <stable@vger.kernel.org> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905071914.3278599-1-boris.brezillon@collabora.com --- drivers/gpu/drm/panthor/panthor_sched.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index 145d983bb129..2aff02ba6949 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -1103,7 +1103,13 @@ cs_slot_sync_queue_state_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs list_move_tail(&group->wait_node, &group->ptdev->scheduler->groups.waiting); } - group->blocked_queues |= BIT(cs_id); + + /* The queue is only blocked if there's no deferred operation + * pending, which can be checked through the scoreboard status. + */ + if (!cs_iface->output->status_scoreboards) + group->blocked_queues |= BIT(cs_id); + queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr; queue->syncwait.ref = cs_iface->output->status_wait_sync_value; status_wait_cond = cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_COND_MASK; -- GitLab From f9e7ac6e2e9986c2ee63224992cb5c8276e46b2a Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Thu, 5 Sep 2024 09:01:54 +0200 Subject: [PATCH 566/970] drm/panthor: Don't add write fences to the shared BOs The only user (the mesa gallium driver) is already assuming explicit synchronization and doing the export/import dance on shared BOs. The only reason we were registering ourselves as writers on external BOs is because Xe, which was the reference back when we developed Panthor, was doing so. Turns out Xe was wrong, and we really want bookkeep on all registered fences, so userspace can explicitly upgrade those to read/write when needed. Fixes: 4bdca1150792 ("drm/panthor: Add the driver frontend block") Cc: Matthew Brost <matthew.brost@intel.com> Cc: Simona Vetter <simona.vetter@ffwll.ch> Cc: <stable@vger.kernel.org> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240905070155.3254011-1-boris.brezillon@collabora.com --- drivers/gpu/drm/panthor/panthor_sched.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index 2aff02ba6949..aee362abb710 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -3443,13 +3443,8 @@ void panthor_job_update_resvs(struct drm_exec *exec, struct drm_sched_job *sched { struct panthor_job *job = container_of(sched_job, struct panthor_job, base); - /* Still not sure why we want USAGE_WRITE for external objects, since I - * was assuming this would be handled through explicit syncs being imported - * to external BOs with DMA_BUF_IOCTL_IMPORT_SYNC_FILE, but other drivers - * seem to pass DMA_RESV_USAGE_WRITE, so there must be a good reason. - */ panthor_vm_update_resvs(job->group->vm, exec, &sched_job->s_fence->finished, - DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE); + DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_BOOKKEEP); } void panthor_sched_unplug(struct panthor_device *ptdev) -- GitLab From 96c6ca71572a3556ed0c37237305657ff47174b7 Mon Sep 17 00:00:00 2001 From: Filipe Manana <fdmanana@suse.com> Date: Thu, 19 Sep 2024 22:20:34 +0100 Subject: [PATCH 567/970] btrfs: send: fix buffer overflow detection when copying path to cache entry Starting with commit c0247d289e73 ("btrfs: send: annotate struct name_cache_entry with __counted_by()") we annotated the variable length array "name" from the name_cache_entry structure with __counted_by() to improve overflow detection. However that alone was not correct, because the length of that array does not match the "name_len" field - it matches that plus 1 to include the NUL string terminator, so that makes a fortified kernel think there's an overflow and report a splat like this: strcpy: detected buffer overflow: 20 byte write of buffer size 19 WARNING: CPU: 3 PID: 3310 at __fortify_report+0x45/0x50 CPU: 3 UID: 0 PID: 3310 Comm: btrfs Not tainted 6.11.0-prnet #1 Hardware name: CompuLab Ltd. sbc-ihsw/Intense-PC2 (IPC2), BIOS IPC2_3.330.7 X64 03/15/2018 RIP: 0010:__fortify_report+0x45/0x50 Code: 48 8b 34 (...) RSP: 0018:ffff97ebc0d6f650 EFLAGS: 00010246 RAX: 7749924ef60fa600 RBX: ffff8bf5446a521a RCX: 0000000000000027 RDX: 00000000ffffdfff RSI: ffff97ebc0d6f548 RDI: ffff8bf84e7a1cc8 RBP: ffff8bf548574080 R08: ffffffffa8c40e10 R09: 0000000000005ffd R10: 0000000000000004 R11: ffffffffa8c70e10 R12: ffff8bf551eef400 R13: 0000000000000000 R14: 0000000000000013 R15: 00000000000003a8 FS: 00007fae144de8c0(0000) GS:ffff8bf84e780000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fae14691690 CR3: 00000001027a2003 CR4: 00000000001706f0 Call Trace: <TASK> ? __warn+0x12a/0x1d0 ? __fortify_report+0x45/0x50 ? report_bug+0x154/0x1c0 ? handle_bug+0x42/0x70 ? exc_invalid_op+0x1a/0x50 ? asm_exc_invalid_op+0x1a/0x20 ? __fortify_report+0x45/0x50 __fortify_panic+0x9/0x10 __get_cur_name_and_parent+0x3bc/0x3c0 get_cur_path+0x207/0x3b0 send_extent_data+0x709/0x10d0 ? find_parent_nodes+0x22df/0x25d0 ? mas_nomem+0x13/0x90 ? mtree_insert_range+0xa5/0x110 ? btrfs_lru_cache_store+0x5f/0x1e0 ? iterate_extent_inodes+0x52d/0x5a0 process_extent+0xa96/0x11a0 ? __pfx_lookup_backref_cache+0x10/0x10 ? __pfx_store_backref_cache+0x10/0x10 ? __pfx_iterate_backrefs+0x10/0x10 ? __pfx_check_extent_item+0x10/0x10 changed_cb+0x6fa/0x930 ? tree_advance+0x362/0x390 ? memcmp_extent_buffer+0xd7/0x160 send_subvol+0xf0a/0x1520 btrfs_ioctl_send+0x106b/0x11d0 ? __pfx___clone_root_cmp_sort+0x10/0x10 _btrfs_ioctl_send+0x1ac/0x240 btrfs_ioctl+0x75b/0x850 __se_sys_ioctl+0xca/0x150 do_syscall_64+0x85/0x160 ? __count_memcg_events+0x69/0x100 ? handle_mm_fault+0x1327/0x15c0 ? __se_sys_rt_sigprocmask+0xf1/0x180 ? syscall_exit_to_user_mode+0x75/0xa0 ? do_syscall_64+0x91/0x160 ? do_user_addr_fault+0x21d/0x630 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fae145eeb4f Code: 00 48 89 (...) RSP: 002b:00007ffdf1cb09b0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007fae145eeb4f RDX: 00007ffdf1cb0ad0 RSI: 0000000040489426 RDI: 0000000000000004 RBP: 00000000000078fe R08: 00007fae144006c0 R09: 00007ffdf1cb0927 R10: 0000000000000008 R11: 0000000000000246 R12: 00007ffdf1cb1ce8 R13: 0000000000000003 R14: 000055c499fab2e0 R15: 0000000000000004 </TASK> Fix this by not storing the NUL string terminator since we don't actually need it for name cache entries, this way "name_len" corresponds to the actual size of the "name" array. This requires marking the "name" array field with __nonstring and using memcpy() instead of strcpy() as recommended by the guidelines at: https://github.com/KSPP/linux/issues/90 Reported-by: David Arendt <admin@prnet.org> Link: https://lore.kernel.org/linux-btrfs/cee4591a-3088-49ba-99b8-d86b4242b8bd@prnet.org/ Fixes: c0247d289e73 ("btrfs: send: annotate struct name_cache_entry with __counted_by()") CC: stable@vger.kernel.org # 6.11 Tested-by: David Arendt <admin@prnet.org> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/send.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 7f48ba6c1c77..5871ca845b0e 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -346,8 +346,10 @@ struct name_cache_entry { u64 parent_gen; int ret; int need_later_update; + /* Name length without NUL terminator. */ int name_len; - char name[] __counted_by(name_len); + /* Not NUL terminated. */ + char name[] __counted_by(name_len) __nonstring; }; /* See the comment at lru_cache.h about struct btrfs_lru_cache_entry. */ @@ -2388,7 +2390,7 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx, /* * Store the result of the lookup in the name cache. */ - nce = kmalloc(sizeof(*nce) + fs_path_len(dest) + 1, GFP_KERNEL); + nce = kmalloc(sizeof(*nce) + fs_path_len(dest), GFP_KERNEL); if (!nce) { ret = -ENOMEM; goto out; @@ -2400,7 +2402,7 @@ static int __get_cur_name_and_parent(struct send_ctx *sctx, nce->parent_gen = *parent_gen; nce->name_len = fs_path_len(dest); nce->ret = ret; - strcpy(nce->name, dest->start); + memcpy(nce->name, dest->start, nce->name_len); if (ino < sctx->send_progress) nce->need_later_update = 0; -- GitLab From 97f9782276fc9cb0de37a5eecb82204e48a5a612 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn <johannes.thumshirn@wdc.com> Date: Thu, 19 Sep 2024 12:16:38 +0200 Subject: [PATCH 568/970] btrfs: also add stripe entries for NOCOW writes NOCOW writes do not generate stripe_extent entries in the RAID stripe tree, as the RAID stripe-tree feature initially was designed with a zoned filesystem in mind and on a zoned filesystem, we do not allow NOCOW writes. But the RAID stripe-tree feature is independent from the zoned feature, so we must also do NOCOW writes for RAID stripe-tree filesystems. Reviewed-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/inode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index edac499fd83d..c6e4b58c334c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3111,6 +3111,11 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) ret = btrfs_update_inode_fallback(trans, inode); if (ret) /* -ENOMEM or corruption */ btrfs_abort_transaction(trans, ret); + + ret = btrfs_insert_raid_extent(trans, ordered_extent); + if (ret) + btrfs_abort_transaction(trans, ret); + goto out; } -- GitLab From db7e68b522c01eb666cfe1f31637775f18997811 Mon Sep 17 00:00:00 2001 From: Josef Bacik <josef@toxicpanda.com> Date: Tue, 24 Sep 2024 16:50:22 -0400 Subject: [PATCH 569/970] btrfs: drop the backref cache during relocation if we commit Since the inception of relocation we have maintained the backref cache across transaction commits, updating the backref cache with the new bytenr whenever we COWed blocks that were in the cache, and then updating their bytenr once we detected a transaction id change. This works as long as we're only ever modifying blocks, not changing the structure of the tree. However relocation does in fact change the structure of the tree. For example, if we are relocating a data extent, we will look up all the leaves that point to this data extent. We will then call do_relocation() on each of these leaves, which will COW down to the leaf and then update the file extent location. But, a key feature of do_relocation() is the pending list. This is all the pending nodes that we modified when we updated the file extent item. We will then process all of these blocks via finish_pending_nodes, which calls do_relocation() on all of the nodes that led up to that leaf. The purpose of this is to make sure we don't break sharing unless we absolutely have to. Consider the case that we have 3 snapshots that all point to this leaf through the same nodes, the initial COW would have created a whole new path. If we did this for all 3 snapshots we would end up with 3x the number of nodes we had originally. To avoid this we will cycle through each of the snapshots that point to each of these nodes and update their pointers to point at the new nodes. Once we update the pointer to the new node we will drop the node we removed the link for and all of its children via btrfs_drop_subtree(). This is essentially just btrfs_drop_snapshot(), but for an arbitrary point in the snapshot. The problem with this is that we will never reflect this in the backref cache. If we do this btrfs_drop_snapshot() for a node that is in the backref tree, we will leave the node in the backref tree. This becomes a problem when we change the transid, as now the backref cache has entire subtrees that no longer exist, but exist as if they still are pointed to by the same roots. In the best case scenario you end up with "adding refs to an existing tree ref" errors from insert_inline_extent_backref(), where we attempt to link in nodes on roots that are no longer valid. Worst case you will double free some random block and re-use it when there's still references to the block. This is extremely subtle, and the consequences are quite bad. There isn't a way to make sure our backref cache is consistent between transid's. In order to fix this we need to simply evict the entire backref cache anytime we cross transid's. This reduces performance in that we have to rebuild this backref cache every time we change transid's, but fixes the bug. This has existed since relocation was added, and is a pretty critical bug. There's a lot more cleanup that can be done now that this functionality is going away, but this patch is as small as possible in order to fix the problem and make it easy for us to backport it to all the kernels it needs to be backported to. Followup series will dismantle more of this code and simplify relocation drastically to remove this functionality. We have a reproducer that reproduced the corruption within a few minutes of running. With this patch it survives several iterations/hours of running the reproducer. Fixes: 3fd0a5585eb9 ("Btrfs: Metadata ENOSPC handling for balance") CC: stable@vger.kernel.org Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/backref.c | 12 ++++--- fs/btrfs/relocation.c | 75 ++----------------------------------------- 2 files changed, 11 insertions(+), 76 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index e2f478ecd7fd..f8e1d5b2c512 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -3179,10 +3179,14 @@ void btrfs_backref_release_cache(struct btrfs_backref_cache *cache) btrfs_backref_cleanup_node(cache, node); } - cache->last_trans = 0; - - for (i = 0; i < BTRFS_MAX_LEVEL; i++) - ASSERT(list_empty(&cache->pending[i])); + for (i = 0; i < BTRFS_MAX_LEVEL; i++) { + while (!list_empty(&cache->pending[i])) { + node = list_first_entry(&cache->pending[i], + struct btrfs_backref_node, + list); + btrfs_backref_cleanup_node(cache, node); + } + } ASSERT(list_empty(&cache->pending_edge)); ASSERT(list_empty(&cache->useless_node)); ASSERT(list_empty(&cache->changed)); diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index ea4ed85919ec..cf1dfeaaf2d8 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -232,70 +232,6 @@ static struct btrfs_backref_node *walk_down_backref( return NULL; } -static void update_backref_node(struct btrfs_backref_cache *cache, - struct btrfs_backref_node *node, u64 bytenr) -{ - struct rb_node *rb_node; - rb_erase(&node->rb_node, &cache->rb_root); - node->bytenr = bytenr; - rb_node = rb_simple_insert(&cache->rb_root, node->bytenr, &node->rb_node); - if (rb_node) - btrfs_backref_panic(cache->fs_info, bytenr, -EEXIST); -} - -/* - * update backref cache after a transaction commit - */ -static int update_backref_cache(struct btrfs_trans_handle *trans, - struct btrfs_backref_cache *cache) -{ - struct btrfs_backref_node *node; - int level = 0; - - if (cache->last_trans == 0) { - cache->last_trans = trans->transid; - return 0; - } - - if (cache->last_trans == trans->transid) - return 0; - - /* - * detached nodes are used to avoid unnecessary backref - * lookup. transaction commit changes the extent tree. - * so the detached nodes are no longer useful. - */ - while (!list_empty(&cache->detached)) { - node = list_entry(cache->detached.next, - struct btrfs_backref_node, list); - btrfs_backref_cleanup_node(cache, node); - } - - while (!list_empty(&cache->changed)) { - node = list_entry(cache->changed.next, - struct btrfs_backref_node, list); - list_del_init(&node->list); - BUG_ON(node->pending); - update_backref_node(cache, node, node->new_bytenr); - } - - /* - * some nodes can be left in the pending list if there were - * errors during processing the pending nodes. - */ - for (level = 0; level < BTRFS_MAX_LEVEL; level++) { - list_for_each_entry(node, &cache->pending[level], list) { - BUG_ON(!node->pending); - if (node->bytenr == node->new_bytenr) - continue; - update_backref_node(cache, node, node->new_bytenr); - } - } - - cache->last_trans = 0; - return 1; -} - static bool reloc_root_is_dead(const struct btrfs_root *root) { /* @@ -551,9 +487,6 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, struct btrfs_backref_edge *new_edge; struct rb_node *rb_node; - if (cache->last_trans > 0) - update_backref_cache(trans, cache); - rb_node = rb_simple_search(&cache->rb_root, src->commit_root->start); if (rb_node) { node = rb_entry(rb_node, struct btrfs_backref_node, rb_node); @@ -3698,11 +3631,9 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) break; } restart: - if (update_backref_cache(trans, &rc->backref_cache)) { - btrfs_end_transaction(trans); - trans = NULL; - continue; - } + if (rc->backref_cache.last_trans != trans->transid) + btrfs_backref_release_cache(&rc->backref_cache); + rc->backref_cache.last_trans = trans->transid; ret = find_next_extent(rc, path, &key); if (ret < 0) -- GitLab From 50c6f6e6806c65e41a039f0edef0816974403253 Mon Sep 17 00:00:00 2001 From: Filipe Manana <fdmanana@suse.com> Date: Wed, 25 Sep 2024 11:38:55 +0100 Subject: [PATCH 570/970] btrfs: tracepoints: end assignment with semicolon at btrfs_qgroup_extent event class While running checkpatch.pl against a patch that modifies the btrfs_qgroup_extent event class, it complained about using a comma instead of a semicolon: $ ./scripts/checkpatch.pl qgroups/0003-btrfs-qgroups-remove-bytenr-field-from-struct-btrfs_.patch WARNING: Possible comma where semicolon could be used #215: FILE: include/trace/events/btrfs.h:1720: + __entry->bytenr = bytenr, __entry->num_bytes = rec->num_bytes; total: 0 errors, 1 warnings, 184 lines checked So replace the comma with a semicolon to silence checkpatch and possibly other tools. It also makes the code consistent with the rest. Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- include/trace/events/btrfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index bf60ad50011e..af6b3827fb1d 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -1716,7 +1716,7 @@ DECLARE_EVENT_CLASS(btrfs_qgroup_extent, ), TP_fast_assign_btrfs(fs_info, - __entry->bytenr = rec->bytenr, + __entry->bytenr = rec->bytenr; __entry->num_bytes = rec->num_bytes; ), -- GitLab From fa630df665aa9ddce3a96ce7b54e10a38e4d2a2b Mon Sep 17 00:00:00 2001 From: Filipe Manana <fdmanana@suse.com> Date: Fri, 27 Sep 2024 10:50:12 +0100 Subject: [PATCH 571/970] btrfs: send: fix invalid clone operation for file that got its size decreased During an incremental send we may end up sending an invalid clone operation, for the last extent of a file which ends at an unaligned offset that matches the final i_size of the file in the send snapshot, in case the file had its initial size (the size in the parent snapshot) decreased in the send snapshot. In this case the destination will fail to apply the clone operation because its end offset is not sector size aligned and it ends before the current size of the file. Sending the truncate operation always happens when we finish processing an inode, after we process all its extents (and xattrs, names, etc). So fix this by ensuring the file has a valid size before we send a clone operation for an unaligned extent that ends at the final i_size of the file. The size we truncate to matches the start offset of the clone range but it could be any value between that start offset and the final size of the file since the clone operation will expand the i_size if the current size is smaller than the end offset. The start offset of the range was chosen because it's always sector size aligned and avoids a truncation into the middle of a page, which results in dirtying the page due to filling part of it with zeroes and then making the clone operation at the receiver trigger IO. The following test reproduces the issue: $ cat test.sh #!/bin/bash DEV=/dev/sdi MNT=/mnt/sdi mkfs.btrfs -f $DEV mount $DEV $MNT # Create a file with a size of 256K + 5 bytes, having two extents, one # with a size of 128K and another one with a size of 128K + 5 bytes. last_ext_size=$((128 * 1024 + 5)) xfs_io -f -d -c "pwrite -S 0xab -b 128K 0 128K" \ -c "pwrite -S 0xcd -b $last_ext_size 128K $last_ext_size" \ $MNT/foo # Another file which we will later clone foo into, but initially with # a larger size than foo. xfs_io -f -c "pwrite -S 0xef 0 1M" $MNT/bar btrfs subvolume snapshot -r $MNT/ $MNT/snap1 # Now resize bar and clone foo into it. xfs_io -c "truncate 0" \ -c "reflink $MNT/foo" $MNT/bar btrfs subvolume snapshot -r $MNT/ $MNT/snap2 rm -f /tmp/send-full /tmp/send-inc btrfs send -f /tmp/send-full $MNT/snap1 btrfs send -p $MNT/snap1 -f /tmp/send-inc $MNT/snap2 umount $MNT mkfs.btrfs -f $DEV mount $DEV $MNT btrfs receive -f /tmp/send-full $MNT btrfs receive -f /tmp/send-inc $MNT umount $MNT Running it before this patch: $ ./test.sh (...) At subvol snap1 At snapshot snap2 ERROR: failed to clone extents to bar: Invalid argument A test case for fstests will be sent soon. Reported-by: Ben Millwood <thebenmachine@gmail.com> Link: https://lore.kernel.org/linux-btrfs/CAJhrHS2z+WViO2h=ojYvBPDLsATwLbg+7JaNCyYomv0fUxEpQQ@mail.gmail.com/ Fixes: 46a6e10a1ab1 ("btrfs: send: allow cloning non-aligned extent if it ends at i_size") CC: stable@vger.kernel.org # 6.11 Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/send.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 5871ca845b0e..27306d98ec43 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -6189,8 +6189,29 @@ static int send_write_or_clone(struct send_ctx *sctx, if (ret < 0) return ret; - if (clone_root->offset + num_bytes == info.size) + if (clone_root->offset + num_bytes == info.size) { + /* + * The final size of our file matches the end offset, but it may + * be that its current size is larger, so we have to truncate it + * to any value between the start offset of the range and the + * final i_size, otherwise the clone operation is invalid + * because it's unaligned and it ends before the current EOF. + * We do this truncate to the final i_size when we finish + * processing the inode, but it's too late by then. And here we + * truncate to the start offset of the range because it's always + * sector size aligned while if it were the final i_size it + * would result in dirtying part of a page, filling part of a + * page with zeroes and then having the clone operation at the + * receiver trigger IO and wait for it due to the dirty page. + */ + if (sctx->parent_root != NULL) { + ret = send_truncate(sctx, sctx->cur_ino, + sctx->cur_inode_gen, offset); + if (ret < 0) + return ret; + } goto clone_data; + } write_data: ret = send_extent_data(sctx, path, offset, num_bytes); -- GitLab From c3b47f49e83197e8dffd023ec568403bcdbb774b Mon Sep 17 00:00:00 2001 From: Qu Wenruo <wqu@suse.com> Date: Sat, 28 Sep 2024 08:05:58 +0930 Subject: [PATCH 572/970] btrfs: fix a NULL pointer dereference when failed to start a new trasacntion [BUG] Syzbot reported a NULL pointer dereference with the following crash: FAULT_INJECTION: forcing a failure. start_transaction+0x830/0x1670 fs/btrfs/transaction.c:676 prepare_to_relocate+0x31f/0x4c0 fs/btrfs/relocation.c:3642 relocate_block_group+0x169/0xd20 fs/btrfs/relocation.c:3678 ... BTRFS info (device loop0): balance: ended with status: -12 Oops: general protection fault, probably for non-canonical address 0xdffffc00000000cc: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000660-0x0000000000000667] RIP: 0010:btrfs_update_reloc_root+0x362/0xa80 fs/btrfs/relocation.c:926 Call Trace: <TASK> commit_fs_roots+0x2ee/0x720 fs/btrfs/transaction.c:1496 btrfs_commit_transaction+0xfaf/0x3740 fs/btrfs/transaction.c:2430 del_balance_item fs/btrfs/volumes.c:3678 [inline] reset_balance_state+0x25e/0x3c0 fs/btrfs/volumes.c:3742 btrfs_balance+0xead/0x10c0 fs/btrfs/volumes.c:4574 btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f [CAUSE] The allocation failure happens at the start_transaction() inside prepare_to_relocate(), and during the error handling we call unset_reloc_control(), which makes fs_info->balance_ctl to be NULL. Then we continue the error path cleanup in btrfs_balance() by calling reset_balance_state() which will call del_balance_item() to fully delete the balance item in the root tree. However during the small window between set_reloc_contrl() and unset_reloc_control(), we can have a subvolume tree update and created a reloc_root for that subvolume. Then we go into the final btrfs_commit_transaction() of del_balance_item(), and into btrfs_update_reloc_root() inside commit_fs_roots(). That function checks if fs_info->reloc_ctl is in the merge_reloc_tree stage, but since fs_info->reloc_ctl is NULL, it results a NULL pointer dereference. [FIX] Just add extra check on fs_info->reloc_ctl inside btrfs_update_reloc_root(), before checking fs_info->reloc_ctl->merge_reloc_tree. That DEAD_RELOC_TREE handling is to prevent further modification to the reloc tree during merge stage, but since there is no reloc_ctl at all, we do not need to bother that. Reported-by: syzbot+283673dbc38527ef9f3d@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-btrfs/66f6bfa7.050a0220.38ace9.0019.GAE@google.com/ CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/relocation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index cf1dfeaaf2d8..f3834f8d26b4 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -856,7 +856,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, btrfs_grab_root(reloc_root); /* root->reloc_root will stay until current relocation finished */ - if (fs_info->reloc_ctl->merge_reloc_tree && + if (fs_info->reloc_ctl && fs_info->reloc_ctl->merge_reloc_tree && btrfs_root_refs(root_item) == 0) { set_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state); /* -- GitLab From 41fd1e94066a815a7ab0a7025359e9b40e4b3576 Mon Sep 17 00:00:00 2001 From: Filipe Manana <fdmanana@suse.com> Date: Tue, 1 Oct 2024 11:06:52 +0100 Subject: [PATCH 573/970] btrfs: wait for fixup workers before stopping cleaner kthread during umount During unmount, at close_ctree(), we have the following steps in this order: 1) Park the cleaner kthread - this doesn't destroy the kthread, it basically halts its execution (wake ups against it work but do nothing); 2) We stop the cleaner kthread - this results in freeing the respective struct task_struct; 3) We call btrfs_stop_all_workers() which waits for any jobs running in all the work queues and then free the work queues. Syzbot reported a case where a fixup worker resulted in a crash when doing a delayed iput on its inode while attempting to wake up the cleaner at btrfs_add_delayed_iput(), because the task_struct of the cleaner kthread was already freed. This can happen during unmount because we don't wait for any fixup workers still running before we call kthread_stop() against the cleaner kthread, which stops and free all its resources. Fix this by waiting for any fixup workers at close_ctree() before we call kthread_stop() against the cleaner and run pending delayed iputs. The stack traces reported by syzbot were the following: BUG: KASAN: slab-use-after-free in __lock_acquire+0x77/0x2050 kernel/locking/lockdep.c:5065 Read of size 8 at addr ffff8880272a8a18 by task kworker/u8:3/52 CPU: 1 UID: 0 PID: 52 Comm: kworker/u8:3 Not tainted 6.12.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Workqueue: btrfs-fixup btrfs_work_helper Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 __lock_acquire+0x77/0x2050 kernel/locking/lockdep.c:5065 lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0xd5/0x120 kernel/locking/spinlock.c:162 class_raw_spinlock_irqsave_constructor include/linux/spinlock.h:551 [inline] try_to_wake_up+0xb0/0x1480 kernel/sched/core.c:4154 btrfs_writepage_fixup_worker+0xc16/0xdf0 fs/btrfs/inode.c:2842 btrfs_work_helper+0x390/0xc50 fs/btrfs/async-thread.c:314 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa63/0x1850 kernel/workqueue.c:3310 worker_thread+0x870/0xd30 kernel/workqueue.c:3391 kthread+0x2f0/0x390 kernel/kthread.c:389 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 </TASK> Allocated by task 2: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 unpoison_slab_object mm/kasan/common.c:319 [inline] __kasan_slab_alloc+0x66/0x80 mm/kasan/common.c:345 kasan_slab_alloc include/linux/kasan.h:247 [inline] slab_post_alloc_hook mm/slub.c:4086 [inline] slab_alloc_node mm/slub.c:4135 [inline] kmem_cache_alloc_node_noprof+0x16b/0x320 mm/slub.c:4187 alloc_task_struct_node kernel/fork.c:180 [inline] dup_task_struct+0x57/0x8c0 kernel/fork.c:1107 copy_process+0x5d1/0x3d50 kernel/fork.c:2206 kernel_clone+0x223/0x880 kernel/fork.c:2787 kernel_thread+0x1bc/0x240 kernel/fork.c:2849 create_kthread kernel/kthread.c:412 [inline] kthreadd+0x60d/0x810 kernel/kthread.c:765 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 Freed by task 61: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x59/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:230 [inline] slab_free_hook mm/slub.c:2343 [inline] slab_free mm/slub.c:4580 [inline] kmem_cache_free+0x1a2/0x420 mm/slub.c:4682 put_task_struct include/linux/sched/task.h:144 [inline] delayed_put_task_struct+0x125/0x300 kernel/exit.c:228 rcu_do_batch kernel/rcu/tree.c:2567 [inline] rcu_core+0xaaa/0x17a0 kernel/rcu/tree.c:2823 handle_softirqs+0x2c5/0x980 kernel/softirq.c:554 __do_softirq kernel/softirq.c:588 [inline] invoke_softirq kernel/softirq.c:428 [inline] __irq_exit_rcu+0xf4/0x1c0 kernel/softirq.c:637 irq_exit_rcu+0x9/0x30 kernel/softirq.c:649 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1037 [inline] sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1037 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702 Last potentially related work creation: kasan_save_stack+0x3f/0x60 mm/kasan/common.c:47 __kasan_record_aux_stack+0xac/0xc0 mm/kasan/generic.c:541 __call_rcu_common kernel/rcu/tree.c:3086 [inline] call_rcu+0x167/0xa70 kernel/rcu/tree.c:3190 context_switch kernel/sched/core.c:5318 [inline] __schedule+0x184b/0x4ae0 kernel/sched/core.c:6675 schedule_idle+0x56/0x90 kernel/sched/core.c:6793 do_idle+0x56a/0x5d0 kernel/sched/idle.c:354 cpu_startup_entry+0x42/0x60 kernel/sched/idle.c:424 start_secondary+0x102/0x110 arch/x86/kernel/smpboot.c:314 common_startup_64+0x13e/0x147 The buggy address belongs to the object at ffff8880272a8000 which belongs to the cache task_struct of size 7424 The buggy address is located 2584 bytes inside of freed 7424-byte region [ffff8880272a8000, ffff8880272a9d00) The buggy address belongs to the physical page: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x272a8 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff) page_type: f5(slab) raw: 00fff00000000040 ffff88801bafa500 dead000000000122 0000000000000000 raw: 0000000000000000 0000000080040004 00000001f5000000 0000000000000000 head: 00fff00000000040 ffff88801bafa500 dead000000000122 0000000000000000 head: 0000000000000000 0000000080040004 00000001f5000000 0000000000000000 head: 00fff00000000003 ffffea00009caa01 ffffffffffffffff 0000000000000000 head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 2, tgid 2 (kthreadd), ts 71247381401, free_ts 71214998153 set_page_owner include/linux/page_owner.h:32 [inline] post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1537 prep_new_page mm/page_alloc.c:1545 [inline] get_page_from_freelist+0x3039/0x3180 mm/page_alloc.c:3457 __alloc_pages_noprof+0x256/0x6c0 mm/page_alloc.c:4733 alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265 alloc_slab_page+0x6a/0x120 mm/slub.c:2413 allocate_slab+0x5a/0x2f0 mm/slub.c:2579 new_slab mm/slub.c:2632 [inline] ___slab_alloc+0xcd1/0x14b0 mm/slub.c:3819 __slab_alloc+0x58/0xa0 mm/slub.c:3909 __slab_alloc_node mm/slub.c:3962 [inline] slab_alloc_node mm/slub.c:4123 [inline] kmem_cache_alloc_node_noprof+0x1fe/0x320 mm/slub.c:4187 alloc_task_struct_node kernel/fork.c:180 [inline] dup_task_struct+0x57/0x8c0 kernel/fork.c:1107 copy_process+0x5d1/0x3d50 kernel/fork.c:2206 kernel_clone+0x223/0x880 kernel/fork.c:2787 kernel_thread+0x1bc/0x240 kernel/fork.c:2849 create_kthread kernel/kthread.c:412 [inline] kthreadd+0x60d/0x810 kernel/kthread.c:765 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 page last free pid 5230 tgid 5230 stack trace: reset_page_owner include/linux/page_owner.h:25 [inline] free_pages_prepare mm/page_alloc.c:1108 [inline] free_unref_page+0xcd0/0xf00 mm/page_alloc.c:2638 discard_slab mm/slub.c:2678 [inline] __put_partials+0xeb/0x130 mm/slub.c:3146 put_cpu_partial+0x17c/0x250 mm/slub.c:3221 __slab_free+0x2ea/0x3d0 mm/slub.c:4450 qlink_free mm/kasan/quarantine.c:163 [inline] qlist_free_all+0x9a/0x140 mm/kasan/quarantine.c:179 kasan_quarantine_reduce+0x14f/0x170 mm/kasan/quarantine.c:286 __kasan_slab_alloc+0x23/0x80 mm/kasan/common.c:329 kasan_slab_alloc include/linux/kasan.h:247 [inline] slab_post_alloc_hook mm/slub.c:4086 [inline] slab_alloc_node mm/slub.c:4135 [inline] kmem_cache_alloc_noprof+0x135/0x2a0 mm/slub.c:4142 getname_flags+0xb7/0x540 fs/namei.c:139 do_sys_openat2+0xd2/0x1d0 fs/open.c:1409 do_sys_open fs/open.c:1430 [inline] __do_sys_openat fs/open.c:1446 [inline] __se_sys_openat fs/open.c:1441 [inline] __x64_sys_openat+0x247/0x2a0 fs/open.c:1441 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Memory state around the buggy address: ffff8880272a8900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8880272a8980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff8880272a8a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff8880272a8a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff8880272a8b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Reported-by: syzbot+8aaf2df2ef0164ffe1fb@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-btrfs/66fb36b1.050a0220.aab67.003b.GAE@google.com/ CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/disk-io.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 25d768e67e37..1238a38c59b2 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -4255,6 +4255,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) /* clear out the rbtree of defraggable inodes */ btrfs_cleanup_defrag_inodes(fs_info); + /* + * Wait for any fixup workers to complete. + * If we don't wait for them here and they are still running by the time + * we call kthread_stop() against the cleaner kthread further below, we + * get an use-after-free on the cleaner because the fixup worker adds an + * inode to the list of delayed iputs and then attempts to wakeup the + * cleaner kthread, which was already stopped and destroyed. We parked + * already the cleaner, but below we run all pending delayed iputs. + */ + btrfs_flush_workqueue(fs_info->fixup_workers); + /* * After we parked the cleaner kthread, ordered extents may have * completed and created new delayed iputs. If one of the async reclaim -- GitLab From d6e7ac65d4c106149d08a0ffba39fc516ae3d21b Mon Sep 17 00:00:00 2001 From: Leo Martins <loemra.dev@gmail.com> Date: Tue, 24 Sep 2024 16:42:29 -0700 Subject: [PATCH 574/970] btrfs: disable rate limiting when debug enabled Disable ratelimiting for btrfs_printk when CONFIG_BTRFS_DEBUG is enabled. This allows for more verbose output which is often needed by functions like btrfs_dump_space_info(). Reviewed-by: Qu Wenruo <wqu@suse.com> Signed-off-by: Leo Martins <loemra.dev@gmail.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/messages.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/messages.c b/fs/btrfs/messages.c index 77752eec125d..363fd28c0268 100644 --- a/fs/btrfs/messages.c +++ b/fs/btrfs/messages.c @@ -239,7 +239,8 @@ void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, vaf.fmt = fmt; vaf.va = &args; - if (__ratelimit(ratelimit)) { + /* Do not ratelimit if CONFIG_BTRFS_DEBUG is enabled. */ + if (IS_ENABLED(CONFIG_BTRFS_DEBUG) || __ratelimit(ratelimit)) { if (fs_info) { char statestr[STATE_STRING_BUF_LEN]; -- GitLab From 68a16708d2503b6303d67abd43801e2ca40c208d Mon Sep 17 00:00:00 2001 From: Ben Dooks <ben.dooks@codethink.co.uk> Date: Tue, 24 Sep 2024 14:40:08 +0100 Subject: [PATCH 575/970] spi: s3c64xx: fix timeout counters in flush_fifo In the s3c64xx_flush_fifo() code, the loops counter is post-decremented in the do { } while(test && loops--) condition. This means the loops is left at the unsigned equivalent of -1 if the loop times out. The test after will never pass as if tests for loops == 0. Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver") Reviewed-by: Andi Shyti <andi.shyti@kernel.org> Link: https://patch.msgid.link/20240924134009.116247-2-ben.dooks@codethink.co.uk Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/spi/spi-s3c64xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 51a002b3f518..8c9e5e97041f 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -245,7 +245,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) loops = msecs_to_loops(1); do { val = readl(regs + S3C64XX_SPI_STATUS); - } while (TX_FIFO_LVL(val, sdd) && loops--); + } while (TX_FIFO_LVL(val, sdd) && --loops); if (loops == 0) dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); @@ -258,7 +258,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) readl(regs + S3C64XX_SPI_RX_DATA); else break; - } while (loops--); + } while (--loops); if (loops == 0) dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); -- GitLab From 8b4865cd904650cbed7f2407e653934c621b8127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <ukleinek@debian.org> Date: Thu, 19 Sep 2024 10:11:21 +0200 Subject: [PATCH 576/970] cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit notify_hwp_interrupt() is called via sysvec_thermal() -> smp_thermal_vector() -> intel_thermal_interrupt() in hard irq context. For this reason it must not use a simple spin_lock that sleeps with PREEMPT_RT enabled. So convert it to a raw spinlock. Reported-by: xiao sheng wen <atzlinux@sina.com> Link: https://bugs.debian.org/1076483 Signed-off-by: Uwe Kleine-König <ukleinek@debian.org> Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Tested-by: xiao sheng wen <atzlinux@sina.com> Link: https://patch.msgid.link/20240919081121.10784-2-ukleinek@debian.org Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/cpufreq/intel_pstate.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index aaea9a39eced..b0018f371ea3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1845,7 +1845,7 @@ static void intel_pstate_notify_work(struct work_struct *work) wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0); } -static DEFINE_SPINLOCK(hwp_notify_lock); +static DEFINE_RAW_SPINLOCK(hwp_notify_lock); static cpumask_t hwp_intr_enable_mask; #define HWP_GUARANTEED_PERF_CHANGE_STATUS BIT(0) @@ -1868,7 +1868,7 @@ void notify_hwp_interrupt(void) if (!(value & status_mask)) return; - spin_lock_irqsave(&hwp_notify_lock, flags); + raw_spin_lock_irqsave(&hwp_notify_lock, flags); if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask)) goto ack_intr; @@ -1876,13 +1876,13 @@ void notify_hwp_interrupt(void) schedule_delayed_work(&all_cpu_data[this_cpu]->hwp_notify_work, msecs_to_jiffies(10)); - spin_unlock_irqrestore(&hwp_notify_lock, flags); + raw_spin_unlock_irqrestore(&hwp_notify_lock, flags); return; ack_intr: wrmsrl_safe(MSR_HWP_STATUS, 0); - spin_unlock_irqrestore(&hwp_notify_lock, flags); + raw_spin_unlock_irqrestore(&hwp_notify_lock, flags); } static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata) @@ -1895,9 +1895,9 @@ static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata) /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00); - spin_lock_irq(&hwp_notify_lock); + raw_spin_lock_irq(&hwp_notify_lock); cancel_work = cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask); - spin_unlock_irq(&hwp_notify_lock); + raw_spin_unlock_irq(&hwp_notify_lock); if (cancel_work) cancel_delayed_work_sync(&cpudata->hwp_notify_work); @@ -1912,10 +1912,10 @@ static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata) if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) { u64 interrupt_mask = HWP_GUARANTEED_PERF_CHANGE_REQ; - spin_lock_irq(&hwp_notify_lock); + raw_spin_lock_irq(&hwp_notify_lock); INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work); cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask); - spin_unlock_irq(&hwp_notify_lock); + raw_spin_unlock_irq(&hwp_notify_lock); if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE)) interrupt_mask |= HWP_HIGHEST_PERF_CHANGE_REQ; -- GitLab From c0f02536fffbbec71aced36d52a765f8c4493dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miquel=20Sabat=C3=A9=20Sol=C3=A0?= <mikisabate@gmail.com> Date: Tue, 17 Sep 2024 15:42:46 +0200 Subject: [PATCH 577/970] cpufreq: Avoid a bad reference count on CPU node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the parse_perf_domain function, if the call to of_parse_phandle_with_args returns an error, then the reference to the CPU device node that was acquired at the start of the function would not be properly decremented. Address this by declaring the variable with the __free(device_node) cleanup attribute. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Link: https://patch.msgid.link/20240917134246.584026-1-mikisabate@gmail.com Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- include/linux/cpufreq.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e0e19d9c1323..7fe0981a7e46 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -1107,10 +1107,9 @@ static inline int parse_perf_domain(int cpu, const char *list_name, const char *cell_name, struct of_phandle_args *args) { - struct device_node *cpu_np; int ret; - cpu_np = of_cpu_device_node_get(cpu); + struct device_node *cpu_np __free(device_node) = of_cpu_device_node_get(cpu); if (!cpu_np) return -ENODEV; @@ -1118,9 +1117,6 @@ static inline int parse_perf_domain(int cpu, const char *list_name, args); if (ret < 0) return ret; - - of_node_put(cpu_np); - return 0; } -- GitLab From ac78288fe062b64e45a479eaae74aaaafcc8ecdd Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Wed, 18 Sep 2024 17:38:49 +0200 Subject: [PATCH 578/970] ACPI: video: Add backlight=native quirk for Dell OptiPlex 5480 AIO Dell All In One (AIO) models released after 2017 may use a backlight controller board connected to an UART. In DSDT this uart port will be defined as: Name (_HID, "DELL0501") Name (_CID, EisaId ("PNP0501") The Dell OptiPlex 5480 AIO has an ACPI device for one of its UARTs with the above _HID + _CID. Loading the dell-uart-backlight driver fails with the following errors: [ 18.261353] dell_uart_backlight serial0-0: Timed out waiting for response. [ 18.261356] dell_uart_backlight serial0-0: error -ETIMEDOUT: getting firmware version [ 18.261359] dell_uart_backlight serial0-0: probe with driver dell_uart_backlight failed with error -110 Indicating that there is no backlight controller board attached to the UART, while the GPU's native backlight control method does work. Add a quirk to use the GPU's native backlight control method on this model. Fixes: cd8e468efb4f ("ACPI: video: Add Dell UART backlight controller detection") Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://patch.msgid.link/20240918153849.37221-1-hdegoede@redhat.com [ rjw: Changelog edit ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/video_detect.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index b70e84e8049a..015bd8e66c1c 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -844,6 +844,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { * controller board in their ACPI tables (and may even have one), but * which need native backlight control nevertheless. */ + { + /* https://github.com/zabbly/linux/issues/26 */ + .callback = video_detect_force_native, + /* Dell OptiPlex 5480 AIO */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 5480 AIO"), + }, + }, { /* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */ .callback = video_detect_force_native, -- GitLab From 04afb0a3c30aeb5fbe890a92debbfc0cc4044b6f Mon Sep 17 00:00:00 2001 From: Thorsten Blum <thorsten.blum@linux.dev> Date: Fri, 27 Sep 2024 16:36:42 +0200 Subject: [PATCH 579/970] ksmbd: Use struct_size() to improve get_file_alternate_info() Use struct_size() to calculate the output buffer length. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/server/smb2pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 7460089c186f..f28346fad894 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4883,7 +4883,7 @@ static void get_file_alternate_info(struct ksmbd_work *work, spin_unlock(&dentry->d_lock); file_info->FileNameLength = cpu_to_le32(conv_len); rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len); + cpu_to_le32(struct_size(file_info, FileName, conv_len)); } static int get_file_stream_info(struct ksmbd_work *work, -- GitLab From 0801c1374ab1552bd7376370987142ff77912527 Mon Sep 17 00:00:00 2001 From: Thorsten Blum <thorsten.blum@linux.dev> Date: Wed, 25 Sep 2024 11:03:13 +0200 Subject: [PATCH 580/970] ksmbd: Annotate struct copychunk_ioctl_req with __counted_by_le() Add the __counted_by_le compiler attribute to the flexible array member Chunks to improve access bounds-checking via CONFIG_UBSAN_BOUNDS and CONFIG_FORTIFY_SOURCE. Change the data type of the flexible array member Chunks from __u8[] to struct srv_copychunk[] for ChunkCount to match the number of elements in the Chunks array. (With __u8[], each srv_copychunk would occupy 24 array entries and the __counted_by compiler attribute wouldn't be applicable.) Use struct_size() to calculate the size of the copychunk_ioctl_req. Read Chunks[0] after checking that ChunkCount is not 0. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/server/smb2pdu.c | 5 ++--- fs/smb/server/smb2pdu.h | 14 +++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index f28346fad894..797b0f24097b 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -7562,7 +7562,6 @@ static int fsctl_copychunk(struct ksmbd_work *work, ci_rsp->TotalBytesWritten = cpu_to_le32(ksmbd_server_side_copy_max_total_size()); - chunks = (struct srv_copychunk *)&ci_req->Chunks[0]; chunk_count = le32_to_cpu(ci_req->ChunkCount); if (chunk_count == 0) goto out; @@ -7570,12 +7569,12 @@ static int fsctl_copychunk(struct ksmbd_work *work, /* verify the SRV_COPYCHUNK_COPY packet */ if (chunk_count > ksmbd_server_side_copy_max_chunk_count() || - input_count < offsetof(struct copychunk_ioctl_req, Chunks) + - chunk_count * sizeof(struct srv_copychunk)) { + input_count < struct_size(ci_req, Chunks, chunk_count)) { rsp->hdr.Status = STATUS_INVALID_PARAMETER; return -EINVAL; } + chunks = &ci_req->Chunks[0]; for (i = 0; i < chunk_count; i++) { if (le32_to_cpu(chunks[i].Length) == 0 || le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size()) diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h index 73aff20e22d0..649dacf7e8c4 100644 --- a/fs/smb/server/smb2pdu.h +++ b/fs/smb/server/smb2pdu.h @@ -190,13 +190,6 @@ struct resume_key_ioctl_rsp { __u8 Context[4]; /* ignored, Windows sets to 4 bytes of zero */ } __packed; -struct copychunk_ioctl_req { - __le64 ResumeKey[3]; - __le32 ChunkCount; - __le32 Reserved; - __u8 Chunks[]; /* array of srv_copychunk */ -} __packed; - struct srv_copychunk { __le64 SourceOffset; __le64 TargetOffset; @@ -204,6 +197,13 @@ struct srv_copychunk { __le32 Reserved; } __packed; +struct copychunk_ioctl_req { + __le64 ResumeKey[3]; + __le32 ChunkCount; + __le32 Reserved; + struct srv_copychunk Chunks[] __counted_by_le(ChunkCount); +} __packed; + struct copychunk_ioctl_rsp { __le32 ChunksWritten; __le32 ChunkBytesWritten; -- GitLab From 9c383396362a4d1db99ed5240f4708d443361ef3 Mon Sep 17 00:00:00 2001 From: Thorsten Blum <thorsten.blum@linux.dev> Date: Sat, 28 Sep 2024 17:00:30 +0200 Subject: [PATCH 581/970] ksmbd: Use struct_size() to improve smb_direct_rdma_xmit() Use struct_size() to calculate the number of bytes to allocate for a new message. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/server/transport_rdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index 44c87e300c16..17c76713c6d0 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -1405,8 +1405,8 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, /* build rdma_rw_ctx for each descriptor */ desc_buf = buf; for (i = 0; i < desc_num; i++) { - msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) + - sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL); + msg = kzalloc(struct_size(msg, sg_list, SG_CHUNK_SIZE), + GFP_KERNEL); if (!msg) { ret = -ENOMEM; goto out; -- GitLab From cfb10de18538e383dbc4f3ce7f477ce49287ff3d Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti <alexghiti@rivosinc.com> Date: Tue, 17 Sep 2024 17:03:28 +0200 Subject: [PATCH 582/970] riscv: Fix kernel stack size when KASAN is enabled We use Kconfig to select the kernel stack size, doubling the default size if KASAN is enabled. But that actually only works if KASAN is selected from the beginning, meaning that if KASAN config is added later (for example using menuconfig), CONFIG_THREAD_SIZE_ORDER won't be updated, keeping the default size, which is not enough for KASAN as reported in [1]. So fix this by moving the logic to compute the right kernel stack into a header. Fixes: a7555f6b62e7 ("riscv: stack: Add config of thread stack size") Reported-by: syzbot+ba9eac24453387a9d502@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/000000000000eb301906222aadc2@google.com/ [1] Cc: stable@vger.kernel.org Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> Link: https://lore.kernel.org/r/20240917150328.59831-1-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> --- arch/riscv/Kconfig | 3 +-- arch/riscv/include/asm/thread_info.h | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 22dc5ea4196c..62545946ecf4 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -777,8 +777,7 @@ config IRQ_STACKS config THREAD_SIZE_ORDER int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT range 0 4 - default 1 if 32BIT && !KASAN - default 3 if 64BIT && KASAN + default 1 if 32BIT default 2 help Specify the Pages of thread stack size (from 4KB to 64KB), which also diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h index ebe52f96da34..9c10fb180f43 100644 --- a/arch/riscv/include/asm/thread_info.h +++ b/arch/riscv/include/asm/thread_info.h @@ -13,7 +13,12 @@ #include <linux/sizes.h> /* thread information allocation */ -#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER +#ifdef CONFIG_KASAN +#define KASAN_STACK_ORDER 1 +#else +#define KASAN_STACK_ORDER 0 +#endif +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER) #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) /* -- GitLab From e764e68103c12aef161480b8da984c36ca99cfb5 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Mon, 30 Sep 2024 18:46:48 -0400 Subject: [PATCH 583/970] bcachefs: Fix bad shift in bch2_read_flag_list() Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c index 42f565c76181..e0a876cbaa6b 100644 --- a/fs/bcachefs/util.c +++ b/fs/bcachefs/util.c @@ -222,7 +222,7 @@ u64 bch2_read_flag_list(const char *opt, const char * const list[]) break; } - ret |= 1 << flag; + ret |= BIT_ULL(flag); } kfree(d); -- GitLab From 59a1c9c7e1d02b43b415ea92627ce095b7c79e47 Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 27 Sep 2024 09:13:08 -0700 Subject: [PATCH 584/970] drm/xe: Prevent null pointer access in xe_migrate_copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xe_migrate_copy designed to copy content of TTM resources. When source resource is null, it will trigger a NULL pointer dereference in xe_migrate_copy. To avoid this situation, update lacks source flag to true for this case, the flag will trigger xe_migrate_clear rather than xe_migrate_copy. Issue trace: <7> [317.089847] xe 0000:00:02.0: [drm:xe_migrate_copy [xe]] Pass 14, sizes: 4194304 & 4194304 <7> [317.089945] xe 0000:00:02.0: [drm:xe_migrate_copy [xe]] Pass 15, sizes: 4194304 & 4194304 <1> [317.128055] BUG: kernel NULL pointer dereference, address: 0000000000000010 <1> [317.128064] #PF: supervisor read access in kernel mode <1> [317.128066] #PF: error_code(0x0000) - not-present page <6> [317.128069] PGD 0 P4D 0 <4> [317.128071] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI <4> [317.128074] CPU: 1 UID: 0 PID: 1440 Comm: kunit_try_catch Tainted: G U N 6.11.0-rc7-xe #1 <4> [317.128078] Tainted: [U]=USER, [N]=TEST <4> [317.128080] Hardware name: Intel Corporation Lunar Lake Client Platform/LNL-M LP5 RVP1, BIOS LNLMFWI1.R00.3221.D80.2407291239 07/29/2024 <4> [317.128082] RIP: 0010:xe_migrate_copy+0x66/0x13e0 [xe] <4> [317.128158] Code: 00 00 48 89 8d e0 fe ff ff 48 8b 40 10 4c 89 85 c8 fe ff ff 44 88 8d bd fe ff ff 65 48 8b 3c 25 28 00 00 00 48 89 7d d0 31 ff <8b> 79 10 48 89 85 a0 fe ff ff 48 8b 00 48 89 b5 d8 fe ff ff 83 ff <4> [317.128162] RSP: 0018:ffffc9000167f9f0 EFLAGS: 00010246 <4> [317.128164] RAX: ffff8881120d8028 RBX: ffff88814d070428 RCX: 0000000000000000 <4> [317.128166] RDX: ffff88813cb99c00 RSI: 0000000004000000 RDI: 0000000000000000 <4> [317.128168] RBP: ffffc9000167fbb8 R08: ffff88814e7b1f08 R09: 0000000000000001 <4> [317.128170] R10: 0000000000000001 R11: 0000000000000001 R12: ffff88814e7b1f08 <4> [317.128172] R13: ffff88814e7b1f08 R14: ffff88813cb99c00 R15: 0000000000000001 <4> [317.128174] FS: 0000000000000000(0000) GS:ffff88846f280000(0000) knlGS:0000000000000000 <4> [317.128176] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4> [317.128178] CR2: 0000000000000010 CR3: 000000011f676004 CR4: 0000000000770ef0 <4> [317.128180] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <4> [317.128182] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 <4> [317.128184] PKRU: 55555554 <4> [317.128185] Call Trace: <4> [317.128187] <TASK> <4> [317.128189] ? show_regs+0x67/0x70 <4> [317.128194] ? __die_body+0x20/0x70 <4> [317.128196] ? __die+0x2b/0x40 <4> [317.128198] ? page_fault_oops+0x15f/0x4e0 <4> [317.128203] ? do_user_addr_fault+0x3fb/0x970 <4> [317.128205] ? lock_acquire+0xc7/0x2e0 <4> [317.128209] ? exc_page_fault+0x87/0x2b0 <4> [317.128212] ? asm_exc_page_fault+0x27/0x30 <4> [317.128216] ? xe_migrate_copy+0x66/0x13e0 [xe] <4> [317.128263] ? __lock_acquire+0xb9d/0x26f0 <4> [317.128265] ? __lock_acquire+0xb9d/0x26f0 <4> [317.128267] ? sg_free_append_table+0x20/0x80 <4> [317.128271] ? lock_acquire+0xc7/0x2e0 <4> [317.128273] ? mark_held_locks+0x4d/0x80 <4> [317.128275] ? trace_hardirqs_on+0x1e/0xd0 <4> [317.128278] ? _raw_spin_unlock_irqrestore+0x31/0x60 <4> [317.128281] ? __pm_runtime_resume+0x60/0xa0 <4> [317.128284] xe_bo_move+0x682/0xc50 [xe] <4> [317.128315] ? lock_is_held_type+0xaa/0x120 <4> [317.128318] ttm_bo_handle_move_mem+0xe5/0x1a0 [ttm] <4> [317.128324] ttm_bo_validate+0xd1/0x1a0 [ttm] <4> [317.128328] shrink_test_run_device+0x721/0xc10 [xe] <4> [317.128360] ? find_held_lock+0x31/0x90 <4> [317.128363] ? lock_release+0xd1/0x2a0 <4> [317.128365] ? __pfx_kunit_generic_run_threadfn_adapter+0x10/0x10 [kunit] <4> [317.128370] xe_bo_shrink_kunit+0x11/0x20 [xe] <4> [317.128397] kunit_try_run_case+0x6e/0x150 [kunit] <4> [317.128400] ? trace_hardirqs_on+0x1e/0xd0 <4> [317.128402] ? _raw_spin_unlock_irqrestore+0x31/0x60 <4> [317.128404] kunit_generic_run_threadfn_adapter+0x1e/0x40 [kunit] <4> [317.128407] kthread+0xf5/0x130 <4> [317.128410] ? __pfx_kthread+0x10/0x10 <4> [317.128412] ret_from_fork+0x39/0x60 <4> [317.128415] ? __pfx_kthread+0x10/0x10 <4> [317.128416] ret_from_fork_asm+0x1a/0x30 <4> [317.128420] </TASK> Fixes: 266c85885263 ("drm/xe/xe2: Handle flat ccs move for igfx.") Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240927161308.862323-2-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/xe_bo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index 5f2f1ec46b57..5e8f60a8d431 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -682,8 +682,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict, tt_has_data = ttm && (ttm_tt_is_populated(ttm) || (ttm->page_flags & TTM_TT_FLAG_SWAPPED)); - move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared) : - (!mem_type_is_vram(old_mem_type) && !tt_has_data); + move_lacks_source = !old_mem || (handle_system_ccs ? (!bo->ccs_cleared) : + (!mem_type_is_vram(old_mem_type) && !tt_has_data)); needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) || (!ttm && ttm_bo->type == ttm_bo_type_device); -- GitLab From a7b3bcc8e8495ff45128caab7ceee2534d1b8e8d Mon Sep 17 00:00:00 2001 From: Tejas Vipin <tejasvipin76@gmail.com> Date: Wed, 25 Sep 2024 13:30:03 +0530 Subject: [PATCH 585/970] drm/panel: elida-kd35t133: transition to mipi_dsi wrapped functions Changes the elida-kd35t133 panel to use multi style functions for improved error handling. Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Tejas Vipin <tejasvipin76@gmail.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240925080003.1250448-1-tejasvipin76@gmail.com --- drivers/gpu/drm/panel/panel-elida-kd35t133.c | 108 ++++++++----------- 1 file changed, 45 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c index 00791ea81e90..b904d5437444 100644 --- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c +++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c @@ -50,55 +50,44 @@ static inline struct kd35t133 *panel_to_kd35t133(struct drm_panel *panel) return container_of(panel, struct kd35t133, panel); } -static int kd35t133_init_sequence(struct kd35t133 *ctx) +static void kd35t133_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) { - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); - struct device *dev = ctx->dev; - /* * Init sequence was supplied by the panel vendor with minimal * documentation. */ - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_POSITIVEGAMMA, - 0x00, 0x13, 0x18, 0x04, 0x0f, 0x06, 0x3a, 0x56, - 0x4d, 0x03, 0x0a, 0x06, 0x30, 0x3e, 0x0f); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_NEGATIVEGAMMA, - 0x00, 0x13, 0x18, 0x01, 0x11, 0x06, 0x38, 0x34, - 0x4d, 0x06, 0x0d, 0x0b, 0x31, 0x37, 0x0f); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_POWERCONTROL1, 0x18, 0x17); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_POWERCONTROL2, 0x41); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_VCOMCONTROL, 0x00, 0x1a, 0x80); - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x48); - mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_INTERFACEMODECTRL, 0x00); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_FRAMERATECTRL, 0xa0); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_DISPLAYINVERSIONCTRL, 0x02); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_DISPLAYFUNCTIONCTRL, - 0x20, 0x02); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_SETIMAGEFUNCTION, 0x00); - mipi_dsi_dcs_write_seq(dsi, KD35T133_CMD_ADJUSTCONTROL3, - 0xa9, 0x51, 0x2c, 0x82); - mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_INVERT_MODE, NULL, 0); - - dev_dbg(dev, "Panel init sequence done\n"); - return 0; + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_POSITIVEGAMMA, + 0x00, 0x13, 0x18, 0x04, 0x0f, 0x06, 0x3a, 0x56, + 0x4d, 0x03, 0x0a, 0x06, 0x30, 0x3e, 0x0f); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_NEGATIVEGAMMA, + 0x00, 0x13, 0x18, 0x01, 0x11, 0x06, 0x38, 0x34, + 0x4d, 0x06, 0x0d, 0x0b, 0x31, 0x37, 0x0f); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_POWERCONTROL1, 0x18, 0x17); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_POWERCONTROL2, 0x41); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_VCOMCONTROL, 0x00, 0x1a, 0x80); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x48); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_INTERFACEMODECTRL, 0x00); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_FRAMERATECTRL, 0xa0); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_DISPLAYINVERSIONCTRL, 0x02); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_DISPLAYFUNCTIONCTRL, + 0x20, 0x02); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_SETIMAGEFUNCTION, 0x00); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, KD35T133_CMD_ADJUSTCONTROL3, + 0xa9, 0x51, 0x2c, 0x82); + mipi_dsi_dcs_write_seq_multi(dsi_ctx, MIPI_DCS_ENTER_INVERT_MODE); } static int kd35t133_unprepare(struct drm_panel *panel) { struct kd35t133 *ctx = panel_to_kd35t133(panel); struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) - dev_err(ctx->dev, "failed to set display off: %d\n", ret); - - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) { - dev_err(ctx->dev, "failed to enter sleep mode: %d\n", ret); - return ret; - } + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + if (dsi_ctx.accum_err) + return dsi_ctx.accum_err; gpiod_set_value_cansleep(ctx->reset_gpio, 1); @@ -112,18 +101,20 @@ static int kd35t133_prepare(struct drm_panel *panel) { struct kd35t133 *ctx = panel_to_kd35t133(panel); struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dev_dbg(ctx->dev, "Resetting the panel\n"); - ret = regulator_enable(ctx->vdd); - if (ret < 0) { - dev_err(ctx->dev, "Failed to enable vdd supply: %d\n", ret); - return ret; + dsi_ctx.accum_err = regulator_enable(ctx->vdd); + if (dsi_ctx.accum_err) { + dev_err(ctx->dev, "Failed to enable vdd supply: %d\n", + dsi_ctx.accum_err); + return dsi_ctx.accum_err; } - ret = regulator_enable(ctx->iovcc); - if (ret < 0) { - dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); + dsi_ctx.accum_err = regulator_enable(ctx->iovcc); + if (dsi_ctx.accum_err) { + dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", + dsi_ctx.accum_err); goto disable_vdd; } @@ -135,27 +126,18 @@ static int kd35t133_prepare(struct drm_panel *panel) msleep(20); - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { - dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret); - goto disable_iovcc; - } + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 250); - msleep(250); + kd35t133_init_sequence(&dsi_ctx); + if (!dsi_ctx.accum_err) + dev_dbg(ctx->dev, "Panel init sequence done\n"); - ret = kd35t133_init_sequence(ctx); - if (ret < 0) { - dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret); - goto disable_iovcc; - } + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 50); - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) { - dev_err(ctx->dev, "Failed to set display on: %d\n", ret); + if (dsi_ctx.accum_err) goto disable_iovcc; - } - - msleep(50); return 0; @@ -163,7 +145,7 @@ static int kd35t133_prepare(struct drm_panel *panel) regulator_disable(ctx->iovcc); disable_vdd: regulator_disable(ctx->vdd); - return ret; + return dsi_ctx.accum_err; } static const struct drm_display_mode default_mode = { -- GitLab From 05cef2c4a421ca09ab9761a95e61423e59e5bfb1 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda <ojeda@kernel.org> Date: Fri, 27 Sep 2024 18:44:14 +0200 Subject: [PATCH 586/970] rust: kunit: use C-string literals to clean warning Starting with upstream Rust commit a5e3a3f9b6bd ("move `manual_c_str_literals` to complexity"), to be released in Rust 1.83.0 [1], Clippy now warns on `manual_c_str_literals` by default, e.g.: error: manually constructing a nul-terminated string --> rust/kernel/kunit.rs:21:13 | 21 | b"\x013%pA\0".as_ptr() as _, | ^^^^^^^^^^^^^ help: use a `c""` literal: `c"\x013%pA"` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals = note: `-D clippy::manual-c-str-literals` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::manual_c_str_literals)]` Apply the suggestion to clean up the warnings. Link: https://github.com/rust-lang/rust-clippy/pull/13263 [1] Reviewed-by: Trevor Gross <tmgross@umich.edu> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20240927164414.560906-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org> --- rust/kernel/kunit.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs index 0ba77276ae7e..824da0e9738a 100644 --- a/rust/kernel/kunit.rs +++ b/rust/kernel/kunit.rs @@ -18,7 +18,7 @@ pub fn err(args: fmt::Arguments<'_>) { #[cfg(CONFIG_PRINTK)] unsafe { bindings::_printk( - b"\x013%pA\0".as_ptr() as _, + c"\x013%pA".as_ptr() as _, &args as *const _ as *const c_void, ); } @@ -34,7 +34,7 @@ pub fn info(args: fmt::Arguments<'_>) { #[cfg(CONFIG_PRINTK)] unsafe { bindings::_printk( - b"\x016%pA\0".as_ptr() as _, + c"\x016%pA".as_ptr() as _, &args as *const _ as *const c_void, ); } -- GitLab From 0d5e5e8a0aa49ea2163abf128da3b509a6c58286 Mon Sep 17 00:00:00 2001 From: Yihan Zhu <Yihan.Zhu@amd.com> Date: Sat, 7 Sep 2024 13:25:19 -0400 Subject: [PATCH 587/970] drm/amd/display: update DML2 policy EnhancedPrefetchScheduleAccelerationFinal DCN35 [WHY & HOW] Mismatch in DCN35 DML2 cause bw validation failed to acquire unexpected DPP pipe to cause grey screen and system hang. Remove EnhancedPrefetchScheduleAccelerationFinal value override to match HW spec. Cc: Mario Limonciello <mario.limonciello@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Charlene Liu <charlene.liu@amd.com> Signed-off-by: Yihan Zhu <Yihan.Zhu@amd.com> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 9dad21f910fcea2bdcff4af46159101d7f9cd8ba) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c index c4c52173ef22..11c904ae2958 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c @@ -303,7 +303,6 @@ void build_unoptimized_policy_settings(enum dml_project_id project, struct dml_m if (project == dml_project_dcn35 || project == dml_project_dcn351) { policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; - policy->EnhancedPrefetchScheduleAccelerationFinal = 0; policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ policy->UseOnlyMaxPrefetchModes = 1; } -- GitLab From d51160ab00969ee6758ed2dcbc0f81dd476a181c Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo <Jerry.Zuo@amd.com> Date: Wed, 4 Sep 2024 15:29:24 -0400 Subject: [PATCH 588/970] drm/amd/display: Restore Optimized pbn Value if Failed to Disable DSC Existing last step of dsc policy is to restore pbn value under minimum compression when try to greedily disable dsc for a stream failed to fit in MST bw. Optimized dsc params result from optimization step is not necessarily the minimum compression, therefore it is not correct to restore the pbn under minimum compression rate. Restore the pbn under minimum compression instead of the value from optimized pbn could result in the dsc params not correct at the modeset where atomic_check failed due to not enough bw. One or more monitors connected could not light up in such case. Restore the optimized pbn value, instead of using the pbn value under minimum compression. Cc: Mario Limonciello <mario.limonciello@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Wayne Lin <wayne.lin@amd.com> Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 352c3165d2b75030169e012461a16bcf97f392fc) Cc: stable@vger.kernel.org --- .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 83a31b97e96b..a08e8a0b696c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -1027,6 +1027,7 @@ static int try_disable_dsc(struct drm_atomic_state *state, int remaining_to_try = 0; int ret; uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link); + int var_pbn; for (i = 0; i < count; i++) { if (vars[i + k].dsc_enabled @@ -1057,13 +1058,18 @@ static int try_disable_dsc(struct drm_atomic_state *state, break; DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index); + var_pbn = vars[next_index].pbn; vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000); ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn); - if (ret < 0) + if (ret < 0) { + DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n", + __func__, __LINE__, next_index, ret); + vars[next_index].pbn = var_pbn; return ret; + } ret = drm_dp_mst_atomic_check(state); if (ret == 0) { @@ -1071,14 +1077,17 @@ static int try_disable_dsc(struct drm_atomic_state *state, vars[next_index].dsc_enabled = false; vars[next_index].bpp_x16 = 0; } else { - DRM_DEBUG_DRIVER("MST_DSC index #%d, restore minimum compression\n", next_index); - vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000); + DRM_DEBUG_DRIVER("MST_DSC index #%d, restore optimized pbn value\n", next_index); + vars[next_index].pbn = var_pbn; ret = drm_dp_atomic_find_time_slots(state, params[next_index].port->mgr, params[next_index].port, vars[next_index].pbn); - if (ret < 0) + if (ret < 0) { + DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n", + __func__, __LINE__, next_index, ret); return ret; + } } tried[next_index] = true; -- GitLab From c36df0f5f5e5acec5d78f23c4725cc500df28843 Mon Sep 17 00:00:00 2001 From: Charlene Liu <Charlene.Liu@amd.com> Date: Wed, 11 Sep 2024 19:45:09 -0400 Subject: [PATCH 589/970] drm/amd/display: avoid set dispclk to 0 [why] set dispclk to 0 cause stability issue. Cc: Mario Limonciello <mario.limonciello@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Charlene Liu <Charlene.Liu@amd.com> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 1c6b16ebf5eb2bc5740be9e37b3a69f1dfe1dded) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index da9101b83e8c..70abd32ce2ad 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -766,6 +766,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_dmub_reallow_idle = false, .static_screen_wait_frames = 2, .notify_dpia_hr_bw = true, + .min_disp_clk_khz = 50000, }; static const struct dc_panel_config panel_config_defaults = { -- GitLab From 05af800704ee7187d9edd461ec90f3679b1c4aba Mon Sep 17 00:00:00 2001 From: Alex Hung <alex.hung@amd.com> Date: Fri, 6 Sep 2024 11:39:18 -0600 Subject: [PATCH 590/970] drm/amd/display: Add HDR workaround for specific eDP [WHY & HOW] Some eDP panels suffer from flicking when HDR is enabled in KDE. This quirk works around it by skipping VSC that is incompatible with eDP panels. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3151 Cc: Mario Limonciello <mario.limonciello@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 4d4257280d7957727998ef90ccc7b69c7cca8376) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++++- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 4 ++++ drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) 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 6e79028c5d78..7a826f20c38a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6735,12 +6735,21 @@ create_stream_for_sink(struct drm_connector *connector, if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || stream->signal == SIGNAL_TYPE_EDP) { + const struct dc_edid_caps *edid_caps; + unsigned int disable_colorimetry = 0; + + if (aconnector->dc_sink) { + edid_caps = &aconnector->dc_sink->edid_caps; + disable_colorimetry = edid_caps->panel_patch.disable_colorimetry; + } + // // should decide stream support vsc sdp colorimetry capability // before building vsc info packet // stream->use_vsc_sdp_for_colorimetry = stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 && - stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED; + stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED && + !disable_colorimetry; if (stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22) tf = TRANSFER_FUNC_GAMMA_22; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 50109d13d967..069e0195e50a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -73,6 +73,10 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps) DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); edid_caps->panel_patch.remove_sink_ext_caps = true; break; + case drm_edid_encode_panel_id('S', 'D', 'C', 0x4154): + DRM_DEBUG_DRIVER("Disabling VSC on monitor with panel id %X\n", panel_id); + edid_caps->panel_patch.disable_colorimetry = true; + break; default: return; } diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index fd6dca735714..6d7989b751e2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -178,6 +178,7 @@ struct dc_panel_patch { unsigned int skip_avmute; unsigned int mst_start_top_delay; unsigned int remove_sink_ext_caps; + unsigned int disable_colorimetry; }; struct dc_edid_caps { -- GitLab From ef785ca7f7c80891580cafd36c8dd86375684310 Mon Sep 17 00:00:00 2001 From: Leo Li <sunpeng.li@amd.com> Date: Wed, 11 Sep 2024 17:27:08 -0400 Subject: [PATCH 591/970] drm/amd/display: Enable idle workqueue for more IPS modes [Why] There are more IPS modes other than DMUB_IPS_ENABLE that enables IPS. We need to enable the hotplug detect idle workqueue for those modes as well. [How] Modify the if condition to initialize the workqueue in all IPS modes except for DMUB_IPS_DISABLE_ALL. Fixes: 65444581a4ae ("drm/amd/display: Determine IPS mode by ASIC and PMFW versions") Signed-off-by: Leo Li <sunpeng.li@amd.com> Reviewed-by: Roman Li <roman.li@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 181db30bcfed097ecc680539b1eabe935c11f57f) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 7a826f20c38a..5109146ef2ba 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2026,7 +2026,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n"); } - if (adev->dm.dc->caps.ips_support && adev->dm.dc->config.disable_ips == DMUB_IPS_ENABLE) + if (adev->dm.dc->caps.ips_support && + adev->dm.dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) adev->dm.idle_workqueue = idle_create_workqueue(adev); if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) { -- GitLab From 52d4e3fb3d340447dcdac0e14ff21a764f326907 Mon Sep 17 00:00:00 2001 From: Tom Chung <chiahsuan.chung@amd.com> Date: Fri, 13 Sep 2024 15:44:40 +0800 Subject: [PATCH 592/970] drm/amd/display: Fix system hang while resume with TBT monitor [Why] Connected with a Thunderbolt monitor and do the suspend and the system may hang while resume. The TBT monitor HPD will be triggered during the resume procedure and call the drm_client_modeset_probe() while struct drm_connector connector->dev->master is NULL. It will mess up the pipe topology after resume. [How] Skip the TBT monitor HPD during the resume procedure because we currently will probe the connectors after resume by default. Reviewed-by: Wayne Lin <wayne.lin@amd.com> Signed-off-by: Tom Chung <chiahsuan.chung@amd.com> Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 453f86a26945207a16b8f66aaed5962dc2b95b85) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++ 1 file changed, 6 insertions(+) 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 5109146ef2ba..60c617fcc97e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -770,6 +770,12 @@ static void dmub_hpd_callback(struct amdgpu_device *adev, return; } + /* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */ + if (notify->type == DMUB_NOTIFICATION_HPD && adev->in_suspend) { + DRM_INFO("Skip DMUB HPD IRQ callback in suspend/resume\n"); + return; + } + link_index = notify->link_index; link = adev->dm.dc->links[link_index]; dev = adev->dm.ddev; -- GitLab From a421e3fe0e6abe27395078f4f0cec5daf466caea Mon Sep 17 00:00:00 2001 From: wangrong <wangrong@uniontech.com> Date: Thu, 20 Jun 2024 16:37:29 +0800 Subject: [PATCH 593/970] smb: client: use actual path when queryfs Due to server permission control, the client does not have access to the shared root directory, but can access subdirectories normally, so users usually mount the shared subdirectories directly. In this case, queryfs should use the actual path instead of the root directory to avoid the call returning an error (EACCES). Signed-off-by: wangrong <wangrong@uniontech.com> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Cc: stable@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/cifsfs.c | 13 ++++++++++++- fs/smb/client/cifsglob.h | 2 +- fs/smb/client/smb1ops.c | 2 +- fs/smb/client/smb2ops.c | 19 ++++++++++++------- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 2a2523c93944..33e286001015 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -313,8 +313,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) struct TCP_Server_Info *server = tcon->ses->server; unsigned int xid; int rc = 0; + const char *full_path; + void *page; xid = get_xid(); + page = alloc_dentry_path(); + + full_path = build_path_from_dentry(dentry, page); + if (IS_ERR(full_path)) { + rc = PTR_ERR(full_path); + goto statfs_out; + } if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0) buf->f_namelen = @@ -330,8 +339,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_ffree = 0; /* unlimited */ if (server->ops->queryfs) - rc = server->ops->queryfs(xid, tcon, cifs_sb, buf); + rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf); +statfs_out: + free_dentry_path(page); free_xid(xid); return rc; } diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index da35c160e7dd..589438b867a9 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -481,7 +481,7 @@ struct smb_version_operations { __u16 net_fid, struct cifsInodeInfo *cifs_inode); /* query remote filesystem */ int (*queryfs)(const unsigned int, struct cifs_tcon *, - struct cifs_sb_info *, struct kstatfs *); + const char *, struct cifs_sb_info *, struct kstatfs *); /* send mandatory brlock to the server */ int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64, __u64, __u32, int, int, bool); diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index e03c91a49650..9a6ece66c4d3 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -909,7 +909,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, static int cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, struct kstatfs *buf) + const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf) { int rc = -EOPNOTSUPP; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 177173072bfa..cd6ff224015a 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2838,7 +2838,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, static int smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, struct kstatfs *buf) + const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf) { struct smb2_query_info_rsp *rsp; struct smb2_fs_full_size_info *info = NULL; @@ -2847,7 +2847,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, int rc; - rc = smb2_query_info_compound(xid, tcon, "", + rc = smb2_query_info_compound(xid, tcon, path, FILE_READ_ATTRIBUTES, FS_FULL_SIZE_INFORMATION, SMB2_O_INFO_FILESYSTEM, @@ -2875,28 +2875,33 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, static int smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, struct kstatfs *buf) + const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf) { int rc; - __le16 srch_path = 0; /* Null - open root of share */ + __le16 *utf16_path = NULL; u8 oplock = SMB2_OPLOCK_LEVEL_NONE; struct cifs_open_parms oparms; struct cifs_fid fid; if (!tcon->posix_extensions) - return smb2_queryfs(xid, tcon, cifs_sb, buf); + return smb2_queryfs(xid, tcon, path, cifs_sb, buf); oparms = (struct cifs_open_parms) { .tcon = tcon, - .path = "", + .path = path, .desired_access = FILE_READ_ATTRIBUTES, .disposition = FILE_OPEN, .create_options = cifs_create_options(cifs_sb, 0), .fid = &fid, }; - rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); + if (utf16_path == NULL) + return -ENOMEM; + + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL, NULL); + kfree(utf16_path); if (rc) return rc; -- GitLab From 134d988208602ccae792e91475c05911c962798e Mon Sep 17 00:00:00 2001 From: Al Viro <viro@zeniv.linux.org.uk> Date: Tue, 5 Dec 2023 21:53:22 -0500 Subject: [PATCH 594/970] parisc: get rid of private asm/unaligned.h Declarations local to arch/*/kernel/*.c are better off *not* in a public header - arch/parisc/kernel/unaligned.h is just fine for those bits. With that done parisc asm/unaligned.h is reduced to include of asm-generic/unaligned.h and can be removed - unaligned.h is in mandatory-y in include/asm-generic/Kbuild. Acked-by: Helge Deller <deller@gmx.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- arch/parisc/include/asm/unaligned.h | 11 ----------- arch/parisc/kernel/traps.c | 2 ++ arch/parisc/kernel/unaligned.c | 1 + arch/parisc/kernel/unaligned.h | 3 +++ 4 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 arch/parisc/include/asm/unaligned.h create mode 100644 arch/parisc/kernel/unaligned.h diff --git a/arch/parisc/include/asm/unaligned.h b/arch/parisc/include/asm/unaligned.h deleted file mode 100644 index c0621295100d..000000000000 --- a/arch/parisc/include/asm/unaligned.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_PARISC_UNALIGNED_H -#define _ASM_PARISC_UNALIGNED_H - -#include <asm-generic/unaligned.h> - -struct pt_regs; -void handle_unaligned(struct pt_regs *regs); -int check_unaligned(struct pt_regs *regs); - -#endif /* _ASM_PARISC_UNALIGNED_H */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 294b0e026c9a..a111d7362d56 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -47,6 +47,8 @@ #include <linux/kgdb.h> #include <linux/kprobes.h> +#include "unaligned.h" + #if defined(CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK) #include <asm/spinlock.h> #endif diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index 3e79e40e361d..99897107d800 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -15,6 +15,7 @@ #include <asm/unaligned.h> #include <asm/hardirq.h> #include <asm/traps.h> +#include "unaligned.h" /* #define DEBUG_UNALIGNED 1 */ diff --git a/arch/parisc/kernel/unaligned.h b/arch/parisc/kernel/unaligned.h new file mode 100644 index 000000000000..c1aa4b12e284 --- /dev/null +++ b/arch/parisc/kernel/unaligned.h @@ -0,0 +1,3 @@ +struct pt_regs; +void handle_unaligned(struct pt_regs *regs); +int check_unaligned(struct pt_regs *regs); -- GitLab From 0d0b8646a66de7f3bf345106f2034a2268799d67 Mon Sep 17 00:00:00 2001 From: Al Viro <viro@zeniv.linux.org.uk> Date: Tue, 1 Oct 2024 23:28:49 -0400 Subject: [PATCH 595/970] ufs_rename(): fix bogus argument of folio_release_kmap() new_dir does *NOT* point into dir_folio - it's an inode, not a pointer to ufs directory entry. Fixes: 516b97cf03dd6 "ufs: Convert directory handling to kmap_local" Acked-by: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- fs/ufs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 24bd12186647..c8390976ab6a 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -307,7 +307,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir, if (old_dir != new_dir) ufs_set_link(old_inode, dir_de, dir_folio, new_dir, 0); else - folio_release_kmap(dir_folio, new_dir); + folio_release_kmap(dir_folio, dir_de); inode_dec_link_count(old_dir); } return 0; -- GitLab From 1c801e7f77445bc56e5e1fec6191fd4503534787 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Tue, 1 Oct 2024 14:14:36 +0200 Subject: [PATCH 596/970] ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs Some time ago, we introduced the obey_preferred_dacs flag for choosing the DAC/pin pairs specified by the driver instead of parsing the paths. This works as expected, per se, but there have been a few cases where we forgot to set this flag while preferred_dacs table is already set up. It ended up with incorrect wiring and made us wondering why it doesn't work. Basically, when the preferred_dacs table is provided, it means that the driver really wants to wire up to follow that. That is, the presence of the preferred_dacs table itself is already a "do-it" flag. In this patch, we simply replace the evaluation of obey_preferred_dacs flag with the presence of preferred_dacs table for fixing the misbehavior. Another patch to drop of the obsoleted flag will follow. Fixes: 242d990c158d ("ALSA: hda/generic: Add option to enforce preferred_dacs pairs") Link: https://bugzilla.suse.com/show_bug.cgi?id=1219803 Link: https://patch.msgid.link/20241001121439.26060-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/hda_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 9cff87dfbecb..b34d84fedcc8 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1383,7 +1383,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, struct nid_path *path; hda_nid_t pin = pins[i]; - if (!spec->obey_preferred_dacs) { + if (!spec->preferred_dacs) { path = snd_hda_get_path_from_idx(codec, path_idx[i]); if (path) { badness += assign_out_path_ctls(codec, path); @@ -1395,7 +1395,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, if (dacs[i]) { if (is_dac_already_used(codec, dacs[i])) badness += bad->shared_primary; - } else if (spec->obey_preferred_dacs) { + } else if (spec->preferred_dacs) { badness += BAD_NO_PRIMARY_DAC; } -- GitLab From 864773f9e7899f5ea72f92ebd75770e25e0b35be Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Tue, 1 Oct 2024 14:14:37 +0200 Subject: [PATCH 597/970] ALSA: hda/generic: Drop obsoleted obey_preferred_dacs flag Now we evaluate directly with preferred_dacs table, the flag is no longer used and merely a placeholder. Let's drop the definition and its users. Link: https://patch.msgid.link/20241001121439.26060-2-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/hda_generic.h | 1 - sound/pci/hda/patch_realtek.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 08544601b4ce..9612afaa61c2 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -232,7 +232,6 @@ struct hda_gen_spec { unsigned int power_down_unused:1; /* power down unused widgets */ unsigned int dac_min_mute:1; /* minimal = mute for DACs */ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */ - unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */ /* other internal flags */ unsigned int no_analog:1; /* digital I/O only */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b42257e03344..eb45a41533dc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6645,10 +6645,8 @@ static void alc289_fixup_asus_ga401(struct hda_codec *codec, }; struct alc_spec *spec = codec->spec; - if (action == HDA_FIXUP_ACT_PRE_PROBE) { + if (action == HDA_FIXUP_ACT_PRE_PROBE) spec->gen.preferred_dacs = preferred_pairs; - spec->gen.obey_preferred_dacs = 1; - } } /* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */ -- GitLab From d75dba49744478c32f6ce1c16b5f391c2d5cef5f Mon Sep 17 00:00:00 2001 From: Abhishek Tamboli <abhishektamboli9@gmail.com> Date: Mon, 30 Sep 2024 20:23:00 +0530 Subject: [PATCH 598/970] ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200 Add the quirk for HP Pavilion Gaming laptop 15z-ec200 for enabling the mute led. The fix apply the ALC285_FIXUP_HP_MUTE_LED quirk for this model. Link: https://bugzilla.kernel.org/show_bug.cgi?id=219303 Signed-off-by: Abhishek Tamboli <abhishektamboli9@gmail.com> Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20240930145300.4604-1-abhishektamboli9@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index eb45a41533dc..5e2e927656cd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10348,6 +10348,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x88dd, "HP Pavilion 15z-ec200", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x890e, "HP 255 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8919, "HP Pavilion Aero Laptop 13-be0xxx", ALC287_FIXUP_HP_GPIO_LED), -- GitLab From 984ed20ece1c6c20789ece040cbff3eb1a388fa9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada <masahiroy@kernel.org> Date: Tue, 1 Oct 2024 18:02:22 +0900 Subject: [PATCH 599/970] kconfig: qconf: fix buffer overflow in debug links If you enable "Option -> Show Debug Info" and click a link, the program terminates with the following error: *** buffer overflow detected ***: terminated The buffer overflow is caused by the following line: strcat(data, "$"); The buffer needs one more byte to accommodate the additional character. Fixes: c4f7398bee9c ("kconfig: qconf: make debug links work again") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/kconfig/qconf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 7dba8014ead4..e260cab1c2af 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -1166,7 +1166,7 @@ void ConfigInfoView::clicked(const QUrl &url) { QByteArray str = url.toEncoded(); const std::size_t count = str.size(); - char *data = new char[count + 1]; + char *data = new char[count + 2]; // '$' + '\0' struct symbol **result; struct menu *m = NULL; -- GitLab From f8ff51a4708451763e6cfa36cc83dea8513d3318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> Date: Tue, 24 Sep 2024 00:06:21 +0100 Subject: [PATCH 600/970] drm/panthor: introduce job cycle and timestamp accounting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable calculations of job submission times in clock cycles and wall time. This is done by expanding the boilerplate command stream when running a job to include instructions that compute said times right before and after a user CS. A separate kernel BO is created per queue to store those values. Jobs can access their sampled data through an index different from that of the queue's ringbuffer. The reason for this is saving memory on the profiling information kernel BO, since the amount of simultaneous profiled jobs we can write into the queue's ringbuffer might be much smaller than for regular jobs, as the former take more CSF instructions. This commit is done in preparation for enabling DRM fdinfo support in the Panthor driver, which depends on the numbers calculated herein. A profile mode mask has been added that will in a future commit allow UM to toggle performance metric sampling behaviour, which is disabled by default to save power. When a ringbuffer CS is constructed, timestamp and cycling sampling instructions are added depending on the enabled flags in the profiling mask. A helper was provided that calculates the number of instructions for a given set of enablement mask, and these are passed as the number of credits when initialising a DRM scheduler job. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923230912.2207320-2-adrian.larumbe@collabora.com --- drivers/gpu/drm/panthor/panthor_device.h | 22 ++ drivers/gpu/drm/panthor/panthor_sched.c | 333 +++++++++++++++++++---- 2 files changed, 306 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h index e388c0472ba7..a48e30d0af30 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -66,6 +66,25 @@ struct panthor_irq { atomic_t suspended; }; +/** + * enum panthor_device_profiling_mode - Profiling state + */ +enum panthor_device_profiling_flags { + /** @PANTHOR_DEVICE_PROFILING_DISABLED: Profiling is disabled. */ + PANTHOR_DEVICE_PROFILING_DISABLED = 0, + + /** @PANTHOR_DEVICE_PROFILING_CYCLES: Sampling job cycles. */ + PANTHOR_DEVICE_PROFILING_CYCLES = BIT(0), + + /** @PANTHOR_DEVICE_PROFILING_TIMESTAMP: Sampling job timestamp. */ + PANTHOR_DEVICE_PROFILING_TIMESTAMP = BIT(1), + + /** @PANTHOR_DEVICE_PROFILING_ALL: Sampling everything. */ + PANTHOR_DEVICE_PROFILING_ALL = + PANTHOR_DEVICE_PROFILING_CYCLES | + PANTHOR_DEVICE_PROFILING_TIMESTAMP, +}; + /** * struct panthor_device - Panthor device */ @@ -162,6 +181,9 @@ struct panthor_device { */ struct page *dummy_latest_flush; } pm; + + /** @profile_mask: User-set profiling flags for job accounting. */ + u32 profile_mask; }; /** diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index a9e3b1ccccc7..e3f8d00a5425 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -93,6 +93,9 @@ #define MIN_CSGS 3 #define MAX_CSG_PRIO 0xf +#define NUM_INSTRS_PER_CACHE_LINE (64 / sizeof(u64)) +#define MAX_INSTRS_PER_JOB 24 + struct panthor_group; /** @@ -474,6 +477,18 @@ struct panthor_queue { */ struct list_head in_flight_jobs; } fence_ctx; + + /** @profiling: Job profiling data slots and access information. */ + struct { + /** @slots: Kernel BO holding the slots. */ + struct panthor_kernel_bo *slots; + + /** @slot_count: Number of jobs ringbuffer can hold at once. */ + u32 slot_count; + + /** @seqno: Index of the next available profiling information slot. */ + u32 seqno; + } profiling; }; /** @@ -659,6 +674,18 @@ struct panthor_group { struct list_head wait_node; }; +struct panthor_job_profiling_data { + struct { + u64 before; + u64 after; + } cycles; + + struct { + u64 before; + u64 after; + } time; +}; + /** * group_queue_work() - Queue a group work * @group: Group to queue the work for. @@ -772,6 +799,15 @@ struct panthor_job { /** @done_fence: Fence signaled when the job is finished or cancelled. */ struct dma_fence *done_fence; + + /** @profiling: Job profiling information. */ + struct { + /** @mask: Current device job profiling enablement bitmask. */ + u32 mask; + + /** @slot: Job index in the profiling slots BO. */ + u32 slot; + } profiling; }; static void @@ -836,6 +872,7 @@ static void group_free_queue(struct panthor_group *group, struct panthor_queue * panthor_kernel_bo_destroy(queue->ringbuf); panthor_kernel_bo_destroy(queue->iface.mem); + panthor_kernel_bo_destroy(queue->profiling.slots); /* Release the last_fence we were holding, if any. */ dma_fence_put(queue->fence_ctx.last_fence); @@ -1980,8 +2017,6 @@ tick_ctx_init(struct panthor_scheduler *sched, } } -#define NUM_INSTRS_PER_SLOT 16 - static void group_term_post_processing(struct panthor_group *group) { @@ -2813,65 +2848,198 @@ static void group_sync_upd_work(struct work_struct *work) group_put(group); } -static struct dma_fence * -queue_run_job(struct drm_sched_job *sched_job) +struct panthor_job_ringbuf_instrs { + u64 buffer[MAX_INSTRS_PER_JOB]; + u32 count; +}; + +struct panthor_job_instr { + u32 profile_mask; + u64 instr; +}; + +#define JOB_INSTR(__prof, __instr) \ + { \ + .profile_mask = __prof, \ + .instr = __instr, \ + } + +static void +copy_instrs_to_ringbuf(struct panthor_queue *queue, + struct panthor_job *job, + struct panthor_job_ringbuf_instrs *instrs) +{ + u64 ringbuf_size = panthor_kernel_bo_size(queue->ringbuf); + u64 start = job->ringbuf.start & (ringbuf_size - 1); + u64 size, written; + + /* + * We need to write a whole slot, including any trailing zeroes + * that may come at the end of it. Also, because instrs.buffer has + * been zero-initialised, there's no need to pad it with 0's + */ + instrs->count = ALIGN(instrs->count, NUM_INSTRS_PER_CACHE_LINE); + size = instrs->count * sizeof(u64); + WARN_ON(size > ringbuf_size); + written = min(ringbuf_size - start, size); + + memcpy(queue->ringbuf->kmap + start, instrs->buffer, written); + + if (written < size) + memcpy(queue->ringbuf->kmap, + &instrs->buffer[written / sizeof(u64)], + size - written); +} + +struct panthor_job_cs_params { + u32 profile_mask; + u64 addr_reg; u64 val_reg; + u64 cycle_reg; u64 time_reg; + u64 sync_addr; u64 times_addr; + u64 cs_start; u64 cs_size; + u32 last_flush; u32 waitall_mask; +}; + +static void +get_job_cs_params(struct panthor_job *job, struct panthor_job_cs_params *params) { - struct panthor_job *job = container_of(sched_job, struct panthor_job, base); struct panthor_group *group = job->group; struct panthor_queue *queue = group->queues[job->queue_idx]; struct panthor_device *ptdev = group->ptdev; struct panthor_scheduler *sched = ptdev->scheduler; - u32 ringbuf_size = panthor_kernel_bo_size(queue->ringbuf); - u32 ringbuf_insert = queue->iface.input->insert & (ringbuf_size - 1); - u64 addr_reg = ptdev->csif_info.cs_reg_count - - ptdev->csif_info.unpreserved_cs_reg_count; - u64 val_reg = addr_reg + 2; - u64 sync_addr = panthor_kernel_bo_gpuva(group->syncobjs) + - job->queue_idx * sizeof(struct panthor_syncobj_64b); - u32 waitall_mask = GENMASK(sched->sb_slot_count - 1, 0); - struct dma_fence *done_fence; - int ret; - u64 call_instrs[NUM_INSTRS_PER_SLOT] = { - /* MOV32 rX+2, cs.latest_flush */ - (2ull << 56) | (val_reg << 48) | job->call_info.latest_flush, + params->addr_reg = ptdev->csif_info.cs_reg_count - + ptdev->csif_info.unpreserved_cs_reg_count; + params->val_reg = params->addr_reg + 2; + params->cycle_reg = params->addr_reg; + params->time_reg = params->val_reg; - /* FLUSH_CACHE2.clean_inv_all.no_wait.signal(0) rX+2 */ - (36ull << 56) | (0ull << 48) | (val_reg << 40) | (0 << 16) | 0x233, + params->sync_addr = panthor_kernel_bo_gpuva(group->syncobjs) + + job->queue_idx * sizeof(struct panthor_syncobj_64b); + params->times_addr = panthor_kernel_bo_gpuva(queue->profiling.slots) + + (job->profiling.slot * sizeof(struct panthor_job_profiling_data)); + params->waitall_mask = GENMASK(sched->sb_slot_count - 1, 0); - /* MOV48 rX:rX+1, cs.start */ - (1ull << 56) | (addr_reg << 48) | job->call_info.start, + params->cs_start = job->call_info.start; + params->cs_size = job->call_info.size; + params->last_flush = job->call_info.latest_flush; - /* MOV32 rX+2, cs.size */ - (2ull << 56) | (val_reg << 48) | job->call_info.size, + params->profile_mask = job->profiling.mask; +} - /* WAIT(0) => waits for FLUSH_CACHE2 instruction */ - (3ull << 56) | (1 << 16), +#define JOB_INSTR_ALWAYS(instr) \ + JOB_INSTR(PANTHOR_DEVICE_PROFILING_DISABLED, (instr)) +#define JOB_INSTR_TIMESTAMP(instr) \ + JOB_INSTR(PANTHOR_DEVICE_PROFILING_TIMESTAMP, (instr)) +#define JOB_INSTR_CYCLES(instr) \ + JOB_INSTR(PANTHOR_DEVICE_PROFILING_CYCLES, (instr)) +static void +prepare_job_instrs(const struct panthor_job_cs_params *params, + struct panthor_job_ringbuf_instrs *instrs) +{ + const struct panthor_job_instr instr_seq[] = { + /* MOV32 rX+2, cs.latest_flush */ + JOB_INSTR_ALWAYS((2ull << 56) | (params->val_reg << 48) | params->last_flush), + /* FLUSH_CACHE2.clean_inv_all.no_wait.signal(0) rX+2 */ + JOB_INSTR_ALWAYS((36ull << 56) | (0ull << 48) | (params->val_reg << 40) | + (0 << 16) | 0x233), + /* MOV48 rX:rX+1, cycles_offset */ + JOB_INSTR_CYCLES((1ull << 56) | (params->cycle_reg << 48) | + (params->times_addr + + offsetof(struct panthor_job_profiling_data, cycles.before))), + /* STORE_STATE cycles */ + JOB_INSTR_CYCLES((40ull << 56) | (params->cycle_reg << 40) | (1ll << 32)), + /* MOV48 rX:rX+1, time_offset */ + JOB_INSTR_TIMESTAMP((1ull << 56) | (params->time_reg << 48) | + (params->times_addr + + offsetof(struct panthor_job_profiling_data, time.before))), + /* STORE_STATE timer */ + JOB_INSTR_TIMESTAMP((40ull << 56) | (params->time_reg << 40) | (0ll << 32)), + /* MOV48 rX:rX+1, cs.start */ + JOB_INSTR_ALWAYS((1ull << 56) | (params->addr_reg << 48) | params->cs_start), + /* MOV32 rX+2, cs.size */ + JOB_INSTR_ALWAYS((2ull << 56) | (params->val_reg << 48) | params->cs_size), + /* WAIT(0) => waits for FLUSH_CACHE2 instruction */ + JOB_INSTR_ALWAYS((3ull << 56) | (1 << 16)), /* CALL rX:rX+1, rX+2 */ - (32ull << 56) | (addr_reg << 40) | (val_reg << 32), - + JOB_INSTR_ALWAYS((32ull << 56) | (params->addr_reg << 40) | + (params->val_reg << 32)), + /* MOV48 rX:rX+1, cycles_offset */ + JOB_INSTR_CYCLES((1ull << 56) | (params->cycle_reg << 48) | + (params->times_addr + + offsetof(struct panthor_job_profiling_data, cycles.after))), + /* STORE_STATE cycles */ + JOB_INSTR_CYCLES((40ull << 56) | (params->cycle_reg << 40) | (1ll << 32)), + /* MOV48 rX:rX+1, time_offset */ + JOB_INSTR_TIMESTAMP((1ull << 56) | (params->time_reg << 48) | + (params->times_addr + + offsetof(struct panthor_job_profiling_data, time.after))), + /* STORE_STATE timer */ + JOB_INSTR_TIMESTAMP((40ull << 56) | (params->time_reg << 40) | (0ll << 32)), /* MOV48 rX:rX+1, sync_addr */ - (1ull << 56) | (addr_reg << 48) | sync_addr, - + JOB_INSTR_ALWAYS((1ull << 56) | (params->addr_reg << 48) | params->sync_addr), /* MOV48 rX+2, #1 */ - (1ull << 56) | (val_reg << 48) | 1, - + JOB_INSTR_ALWAYS((1ull << 56) | (params->val_reg << 48) | 1), /* WAIT(all) */ - (3ull << 56) | (waitall_mask << 16), - + JOB_INSTR_ALWAYS((3ull << 56) | (params->waitall_mask << 16)), /* SYNC_ADD64.system_scope.propage_err.nowait rX:rX+1, rX+2*/ - (51ull << 56) | (0ull << 48) | (addr_reg << 40) | (val_reg << 32) | (0 << 16) | 1, + JOB_INSTR_ALWAYS((51ull << 56) | (0ull << 48) | (params->addr_reg << 40) | + (params->val_reg << 32) | (0 << 16) | 1), + /* ERROR_BARRIER, so we can recover from faults at job boundaries. */ + JOB_INSTR_ALWAYS((47ull << 56)), + }; + u32 pad; - /* ERROR_BARRIER, so we can recover from faults at job - * boundaries. - */ - (47ull << 56), + instrs->count = 0; + + /* NEED to be cacheline aligned to please the prefetcher. */ + static_assert(sizeof(instrs->buffer) % 64 == 0, + "panthor_job_ringbuf_instrs::buffer is not aligned on a cacheline"); + + /* Make sure we have enough storage to store the whole sequence. */ + static_assert(ALIGN(ARRAY_SIZE(instr_seq), NUM_INSTRS_PER_CACHE_LINE) == + ARRAY_SIZE(instrs->buffer), + "instr_seq vs panthor_job_ringbuf_instrs::buffer size mismatch"); + + for (u32 i = 0; i < ARRAY_SIZE(instr_seq); i++) { + /* If the profile mask of this instruction is not enabled, skip it. */ + if (instr_seq[i].profile_mask && + !(instr_seq[i].profile_mask & params->profile_mask)) + continue; + + instrs->buffer[instrs->count++] = instr_seq[i].instr; + } + + pad = ALIGN(instrs->count, NUM_INSTRS_PER_CACHE_LINE); + memset(&instrs->buffer[instrs->count], 0, + (pad - instrs->count) * sizeof(instrs->buffer[0])); + instrs->count = pad; +} + +static u32 calc_job_credits(u32 profile_mask) +{ + struct panthor_job_ringbuf_instrs instrs; + struct panthor_job_cs_params params = { + .profile_mask = profile_mask, }; - /* Need to be cacheline aligned to please the prefetcher. */ - static_assert(sizeof(call_instrs) % 64 == 0, - "call_instrs is not aligned on a cacheline"); + prepare_job_instrs(¶ms, &instrs); + return instrs.count; +} + +static struct dma_fence * +queue_run_job(struct drm_sched_job *sched_job) +{ + struct panthor_job *job = container_of(sched_job, struct panthor_job, base); + struct panthor_group *group = job->group; + struct panthor_queue *queue = group->queues[job->queue_idx]; + struct panthor_device *ptdev = group->ptdev; + struct panthor_scheduler *sched = ptdev->scheduler; + struct panthor_job_ringbuf_instrs instrs; + struct panthor_job_cs_params cs_params; + struct dma_fence *done_fence; + int ret; /* Stream size is zero, nothing to do except making sure all previously * submitted jobs are done before we signal the @@ -2898,17 +3066,23 @@ queue_run_job(struct drm_sched_job *sched_job) queue->fence_ctx.id, atomic64_inc_return(&queue->fence_ctx.seqno)); - memcpy(queue->ringbuf->kmap + ringbuf_insert, - call_instrs, sizeof(call_instrs)); + job->profiling.slot = queue->profiling.seqno++; + if (queue->profiling.seqno == queue->profiling.slot_count) + queue->profiling.seqno = 0; + + job->ringbuf.start = queue->iface.input->insert; + + get_job_cs_params(job, &cs_params); + prepare_job_instrs(&cs_params, &instrs); + copy_instrs_to_ringbuf(queue, job, &instrs); + + job->ringbuf.end = job->ringbuf.start + (instrs.count * sizeof(u64)); panthor_job_get(&job->base); spin_lock(&queue->fence_ctx.lock); list_add_tail(&job->node, &queue->fence_ctx.in_flight_jobs); spin_unlock(&queue->fence_ctx.lock); - job->ringbuf.start = queue->iface.input->insert; - job->ringbuf.end = job->ringbuf.start + sizeof(call_instrs); - /* Make sure the ring buffer is updated before the INSERT * register. */ @@ -3001,6 +3175,33 @@ static const struct drm_sched_backend_ops panthor_queue_sched_ops = { .free_job = queue_free_job, }; +static u32 calc_profiling_ringbuf_num_slots(struct panthor_device *ptdev, + u32 cs_ringbuf_size) +{ + u32 min_profiled_job_instrs = U32_MAX; + u32 last_flag = fls(PANTHOR_DEVICE_PROFILING_ALL); + + /* + * We want to calculate the minimum size of a profiled job's CS, + * because since they need additional instructions for the sampling + * of performance metrics, they might take up further slots in + * the queue's ringbuffer. This means we might not need as many job + * slots for keeping track of their profiling information. What we + * need is the maximum number of slots we should allocate to this end, + * which matches the maximum number of profiled jobs we can place + * simultaneously in the queue's ring buffer. + * That has to be calculated separately for every single job profiling + * flag, but not in the case job profiling is disabled, since unprofiled + * jobs don't need to keep track of this at all. + */ + for (u32 i = 0; i < last_flag; i++) { + min_profiled_job_instrs = + min(min_profiled_job_instrs, calc_job_credits(BIT(i))); + } + + return DIV_ROUND_UP(cs_ringbuf_size, min_profiled_job_instrs * sizeof(u64)); +} + static struct panthor_queue * group_create_queue(struct panthor_group *group, const struct drm_panthor_queue_create *args) @@ -3054,9 +3255,35 @@ group_create_queue(struct panthor_group *group, goto err_free_queue; } + queue->profiling.slot_count = + calc_profiling_ringbuf_num_slots(group->ptdev, args->ringbuf_size); + + queue->profiling.slots = + panthor_kernel_bo_create(group->ptdev, group->vm, + queue->profiling.slot_count * + sizeof(struct panthor_job_profiling_data), + DRM_PANTHOR_BO_NO_MMAP, + DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | + DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, + PANTHOR_VM_KERNEL_AUTO_VA); + + if (IS_ERR(queue->profiling.slots)) { + ret = PTR_ERR(queue->profiling.slots); + goto err_free_queue; + } + + ret = panthor_kernel_bo_vmap(queue->profiling.slots); + if (ret) + goto err_free_queue; + + /* + * Credit limit argument tells us the total number of instructions + * across all CS slots in the ringbuffer, with some jobs requiring + * twice as many as others, depending on their profiling status. + */ ret = drm_sched_init(&queue->scheduler, &panthor_queue_sched_ops, group->ptdev->scheduler->wq, 1, - args->ringbuf_size / (NUM_INSTRS_PER_SLOT * sizeof(u64)), + args->ringbuf_size / sizeof(u64), 0, msecs_to_jiffies(JOB_TIMEOUT_MS), group->ptdev->reset.wq, NULL, "panthor-queue", group->ptdev->base.dev); @@ -3352,6 +3579,7 @@ panthor_job_create(struct panthor_file *pfile, { struct panthor_group_pool *gpool = pfile->groups; struct panthor_job *job; + u32 credits; int ret; if (qsubmit->pad) @@ -3405,9 +3633,16 @@ panthor_job_create(struct panthor_file *pfile, } } + job->profiling.mask = pfile->ptdev->profile_mask; + credits = calc_job_credits(job->profiling.mask); + if (credits == 0) { + ret = -EINVAL; + goto err_put_job; + } + ret = drm_sched_job_init(&job->base, &job->group->queues[job->queue_idx]->entity, - 1, job->group); + credits, job->group); if (ret) goto err_put_job; -- GitLab From 37591ae11f89cdfc0a647945a589468642a44c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> Date: Tue, 24 Sep 2024 00:06:22 +0100 Subject: [PATCH 601/970] drm/panthor: record current and maximum device clock frequencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to support UM in calculating rates of GPU utilisation, the current operating and maximum GPU clock frequencies must be recorded during device initialisation, and also during OPP state transitions. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923230912.2207320-3-adrian.larumbe@collabora.com --- drivers/gpu/drm/panthor/panthor_devfreq.c | 18 +++++++++++++++++- drivers/gpu/drm/panthor/panthor_device.h | 6 ++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panthor/panthor_devfreq.c b/drivers/gpu/drm/panthor/panthor_devfreq.c index c6d3c327cc24..9d0f891b9b53 100644 --- a/drivers/gpu/drm/panthor/panthor_devfreq.c +++ b/drivers/gpu/drm/panthor/panthor_devfreq.c @@ -62,14 +62,20 @@ static void panthor_devfreq_update_utilization(struct panthor_devfreq *pdevfreq) static int panthor_devfreq_target(struct device *dev, unsigned long *freq, u32 flags) { + struct panthor_device *ptdev = dev_get_drvdata(dev); struct dev_pm_opp *opp; + int err; opp = devfreq_recommended_opp(dev, freq, flags); if (IS_ERR(opp)) return PTR_ERR(opp); dev_pm_opp_put(opp); - return dev_pm_opp_set_rate(dev, *freq); + err = dev_pm_opp_set_rate(dev, *freq); + if (!err) + ptdev->current_frequency = *freq; + + return err; } static void panthor_devfreq_reset(struct panthor_devfreq *pdevfreq) @@ -130,6 +136,7 @@ int panthor_devfreq_init(struct panthor_device *ptdev) struct panthor_devfreq *pdevfreq; struct dev_pm_opp *opp; unsigned long cur_freq; + unsigned long freq = ULONG_MAX; int ret; pdevfreq = drmm_kzalloc(&ptdev->base, sizeof(*ptdev->devfreq), GFP_KERNEL); @@ -161,6 +168,7 @@ int panthor_devfreq_init(struct panthor_device *ptdev) return PTR_ERR(opp); panthor_devfreq_profile.initial_freq = cur_freq; + ptdev->current_frequency = cur_freq; /* Regulator coupling only takes care of synchronizing/balancing voltage * updates, but the coupled regulator needs to be enabled manually. @@ -204,6 +212,14 @@ int panthor_devfreq_init(struct panthor_device *ptdev) dev_pm_opp_put(opp); + /* Find the fastest defined rate */ + opp = dev_pm_opp_find_freq_floor(dev, &freq); + if (IS_ERR(opp)) + return PTR_ERR(opp); + ptdev->fast_rate = freq; + + dev_pm_opp_put(opp); + /* * Setup default thresholds for the simple_ondemand governor. * The values are chosen based on experiments. diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h index a48e30d0af30..2109905813e8 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -184,6 +184,12 @@ struct panthor_device { /** @profile_mask: User-set profiling flags for job accounting. */ u32 profile_mask; + + /** @current_frequency: Device clock frequency at present. Set by DVFS*/ + unsigned long current_frequency; + + /** @fast_rate: Maximum device clock frequency. Set by DVFS */ + unsigned long fast_rate; }; /** -- GitLab From e16635d88fa07ba5801aa9e57ad7fe3c053234e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> Date: Tue, 24 Sep 2024 00:06:23 +0100 Subject: [PATCH 602/970] drm/panthor: add DRM fdinfo support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drawing from the FW-calculated values in a previous commit, we can increase the numbers for an open file by collecting them from finished jobs when updating their group synchronisation objects. Display of fdinfo key-value pairs is governed by a bitmask that is by default unset in the present commit, and supporting manual toggle of it will be the matter of a later commit. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923230912.2207320-4-adrian.larumbe@collabora.com --- drivers/gpu/drm/panthor/panthor_device.h | 8 ++++ drivers/gpu/drm/panthor/panthor_drv.c | 34 +++++++++++++++ drivers/gpu/drm/panthor/panthor_sched.c | 53 ++++++++++++++++++++++++ drivers/gpu/drm/panthor/panthor_sched.h | 2 + 4 files changed, 97 insertions(+) diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h index 2109905813e8..0e68f5a70d20 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -192,6 +192,11 @@ struct panthor_device { unsigned long fast_rate; }; +struct panthor_gpu_usage { + u64 time; + u64 cycles; +}; + /** * struct panthor_file - Panthor file */ @@ -204,6 +209,9 @@ struct panthor_file { /** @groups: Scheduling group pool attached to this file. */ struct panthor_group_pool *groups; + + /** @stats: cycle and timestamp measures for job execution. */ + struct panthor_gpu_usage stats; }; int panthor_device_init(struct panthor_device *ptdev); diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 0d825d63d712..388d1aea389d 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -13,6 +13,7 @@ #include <linux/pagemap.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/time64.h> #include <drm/drm_auth.h> #include <drm/drm_debugfs.h> @@ -1435,6 +1436,37 @@ static int panthor_mmap(struct file *filp, struct vm_area_struct *vma) return ret; } +static void panthor_gpu_show_fdinfo(struct panthor_device *ptdev, + struct panthor_file *pfile, + struct drm_printer *p) +{ + if (ptdev->profile_mask & PANTHOR_DEVICE_PROFILING_ALL) + panthor_fdinfo_gather_group_samples(pfile); + + if (ptdev->profile_mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP) { +#ifdef CONFIG_ARM_ARCH_TIMER + drm_printf(p, "drm-engine-panthor:\t%llu ns\n", + DIV_ROUND_UP_ULL((pfile->stats.time * NSEC_PER_SEC), + arch_timer_get_cntfrq())); +#endif + } + if (ptdev->profile_mask & PANTHOR_DEVICE_PROFILING_CYCLES) + drm_printf(p, "drm-cycles-panthor:\t%llu\n", pfile->stats.cycles); + + drm_printf(p, "drm-maxfreq-panthor:\t%lu Hz\n", ptdev->fast_rate); + drm_printf(p, "drm-curfreq-panthor:\t%lu Hz\n", ptdev->current_frequency); +} + +static void panthor_show_fdinfo(struct drm_printer *p, struct drm_file *file) +{ + struct drm_device *dev = file->minor->dev; + struct panthor_device *ptdev = container_of(dev, struct panthor_device, base); + + panthor_gpu_show_fdinfo(ptdev, file->driver_priv, p); + + drm_show_memory_stats(p, file); +} + static const struct file_operations panthor_drm_driver_fops = { .open = drm_open, .release = drm_release, @@ -1444,6 +1476,7 @@ static const struct file_operations panthor_drm_driver_fops = { .read = drm_read, .llseek = noop_llseek, .mmap = panthor_mmap, + .show_fdinfo = drm_show_fdinfo, }; #ifdef CONFIG_DEBUG_FS @@ -1465,6 +1498,7 @@ static const struct drm_driver panthor_drm_driver = { DRIVER_SYNCOBJ_TIMELINE | DRIVER_GEM_GPUVA, .open = panthor_open, .postclose = panthor_postclose, + .show_fdinfo = panthor_show_fdinfo, .ioctls = panthor_drm_driver_ioctls, .num_ioctls = ARRAY_SIZE(panthor_drm_driver_ioctls), .fops = &panthor_drm_driver_fops, diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index e3f8d00a5425..c7b350fc3eba 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -617,6 +617,18 @@ struct panthor_group { */ struct panthor_kernel_bo *syncobjs; + /** @fdinfo: Per-file total cycle and timestamp values reference. */ + struct { + /** @data: Total sampled values for jobs in queues from this group. */ + struct panthor_gpu_usage data; + + /** + * @lock: Mutex to govern concurrent access from drm file's fdinfo callback + * and job post-completion processing function + */ + struct mutex lock; + } fdinfo; + /** @state: Group state. */ enum panthor_group_state state; @@ -887,6 +899,8 @@ static void group_release_work(struct work_struct *work) release_work); u32 i; + mutex_destroy(&group->fdinfo.lock); + for (i = 0; i < group->queue_count; i++) group_free_queue(group, group->queues[i]); @@ -2809,6 +2823,41 @@ void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed) } } +static void update_fdinfo_stats(struct panthor_job *job) +{ + struct panthor_group *group = job->group; + struct panthor_queue *queue = group->queues[job->queue_idx]; + struct panthor_gpu_usage *fdinfo = &group->fdinfo.data; + struct panthor_job_profiling_data *slots = queue->profiling.slots->kmap; + struct panthor_job_profiling_data *data = &slots[job->profiling.slot]; + + mutex_lock(&group->fdinfo.lock); + if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_CYCLES) + fdinfo->cycles += data->cycles.after - data->cycles.before; + if (job->profiling.mask & PANTHOR_DEVICE_PROFILING_TIMESTAMP) + fdinfo->time += data->time.after - data->time.before; + mutex_unlock(&group->fdinfo.lock); +} + +void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile) +{ + struct panthor_group_pool *gpool = pfile->groups; + struct panthor_group *group; + unsigned long i; + + if (IS_ERR_OR_NULL(gpool)) + return; + + xa_for_each(&gpool->xa, i, group) { + mutex_lock(&group->fdinfo.lock); + pfile->stats.cycles += group->fdinfo.data.cycles; + pfile->stats.time += group->fdinfo.data.time; + group->fdinfo.data.cycles = 0; + group->fdinfo.data.time = 0; + mutex_unlock(&group->fdinfo.lock); + } +} + static void group_sync_upd_work(struct work_struct *work) { struct panthor_group *group = @@ -2841,6 +2890,8 @@ static void group_sync_upd_work(struct work_struct *work) dma_fence_end_signalling(cookie); list_for_each_entry_safe(job, job_tmp, &done_jobs, node) { + if (job->profiling.mask) + update_fdinfo_stats(job); list_del_init(&job->node); panthor_job_put(&job->base); } @@ -3424,6 +3475,8 @@ int panthor_group_create(struct panthor_file *pfile, } mutex_unlock(&sched->reset.lock); + mutex_init(&group->fdinfo.lock); + return gid; err_put_group: diff --git a/drivers/gpu/drm/panthor/panthor_sched.h b/drivers/gpu/drm/panthor/panthor_sched.h index 3a30d2328b30..5ae6b4bde7c5 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.h +++ b/drivers/gpu/drm/panthor/panthor_sched.h @@ -47,4 +47,6 @@ void panthor_sched_resume(struct panthor_device *ptdev); void panthor_sched_report_mmu_fault(struct panthor_device *ptdev); void panthor_sched_report_fw_events(struct panthor_device *ptdev, u32 events); +void panthor_fdinfo_gather_group_samples(struct panthor_file *pfile); + #endif -- GitLab From 064bb57479b7473ef8415cd629cbfac8db67b751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> Date: Tue, 24 Sep 2024 00:06:24 +0100 Subject: [PATCH 603/970] drm/panthor: enable fdinfo for memory stats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement drm object's status callback. Also, we consider a PRIME imported BO to be resident if its matching dma_buf has an open attachment, which means its backing storage had already been allocated. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923230912.2207320-5-adrian.larumbe@collabora.com --- drivers/gpu/drm/panthor/panthor_gem.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c index 38f560864879..c60b599665d8 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -145,6 +145,17 @@ panthor_gem_prime_export(struct drm_gem_object *obj, int flags) return drm_gem_prime_export(obj, flags); } +static enum drm_gem_object_status panthor_gem_status(struct drm_gem_object *obj) +{ + struct panthor_gem_object *bo = to_panthor_bo(obj); + enum drm_gem_object_status res = 0; + + if (bo->base.base.import_attach || bo->base.pages) + res |= DRM_GEM_OBJECT_RESIDENT; + + return res; +} + static const struct drm_gem_object_funcs panthor_gem_funcs = { .free = panthor_gem_free_object, .print_info = drm_gem_shmem_object_print_info, @@ -154,6 +165,7 @@ static const struct drm_gem_object_funcs panthor_gem_funcs = { .vmap = drm_gem_shmem_object_vmap, .vunmap = drm_gem_shmem_object_vunmap, .mmap = panthor_gem_mmap, + .status = panthor_gem_status, .export = panthor_gem_prime_export, .vm_ops = &drm_gem_shmem_vm_ops, }; -- GitLab From 6a797bdfde77041a0a9711082d7919162d1d7061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> Date: Tue, 24 Sep 2024 00:06:25 +0100 Subject: [PATCH 604/970] drm/panthor: add sysfs knob for enabling job profiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces a DRM device sysfs attribute that lets UM control the job accounting status in the device. The knob variable had been brought in as part of a previous commit, but now we're able to fix it manually. As sysfs files are part of a driver's uAPI, describe its legitimate input values and output format in a documentation file. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923230912.2207320-6-adrian.larumbe@collabora.com --- .../testing/sysfs-driver-panthor-profiling | 10 ++++ Documentation/gpu/panthor.rst | 46 +++++++++++++++++++ drivers/gpu/drm/panthor/panthor_drv.c | 39 ++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-panthor-profiling create mode 100644 Documentation/gpu/panthor.rst diff --git a/Documentation/ABI/testing/sysfs-driver-panthor-profiling b/Documentation/ABI/testing/sysfs-driver-panthor-profiling new file mode 100644 index 000000000000..af05fccedc15 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-panthor-profiling @@ -0,0 +1,10 @@ +What: /sys/bus/platform/drivers/panthor/.../profiling +Date: September 2024 +KernelVersion: 6.11.0 +Contact: Adrian Larumbe <adrian.larumbe@collabora.com> +Description: + Bitmask to enable drm fdinfo's job profiling measurements. + Valid values are: + 0: Don't enable fdinfo job profiling sources. + 1: Enable GPU cycle measurements for running jobs. + 2: Enable GPU timestamp sampling for running jobs. diff --git a/Documentation/gpu/panthor.rst b/Documentation/gpu/panthor.rst new file mode 100644 index 000000000000..cbf5c4429a2d --- /dev/null +++ b/Documentation/gpu/panthor.rst @@ -0,0 +1,46 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +========================= + drm/Panthor CSF driver +========================= + +.. _panfrost-usage-stats: + +Panthor DRM client usage stats implementation +============================================== + +The drm/Panthor driver implements the DRM client usage stats specification as +documented in :ref:`drm-client-usage-stats`. + +Example of the output showing the implemented key value pairs and entirety of +the currently possible format options: + +:: + pos: 0 + flags: 02400002 + mnt_id: 29 + ino: 491 + drm-driver: panthor + drm-client-id: 10 + drm-engine-panthor: 111110952750 ns + drm-cycles-panthor: 94439687187 + drm-maxfreq-panthor: 1000000000 Hz + drm-curfreq-panthor: 1000000000 Hz + drm-total-memory: 16480 KiB + drm-shared-memory: 0 + drm-active-memory: 16200 KiB + drm-resident-memory: 16480 KiB + drm-purgeable-memory: 0 + +Possible `drm-engine-` key names are: `panthor`. +`drm-curfreq-` values convey the current operating frequency for that engine. + +Users must bear in mind that engine and cycle sampling are disabled by default, +because of power saving concerns. `fdinfo` users and benchmark applications which +query the fdinfo file must make sure to toggle the job profiling status of the +driver by writing into the appropriate sysfs node:: + + echo <N> > /sys/bus/platform/drivers/panthor/[a-f0-9]*.gpu/profiling + +Where `N` is a bit mask where cycle and timestamp sampling are respectively +enabled by the first and second bits. diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 388d1aea389d..f9b93f84d611 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -1536,6 +1536,44 @@ static void panthor_remove(struct platform_device *pdev) panthor_device_unplug(ptdev); } +static ssize_t profiling_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct panthor_device *ptdev = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%d\n", ptdev->profile_mask); +} + +static ssize_t profiling_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct panthor_device *ptdev = dev_get_drvdata(dev); + u32 value; + int err; + + err = kstrtou32(buf, 0, &value); + if (err) + return err; + + if ((value & ~PANTHOR_DEVICE_PROFILING_ALL) != 0) + return -EINVAL; + + ptdev->profile_mask = value; + + return len; +} + +static DEVICE_ATTR_RW(profiling); + +static struct attribute *panthor_attrs[] = { + &dev_attr_profiling.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(panthor); + static const struct of_device_id dt_match[] = { { .compatible = "rockchip,rk3588-mali" }, { .compatible = "arm,mali-valhall-csf" }, @@ -1555,6 +1593,7 @@ static struct platform_driver panthor_driver = { .name = "panthor", .pm = pm_ptr(&panthor_pm_ops), .of_match_table = dt_match, + .dev_groups = panthor_groups, }, }; -- GitLab From 5a431e50e9d4189800be1607eef9deaf95959fc3 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra <vigneshr@ti.com> Date: Wed, 2 Oct 2024 12:49:01 +0530 Subject: [PATCH 605/970] gpio: davinci: Fix condition for irqchip registration Since commit d29e741cad3f ("gpio: davinci: drop platform data support"), irqchip is no longer being registered on platforms what don't use unbanked gpios. Fix this. Reported-by: Sabeeh Khan <sabeeh-khan@ti.com> Fixes: d29e741cad3f ("gpio: davinci: drop platform data support") Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com> Link: https://lore.kernel.org/r/20241002071901.2752757-1-vigneshr@ti.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> --- drivers/gpio/gpio-davinci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 790595f3b949..76b58c70b257 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -472,7 +472,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) return PTR_ERR(clk); } - if (chips->gpio_unbanked) { + if (!chips->gpio_unbanked) { irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0); if (irq < 0) { dev_err(dev, "Couldn't allocate IRQ numbers\n"); -- GitLab From ee703a7068f95764cfb62b57db1d36e465cb9b26 Mon Sep 17 00:00:00 2001 From: Zhao Mengmeng <zhaomengmeng@kylinos.cn> Date: Tue, 1 Oct 2024 19:54:23 +0800 Subject: [PATCH 606/970] udf: refactor udf_current_aext() to handle error As Jan suggested in links below, refactor udf_current_aext() to differentiate between error, hit EOF and success, it now takes pointer to etype to store the extent type, return 1 when getting etype success, return 0 when hitting EOF and return -errno when err. Link: https://lore.kernel.org/all/20240912111235.6nr3wuqvktecy3vh@quack3/ Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn> Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20241001115425.266556-2-zhaomzhao@126.com --- fs/udf/inode.c | 40 ++++++++++++++++++++++++++-------------- fs/udf/truncate.c | 10 ++++++++-- fs/udf/udfdecl.h | 5 +++-- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index eaee57b91c6c..295145b583b4 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1953,6 +1953,7 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block, struct extent_position nepos; struct kernel_lb_addr neloc; int ver, adsize; + int err = 0; if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT) adsize = sizeof(struct short_ad); @@ -1997,10 +1998,12 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block, if (epos->offset + adsize > sb->s_blocksize) { struct kernel_lb_addr cp_loc; uint32_t cp_len; - int cp_type; + int8_t cp_type; epos->offset -= adsize; - cp_type = udf_current_aext(inode, epos, &cp_loc, &cp_len, 0); + err = udf_current_aext(inode, epos, &cp_loc, &cp_len, &cp_type, 0); + if (err <= 0) + goto err_out; cp_len |= ((uint32_t)cp_type) << 30; __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1); @@ -2015,6 +2018,9 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block, *epos = nepos; return 0; +err_out: + brelse(bh); + return err; } /* @@ -2165,9 +2171,12 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, { int8_t etype; unsigned int indirections = 0; + int ret = 0; - while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == - (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { + while ((ret = udf_current_aext(inode, epos, eloc, elen, + &etype, inc)) > 0) { + if (etype != (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) + break; udf_pblk_t block; if (++indirections > UDF_MAX_INDIR_EXTS) { @@ -2188,14 +2197,17 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, } } - return etype; + return ret > 0 ? etype : -1; } -int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, - struct kernel_lb_addr *eloc, uint32_t *elen, int inc) +/* + * Returns 1 on success, -errno on error, 0 on hit EOF. + */ +int udf_current_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype, + int inc) { int alen; - int8_t etype; uint8_t *ptr; struct short_ad *sad; struct long_ad *lad; @@ -2222,8 +2234,8 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, case ICBTAG_FLAG_AD_SHORT: sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc); if (!sad) - return -1; - etype = le32_to_cpu(sad->extLength) >> 30; + return 0; + *etype = le32_to_cpu(sad->extLength) >> 30; eloc->logicalBlockNum = le32_to_cpu(sad->extPosition); eloc->partitionReferenceNum = iinfo->i_location.partitionReferenceNum; @@ -2232,17 +2244,17 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, case ICBTAG_FLAG_AD_LONG: lad = udf_get_filelongad(ptr, alen, &epos->offset, inc); if (!lad) - return -1; - etype = le32_to_cpu(lad->extLength) >> 30; + return 0; + *etype = le32_to_cpu(lad->extLength) >> 30; *eloc = lelb_to_cpu(lad->extLocation); *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK; break; default: udf_debug("alloc_type = %u unsupported\n", iinfo->i_alloc_type); - return -1; + return -EINVAL; } - return etype; + return 1; } static int udf_insert_aext(struct inode *inode, struct extent_position epos, diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index a686c10fd709..4758ba7b5f51 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -188,6 +188,7 @@ int udf_truncate_extents(struct inode *inode) loff_t byte_offset; int adsize; struct udf_inode_info *iinfo = UDF_I(inode); + int ret = 0; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) adsize = sizeof(struct short_ad); @@ -217,8 +218,8 @@ int udf_truncate_extents(struct inode *inode) else lenalloc -= sizeof(struct allocExtDesc); - while ((etype = udf_current_aext(inode, &epos, &eloc, - &elen, 0)) != -1) { + while ((ret = udf_current_aext(inode, &epos, &eloc, + &elen, &etype, 0)) > 0) { if (etype == (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { udf_write_aext(inode, &epos, &neloc, nelen, 0); if (indirect_ext_len) { @@ -253,6 +254,11 @@ int udf_truncate_extents(struct inode *inode) } } + if (ret < 0) { + brelse(epos.bh); + return ret; + } + if (indirect_ext_len) { BUG_ON(!epos.bh); udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len); diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 88692512a466..d893db95ac70 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -171,8 +171,9 @@ extern void udf_write_aext(struct inode *, struct extent_position *, extern int8_t udf_delete_aext(struct inode *, struct extent_position); extern int8_t udf_next_aext(struct inode *, struct extent_position *, struct kernel_lb_addr *, uint32_t *, int); -extern int8_t udf_current_aext(struct inode *, struct extent_position *, - struct kernel_lb_addr *, uint32_t *, int); +extern int udf_current_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, + int8_t *etype, int inc); extern void udf_update_extra_perms(struct inode *inode, umode_t mode); /* misc.c */ -- GitLab From df5215618fbe425875336d3a2d31bd599ae8c401 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela <perex@perex.cz> Date: Wed, 2 Oct 2024 10:13:06 +0200 Subject: [PATCH 607/970] ALSA: hda: fix trigger_tstamp_latched When the trigger_tstamp_latched flag is set, the PCM core code assumes that the low-level driver handles the trigger timestamping itself. Ensure that runtime->trigger_tstamp is always updated. Buglink: https://github.com/alsa-project/alsa-lib/issues/387 Reported-by: Zeno Endemann <zeno.endemann@mailbox.org> Signed-off-by: Jaroslav Kysela <perex@perex.cz> Link: https://patch.msgid.link/20241002081306.1788405-1-perex@perex.cz Signed-off-by: Takashi Iwai <tiwai@suse.de> --- include/sound/hdaudio.h | 2 +- sound/hda/hdac_stream.c | 6 +++++- sound/pci/hda/hda_controller.c | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 7e39d486374a..b098ceadbe74 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -590,7 +590,7 @@ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set, void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, unsigned int streams); void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, - unsigned int streams); + unsigned int streams, bool start); int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus, struct snd_pcm_substream *substream); diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index b53de020309f..0411a8fe9d6f 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -664,7 +664,7 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, * updated accordingly, too. */ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, - unsigned int streams) + unsigned int streams, bool start) { struct hdac_bus *bus = azx_dev->bus; struct snd_pcm_runtime *runtime = azx_dev->substream->runtime; @@ -672,6 +672,9 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, bool inited = false; u64 cycle_last = 0; + if (!start) + goto skip; + list_for_each_entry(s, &bus->stream_list, list) { if ((streams & (1 << s->index))) { azx_timecounter_init(s, inited, cycle_last); @@ -682,6 +685,7 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, } } +skip: snd_pcm_gettime(runtime, &runtime->trigger_tstamp); runtime->trigger_tstamp_latched = true; } diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 5d86e5a9c814..f3330b7e0fcf 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -275,8 +275,7 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) spin_lock(&bus->reg_lock); /* reset SYNC bits */ snd_hdac_stream_sync_trigger(hstr, false, sbits, sync_reg); - if (start) - snd_hdac_stream_timecounter_init(hstr, sbits); + snd_hdac_stream_timecounter_init(hstr, sbits, start); spin_unlock(&bus->reg_lock); return 0; } -- GitLab From b405c1e58b73981da0f8df03b00666b22b9397ae Mon Sep 17 00:00:00 2001 From: Zhao Mengmeng <zhaomengmeng@kylinos.cn> Date: Tue, 1 Oct 2024 19:54:24 +0800 Subject: [PATCH 608/970] udf: refactor udf_next_aext() to handle error Since udf_current_aext() has error handling, udf_next_aext() should have error handling too. Besides, when too many indirect extents found in one inode, return -EFSCORRUPTED; when reading block failed, return -EIO. Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn> Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20241001115425.266556-3-zhaomzhao@126.com --- fs/udf/balloc.c | 38 +++++++++----- fs/udf/directory.c | 10 +++- fs/udf/inode.c | 125 ++++++++++++++++++++++++++++++--------------- fs/udf/super.c | 3 +- fs/udf/truncate.c | 27 ++++++++-- fs/udf/udfdecl.h | 5 +- 6 files changed, 143 insertions(+), 65 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index d8fc11765d61..807c493ed0cd 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -370,6 +370,7 @@ static void udf_table_free_blocks(struct super_block *sb, struct extent_position oepos, epos; int8_t etype; struct udf_inode_info *iinfo; + int ret = 0; mutex_lock(&sbi->s_alloc_mutex); iinfo = UDF_I(table); @@ -383,8 +384,12 @@ static void udf_table_free_blocks(struct super_block *sb, epos.block = oepos.block = iinfo->i_location; epos.bh = oepos.bh = NULL; - while (count && - (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) { + while (count) { + ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1); + if (ret < 0) + goto error_return; + if (ret == 0) + break; if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == start)) { if ((0x3FFFFFFF - elen) < @@ -459,11 +464,8 @@ static void udf_table_free_blocks(struct super_block *sb, adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) adsize = sizeof(struct long_ad); - else { - brelse(oepos.bh); - brelse(epos.bh); + else goto error_return; - } if (epos.offset + (2 * adsize) > sb->s_blocksize) { /* Steal a block from the extent being free'd */ @@ -479,10 +481,10 @@ static void udf_table_free_blocks(struct super_block *sb, __udf_add_aext(table, &epos, &eloc, elen, 1); } +error_return: brelse(epos.bh); brelse(oepos.bh); -error_return: mutex_unlock(&sbi->s_alloc_mutex); return; } @@ -498,6 +500,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, struct extent_position epos; int8_t etype = -1; struct udf_inode_info *iinfo; + int ret = 0; if (first_block >= sbi->s_partmaps[partition].s_partition_len) return 0; @@ -516,11 +519,14 @@ static int udf_table_prealloc_blocks(struct super_block *sb, epos.bh = NULL; eloc.logicalBlockNum = 0xFFFFFFFF; - while (first_block != eloc.logicalBlockNum && - (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) { + while (first_block != eloc.logicalBlockNum) { + ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1); + if (ret < 0) + goto err_out; + if (ret == 0) + break; udf_debug("eloc=%u, elen=%u, first_block=%u\n", eloc.logicalBlockNum, elen, first_block); - ; /* empty loop body */ } if (first_block == eloc.logicalBlockNum) { @@ -539,6 +545,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, alloc_count = 0; } +err_out: brelse(epos.bh); if (alloc_count) @@ -560,6 +567,7 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb, struct extent_position epos, goal_epos; int8_t etype; struct udf_inode_info *iinfo = UDF_I(table); + int ret = 0; *err = -ENOSPC; @@ -583,8 +591,10 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb, epos.block = iinfo->i_location; epos.bh = goal_epos.bh = NULL; - while (spread && - (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) { + while (spread) { + ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1); + if (ret <= 0) + break; if (goal >= eloc.logicalBlockNum) { if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) @@ -612,9 +622,11 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb, brelse(epos.bh); - if (spread == 0xFFFFFFFF) { + if (ret < 0 || spread == 0xFFFFFFFF) { brelse(goal_epos.bh); mutex_unlock(&sbi->s_alloc_mutex); + if (ret < 0) + *err = ret; return 0; } diff --git a/fs/udf/directory.c b/fs/udf/directory.c index 93153665eb37..c6950050e7ae 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -166,13 +166,19 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter) */ static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter) { + int8_t etype = -1; + int err = 0; + iter->loffset++; if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits)) return 0; iter->loffset = 0; - if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1) - != (EXT_RECORDED_ALLOCATED >> 30)) { + err = udf_next_aext(iter->dir, &iter->epos, &iter->eloc, + &iter->elen, &etype, 1); + if (err < 0) + return err; + else if (err == 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) { if (iter->pos == iter->dir->i_size) { iter->elen = 0; return 0; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 295145b583b4..30f925f891b6 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -543,6 +543,7 @@ static int udf_do_extend_file(struct inode *inode, } else { struct kernel_lb_addr tmploc; uint32_t tmplen; + int8_t tmptype; udf_write_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); @@ -552,8 +553,12 @@ static int udf_do_extend_file(struct inode *inode, * more extents, we may need to enter possible following * empty indirect extent. */ - if (new_block_bytes) - udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); + if (new_block_bytes) { + err = udf_next_aext(inode, last_pos, &tmploc, &tmplen, + &tmptype, 0); + if (err < 0) + goto out_err; + } } iinfo->i_lenExtents += add; @@ -672,8 +677,10 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED; } else { epos.offset -= adsize; - etype = udf_next_aext(inode, &epos, &extent.extLocation, - &extent.extLength, 0); + err = udf_next_aext(inode, &epos, &extent.extLocation, + &extent.extLength, &etype, 0); + if (err <= 0) + goto out; extent.extLength |= etype << 30; } @@ -710,11 +717,11 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map) loff_t lbcount = 0, b_off = 0; udf_pblk_t newblocknum; sector_t offset = 0; - int8_t etype; + int8_t etype, tmpetype; struct udf_inode_info *iinfo = UDF_I(inode); udf_pblk_t goal = 0, pgoal = iinfo->i_location.logicalBlockNum; int lastblock = 0; - bool isBeyondEOF; + bool isBeyondEOF = false; int ret = 0; prev_epos.offset = udf_file_entry_alloc_offset(inode); @@ -746,9 +753,13 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map) prev_epos.offset = cur_epos.offset; cur_epos.offset = next_epos.offset; - etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1); - if (etype == -1) + ret = udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 1); + if (ret < 0) { + goto out_free; + } else if (ret == 0) { + isBeyondEOF = true; break; + } c = !c; @@ -769,13 +780,17 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map) * Move prev_epos and cur_epos into indirect extent if we are at * the pointer to it */ - udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); - udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); + ret = udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, &tmpetype, 0); + if (ret < 0) + goto out_free; + ret = udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, &tmpetype, 0); + if (ret < 0) + goto out_free; /* if the extent is allocated and recorded, return the block if the extent is not a multiple of the blocksize, round up */ - if (etype == (EXT_RECORDED_ALLOCATED >> 30)) { + if (!isBeyondEOF && etype == (EXT_RECORDED_ALLOCATED >> 30)) { if (elen & (inode->i_sb->s_blocksize - 1)) { elen = EXT_RECORDED_ALLOCATED | ((elen + inode->i_sb->s_blocksize - 1) & @@ -791,10 +806,9 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map) } /* Are we beyond EOF and preallocated extent? */ - if (etype == -1) { + if (isBeyondEOF) { loff_t hole_len; - isBeyondEOF = true; if (count) { if (c) laarr[0] = laarr[1]; @@ -830,7 +844,6 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map) endnum = c + 1; lastblock = 1; } else { - isBeyondEOF = false; endnum = startnum = ((count > 2) ? 2 : count); /* if the current extent is in position 0, @@ -844,15 +857,17 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map) /* if the current block is located in an extent, read the next extent */ - etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0); - if (etype != -1) { + ret = udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 0); + if (ret > 0) { laarr[c + 1].extLength = (etype << 30) | elen; laarr[c + 1].extLocation = eloc; count++; startnum++; endnum++; - } else + } else if (ret == 0) lastblock = 1; + else + goto out_free; } /* if the current extent is not recorded but allocated, get the @@ -1170,6 +1185,7 @@ static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, int start = 0, i; struct kernel_lb_addr tmploc; uint32_t tmplen; + int8_t tmpetype; int err; if (startnum > endnum) { @@ -1187,14 +1203,19 @@ static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, */ if (err < 0) return err; - udf_next_aext(inode, epos, &laarr[i].extLocation, - &laarr[i].extLength, 1); + err = udf_next_aext(inode, epos, &laarr[i].extLocation, + &laarr[i].extLength, &tmpetype, 1); + if (err < 0) + return err; start++; } } for (i = start; i < endnum; i++) { - udf_next_aext(inode, epos, &tmploc, &tmplen, 0); + err = udf_next_aext(inode, epos, &tmploc, &tmplen, &tmpetype, 0); + if (err < 0) + return err; + udf_write_aext(inode, epos, &laarr[i].extLocation, laarr[i].extLength, 1); } @@ -2166,24 +2187,30 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos, */ #define UDF_MAX_INDIR_EXTS 16 -int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, - struct kernel_lb_addr *eloc, uint32_t *elen, int inc) +/* + * Returns 1 on success, -errno on error, 0 on hit EOF. + */ +int udf_next_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype, + int inc) { - int8_t etype; unsigned int indirections = 0; int ret = 0; + udf_pblk_t block; - while ((ret = udf_current_aext(inode, epos, eloc, elen, - &etype, inc)) > 0) { - if (etype != (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) - break; - udf_pblk_t block; + while (1) { + ret = udf_current_aext(inode, epos, eloc, elen, + etype, inc); + if (ret <= 0) + return ret; + if (*etype != (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) + return ret; if (++indirections > UDF_MAX_INDIR_EXTS) { udf_err(inode->i_sb, "too many indirect extents in inode %lu\n", inode->i_ino); - return -1; + return -EFSCORRUPTED; } epos->block = *eloc; @@ -2193,11 +2220,9 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, epos->bh = sb_bread(inode->i_sb, block); if (!epos->bh) { udf_debug("reading block %u failed!\n", block); - return -1; + return -EIO; } } - - return ret > 0 ? etype : -1; } /* @@ -2263,20 +2288,24 @@ static int udf_insert_aext(struct inode *inode, struct extent_position epos, struct kernel_lb_addr oeloc; uint32_t oelen; int8_t etype; - int err; + int ret; if (epos.bh) get_bh(epos.bh); - while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) { + while (1) { + ret = udf_next_aext(inode, &epos, &oeloc, &oelen, &etype, 0); + if (ret <= 0) + break; udf_write_aext(inode, &epos, &neloc, nelen, 1); neloc = oeloc; nelen = (etype << 30) | oelen; } - err = udf_add_aext(inode, &epos, &neloc, nelen, 1); + if (ret == 0) + ret = udf_add_aext(inode, &epos, &neloc, nelen, 1); brelse(epos.bh); - return err; + return ret; } int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) @@ -2288,6 +2317,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) struct udf_inode_info *iinfo; struct kernel_lb_addr eloc; uint32_t elen; + int ret; if (epos.bh) { get_bh(epos.bh); @@ -2303,10 +2333,18 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) adsize = 0; oepos = epos; - if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1) + if (udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1) <= 0) return -1; - while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { + while (1) { + ret = udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1); + if (ret < 0) { + brelse(epos.bh); + brelse(oepos.bh); + return -1; + } + if (ret == 0) + break; udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1); if (oepos.bh != epos.bh) { oepos.block = epos.block; @@ -2371,6 +2409,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block, loff_t lbcount = 0, bcount = (loff_t) block << blocksize_bits; int8_t etype; struct udf_inode_info *iinfo; + int err = 0; iinfo = UDF_I(inode); if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) { @@ -2380,10 +2419,12 @@ int8_t inode_bmap(struct inode *inode, sector_t block, } *elen = 0; do { - etype = udf_next_aext(inode, pos, eloc, elen, 1); - if (etype == -1) { - *offset = (bcount - lbcount) >> blocksize_bits; - iinfo->i_lenExtents = lbcount; + err = udf_next_aext(inode, pos, eloc, elen, &etype, 1); + if (err <= 0) { + if (err == 0) { + *offset = (bcount - lbcount) >> blocksize_bits; + iinfo->i_lenExtents = lbcount; + } return -1; } lbcount += *elen; diff --git a/fs/udf/super.c b/fs/udf/super.c index 3460ecc826d1..1c8a736b3309 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2482,13 +2482,14 @@ static unsigned int udf_count_free_table(struct super_block *sb, uint32_t elen; struct kernel_lb_addr eloc; struct extent_position epos; + int8_t etype; mutex_lock(&UDF_SB(sb)->s_alloc_mutex); epos.block = UDF_I(table)->i_location; epos.offset = sizeof(struct unallocSpaceEntry); epos.bh = NULL; - while (udf_next_aext(table, &epos, &eloc, &elen, 1) != -1) + while (udf_next_aext(table, &epos, &eloc, &elen, &etype, 1) > 0) accum += (elen >> table->i_sb->s_blocksize_bits); brelse(epos.bh); diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 4758ba7b5f51..399958f891d1 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -69,6 +69,7 @@ void udf_truncate_tail_extent(struct inode *inode) int8_t etype = -1, netype; int adsize; struct udf_inode_info *iinfo = UDF_I(inode); + int ret; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || inode->i_size == iinfo->i_lenExtents) @@ -85,7 +86,10 @@ void udf_truncate_tail_extent(struct inode *inode) BUG(); /* Find the last extent in the file */ - while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { + while (1) { + ret = udf_next_aext(inode, &epos, &eloc, &elen, &netype, 1); + if (ret <= 0) + break; etype = netype; lbcount += elen; if (lbcount > inode->i_size) { @@ -101,7 +105,8 @@ void udf_truncate_tail_extent(struct inode *inode) epos.offset -= adsize; extent_trunc(inode, &epos, &eloc, etype, elen, nelen); epos.offset += adsize; - if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1) + if (udf_next_aext(inode, &epos, &eloc, &elen, + &netype, 1) > 0) udf_err(inode->i_sb, "Extent after EOF in inode %u\n", (unsigned)inode->i_ino); @@ -110,7 +115,8 @@ void udf_truncate_tail_extent(struct inode *inode) } /* This inode entry is in-memory only and thus we don't have to mark * the inode dirty */ - iinfo->i_lenExtents = inode->i_size; + if (ret == 0) + iinfo->i_lenExtents = inode->i_size; brelse(epos.bh); } @@ -124,6 +130,8 @@ void udf_discard_prealloc(struct inode *inode) int8_t etype = -1; struct udf_inode_info *iinfo = UDF_I(inode); int bsize = i_blocksize(inode); + int8_t tmpetype = -1; + int ret; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB || ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize)) @@ -132,15 +140,23 @@ void udf_discard_prealloc(struct inode *inode) epos.block = iinfo->i_location; /* Find the last extent in the file */ - while (udf_next_aext(inode, &epos, &eloc, &elen, 0) != -1) { + while (1) { + ret = udf_next_aext(inode, &epos, &eloc, &elen, &tmpetype, 0); + if (ret < 0) + goto out; + if (ret == 0) + break; brelse(prev_epos.bh); prev_epos = epos; if (prev_epos.bh) get_bh(prev_epos.bh); - etype = udf_next_aext(inode, &epos, &eloc, &elen, 1); + ret = udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1); + if (ret < 0) + goto out; lbcount += elen; } + if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { lbcount -= elen; udf_delete_aext(inode, prev_epos); @@ -150,6 +166,7 @@ void udf_discard_prealloc(struct inode *inode) /* This inode entry is in-memory only and thus we don't have to mark * the inode dirty */ iinfo->i_lenExtents = lbcount; +out: brelse(epos.bh); brelse(prev_epos.bh); } diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index d893db95ac70..5067ed68a8b4 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -169,8 +169,9 @@ extern int udf_add_aext(struct inode *, struct extent_position *, extern void udf_write_aext(struct inode *, struct extent_position *, struct kernel_lb_addr *, uint32_t, int); extern int8_t udf_delete_aext(struct inode *, struct extent_position); -extern int8_t udf_next_aext(struct inode *, struct extent_position *, - struct kernel_lb_addr *, uint32_t *, int); +extern int udf_next_aext(struct inode *inode, struct extent_position *epos, + struct kernel_lb_addr *eloc, uint32_t *elen, + int8_t *etype, int inc); extern int udf_current_aext(struct inode *inode, struct extent_position *epos, struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype, int inc); -- GitLab From c226964ec786f3797ed389a16392ce4357697d24 Mon Sep 17 00:00:00 2001 From: Zhao Mengmeng <zhaomengmeng@kylinos.cn> Date: Tue, 1 Oct 2024 19:54:25 +0800 Subject: [PATCH 609/970] udf: refactor inode_bmap() to handle error Refactor inode_bmap() to handle error since udf_next_aext() can return error now. On situations like ftruncate, udf_extend_file() can now detect errors and bail out early without resorting to checking for particular offsets and assuming internal behavior of these functions. Reported-by: syzbot+7a4842f0b1801230a989@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=7a4842f0b1801230a989 Tested-by: syzbot+7a4842f0b1801230a989@syzkaller.appspotmail.com Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn> Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20241001115425.266556-4-zhaomzhao@126.com --- fs/udf/directory.c | 13 ++++++++----- fs/udf/inode.c | 40 +++++++++++++++++++++++++--------------- fs/udf/partition.c | 6 ++++-- fs/udf/truncate.c | 6 ++++-- fs/udf/udfdecl.h | 5 +++-- 5 files changed, 44 insertions(+), 26 deletions(-) diff --git a/fs/udf/directory.c b/fs/udf/directory.c index c6950050e7ae..632453aa3893 100644 --- a/fs/udf/directory.c +++ b/fs/udf/directory.c @@ -246,6 +246,7 @@ int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir, { struct udf_inode_info *iinfo = UDF_I(dir); int err = 0; + int8_t etype; iter->dir = dir; iter->bh[0] = iter->bh[1] = NULL; @@ -265,9 +266,9 @@ int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir, goto out; } - if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, - &iter->eloc, &iter->elen, &iter->loffset) != - (EXT_RECORDED_ALLOCATED >> 30)) { + err = inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, + &iter->eloc, &iter->elen, &iter->loffset, &etype); + if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) { if (pos == dir->i_size) return 0; udf_err(dir->i_sb, @@ -463,6 +464,7 @@ int udf_fiiter_append_blk(struct udf_fileident_iter *iter) sector_t block; uint32_t old_elen = iter->elen; int err; + int8_t etype; if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)) return -EINVAL; @@ -477,8 +479,9 @@ int udf_fiiter_append_blk(struct udf_fileident_iter *iter) udf_fiiter_update_elen(iter, old_elen); return err; } - if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, - &iter->loffset) != (EXT_RECORDED_ALLOCATED >> 30)) { + err = inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, + &iter->loffset, &etype); + if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) { udf_err(iter->dir->i_sb, "block %llu not allocated in directory (ino %lu)\n", (unsigned long long)block, iter->dir->i_ino); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 30f925f891b6..75c8cccfebd4 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -404,7 +404,7 @@ struct udf_map_rq { static int udf_map_block(struct inode *inode, struct udf_map_rq *map) { - int err; + int ret; struct udf_inode_info *iinfo = UDF_I(inode); if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)) @@ -416,18 +416,24 @@ static int udf_map_block(struct inode *inode, struct udf_map_rq *map) uint32_t elen; sector_t offset; struct extent_position epos = {}; + int8_t etype; down_read(&iinfo->i_data_sem); - if (inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset) - == (EXT_RECORDED_ALLOCATED >> 30)) { + ret = inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset, + &etype); + if (ret < 0) + goto out_read; + if (ret > 0 && etype == (EXT_RECORDED_ALLOCATED >> 30)) { map->pblk = udf_get_lb_pblock(inode->i_sb, &eloc, offset); map->oflags |= UDF_BLK_MAPPED; + ret = 0; } +out_read: up_read(&iinfo->i_data_sem); brelse(epos.bh); - return 0; + return ret; } down_write(&iinfo->i_data_sem); @@ -438,9 +444,9 @@ static int udf_map_block(struct inode *inode, struct udf_map_rq *map) if (((loff_t)map->lblk) << inode->i_blkbits >= iinfo->i_lenExtents) udf_discard_prealloc(inode); udf_clear_extent_cache(inode); - err = inode_getblk(inode, map); + ret = inode_getblk(inode, map); up_write(&iinfo->i_data_sem); - return err; + return ret; } static int __udf_get_block(struct inode *inode, sector_t block, @@ -662,8 +668,10 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) */ udf_discard_prealloc(inode); - etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); - within_last_ext = (etype != -1); + err = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &etype); + if (err < 0) + goto out; + within_last_ext = (err == 1); /* We don't expect extents past EOF... */ WARN_ON_ONCE(within_last_ext && elen > ((loff_t)offset + 1) << inode->i_blkbits); @@ -2401,13 +2409,15 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) return (elen >> 30); } -int8_t inode_bmap(struct inode *inode, sector_t block, - struct extent_position *pos, struct kernel_lb_addr *eloc, - uint32_t *elen, sector_t *offset) +/* + * Returns 1 on success, -errno on error, 0 on hit EOF. + */ +int inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos, + struct kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset, + int8_t *etype) { unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; loff_t lbcount = 0, bcount = (loff_t) block << blocksize_bits; - int8_t etype; struct udf_inode_info *iinfo; int err = 0; @@ -2419,13 +2429,13 @@ int8_t inode_bmap(struct inode *inode, sector_t block, } *elen = 0; do { - err = udf_next_aext(inode, pos, eloc, elen, &etype, 1); + err = udf_next_aext(inode, pos, eloc, elen, etype, 1); if (err <= 0) { if (err == 0) { *offset = (bcount - lbcount) >> blocksize_bits; iinfo->i_lenExtents = lbcount; } - return -1; + return err; } lbcount += *elen; } while (lbcount <= bcount); @@ -2433,5 +2443,5 @@ int8_t inode_bmap(struct inode *inode, sector_t block, udf_update_extent_cache(inode, lbcount - *elen, pos); *offset = (bcount + *elen - lbcount) >> blocksize_bits; - return etype; + return 1; } diff --git a/fs/udf/partition.c b/fs/udf/partition.c index af877991edc1..2b85c9501bed 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c @@ -282,9 +282,11 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, sector_t ext_offset; struct extent_position epos = {}; uint32_t phyblock; + int8_t etype; + int err = 0; - if (inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset) != - (EXT_RECORDED_ALLOCATED >> 30)) + err = inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset, &etype); + if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) phyblock = 0xFFFFFFFF; else { map = &UDF_SB(sb)->s_partmaps[partition]; diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 399958f891d1..4f33a4a48886 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -214,10 +214,12 @@ int udf_truncate_extents(struct inode *inode) else BUG(); - etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); + ret = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &etype); + if (ret < 0) + return ret; byte_offset = (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize - 1)); - if (etype == -1) { + if (ret == 0) { /* We should extend the file? */ WARN_ON(byte_offset); return 0; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 5067ed68a8b4..d159f20d61e8 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -157,8 +157,9 @@ extern struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, extern int udf_setsize(struct inode *, loff_t); extern void udf_evict_inode(struct inode *); extern int udf_write_inode(struct inode *, struct writeback_control *wbc); -extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, - struct kernel_lb_addr *, uint32_t *, sector_t *); +extern int inode_bmap(struct inode *inode, sector_t block, + struct extent_position *pos, struct kernel_lb_addr *eloc, + uint32_t *elen, sector_t *offset, int8_t *etype); int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); extern int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block, struct extent_position *epos); -- GitLab From 264db9d666ad9a35075cc9ed9ec09d021580fbb1 Mon Sep 17 00:00:00 2001 From: Gianfranco Trad <gianf.trad@gmail.com> Date: Wed, 25 Sep 2024 09:46:15 +0200 Subject: [PATCH 610/970] udf: fix uninit-value use in udf_get_fileshortad Check for overflow when computing alen in udf_current_aext to mitigate later uninit-value use in udf_get_fileshortad KMSAN bug[1]. After applying the patch reproducer did not trigger any issue[2]. [1] https://syzkaller.appspot.com/bug?extid=8901c4560b7ab5c2f9df [2] https://syzkaller.appspot.com/x/log.txt?x=10242227980000 Reported-by: syzbot+8901c4560b7ab5c2f9df@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8901c4560b7ab5c2f9df Tested-by: syzbot+8901c4560b7ab5c2f9df@syzkaller.appspotmail.com Suggested-by: Jan Kara <jack@suse.com> Signed-off-by: Gianfranco Trad <gianf.trad@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240925074613.8475-3-gianf.trad@gmail.com --- fs/udf/inode.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 75c8cccfebd4..70c907fe8af9 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -2255,12 +2255,15 @@ int udf_current_aext(struct inode *inode, struct extent_position *epos, alen = udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc; } else { + struct allocExtDesc *header = + (struct allocExtDesc *)epos->bh->b_data; + if (!epos->offset) epos->offset = sizeof(struct allocExtDesc); ptr = epos->bh->b_data + epos->offset; - alen = sizeof(struct allocExtDesc) + - le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)-> - lengthAllocDescs); + if (check_add_overflow(sizeof(struct allocExtDesc), + le32_to_cpu(header->lengthAllocDescs), &alen)) + return -1; } switch (iinfo->i_alloc_type) { -- GitLab From bbd1e5ea66f6ca88624faefe0a153637f53ad15d Mon Sep 17 00:00:00 2001 From: Alexey Klimov <alexey.klimov@linaro.org> Date: Wed, 2 Oct 2024 03:20:09 +0100 Subject: [PATCH 611/970] ASoC: dt-bindings: qcom,sm8250: add qrb4210-rb2-sndcard Add adsp-backed soundcard compatible for QRB4210 RB2 platform, which as of now looks fully compatible with SM8250. Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://patch.msgid.link/20241002022015.867031-2-alexey.klimov@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org> --- Documentation/devicetree/bindings/sound/qcom,sm8250.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml index 1d3acdc0c733..2e2e01493a5f 100644 --- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml @@ -30,6 +30,7 @@ properties: - qcom,apq8096-sndcard - qcom,qcm6490-idp-sndcard - qcom,qcs6490-rb3gen2-sndcard + - qcom,qrb4210-rb2-sndcard - qcom,qrb5165-rb5-sndcard - qcom,sc7180-qdsp6-sndcard - qcom,sc8280xp-sndcard -- GitLab From b97bc0656a66f89f78098d4d72dc04fa9518ab11 Mon Sep 17 00:00:00 2001 From: Alexey Klimov <alexey.klimov@linaro.org> Date: Wed, 2 Oct 2024 03:20:10 +0100 Subject: [PATCH 612/970] ASoC: qcom: sm8250: add qrb4210-rb2-sndcard compatible string Add "qcom,qrb4210-rb2-sndcard" to the list of recognizable devices. Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org> Link: https://patch.msgid.link/20241002022015.867031-3-alexey.klimov@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/qcom/sm8250.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 274bab28209a..19adadedc88a 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -174,6 +174,7 @@ static int sm8250_platform_probe(struct platform_device *pdev) static const struct of_device_id snd_sm8250_dt_match[] = { {.compatible = "qcom,sm8250-sndcard"}, + {.compatible = "qcom,qrb4210-rb2-sndcard"}, {.compatible = "qcom,qrb5165-rb5-sndcard"}, {} }; -- GitLab From 17d8adc4cd5181c13c1041b197b76efc09eaf8a8 Mon Sep 17 00:00:00 2001 From: Miquel Raynal <miquel.raynal@bootlin.com> Date: Tue, 1 Oct 2024 22:47:49 +0200 Subject: [PATCH 613/970] ASoC: dt-bindings: davinci-mcasp: Fix interrupts property My understanding of the interrupts property is that it can either be: 1/ - TX 2/ - TX - RX 3/ - Common/combined. There are very little chances that either: - TX - Common/combined or even - TX - RX - Common/combined could be a thing. Looking at the interrupt-names definition (which uses oneOf instead of anyOf), it makes indeed little sense to use anyOf in the interrupts definition. I believe this is just a mistake, hence let's fix it. Fixes: 8be90641a0bb ("ASoC: dt-bindings: davinci-mcasp: convert McASP bindings to yaml schema") Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://patch.msgid.link/20241001204749.390054-1-miquel.raynal@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org> --- .../devicetree/bindings/sound/davinci-mcasp-audio.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml index 7735e08d35ba..ab3206ffa4af 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml @@ -102,7 +102,7 @@ properties: default: 2 interrupts: - anyOf: + oneOf: - minItems: 1 items: - description: TX interrupt -- GitLab From 47d7d3fd72afc7dcd548806291793ee6f3848215 Mon Sep 17 00:00:00 2001 From: Hui Wang <hui.wang@canonical.com> Date: Wed, 2 Oct 2024 10:56:59 +0800 Subject: [PATCH 614/970] ASoC: imx-card: Set card.owner to avoid a warning calltrace if SND=m In most Linux distribution kernels, the SND is set to m, in such a case, when booting the kernel on i.MX8MP EVK board, there is a warning calltrace like below: Call trace: snd_card_init+0x484/0x4cc [snd] snd_card_new+0x70/0xa8 [snd] snd_soc_bind_card+0x310/0xbd0 [snd_soc_core] snd_soc_register_card+0xf0/0x108 [snd_soc_core] devm_snd_soc_register_card+0x4c/0xa4 [snd_soc_core] That is because the card.owner is not set, a warning calltrace is raised in the snd_card_init() due to it. Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") Signed-off-by: Hui Wang <hui.wang@canonical.com> Link: https://patch.msgid.link/20241002025659.723544-1-hui.wang@canonical.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/fsl/imx-card.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index 98b37dd2b901..a7215bad6484 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -710,6 +710,7 @@ static int imx_card_probe(struct platform_device *pdev) data->plat_data = plat_data; data->card.dev = &pdev->dev; + data->card.owner = THIS_MODULE; dev_set_drvdata(&pdev->dev, &data->card); snd_soc_card_set_drvdata(&data->card, data); -- GitLab From 2c0b2b484b164072ba6cf52af1bde85158fc75d4 Mon Sep 17 00:00:00 2001 From: Charles Han <hanchunchao@inspur.com> Date: Wed, 25 Sep 2024 16:00:30 +0800 Subject: [PATCH 615/970] ASoC: intel: sof_sdw: Add check devm_kasprintf() returned value devm_kasprintf() can return a NULL pointer on failure but this returned value is not checked. Fixes: b359760d95ee ("ASoC: intel: sof_sdw: Add simple DAI link creation helper") Signed-off-by: Charles Han <hanchunchao@inspur.com> Link: https://patch.msgid.link/20240925080030.11262-1-hanchunchao@inspur.com Signed-off-by: Mark Brown <broonie@kernel.org> --- sound/soc/intel/boards/sof_sdw.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 5196d96f5c0e..35d707d3ae9c 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -800,6 +800,9 @@ static int create_ssp_dailinks(struct snd_soc_card *card, char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); char *codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", ssp_info->acpi_id, j++); + if (!name || !cpu_dai_name || !codec_name) + return -ENOMEM; + int playback = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; int capture = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; @@ -866,6 +869,9 @@ static int create_hdmi_dailinks(struct snd_soc_card *card, for (i = 0; i < hdmi_num; i++) { char *name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1); char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1); + if (!name || !cpu_dai_name) + return -ENOMEM; + char *codec_name, *codec_dai_name; if (intel_ctx->hdmi.idisp_codec) { @@ -877,6 +883,9 @@ static int create_hdmi_dailinks(struct snd_soc_card *card, codec_dai_name = "snd-soc-dummy-dai"; } + if (!codec_dai_name) + return -ENOMEM; + ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, 1, 0, // HDMI only supports playback cpu_dai_name, platform_component->name, @@ -900,6 +909,9 @@ static int create_bt_dailinks(struct snd_soc_card *card, SOF_BT_OFFLOAD_SSP_SHIFT; char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); + if (!name || !cpu_dai_name) + return -ENOMEM; + int ret; ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, -- GitLab From 35ceae44742e1101f9d20adadbbbd92c05d7d659 Mon Sep 17 00:00:00 2001 From: Jan Kara <jack@suse.cz> Date: Wed, 17 Jul 2024 16:06:23 +0200 Subject: [PATCH 616/970] fsnotify: Avoid data race between fsnotify_recalc_mask() and fsnotify_object_watched() When __fsnotify_recalc_mask() recomputes the mask on the watched object, the compiler can "optimize" the code to perform partial updates to the mask (including zeroing it at the beginning). Thus places checking the object mask without conn->lock such as fsnotify_object_watched() could see invalid states of the mask. Make sure the mask update is performed by one memory store using WRITE_ONCE(). Reported-by: syzbot+701037856c25b143f1ad@syzkaller.appspotmail.com Reported-by: Dmitry Vyukov <dvyukov@google.com> Link: https://lore.kernel.org/all/CACT4Y+Zk0ohwwwHSD63U2-PQ=UuamXczr1mKBD6xtj2dyYKBvA@mail.gmail.com Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20240717140623.27768-1-jack@suse.cz --- fs/notify/fsnotify.c | 21 ++++++++++++--------- fs/notify/inotify/inotify_user.c | 2 +- fs/notify/mark.c | 8 ++++++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 272c8a1dab3c..82ae8254c068 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -183,8 +183,10 @@ static bool fsnotify_event_needs_parent(struct inode *inode, __u32 mnt_mask, BUILD_BUG_ON(FS_EVENTS_POSS_ON_CHILD & ~FS_EVENTS_POSS_TO_PARENT); /* Did either inode/sb/mount subscribe for events with parent/name? */ - marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask); - marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask); + marks_mask |= fsnotify_parent_needed_mask( + READ_ONCE(inode->i_fsnotify_mask)); + marks_mask |= fsnotify_parent_needed_mask( + READ_ONCE(inode->i_sb->s_fsnotify_mask)); marks_mask |= fsnotify_parent_needed_mask(mnt_mask); /* Did they subscribe for this event with parent/name info? */ @@ -195,8 +197,8 @@ static bool fsnotify_event_needs_parent(struct inode *inode, __u32 mnt_mask, static inline bool fsnotify_object_watched(struct inode *inode, __u32 mnt_mask, __u32 mask) { - __u32 marks_mask = inode->i_fsnotify_mask | mnt_mask | - inode->i_sb->s_fsnotify_mask; + __u32 marks_mask = READ_ONCE(inode->i_fsnotify_mask) | mnt_mask | + READ_ONCE(inode->i_sb->s_fsnotify_mask); return mask & marks_mask & ALL_FSNOTIFY_EVENTS; } @@ -213,7 +215,8 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, int data_type) { const struct path *path = fsnotify_data_path(data, data_type); - __u32 mnt_mask = path ? real_mount(path->mnt)->mnt_fsnotify_mask : 0; + __u32 mnt_mask = path ? + READ_ONCE(real_mount(path->mnt)->mnt_fsnotify_mask) : 0; struct inode *inode = d_inode(dentry); struct dentry *parent; bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED; @@ -557,13 +560,13 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, (!inode2 || !inode2->i_fsnotify_marks)) return 0; - marks_mask = sb->s_fsnotify_mask; + marks_mask = READ_ONCE(sb->s_fsnotify_mask); if (mnt) - marks_mask |= mnt->mnt_fsnotify_mask; + marks_mask |= READ_ONCE(mnt->mnt_fsnotify_mask); if (inode) - marks_mask |= inode->i_fsnotify_mask; + marks_mask |= READ_ONCE(inode->i_fsnotify_mask); if (inode2) - marks_mask |= inode2->i_fsnotify_mask; + marks_mask |= READ_ONCE(inode2->i_fsnotify_mask); /* diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index c7e451d5bd51..0794dcaf1e47 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -569,7 +569,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, /* more bits in old than in new? */ int dropped = (old_mask & ~new_mask); /* more bits in this fsn_mark than the inode's mask? */ - int do_inode = (new_mask & ~inode->i_fsnotify_mask); + int do_inode = (new_mask & ~READ_ONCE(inode->i_fsnotify_mask)); /* update the inode with this new fsn_mark */ if (dropped || do_inode) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 5e170e713088..c45b222cf9c1 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -128,7 +128,7 @@ __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn) if (WARN_ON(!fsnotify_valid_obj_type(conn->type))) return 0; - return *fsnotify_conn_mask_p(conn); + return READ_ONCE(*fsnotify_conn_mask_p(conn)); } static void fsnotify_get_sb_watched_objects(struct super_block *sb) @@ -245,7 +245,11 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) !(mark->flags & FSNOTIFY_MARK_FLAG_NO_IREF)) want_iref = true; } - *fsnotify_conn_mask_p(conn) = new_mask; + /* + * We use WRITE_ONCE() to prevent silly compiler optimizations from + * confusing readers not holding conn->lock with partial updates. + */ + WRITE_ONCE(*fsnotify_conn_mask_p(conn), new_mask); return fsnotify_update_iref(conn, want_iref); } -- GitLab From cad3f4a22cfa4081cc2d465d1118cf31708fd82b Mon Sep 17 00:00:00 2001 From: Lizhi Xu <lizhi.xu@windriver.com> Date: Fri, 27 Sep 2024 22:36:42 +0800 Subject: [PATCH 617/970] inotify: Fix possible deadlock in fsnotify_destroy_mark [Syzbot reported] WARNING: possible circular locking dependency detected 6.11.0-rc4-syzkaller-00019-gb311c1b497e5 #0 Not tainted ------------------------------------------------------ kswapd0/78 is trying to acquire lock: ffff88801b8d8930 (&group->mark_mutex){+.+.}-{3:3}, at: fsnotify_group_lock include/linux/fsnotify_backend.h:270 [inline] ffff88801b8d8930 (&group->mark_mutex){+.+.}-{3:3}, at: fsnotify_destroy_mark+0x38/0x3c0 fs/notify/mark.c:578 but task is already holding lock: ffffffff8ea2fd60 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat mm/vmscan.c:6841 [inline] ffffffff8ea2fd60 (fs_reclaim){+.+.}-{0:0}, at: kswapd+0xbb4/0x35a0 mm/vmscan.c:7223 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (fs_reclaim){+.+.}-{0:0}: ... kmem_cache_alloc_noprof+0x3d/0x2a0 mm/slub.c:4044 inotify_new_watch fs/notify/inotify/inotify_user.c:599 [inline] inotify_update_watch fs/notify/inotify/inotify_user.c:647 [inline] __do_sys_inotify_add_watch fs/notify/inotify/inotify_user.c:786 [inline] __se_sys_inotify_add_watch+0x72e/0x1070 fs/notify/inotify/inotify_user.c:729 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f -> #0 (&group->mark_mutex){+.+.}-{3:3}: ... __mutex_lock+0x136/0xd70 kernel/locking/mutex.c:752 fsnotify_group_lock include/linux/fsnotify_backend.h:270 [inline] fsnotify_destroy_mark+0x38/0x3c0 fs/notify/mark.c:578 fsnotify_destroy_marks+0x14a/0x660 fs/notify/mark.c:934 fsnotify_inoderemove include/linux/fsnotify.h:264 [inline] dentry_unlink_inode+0x2e0/0x430 fs/dcache.c:403 __dentry_kill+0x20d/0x630 fs/dcache.c:610 shrink_kill+0xa9/0x2c0 fs/dcache.c:1055 shrink_dentry_list+0x2c0/0x5b0 fs/dcache.c:1082 prune_dcache_sb+0x10f/0x180 fs/dcache.c:1163 super_cache_scan+0x34f/0x4b0 fs/super.c:221 do_shrink_slab+0x701/0x1160 mm/shrinker.c:435 shrink_slab+0x1093/0x14d0 mm/shrinker.c:662 shrink_one+0x43b/0x850 mm/vmscan.c:4815 shrink_many mm/vmscan.c:4876 [inline] lru_gen_shrink_node mm/vmscan.c:4954 [inline] shrink_node+0x3799/0x3de0 mm/vmscan.c:5934 kswapd_shrink_node mm/vmscan.c:6762 [inline] balance_pgdat mm/vmscan.c:6954 [inline] kswapd+0x1bcd/0x35a0 mm/vmscan.c:7223 [Analysis] The problem is that inotify_new_watch() is using GFP_KERNEL to allocate new watches under group->mark_mutex, however if dentry reclaim races with unlinking of an inode, it can end up dropping the last dentry reference for an unlinked inode resulting in removal of fsnotify mark from reclaim context which wants to acquire group->mark_mutex as well. This scenario shows that all notification groups are in principle prone to this kind of a deadlock (previously, we considered only fanotify and dnotify to be problematic for other reasons) so make sure all allocations under group->mark_mutex happen with GFP_NOFS. Reported-and-tested-by: syzbot+c679f13773f295d2da53@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c679f13773f295d2da53 Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240927143642.2369508-1-lizhi.xu@windriver.com --- fs/nfsd/filecache.c | 2 +- fs/notify/dnotify/dnotify.c | 3 +-- fs/notify/fanotify/fanotify_user.c | 2 +- fs/notify/group.c | 11 ----------- include/linux/fsnotify_backend.h | 10 +++------- 5 files changed, 6 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 19bb88c7eebd..ea1ca374cdab 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -792,7 +792,7 @@ nfsd_file_cache_init(void) } nfsd_file_fsnotify_group = fsnotify_alloc_group(&nfsd_file_fsnotify_ops, - FSNOTIFY_GROUP_NOFS); + 0); if (IS_ERR(nfsd_file_fsnotify_group)) { pr_err("nfsd: unable to create fsnotify group: %ld\n", PTR_ERR(nfsd_file_fsnotify_group)); diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 46440fbb8662..d5dbef7f5c95 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -406,8 +406,7 @@ static int __init dnotify_init(void) SLAB_PANIC|SLAB_ACCOUNT); dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC|SLAB_ACCOUNT); - dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops, - FSNOTIFY_GROUP_NOFS); + dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops, 0); if (IS_ERR(dnotify_group)) panic("unable to allocate fsnotify group for dnotify\n"); dnotify_sysctl_init(); diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 13454e5fd3fb..9644bc72e457 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1480,7 +1480,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ group = fsnotify_alloc_group(&fanotify_fsnotify_ops, - FSNOTIFY_GROUP_USER | FSNOTIFY_GROUP_NOFS); + FSNOTIFY_GROUP_USER); if (IS_ERR(group)) { return PTR_ERR(group); } diff --git a/fs/notify/group.c b/fs/notify/group.c index 1de6631a3925..18446b7b0d49 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -115,7 +115,6 @@ static struct fsnotify_group *__fsnotify_alloc_group( const struct fsnotify_ops *ops, int flags, gfp_t gfp) { - static struct lock_class_key nofs_marks_lock; struct fsnotify_group *group; group = kzalloc(sizeof(struct fsnotify_group), gfp); @@ -136,16 +135,6 @@ static struct fsnotify_group *__fsnotify_alloc_group( group->ops = ops; group->flags = flags; - /* - * For most backends, eviction of inode with a mark is not expected, - * because marks hold a refcount on the inode against eviction. - * - * Use a different lockdep class for groups that support evictable - * inode marks, because with evictable marks, mark_mutex is NOT - * fs-reclaim safe - the mutex is taken when evicting inodes. - */ - if (flags & FSNOTIFY_GROUP_NOFS) - lockdep_set_class(&group->mark_mutex, &nofs_marks_lock); return group; } diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 8be029bc50b1..3ecf7768e577 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -217,7 +217,6 @@ struct fsnotify_group { #define FSNOTIFY_GROUP_USER 0x01 /* user allocated group */ #define FSNOTIFY_GROUP_DUPS 0x02 /* allow multiple marks per object */ -#define FSNOTIFY_GROUP_NOFS 0x04 /* group lock is not direct reclaim safe */ int flags; unsigned int owner_flags; /* stored flags of mark_mutex owner */ @@ -268,22 +267,19 @@ struct fsnotify_group { static inline void fsnotify_group_lock(struct fsnotify_group *group) { mutex_lock(&group->mark_mutex); - if (group->flags & FSNOTIFY_GROUP_NOFS) - group->owner_flags = memalloc_nofs_save(); + group->owner_flags = memalloc_nofs_save(); } static inline void fsnotify_group_unlock(struct fsnotify_group *group) { - if (group->flags & FSNOTIFY_GROUP_NOFS) - memalloc_nofs_restore(group->owner_flags); + memalloc_nofs_restore(group->owner_flags); mutex_unlock(&group->mark_mutex); } static inline void fsnotify_group_assert_locked(struct fsnotify_group *group) { WARN_ON_ONCE(!mutex_is_locked(&group->mark_mutex)); - if (group->flags & FSNOTIFY_GROUP_NOFS) - WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS)); + WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS)); } /* When calling fsnotify tell it if the data is a path or inode */ -- GitLab From 0ab42843003f27db509e42f2060bb3fa6ffad38d Mon Sep 17 00:00:00 2001 From: Keith Busch <kbusch@kernel.org> Date: Sun, 22 Sep 2024 07:18:00 -0700 Subject: [PATCH 618/970] block: fix blk_rq_map_integrity_sg kernel-doc Fix the documentation to match the new function signature. Fixes: 76c313f658d2752 ("blk-integrity: improved sg segment mapping") Signed-off-by: Keith Busch <kbusch@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20240922141800.3622319-1-kbusch@meta.com Signed-off-by: Jens Axboe <axboe@kernel.dk> --- block/blk-integrity.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 0a2b1c5d0ebf..83b696ba0cac 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -56,8 +56,7 @@ int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio) /** * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist - * @q: request queue - * @bio: bio with integrity metadata attached + * @rq: request to map * @sglist: target scatterlist * * Description: Map the integrity vectors in request into a -- GitLab From 14d57ec3b86369d0037567f12caae0c9e9eaad9e Mon Sep 17 00:00:00 2001 From: Dan Carpenter <dan.carpenter@linaro.org> Date: Wed, 2 Oct 2024 13:47:21 +0300 Subject: [PATCH 619/970] blk_iocost: remove some duplicate irq disable/enables These are called from blkcg_print_blkgs() which already disables IRQs so disabling it again is wrong. It means that IRQs will be enabled slightly earlier than intended, however, so far as I can see, this bug is harmless. Fixes: 35198e323001 ("blk-iocost: read params inside lock in sysfs apis") Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/Zv0kudA9xyGdaA4g@stanley.mountain Signed-off-by: Jens Axboe <axboe@kernel.dk> --- block/blk-iocost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 9dc9323f84ac..384aa15e8260 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -3166,7 +3166,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd, if (!dname) return 0; - spin_lock_irq(&ioc->lock); + spin_lock(&ioc->lock); seq_printf(sf, "%s enable=%d ctrl=%s rpct=%u.%02u rlat=%u wpct=%u.%02u wlat=%u min=%u.%02u max=%u.%02u\n", dname, ioc->enabled, ioc->user_qos_params ? "user" : "auto", ioc->params.qos[QOS_RPPM] / 10000, @@ -3179,7 +3179,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd, ioc->params.qos[QOS_MIN] % 10000 / 100, ioc->params.qos[QOS_MAX] / 10000, ioc->params.qos[QOS_MAX] % 10000 / 100); - spin_unlock_irq(&ioc->lock); + spin_unlock(&ioc->lock); return 0; } @@ -3366,14 +3366,14 @@ static u64 ioc_cost_model_prfill(struct seq_file *sf, if (!dname) return 0; - spin_lock_irq(&ioc->lock); + spin_lock(&ioc->lock); seq_printf(sf, "%s ctrl=%s model=linear " "rbps=%llu rseqiops=%llu rrandiops=%llu " "wbps=%llu wseqiops=%llu wrandiops=%llu\n", dname, ioc->user_cost_model ? "user" : "auto", u[I_LCOEF_RBPS], u[I_LCOEF_RSEQIOPS], u[I_LCOEF_RRANDIOPS], u[I_LCOEF_WBPS], u[I_LCOEF_WSEQIOPS], u[I_LCOEF_WRANDIOPS]); - spin_unlock_irq(&ioc->lock); + spin_unlock(&ioc->lock); return 0; } -- GitLab From 6d6e54fc71ad1ab0a87047fd9c211e75d86084a3 Mon Sep 17 00:00:00 2001 From: Chun-Yi Lee <joeyli.kernel@gmail.com> Date: Wed, 2 Oct 2024 11:54:58 +0800 Subject: [PATCH 620/970] aoe: fix the potential use-after-free problem in more places For fixing CVE-2023-6270, f98364e92662 ("aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts") makes tx() calling dev_put() instead of doing in aoecmd_cfg_pkts(). It avoids that the tx() runs into use-after-free. Then Nicolai Stange found more places in aoe have potential use-after-free problem with tx(). e.g. revalidate(), aoecmd_ata_rw(), resend(), probe() and aoecmd_cfg_rsp(). Those functions also use aoenet_xmit() to push packet to tx queue. So they should also use dev_hold() to increase the refcnt of skb->dev. On the other hand, moving dev_put() to tx() causes that the refcnt of skb->dev be reduced to a negative value, because corresponding dev_hold() are not called in revalidate(), aoecmd_ata_rw(), resend(), probe(), and aoecmd_cfg_rsp(). This patch fixed this issue. Cc: stable@vger.kernel.org Link: https://nvd.nist.gov/vuln/detail/CVE-2023-6270 Fixes: f98364e92662 ("aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts") Reported-by: Nicolai Stange <nstange@suse.com> Signed-off-by: Chun-Yi Lee <jlee@suse.com> Link: https://lore.kernel.org/stable/20240624064418.27043-1-jlee%40suse.com Link: https://lore.kernel.org/r/20241002035458.24401-1-jlee@suse.com Signed-off-by: Jens Axboe <axboe@kernel.dk> --- drivers/block/aoe/aoecmd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index cc9077b588d7..d1f4ddc57645 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -361,6 +361,7 @@ ata_rw_frameinit(struct frame *f) } ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; + dev_hold(t->ifp->nd); skb->dev = t->ifp->nd; } @@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d) __skb_queue_head_init(&queue); __skb_queue_tail(&queue, skb); aoenet_xmit(&queue); + } else { + dev_put(f->t->ifp->nd); } return 1; } @@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *f) memcpy(h->dst, t->addr, sizeof h->dst); memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); + dev_hold(t->ifp->nd); skb->dev = t->ifp->nd; skb = skb_clone(skb, GFP_ATOMIC); - if (skb == NULL) + if (skb == NULL) { + dev_put(t->ifp->nd); return; + } f->sent = ktime_get(); __skb_queue_head_init(&queue); __skb_queue_tail(&queue, skb); @@ -617,6 +623,8 @@ probe(struct aoetgt *t) __skb_queue_head_init(&queue); __skb_queue_tail(&queue, skb); aoenet_xmit(&queue); + } else { + dev_put(f->t->ifp->nd); } } @@ -1395,6 +1403,7 @@ aoecmd_ata_id(struct aoedev *d) ah->cmdstat = ATA_CMD_ID_ATA; ah->lba3 = 0xa0; + dev_hold(t->ifp->nd); skb->dev = t->ifp->nd; d->rttavg = RTTAVG_INIT; @@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d) skb = skb_clone(skb, GFP_ATOMIC); if (skb) f->sent = ktime_get(); + else + dev_put(t->ifp->nd); return skb; } -- GitLab From 63e0695597a044c96bf369e4d8ba031291449d95 Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Fri, 27 Sep 2024 16:22:28 -0700 Subject: [PATCH 621/970] drm/xe: Fix memory leak when aborting binds Make sure to call xe_pt_update_ops_fini in xe_pt_update_ops_abort to free any memory the bind allocated. Caught by kmemleak when running Vulkan CTS tests on LNL. The leak seems to happen only when there's some kind of failure happening, like the lack of memory. Example output: unreferenced object 0xffff9120bdf62000 (size 8192): comm "deqp-vk", pid 115008, jiffies 4310295728 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 1b 05 f9 28 01 00 00 40 ...........(...@ 00 00 00 00 00 00 00 00 1b 15 f9 28 01 00 00 40 ...........(...@ backtrace (crc 7a56be79): [<ffffffff86dd81f0>] __kmalloc_cache_noprof+0x310/0x3d0 [<ffffffffc08e8211>] xe_pt_new_shared.constprop.0+0x81/0xb0 [xe] [<ffffffffc08e8309>] xe_pt_insert_entry+0xb9/0x140 [xe] [<ffffffffc08eab6d>] xe_pt_stage_bind_entry+0x12d/0x5b0 [xe] [<ffffffffc08ecbca>] xe_pt_walk_range+0xea/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08e9eff>] xe_pt_stage_bind.constprop.0+0x25f/0x580 [xe] [<ffffffffc08eb21a>] bind_op_prepare+0xea/0x6e0 [xe] [<ffffffffc08ebab8>] xe_pt_update_ops_prepare+0x1c8/0x440 [xe] [<ffffffffc08ffbf3>] ops_execute+0x143/0x850 [xe] [<ffffffffc0900b64>] vm_bind_ioctl_ops_execute+0x244/0x800 [xe] [<ffffffffc0906467>] xe_vm_bind_ioctl+0x1877/0x2370 [xe] [<ffffffffc05e92b3>] drm_ioctl_kernel+0xb3/0x110 [drm] unreferenced object 0xffff9120bdf72000 (size 8192): comm "deqp-vk", pid 115008, jiffies 4310295728 hex dump (first 32 bytes): 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk backtrace (crc 23b2f0b5): [<ffffffff86dd81f0>] __kmalloc_cache_noprof+0x310/0x3d0 [<ffffffffc08e8211>] xe_pt_new_shared.constprop.0+0x81/0xb0 [xe] [<ffffffffc08e8453>] xe_pt_stage_unbind_post_descend+0xb3/0x150 [xe] [<ffffffffc08ecd26>] xe_pt_walk_range+0x246/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08ece31>] xe_pt_walk_shared+0xc1/0x110 [xe] [<ffffffffc08e7b2a>] xe_pt_stage_unbind+0x9a/0xd0 [xe] [<ffffffffc08e913d>] unbind_op_prepare+0xdd/0x270 [xe] [<ffffffffc08eb9f6>] xe_pt_update_ops_prepare+0x106/0x440 [xe] [<ffffffffc08ffbf3>] ops_execute+0x143/0x850 [xe] [<ffffffffc0900b64>] vm_bind_ioctl_ops_execute+0x244/0x800 [xe] [<ffffffffc0906467>] xe_vm_bind_ioctl+0x1877/0x2370 [xe] [<ffffffffc05e92b3>] drm_ioctl_kernel+0xb3/0x110 [drm] [<ffffffffc05e95a0>] drm_ioctl+0x280/0x4e0 [drm] Reported-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2877 Fixes: a708f6501c69 ("drm/xe: Update PT layer with better error handling") Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240927232228.3255246-1-matthew.brost@intel.com --- drivers/gpu/drm/xe/xe_pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c index d6353e8969f0..f27f579f4d85 100644 --- a/drivers/gpu/drm/xe/xe_pt.c +++ b/drivers/gpu/drm/xe/xe_pt.c @@ -2188,5 +2188,5 @@ void xe_pt_update_ops_abort(struct xe_tile *tile, struct xe_vma_ops *vops) pt_op->num_entries); } - xe_bo_put_commit(&vops->pt_update_ops[tile->id].deferred); + xe_pt_update_ops_fini(tile, vops); } -- GitLab From 9af48210ea5f1539e1999154b0acd343efdb370b Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn <lukas.bulwahn@redhat.com> Date: Mon, 30 Sep 2024 11:06:50 +0200 Subject: [PATCH 622/970] xen: Fix config option reference in XEN_PRIVCMD definition Commit 2fae6bb7be32 ("xen/privcmd: Add new syscall to get gsi from dev") adds a weak reverse dependency to the config XEN_PRIVCMD definition, referring to CONFIG_XEN_PCIDEV_BACKEND. In Kconfig files, one refers to config options without the CONFIG prefix, though. So in its current form, this does not create the reverse dependency as intended, but is an attribute with no effect. Refer to the intended config option XEN_PCIDEV_BACKEND in the XEN_PRIVCMD definition. Fixes: 2fae6bb7be32 ("xen/privcmd: Add new syscall to get gsi from dev") Signed-off-by: Lukas Bulwahn <lukas.bulwahn@redhat.com> Reviewed-by: Juergen Gross <jgross@suse.com> Message-ID: <20240930090650.429813-1-lukas.bulwahn@redhat.com> Signed-off-by: Juergen Gross <jgross@suse.com> --- drivers/xen/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 62035fe16bb8..72ddee4c1544 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -261,7 +261,7 @@ config XEN_SCSI_BACKEND config XEN_PRIVCMD tristate "Xen hypercall passthrough driver" depends on XEN - imply CONFIG_XEN_PCIDEV_BACKEND + imply XEN_PCIDEV_BACKEND default m help The hypercall passthrough driver allows privileged user programs to -- GitLab From 462763212dd71c41f092b48eaa352bc1f5ed5d66 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka <mpatocka@redhat.com> Date: Wed, 2 Oct 2024 15:56:18 +0200 Subject: [PATCH 623/970] Revert: "dm-verity: restart or panic on an I/O error" This reverts commit e6a3531dd542cb127c8de32ab1e54a48ae19962b. The problem that the commit e6a3531dd542cb127c8de32ab1e54a48ae19962b fixes was reported as a security bug, but Google engineers working on Android and ChromeOS didn't want to change the default behavior, they want to get -EIO rather than restarting the system, so I am reverting that commit. Note also that calling machine_restart from the I/O handling code is potentially unsafe (the reboot notifiers may wait for the bio that triggered the restart), but Android uses the reboot notifiers to store the reboot reason into the PMU microcontroller, so machine_restart must be used. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Fixes: e6a3531dd542 ("dm-verity: restart or panic on an I/O error") Suggested-by: Sami Tolvanen <samitolvanen@google.com> Suggested-by: Will Drewry <wad@chromium.org> --- drivers/md/dm-verity-target.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 36e4ddfe2d15..24ba9a10444c 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -273,10 +273,8 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type, if (v->mode == DM_VERITY_MODE_LOGGING) return 0; - if (v->mode == DM_VERITY_MODE_RESTART) { - pr_emerg("dm-verity device corrupted\n"); - emergency_restart(); - } + if (v->mode == DM_VERITY_MODE_RESTART) + kernel_restart("dm-verity device corrupted"); if (v->mode == DM_VERITY_MODE_PANIC) panic("dm-verity device corrupted"); @@ -599,23 +597,6 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status) if (!static_branch_unlikely(&use_bh_wq_enabled) || !io->in_bh) verity_fec_finish_io(io); - if (unlikely(status != BLK_STS_OK) && - unlikely(!(bio->bi_opf & REQ_RAHEAD)) && - !verity_is_system_shutting_down()) { - if (v->mode == DM_VERITY_MODE_RESTART || - v->mode == DM_VERITY_MODE_PANIC) - DMERR_LIMIT("%s has error: %s", v->data_dev->name, - blk_status_to_str(status)); - - if (v->mode == DM_VERITY_MODE_RESTART) { - pr_emerg("dm-verity device corrupted\n"); - emergency_restart(); - } - - if (v->mode == DM_VERITY_MODE_PANIC) - panic("dm-verity device corrupted"); - } - bio_endio(bio); } -- GitLab From f811b83879fb6717cdb288e34253cf26d135b019 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka <mpatocka@redhat.com> Date: Wed, 2 Oct 2024 16:03:41 +0200 Subject: [PATCH 624/970] dm-verity: introduce the options restart_on_error and panic_on_error This patch introduces the options restart_on_error and panic_on_error on dm-verity. Previously, restarting on error was handled by the patch e6a3531dd542cb127c8de32ab1e54a48ae19962b, but Google engineers wanted to have a special option for it. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Suggested-by: Sami Tolvanen <samitolvanen@google.com> Suggested-by: Will Drewry <wad@chromium.org> --- drivers/md/dm-verity-target.c | 83 ++++++++++++++++++++++++++++++++++- drivers/md/dm-verity.h | 1 + 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 24ba9a10444c..7d4d90b4395a 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -36,11 +36,13 @@ #define DM_VERITY_OPT_LOGGING "ignore_corruption" #define DM_VERITY_OPT_RESTART "restart_on_corruption" #define DM_VERITY_OPT_PANIC "panic_on_corruption" +#define DM_VERITY_OPT_ERROR_RESTART "restart_on_error" +#define DM_VERITY_OPT_ERROR_PANIC "panic_on_error" #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" #define DM_VERITY_OPT_TASKLET_VERIFY "try_verify_in_tasklet" -#define DM_VERITY_OPTS_MAX (4 + DM_VERITY_OPTS_FEC + \ +#define DM_VERITY_OPTS_MAX (5 + DM_VERITY_OPTS_FEC + \ DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; @@ -583,6 +585,11 @@ static inline bool verity_is_system_shutting_down(void) || system_state == SYSTEM_RESTART; } +static void restart_io_error(struct work_struct *w) +{ + kernel_restart("dm-verity device has I/O error"); +} + /* * End one "io" structure with a given error. */ @@ -597,6 +604,23 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status) if (!static_branch_unlikely(&use_bh_wq_enabled) || !io->in_bh) verity_fec_finish_io(io); + if (unlikely(status != BLK_STS_OK) && + unlikely(!(bio->bi_opf & REQ_RAHEAD)) && + !verity_is_system_shutting_down()) { + if (v->error_mode == DM_VERITY_MODE_PANIC) { + panic("dm-verity device has I/O error"); + } + if (v->error_mode == DM_VERITY_MODE_RESTART) { + static DECLARE_WORK(restart_work, restart_io_error); + queue_work(v->verify_wq, &restart_work); + /* + * We deliberately don't call bio_endio here, because + * the machine will be restarted anyway. + */ + return; + } + } + bio_endio(bio); } @@ -805,6 +829,8 @@ static void verity_status(struct dm_target *ti, status_type_t type, DMEMIT("%02x", v->salt[x]); if (v->mode != DM_VERITY_MODE_EIO) args++; + if (v->error_mode != DM_VERITY_MODE_EIO) + args++; if (verity_fec_is_enabled(v)) args += DM_VERITY_OPTS_FEC; if (v->zero_digest) @@ -834,6 +860,19 @@ static void verity_status(struct dm_target *ti, status_type_t type, BUG(); } } + if (v->error_mode != DM_VERITY_MODE_EIO) { + DMEMIT(" "); + switch (v->error_mode) { + case DM_VERITY_MODE_RESTART: + DMEMIT(DM_VERITY_OPT_ERROR_RESTART); + break; + case DM_VERITY_MODE_PANIC: + DMEMIT(DM_VERITY_OPT_ERROR_PANIC); + break; + default: + BUG(); + } + } if (v->zero_digest) DMEMIT(" " DM_VERITY_OPT_IGN_ZEROES); if (v->validated_blocks) @@ -886,6 +925,19 @@ static void verity_status(struct dm_target *ti, status_type_t type, DMEMIT("invalid"); } } + if (v->error_mode != DM_VERITY_MODE_EIO) { + DMEMIT(",verity_error_mode="); + switch (v->error_mode) { + case DM_VERITY_MODE_RESTART: + DMEMIT(DM_VERITY_OPT_ERROR_RESTART); + break; + case DM_VERITY_MODE_PANIC: + DMEMIT(DM_VERITY_OPT_ERROR_PANIC); + break; + default: + DMEMIT("invalid"); + } + } DMEMIT(";"); break; } @@ -1088,6 +1140,25 @@ static int verity_parse_verity_mode(struct dm_verity *v, const char *arg_name) return 0; } +static inline bool verity_is_verity_error_mode(const char *arg_name) +{ + return (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART) || + !strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC)); +} + +static int verity_parse_verity_error_mode(struct dm_verity *v, const char *arg_name) +{ + if (v->error_mode) + return -EINVAL; + + if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART)) + v->error_mode = DM_VERITY_MODE_RESTART; + else if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC)) + v->error_mode = DM_VERITY_MODE_PANIC; + + return 0; +} + static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, struct dm_verity_sig_opts *verify_args, bool only_modifier_opts) @@ -1122,6 +1193,16 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, } continue; + } else if (verity_is_verity_error_mode(arg_name)) { + if (only_modifier_opts) + continue; + r = verity_parse_verity_error_mode(v, arg_name); + if (r) { + ti->error = "Conflicting error handling parameters"; + return r; + } + continue; + } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) { if (only_modifier_opts) continue; diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h index 754e70bb5fe0..6b75159bf835 100644 --- a/drivers/md/dm-verity.h +++ b/drivers/md/dm-verity.h @@ -64,6 +64,7 @@ struct dm_verity { unsigned int digest_size; /* digest size for the current hash algorithm */ unsigned int hash_reqsize; /* the size of temporary space for crypto */ enum verity_mode mode; /* mode for handling verification errors */ + enum verity_mode error_mode;/* mode for handling I/O errors */ unsigned int corrupted_errs;/* Number of errors for corrupted blocks */ struct workqueue_struct *verify_wq; -- GitLab From 3f1dd33f99677e7025b45a2b8d2baa04985ff4dc Mon Sep 17 00:00:00 2001 From: Vlastimil Babka <vbabka@suse.cz> Date: Tue, 1 Oct 2024 18:20:48 +0200 Subject: [PATCH 625/970] mm, slab: suppress warnings in test_leak_destroy kunit test The test_leak_destroy kunit test intends to test the detection of stray objects in kmem_cache_destroy(), which normally produces a warning. The other slab kunit tests suppress the warnings in the kunit test context, so suppress warnings and related printk output in this test as well. Automated test running environments then don't need to learn to filter the warnings. Also rename the test's kmem_cache, the name was wrongly copy-pasted from test_kfree_rcu. Fixes: 4e1c44b3db79 ("kunit, slub: add test_kfree_rcu() and test_leak_destroy()") Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202408251723.42f3d902-oliver.sang@intel.com Reported-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Closes: https://lore.kernel.org/all/CAB=+i9RHHbfSkmUuLshXGY_ifEZg9vCZi3fqr99+kmmnpDus7Q@mail.gmail.com/ Reported-by: Guenter Roeck <linux@roeck-us.net> Closes: https://lore.kernel.org/all/6fcb1252-7990-4f0d-8027-5e83f0fb9409@roeck-us.net/ Tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> --- lib/slub_kunit.c | 4 ++-- mm/slab.h | 6 ++++++ mm/slab_common.c | 5 +++-- mm/slub.c | 5 +++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c index 6e3a1e5a7142..85d51ec09846 100644 --- a/lib/slub_kunit.c +++ b/lib/slub_kunit.c @@ -177,13 +177,13 @@ static void test_kfree_rcu(struct kunit *test) static void test_leak_destroy(struct kunit *test) { - struct kmem_cache *s = test_kmem_cache_create("TestSlub_kfree_rcu", + struct kmem_cache *s = test_kmem_cache_create("TestSlub_leak_destroy", 64, SLAB_NO_MERGE); kmem_cache_alloc(s, GFP_KERNEL); kmem_cache_destroy(s); - KUNIT_EXPECT_EQ(test, 1, slab_errors); + KUNIT_EXPECT_EQ(test, 2, slab_errors); } static int test_init(struct kunit *test) diff --git a/mm/slab.h b/mm/slab.h index 3e0a08ea4c42..6c6fe6d630ce 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -546,6 +546,12 @@ static inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t fla return false; } +#if IS_ENABLED(CONFIG_SLUB_DEBUG) && IS_ENABLED(CONFIG_KUNIT) +bool slab_in_kunit_test(void); +#else +static inline bool slab_in_kunit_test(void) { return false; } +#endif + #ifdef CONFIG_SLAB_OBJ_EXT /* diff --git a/mm/slab_common.c b/mm/slab_common.c index 744324465615..3d26c257ed8b 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -508,8 +508,9 @@ void kmem_cache_destroy(struct kmem_cache *s) kasan_cache_shutdown(s); err = __kmem_cache_shutdown(s); - WARN(err, "%s %s: Slab cache still has objects when called from %pS", - __func__, s->name, (void *)_RET_IP_); + if (!slab_in_kunit_test()) + WARN(err, "%s %s: Slab cache still has objects when called from %pS", + __func__, s->name, (void *)_RET_IP_); list_del(&s->list); diff --git a/mm/slub.c b/mm/slub.c index 21f71cb6cc06..5b832512044e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -827,7 +827,7 @@ static bool slab_add_kunit_errors(void) return true; } -static bool slab_in_kunit_test(void) +bool slab_in_kunit_test(void) { struct kunit_resource *resource; @@ -843,7 +843,6 @@ static bool slab_in_kunit_test(void) } #else static inline bool slab_add_kunit_errors(void) { return false; } -static inline bool slab_in_kunit_test(void) { return false; } #endif static inline unsigned int size_from_object(struct kmem_cache *s) @@ -5436,6 +5435,8 @@ static void list_slab_objects(struct kmem_cache *s, struct slab *slab, for_each_object(p, s, addr, slab->objects) { if (!test_bit(__obj_to_index(s, addr, p), object_map)) { + if (slab_add_kunit_errors()) + continue; pr_err("Object 0x%p @offset=%tu\n", p, p - addr); print_tracking(s, p); } -- GitLab From cac39b0706f186ce01b9dd1c3802846528d1bbca Mon Sep 17 00:00:00 2001 From: Vlastimil Babka <vbabka@suse.cz> Date: Tue, 1 Oct 2024 18:20:49 +0200 Subject: [PATCH 626/970] slub/kunit: skip test_kfree_rcu when the slub kunit test is built-in Guenter Roeck reports that the new slub kunit tests added by commit 4e1c44b3db79 ("kunit, slub: add test_kfree_rcu() and test_leak_destroy()") cause a lockup on boot on several architectures when the kunit tests are configured to be built-in and not modules. The test_kfree_rcu test invokes kfree_rcu() and boot sequence inspection showed the runner for built-in kunit tests kunit_run_all_tests() is called before setting system_state to SYSTEM_RUNNING and calling rcu_end_inkernel_boot(), so this seems like a likely cause. So while I was unable to reproduce the problem myself, skipping the test when the slub_kunit module is built-in should avoid the issue. An alternative fix that was moving the call to kunit_run_all_tests() a bit later in the boot was tried, but has broken tests with functions marked as __init due to free_initmem() already being done. Fixes: 4e1c44b3db79 ("kunit, slub: add test_kfree_rcu() and test_leak_destroy()") Reported-by: Guenter Roeck <linux@roeck-us.net> Closes: https://lore.kernel.org/all/6fcb1252-7990-4f0d-8027-5e83f0fb9409@roeck-us.net/ Cc: Paul E. McKenney <paulmck@kernel.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Uladzislau Rezki <urezki@gmail.com> Cc: rcu@vger.kernel.org Cc: Brendan Higgins <brendanhiggins@google.com> Cc: David Gow <davidgow@google.com> Cc: Rae Moar <rmoar@google.com> Cc: linux-kselftest@vger.kernel.org Cc: kunit-dev@googlegroups.com Tested-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> --- lib/slub_kunit.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c index 85d51ec09846..80e39f003344 100644 --- a/lib/slub_kunit.c +++ b/lib/slub_kunit.c @@ -164,10 +164,16 @@ struct test_kfree_rcu_struct { static void test_kfree_rcu(struct kunit *test) { - struct kmem_cache *s = test_kmem_cache_create("TestSlub_kfree_rcu", - sizeof(struct test_kfree_rcu_struct), - SLAB_NO_MERGE); - struct test_kfree_rcu_struct *p = kmem_cache_alloc(s, GFP_KERNEL); + struct kmem_cache *s; + struct test_kfree_rcu_struct *p; + + if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST)) + kunit_skip(test, "can't do kfree_rcu() when test is built-in"); + + s = test_kmem_cache_create("TestSlub_kfree_rcu", + sizeof(struct test_kfree_rcu_struct), + SLAB_NO_MERGE); + p = kmem_cache_alloc(s, GFP_KERNEL); kfree_rcu(p, rcu); kmem_cache_destroy(s); -- GitLab From 1ca4169c391c370e0f3a92938df2862900575096 Mon Sep 17 00:00:00 2001 From: David Howells <dhowells@redhat.com> Date: Wed, 2 Oct 2024 15:45:50 +0100 Subject: [PATCH 627/970] netfs: Fix missing wakeup after issuing writes After dividing up a proposed write into subrequests, netfslib sets NETFS_RREQ_ALL_QUEUED to indicate to the collector that it can move on to the final cleanup once it has emptied the subrequest queues. Now, whilst the collector will normally end up running at least once after this bit is set just because it takes a while to process all the write subrequests before the collector runs out of subrequests, there exists the possibility that the issuing thread will be forced to sleep and the collector thread will clean up all the subrequests before ALL_QUEUED gets set. In such a case, the collector thread will not get triggered again and will never clear NETFS_RREQ_IN_PROGRESS thus leaving a request uncompleted and causing a potential futute hang. Fix this by scheduling the write collector if all the subrequest queues are empty (and thus no writes pending issuance). Note that we'd do this ideally before queuing the subrequest, but in the case of buffered writeback, at least, we can't find out that we've run out of folios until after we've called writeback_iter() and it has returned NULL - at which point we might not actually have any subrequests still under construction. Fixes: 288ace2f57c9 ("netfs: New writeback implementation") Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/3317784.1727880350@warthog.procyon.org.uk cc: Jeff Layton <jlayton@kernel.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/netfs/write_issue.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c index 6293f547e4c3..bf6d507578e5 100644 --- a/fs/netfs/write_issue.c +++ b/fs/netfs/write_issue.c @@ -508,6 +508,30 @@ static int netfs_write_folio(struct netfs_io_request *wreq, return 0; } +/* + * End the issuing of writes, letting the collector know we're done. + */ +static void netfs_end_issue_write(struct netfs_io_request *wreq) +{ + bool needs_poke = true; + + smp_wmb(); /* Write subreq lists before ALL_QUEUED. */ + set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags); + + for (int s = 0; s < NR_IO_STREAMS; s++) { + struct netfs_io_stream *stream = &wreq->io_streams[s]; + + if (!stream->active) + continue; + if (!list_empty(&stream->subrequests)) + needs_poke = false; + netfs_issue_write(wreq, stream); + } + + if (needs_poke) + netfs_wake_write_collector(wreq, false); +} + /* * Write some of the pending data back to the server */ @@ -559,10 +583,7 @@ int netfs_writepages(struct address_space *mapping, break; } while ((folio = writeback_iter(mapping, wbc, folio, &error))); - for (int s = 0; s < NR_IO_STREAMS; s++) - netfs_issue_write(wreq, &wreq->io_streams[s]); - smp_wmb(); /* Write lists before ALL_QUEUED. */ - set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags); + netfs_end_issue_write(wreq); mutex_unlock(&ictx->wb_lock); @@ -650,10 +671,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_contr if (writethrough_cache) netfs_write_folio(wreq, wbc, writethrough_cache); - netfs_issue_write(wreq, &wreq->io_streams[0]); - netfs_issue_write(wreq, &wreq->io_streams[1]); - smp_wmb(); /* Write lists before ALL_QUEUED. */ - set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags); + netfs_end_issue_write(wreq); mutex_unlock(&ictx->wb_lock); @@ -699,13 +717,7 @@ int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t break; } - netfs_issue_write(wreq, upload); - - smp_wmb(); /* Write lists before ALL_QUEUED. */ - set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags); - if (list_empty(&upload->subrequests)) - netfs_wake_write_collector(wreq, false); - + netfs_end_issue_write(wreq); _leave(" = %d", error); return error; } -- GitLab From 3f7f36a4559ef78a6418c5f0447fbfbdcf671956 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Wed, 2 Oct 2024 17:59:39 +0200 Subject: [PATCH 628/970] Revert "ALSA: hda: Conditionally use snooping for AMD HDMI" This reverts commit 478689b5990deb626a0b3f1ebf165979914d6be4. The fix seems leading to regressions for other systems. Also, the way to check the presence of IOMMU via get_dma_ops() isn't reliable and it's no longer applicable for 6.12. After all, it's no right fix, so let's revert it at first. To be noted, the PCM buffer allocation has been changed to try the continuous pages at first since 6.12, so the problem could be already addressed without this hackish workaround. Reported-by: Salvatore Bonaccorso <carnil@debian.org> Closes: https://lore.kernel.org/ZvgCdYfKgwHpJXGE@eldamar.lan Link: https://patch.msgid.link/20241002155948.4859-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/hda_controller.h | 2 +- sound/pci/hda/hda_intel.c | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 68c883f202ca..c2d0109866e6 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -28,7 +28,7 @@ #else #define AZX_DCAPS_I915_COMPONENT 0 /* NOP */ #endif -#define AZX_DCAPS_AMD_ALLOC_FIX (1 << 14) /* AMD allocation workaround */ +/* 14 unused */ #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ #define AZX_DCAPS_AMD_WORKAROUND (1 << 17) /* AMD-specific workaround */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index edeaf3ee273c..bf9c9bfd38e3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -40,7 +40,6 @@ #ifdef CONFIG_X86 /* for snoop control */ -#include <linux/dma-map-ops.h> #include <asm/set_memory.h> #include <asm/cpufeature.h> #endif @@ -307,7 +306,7 @@ enum { /* quirks for ATI HDMI with snoop off */ #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ - (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_AMD_ALLOC_FIX) + (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) /* quirks for AMD SB */ #define AZX_DCAPS_PRESET_AMD_SB \ @@ -1707,13 +1706,6 @@ static void azx_check_snoop_available(struct azx *chip) if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF) snoop = false; -#ifdef CONFIG_X86 - /* check the presence of DMA ops (i.e. IOMMU), disable snoop conditionally */ - if ((chip->driver_caps & AZX_DCAPS_AMD_ALLOC_FIX) && - !get_dma_ops(chip->card->dev)) - snoop = false; -#endif - chip->snoop = snoop; if (!snoop) { dev_info(chip->card->dev, "Force to non-snoop mode\n"); -- GitLab From 86309cbed26139e1caae7629dcca1027d9a28e75 Mon Sep 17 00:00:00 2001 From: Armin Wolf <W_Armin@gmx.de> Date: Tue, 1 Oct 2024 23:28:33 +0200 Subject: [PATCH 629/970] ACPI: battery: Simplify battery hook locking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the conditional locking from __battery_hook_unregister() into battery_hook_unregister() and rename the low-level function to simplify the locking during battery hook removal. Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Reviewed-by: Pali Rohár <pali@kernel.org> Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://patch.msgid.link/20241001212835.341788-2-W_Armin@gmx.de Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/battery.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index f4599261cfc3..dda59ee5a11e 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -703,28 +703,28 @@ static LIST_HEAD(acpi_battery_list); static LIST_HEAD(battery_hook_list); static DEFINE_MUTEX(hook_mutex); -static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) +static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) { struct acpi_battery *battery; + /* * In order to remove a hook, we first need to * de-register all the batteries that are registered. */ - if (lock) - mutex_lock(&hook_mutex); list_for_each_entry(battery, &acpi_battery_list, list) { if (!hook->remove_battery(battery->bat, hook)) power_supply_changed(battery->bat); } list_del(&hook->list); - if (lock) - mutex_unlock(&hook_mutex); + pr_info("extension unregistered: %s\n", hook->name); } void battery_hook_unregister(struct acpi_battery_hook *hook) { - __battery_hook_unregister(hook, 1); + mutex_lock(&hook_mutex); + battery_hook_unregister_unlocked(hook); + mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_unregister); @@ -750,7 +750,7 @@ void battery_hook_register(struct acpi_battery_hook *hook) * hooks. */ pr_err("extension failed to load: %s", hook->name); - __battery_hook_unregister(hook, 0); + battery_hook_unregister_unlocked(hook); goto end; } @@ -804,7 +804,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery) */ pr_err("error in extension, unloading: %s", hook_node->name); - __battery_hook_unregister(hook_node, 0); + battery_hook_unregister_unlocked(hook_node); } } mutex_unlock(&hook_mutex); @@ -837,7 +837,7 @@ static void __exit battery_hook_exit(void) * need to remove the hooks. */ list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { - __battery_hook_unregister(hook, 1); + battery_hook_unregister(hook); } mutex_destroy(&hook_mutex); } -- GitLab From 76959aff14a0012ad6b984ec7686d163deccdc16 Mon Sep 17 00:00:00 2001 From: Armin Wolf <W_Armin@gmx.de> Date: Tue, 1 Oct 2024 23:28:34 +0200 Subject: [PATCH 630/970] ACPI: battery: Fix possible crash when unregistering a battery hook When a battery hook returns an error when adding a new battery, then the battery hook is automatically unregistered. However the battery hook provider cannot know that, so it will later call battery_hook_unregister() on the already unregistered battery hook, resulting in a crash. Fix this by using the list head to mark already unregistered battery hooks as already being unregistered so that they can be ignored by battery_hook_unregister(). Fixes: fa93854f7a7e ("battery: Add the battery hooking API") Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://patch.msgid.link/20241001212835.341788-3-W_Armin@gmx.de Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/battery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dda59ee5a11e..1c45ff6dbb83 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -715,7 +715,7 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) if (!hook->remove_battery(battery->bat, hook)) power_supply_changed(battery->bat); } - list_del(&hook->list); + list_del_init(&hook->list); pr_info("extension unregistered: %s\n", hook->name); } @@ -723,7 +723,14 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) void battery_hook_unregister(struct acpi_battery_hook *hook) { mutex_lock(&hook_mutex); - battery_hook_unregister_unlocked(hook); + /* + * Ignore already unregistered battery hooks. This might happen + * if a battery hook was previously unloaded due to an error when + * adding a new battery. + */ + if (!list_empty(&hook->list)) + battery_hook_unregister_unlocked(hook); + mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_unregister); @@ -733,7 +740,6 @@ void battery_hook_register(struct acpi_battery_hook *hook) struct acpi_battery *battery; mutex_lock(&hook_mutex); - INIT_LIST_HEAD(&hook->list); list_add(&hook->list, &battery_hook_list); /* * Now that the driver is registered, we need -- GitLab From 33027006ecf3f4204de54c446b1fe9b770e99f44 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela <perex@perex.cz> Date: Wed, 2 Oct 2024 17:15:36 +0200 Subject: [PATCH 631/970] MAINTAINERS: ALSA: use linux-sound@vger.kernel.org list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are now using the linux-sound@vger.kernel.org list for kernel related work. This patch converts all remaining entries that reference the former alsa-devel mailing list. All ALSA developers should subscribe to the linux-sound mailing list. Thank you. Cc: linux-kernel@vger.kernel.org Cc: Ban Tao <fengzheng923@gmail.com> Cc: Lars-Peter Clausen <lars@metafoo.de> Cc: Nuno Sá <nuno.sa@analog.com> Cc: Johannes Berg <johannes@sipsolutions.net> Cc: Jerome Brunet <jbrunet@baylibre.com> Cc: Martin PoviÅ¡er <povik+lin@cutebit.org> Cc: Peter Rosin <peda@axentia.se> Cc: Clemens Ladisch <clemens@ladisch.de> Cc: Takashi Sakamoto <o-takashi@sakamocchi.jp> Cc: Geoffrey D. Bennett <g@b4.vu> Cc: Shengjiu Wang <shengjiu.wang@gmail.com> Cc: Xiubo Li <Xiubo.Lee@gmail.com> Cc: Fabio Estevam <festevam@gmail.com> Cc: Nicolin Chen <nicoleotsuka@gmail.com> Cc: J.M.B. Downing <jonathan.downing@nautel.com> Cc: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com> Cc: Vladimir Zapolskiy <vz@mleia.com> Cc: Herve Codina <herve.codina@bootlin.com> Cc: Cezary Rojewski <cezary.rojewski@intel.com> Cc: Liam Girdwood <liam.r.girdwood@linux.intel.com> Cc: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Cc: Bard Liao <yung-chuan.liao@linux.intel.com> Cc: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Cc: Kai Vehmanen <kai.vehmanen@linux.intel.com> Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> Cc: Kiseok Jo <kiseok.jo@irondevice.com> Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev> Cc: Daniel Mack <zonque@gmail.com> Cc: Stephan Gerhold <stephan@gerhold.net> Cc: Peter Ujfalusi <peter.ujfalusi@gmail.com> Cc: Jarkko Nikula <jarkko.nikula@bitmer.com> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Cc: Sylwester Nawrocki <s.nawrocki@samsung.com> Cc: Vinod Koul <vkoul@kernel.org> Cc: Sanyog Kale <sanyog.r.kale@intel.com> Cc: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> Cc: Olivier Moysan <olivier.moysan@foss.st.com> Cc: Shenghao Ding <shenghao-ding@ti.com> Cc: Kevin Lu <kevin-lu@ti.com> Cc: Baojun Xu <baojun.xu@ti.com> Cc: M R Swami Reddy <mr.swami.reddy@ti.com> Cc: Vishwas A Deshpande <vishwas.a.deshpande@ti.com> Cc: Kirill Marinushkin <kmarinushkin@birdec.com> Cc: Kevin Cernekee <cernekee@chromium.org> Cc: Anton Yakovlev <anton.yakovlev@opensynergy.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz> Link: https://patch.msgid.link/20241002151536.1855793-1-perex@perex.cz Signed-off-by: Takashi Iwai <tiwai@suse.de> --- MAINTAINERS | 86 ++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index c27f3190737f..a0a9a9f020ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -860,7 +860,7 @@ F: drivers/crypto/allwinner/ ALLWINNER DMIC DRIVERS M: Ban Tao <fengzheng923@gmail.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml F: sound/soc/sunxi/sun50i-dmic.c @@ -1517,7 +1517,7 @@ F: drivers/iio/gyro/adxrs290.c ANALOG DEVICES INC ASOC CODEC DRIVERS M: Lars-Peter Clausen <lars@metafoo.de> M: Nuno Sá <nuno.sa@analog.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Supported W: http://wiki.analog.com/ W: https://ez.analog.com/linux-software-drivers @@ -1594,7 +1594,7 @@ F: drivers/rtc/rtc-goldfish.c AOA (Apple Onboard Audio) ALSA DRIVER M: Johannes Berg <johannes@sipsolutions.net> L: linuxppc-dev@lists.ozlabs.org -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: sound/aoa/ @@ -2091,7 +2091,7 @@ F: drivers/crypto/amlogic/ ARM/Amlogic Meson SoC Sound Drivers M: Jerome Brunet <jbrunet@baylibre.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/amlogic* F: sound/soc/meson/ @@ -2129,7 +2129,7 @@ F: drivers/*/*alpine* ARM/APPLE MACHINE SOUND DRIVERS M: Martin PoviÅ¡er <povik+lin@cutebit.org> L: asahi@lists.linux.dev -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/adi,ssm3515.yaml F: Documentation/devicetree/bindings/sound/apple,* @@ -3732,7 +3732,7 @@ F: arch/arm/boot/dts/microchip/at91-tse850-3.dts AXENTIA ASOC DRIVERS M: Peter Rosin <peda@axentia.se> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/axentia,* F: sound/soc/atmel/tse850-pcm5142.c @@ -4851,7 +4851,7 @@ F: include/uapi/linux/bsg.h BT87X AUDIO DRIVER M: Clemens Ladisch <clemens@ladisch.de> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: Documentation/sound/cards/bt87x.rst @@ -4913,7 +4913,7 @@ F: drivers/net/can/bxcan.c C-MEDIA CMI8788 DRIVER M: Clemens Ladisch <clemens@ladisch.de> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/pci/oxygen/ @@ -8252,7 +8252,7 @@ F: drivers/edac/ti_edac.c EDIROL UA-101/UA-1000 DRIVER M: Clemens Ladisch <clemens@ladisch.de> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/usb/misc/ua101.c @@ -8814,7 +8814,7 @@ F: drivers/net/can/usb/f81604.c FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE M: Clemens Ladisch <clemens@ladisch.de> M: Takashi Sakamoto <o-takashi@sakamocchi.jp> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: include/uapi/sound/firewire.h @@ -8888,7 +8888,7 @@ F: drivers/input/joystick/fsia6b.c FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett) M: Geoffrey D. Bennett <g@b4.vu> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained W: https://github.com/geoffreybennett/scarlett-gen2 B: https://github.com/geoffreybennett/scarlett-gen2/issues @@ -9209,7 +9209,7 @@ M: Shengjiu Wang <shengjiu.wang@gmail.com> M: Xiubo Li <Xiubo.Lee@gmail.com> R: Fabio Estevam <festevam@gmail.com> R: Nicolin Chen <nicoleotsuka@gmail.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org L: linuxppc-dev@lists.ozlabs.org S: Maintained F: sound/soc/fsl/fsl* @@ -9219,7 +9219,7 @@ FREESCALE SOC LPC32XX SOUND DRIVERS M: J.M.B. Downing <jonathan.downing@nautel.com> M: Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com> R: Vladimir Zapolskiy <vz@mleia.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org L: linuxppc-dev@lists.ozlabs.org S: Maintained F: Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml @@ -9227,7 +9227,7 @@ F: sound/soc/fsl/lpc3xxx-* FREESCALE SOC SOUND QMC DRIVER M: Herve Codina <herve.codina@bootlin.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org L: linuxppc-dev@lists.ozlabs.org S: Maintained F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml @@ -11154,7 +11154,7 @@ F: drivers/iio/pressure/dps310.c INFINEON PEB2466 ASoC CODEC M: Herve Codina <herve.codina@bootlin.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/infineon,peb2466.yaml F: sound/soc/codecs/peb2466.c @@ -11317,7 +11317,7 @@ M: Bard Liao <yung-chuan.liao@linux.intel.com> M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> M: Kai Vehmanen <kai.vehmanen@linux.intel.com> R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Supported F: sound/soc/intel/ @@ -12001,7 +12001,7 @@ F: drivers/tty/ipwireless/ IRON DEVICE AUDIO CODEC DRIVERS M: Kiseok Jo <kiseok.jo@irondevice.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/irondevice,* F: sound/soc/codecs/sma* @@ -13952,7 +13952,7 @@ F: drivers/media/i2c/max96717.c MAX9860 MONO AUDIO VOICE CODEC DRIVER M: Peter Rosin <peda@axentia.se> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/max9860.txt F: sound/soc/codecs/max9860.* @@ -15085,7 +15085,7 @@ F: drivers/spi/spi-at91-usart.c MICROCHIP AUDIO ASOC DRIVERS M: Claudiu Beznea <claudiu.beznea@tuxon.dev> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/sound/atmel* F: Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt @@ -15957,7 +15957,7 @@ F: include/linux/mtd/*nand*.h NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER M: Daniel Mack <zonque@gmail.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained W: http://www.native-instruments.com F: sound/usb/caiaq/ @@ -16728,7 +16728,7 @@ F: drivers/extcon/extcon-ptn5150.c NXP SGTL5000 DRIVER M: Fabio Estevam <festevam@gmail.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/fsl,sgtl5000.yaml F: sound/soc/codecs/sgtl5000* @@ -16752,7 +16752,7 @@ K: "nxp,tda998x" NXP TFA9879 DRIVER M: Peter Rosin <peda@axentia.se> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml F: sound/soc/codecs/tfa9879* @@ -16764,7 +16764,7 @@ F: drivers/nfc/nxp-nci NXP/Goodix TFA989X (TFA1) DRIVER M: Stephan Gerhold <stephan@gerhold.net> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml F: sound/soc/codecs/tfa989x.c @@ -16850,7 +16850,7 @@ F: include/uapi/misc/ocxl.h OMAP AUDIO SUPPORT M: Peter Ujfalusi <peter.ujfalusi@gmail.com> M: Jarkko Nikula <jarkko.nikula@bitmer.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org L: linux-omap@vger.kernel.org S: Maintained F: sound/soc/ti/n810.c @@ -17407,7 +17407,7 @@ F: include/linux/pm_opp.h OPL4 DRIVER M: Clemens Ladisch <clemens@ladisch.de> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/drivers/opl4/ @@ -18790,7 +18790,7 @@ F: drivers/crypto/intel/qat/ QCOM AUDIO (ASoC) DRIVERS M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org L: linux-arm-msm@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/soc/qcom/qcom,apr* @@ -19652,7 +19652,7 @@ F: drivers/net/ethernet/renesas/rtsn.* RENESAS IDT821034 ASoC CODEC M: Herve Codina <herve.codina@bootlin.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/renesas,idt821034.yaml F: sound/soc/codecs/idt821034.c @@ -20403,7 +20403,7 @@ F: security/safesetid/ SAMSUNG AUDIO (ASoC) DRIVERS M: Sylwester Nawrocki <s.nawrocki@samsung.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained B: mailto:linux-samsung-soc@vger.kernel.org F: Documentation/devicetree/bindings/sound/samsung* @@ -20939,7 +20939,7 @@ F: drivers/media/rc/serial_ir.c SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/slimbus/ F: drivers/slimbus/ @@ -21373,7 +21373,7 @@ F: Documentation/devicetree/bindings/i2c/socionext,synquacer-i2c.yaml F: drivers/i2c/busses/i2c-synquacer.c SOCIONEXT UNIPHIER SOUND DRIVER -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Orphan F: sound/soc/uniphier/ @@ -21632,7 +21632,7 @@ F: tools/testing/selftests/alsa SOUND - COMPRESSED AUDIO M: Vinod Koul <vkoul@kernel.org> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: Documentation/sound/designs/compress-offload.rst @@ -21695,7 +21695,7 @@ M: Vinod Koul <vkoul@kernel.org> M: Bard Liao <yung-chuan.liao@linux.intel.com> R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> R: Sanyog Kale <sanyog.r.kale@intel.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git F: Documentation/driver-api/soundwire/ @@ -22168,7 +22168,7 @@ F: kernel/static_call.c STI AUDIO (ASoC) DRIVERS M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt F: sound/soc/sti/ @@ -22189,7 +22189,7 @@ F: drivers/media/usb/stk1160/ STM32 AUDIO (ASoC) DRIVERS M: Olivier Moysan <olivier.moysan@foss.st.com> M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml F: Documentation/devicetree/bindings/sound/st,stm32-*.yaml @@ -22892,7 +22892,7 @@ F: drivers/irqchip/irq-xtensa-* TEXAS INSTRUMENTS ASoC DRIVERS M: Peter Ujfalusi <peter.ujfalusi@gmail.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml F: sound/soc/ti/ @@ -22901,7 +22901,7 @@ TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS M: Shenghao Ding <shenghao-ding@ti.com> M: Kevin Lu <kevin-lu@ti.com> M: Baojun Xu <baojun.xu@ti.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/tas2552.txt F: Documentation/devicetree/bindings/sound/ti,tas2562.yaml @@ -23269,7 +23269,7 @@ F: drivers/soc/ti/* TI LM49xxx FAMILY ASoC CODEC DRIVERS M: M R Swami Reddy <mr.swami.reddy@ti.com> M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: sound/soc/codecs/isabelle* F: sound/soc/codecs/lm49453* @@ -23284,14 +23284,14 @@ F: drivers/iio/adc/ti-lmp92064.c TI PCM3060 ASoC CODEC DRIVER M: Kirill Marinushkin <kmarinushkin@birdec.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/pcm3060.txt F: sound/soc/codecs/pcm3060* TI TAS571X FAMILY ASoC CODEC DRIVER M: Kevin Cernekee <cernekee@chromium.org> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Odd Fixes F: sound/soc/codecs/tas571x* @@ -23319,7 +23319,7 @@ F: drivers/iio/adc/ti-tsc2046.c TI TWL4030 SERIES SOC CODEC DRIVER M: Peter Ujfalusi <peter.ujfalusi@gmail.com> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: sound/soc/codecs/twl4030* @@ -23995,7 +23995,7 @@ F: drivers/usb/storage/ USB MIDI DRIVER M: Clemens Ladisch <clemens@ladisch.de> -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/usb/midi.* @@ -24655,7 +24655,7 @@ VIRTIO SOUND DRIVER M: Anton Yakovlev <anton.yakovlev@opensynergy.com> M: "Michael S. Tsirkin" <mst@redhat.com> L: virtualization@lists.linux.dev -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Maintained F: include/uapi/linux/virtio_snd.h F: sound/virtio/* @@ -25384,7 +25384,7 @@ F: include/xen/interface/io/usbif.h XEN SOUND FRONTEND DRIVER M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> L: xen-devel@lists.xenproject.org (moderated for non-subscribers) -L: alsa-devel@alsa-project.org (moderated for non-subscribers) +L: linux-sound@vger.kernel.org S: Supported F: sound/xen/* -- GitLab From a19008256d05e726f29f43c6a307e45482c082c3 Mon Sep 17 00:00:00 2001 From: Alessandro Zanni <alessandro.zanni87@gmail.com> Date: Tue, 6 Aug 2024 14:14:50 +0200 Subject: [PATCH 632/970] kselftest/devices/probe: Fix SyntaxWarning in regex strings for Python3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Insert raw strings to prevent Python3 from interpreting string literals as Unicode strings and "\d" as invalid escaped sequence. Fix the warnings: tools/testing/selftests/devices/probe/test_discoverable_devices.py:48: SyntaxWarning: invalid escape sequence '\d' usb_controller_sysfs_dir = "usb[\d]+" tools/testing/selftests/devices/probe/test_discoverable_devices.py: 94: SyntaxWarning: invalid escape sequence '\d' re_usb_version = re.compile("PRODUCT=.*/(\d)/.*") Fixes: dacf1d7a78bf ("kselftest: Add test to verify probe of devices from discoverable buses") Reviewed-by: NÃcolas F. R. A. Prado <nfraprado@collabora.com> Signed-off-by: Alessandro Zanni <alessandro.zanni87@gmail.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- .../selftests/devices/probe/test_discoverable_devices.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/devices/probe/test_discoverable_devices.py b/tools/testing/selftests/devices/probe/test_discoverable_devices.py index d94a74b8a054..d7a2bb91c807 100755 --- a/tools/testing/selftests/devices/probe/test_discoverable_devices.py +++ b/tools/testing/selftests/devices/probe/test_discoverable_devices.py @@ -45,7 +45,7 @@ def find_pci_controller_dirs(): def find_usb_controller_dirs(): - usb_controller_sysfs_dir = "usb[\d]+" + usb_controller_sysfs_dir = r"usb[\d]+" dir_regex = re.compile(usb_controller_sysfs_dir) for d in os.scandir(sysfs_usb_devices): @@ -91,7 +91,7 @@ def get_acpi_uid(sysfs_dev_dir): def get_usb_version(sysfs_dev_dir): - re_usb_version = re.compile("PRODUCT=.*/(\d)/.*") + re_usb_version = re.compile(r"PRODUCT=.*/(\d)/.*") with open(os.path.join(sysfs_dev_dir, "uevent")) as f: return int(re_usb_version.search(f.read()).group(1)) -- GitLab From c66be905cda24fb782b91053b196bd2e966f95b7 Mon Sep 17 00:00:00 2001 From: Yifei Liu <yifei.l.liu@oracle.com> Date: Mon, 30 Sep 2024 15:40:25 -0700 Subject: [PATCH 633/970] selftests: breakpoints: use remaining time to check if suspend succeed step_after_suspend_test fails with device busy error while writing to /sys/power/state to start suspend. The test believes it failed to enter suspend state with $ sudo ./step_after_suspend_test TAP version 13 Bail out! Failed to enter Suspend state However, in the kernel message, I indeed see the system get suspended and then wake up later. [611172.033108] PM: suspend entry (s2idle) [611172.044940] Filesystems sync: 0.006 seconds [611172.052254] Freezing user space processes [611172.059319] Freezing user space processes completed (elapsed 0.001 seconds) [611172.067920] OOM killer disabled. [611172.072465] Freezing remaining freezable tasks [611172.080332] Freezing remaining freezable tasks completed (elapsed 0.001 seconds) [611172.089724] printk: Suspending console(s) (use no_console_suspend to debug) [611172.117126] serial 00:03: disabled some other hardware get reconnected [611203.136277] OOM killer enabled. [611203.140637] Restarting tasks ... [611203.141135] usb 1-8.1: USB disconnect, device number 7 [611203.141755] done. [611203.155268] random: crng reseeded on system resumption [611203.162059] PM: suspend exit After investigation, I noticed that for the code block if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem")) ksft_exit_fail_msg("Failed to enter Suspend state\n"); The write will return -1 and errno is set to 16 (device busy). It should be caused by the write function is not successfully returned before the system suspend and the return value get messed when waking up. As a result, It may be better to check the time passed of those few instructions to determine whether the suspend is executed correctly for it is pretty hard to execute those few lines for 5 seconds. The timer to wake up the system is set to expire after 5 seconds and no re-arm. If the timer remaining time is 0 second and 0 nano secomd, it means the timer expired and wake the system up. Otherwise, the system could be considered to enter the suspend state failed if there is any remaining time. After appling this patch, the test would not fail for it believes the system does not go to suspend by mistake. It now could continue to the rest part of the test after suspend. Fixes: bfd092b8c272 ("selftests: breakpoint: add step_after_suspend_test") Reported-by: Sinadin Shan <sinadin.shan@oracle.com> Signed-off-by: Yifei Liu <yifei.l.liu@oracle.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> --- .../testing/selftests/breakpoints/step_after_suspend_test.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c index dfec31fb9b30..8d275f03e977 100644 --- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c +++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c @@ -152,7 +152,10 @@ void suspend(void) if (err < 0) ksft_exit_fail_msg("timerfd_settime() failed\n"); - if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem")) + system("(echo mem > /sys/power/state) 2> /dev/null"); + + timerfd_gettime(timerfd, &spec); + if (spec.it_value.tv_sec != 0 || spec.it_value.tv_nsec != 0) ksft_exit_fail_msg("Failed to enter Suspend state\n"); close(timerfd); -- GitLab From 00429083f404efe230fee577aa3dfbf2dea9b1f1 Mon Sep 17 00:00:00 2001 From: Al Viro <viro@zeniv.linux.org.uk> Date: Tue, 5 Dec 2023 21:53:22 -0500 Subject: [PATCH 634/970] arc: get rid of private asm/unaligned.h Declarations local to arch/*/kernel/*.c are better off *not* in a public header - arch/arc/kernel/unaligned.h is just fine for those bits. Unlike the parisc case, here we have an extra twist - asm/mmu.h has an implicit dependency on struct pt_regs, and in some users that used to be satisfied by include of asm/ptrace.h from asm/unaligned.h (note that asm/mmu.h itself did _not_ pull asm/unaligned.h - it relied upon the users having pulled asm/unaligned.h before asm/mmu.h got there). Seeing that asm/mmu.h only wants struct pt_regs * arguments in an extern, just pre-declare it there - less brittle that way. With that done _all_ asm/unaligned.h instances are reduced to include of asm-generic/unaligned.h and can be removed - unaligned.h is in mandatory-y in include/asm-generic/Kbuild. What's more, we can move asm-generic/unaligned.h to linux/unaligned.h and switch includes of <asm/unaligned.h> to <linux/unaligned.h>; that's better off as an auto-generated commit, though, to be done by Linus at -rc1 time next cycle. Acked-by: Vineet Gupta <vgupta@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- arch/arc/include/asm/mmu.h | 1 + arch/arc/include/asm/unaligned.h | 27 --------------------------- arch/arc/kernel/traps.c | 1 + arch/arc/kernel/unaligned.c | 1 + arch/arc/kernel/unaligned.h | 16 ++++++++++++++++ 5 files changed, 19 insertions(+), 27 deletions(-) delete mode 100644 arch/arc/include/asm/unaligned.h create mode 100644 arch/arc/kernel/unaligned.h diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h index 9febf5bc3de6..4ae2db59d494 100644 --- a/arch/arc/include/asm/mmu.h +++ b/arch/arc/include/asm/mmu.h @@ -14,6 +14,7 @@ typedef struct { unsigned long asid[NR_CPUS]; /* 8 bit MMU PID + Generation cycle */ } mm_context_t; +struct pt_regs; extern void do_tlb_overlap_fault(unsigned long, unsigned long, struct pt_regs *); #endif diff --git a/arch/arc/include/asm/unaligned.h b/arch/arc/include/asm/unaligned.h deleted file mode 100644 index cf5a02382e0e..000000000000 --- a/arch/arc/include/asm/unaligned.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - */ - -#ifndef _ASM_ARC_UNALIGNED_H -#define _ASM_ARC_UNALIGNED_H - -/* ARC700 can't handle unaligned Data accesses. */ - -#include <asm-generic/unaligned.h> -#include <asm/ptrace.h> - -#ifdef CONFIG_ARC_EMUL_UNALIGNED -int misaligned_fixup(unsigned long address, struct pt_regs *regs, - struct callee_regs *cregs); -#else -static inline int -misaligned_fixup(unsigned long address, struct pt_regs *regs, - struct callee_regs *cregs) -{ - /* Not fixed */ - return 1; -} -#endif - -#endif /* _ASM_ARC_UNALIGNED_H */ diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index a19751e824fb..41af02081549 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -20,6 +20,7 @@ #include <asm/setup.h> #include <asm/unaligned.h> #include <asm/kprobes.h> +#include "unaligned.h" void die(const char *str, struct pt_regs *regs, unsigned long address) { diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c index 99a9b92ed98d..d2f5ceaaed1b 100644 --- a/arch/arc/kernel/unaligned.c +++ b/arch/arc/kernel/unaligned.c @@ -12,6 +12,7 @@ #include <linux/ptrace.h> #include <linux/uaccess.h> #include <asm/disasm.h> +#include "unaligned.h" #ifdef CONFIG_CPU_BIG_ENDIAN #define BE 1 diff --git a/arch/arc/kernel/unaligned.h b/arch/arc/kernel/unaligned.h new file mode 100644 index 000000000000..5244453bb85f --- /dev/null +++ b/arch/arc/kernel/unaligned.h @@ -0,0 +1,16 @@ +struct pt_regs; +struct callee_regs; + +#ifdef CONFIG_ARC_EMUL_UNALIGNED +int misaligned_fixup(unsigned long address, struct pt_regs *regs, + struct callee_regs *cregs); +#else +static inline int +misaligned_fixup(unsigned long address, struct pt_regs *regs, + struct callee_regs *cregs) +{ + /* Not fixed */ + return 1; +} +#endif + -- GitLab From 5f60d5f6bbc12e782fac78110b0ee62698f3b576 Mon Sep 17 00:00:00 2001 From: Al Viro <viro@zeniv.linux.org.uk> Date: Tue, 1 Oct 2024 15:35:57 -0400 Subject: [PATCH 635/970] move asm/unaligned.h to linux/unaligned.h asm/unaligned.h is always an include of asm-generic/unaligned.h; might as well move that thing to linux/unaligned.h and include that - there's nothing arch-specific in that header. auto-generated by the following: for i in `git grep -l -w asm/unaligned.h`; do sed -i -e "s/asm\/unaligned.h/linux\/unaligned.h/" $i done for i in `git grep -l -w asm-generic/unaligned.h`; do sed -i -e "s/asm-generic\/unaligned.h/linux\/unaligned.h/" $i done git mv include/asm-generic/unaligned.h include/linux/unaligned.h git mv tools/include/asm-generic/unaligned.h tools/include/linux/unaligned.h sed -i -e "/unaligned.h/d" include/asm-generic/Kbuild sed -i -e "s/__ASM_GENERIC/__LINUX/" include/linux/unaligned.h tools/include/linux/unaligned.h --- Documentation/arch/arm/mem_alignment.rst | 2 +- Documentation/core-api/unaligned-memory-access.rst | 2 +- .../translations/zh_CN/core-api/unaligned-memory-access.rst | 2 +- arch/alpha/kernel/traps.c | 2 +- arch/arc/include/asm/io.h | 2 +- arch/arc/kernel/traps.c | 2 +- arch/arc/kernel/unwind.c | 2 +- arch/arm/crypto/aes-ce-glue.c | 2 +- arch/arm/crypto/crc32-ce-glue.c | 2 +- arch/arm/crypto/ghash-ce-glue.c | 2 +- arch/arm/crypto/poly1305-glue.c | 2 +- arch/arm/crypto/sha2-ce-glue.c | 2 +- arch/arm/include/asm/uaccess.h | 2 +- arch/arm/mm/alignment.c | 2 +- arch/arm64/crypto/aes-ce-ccm-glue.c | 2 +- arch/arm64/crypto/aes-ce-glue.c | 2 +- arch/arm64/crypto/ghash-ce-glue.c | 2 +- arch/arm64/crypto/poly1305-glue.c | 2 +- arch/arm64/crypto/sha1-ce-glue.c | 2 +- arch/arm64/crypto/sha2-ce-glue.c | 2 +- arch/arm64/crypto/sha3-ce-glue.c | 2 +- arch/arm64/crypto/sha512-ce-glue.c | 2 +- arch/arm64/crypto/sm3-ce-glue.c | 2 +- arch/arm64/crypto/sm3-neon-glue.c | 2 +- arch/loongarch/crypto/crc32-loongarch.c | 2 +- arch/microblaze/include/asm/flat.h | 2 +- arch/mips/boot/compressed/decompress.c | 2 +- arch/mips/crypto/crc32-mips.c | 2 +- arch/mips/crypto/poly1305-glue.c | 2 +- arch/nios2/kernel/misaligned.c | 2 +- arch/parisc/boot/compressed/misc.c | 2 +- arch/parisc/kernel/traps.c | 2 +- arch/parisc/kernel/unaligned.c | 2 +- arch/powerpc/crypto/aes-gcm-p10-glue.c | 2 +- arch/powerpc/crypto/poly1305-p10-glue.c | 2 +- arch/powerpc/platforms/pseries/papr_scm.c | 2 +- arch/sh/include/asm/flat.h | 2 +- arch/sh/kernel/dwarf.c | 2 +- arch/sh/kernel/module.c | 2 +- arch/sparc/crypto/crc32c_glue.c | 2 +- arch/um/drivers/virt-pci.c | 2 +- arch/um/include/asm/uaccess.h | 2 +- arch/x86/crypto/camellia_glue.c | 2 +- arch/x86/crypto/ghash-clmulni-intel_glue.c | 2 +- arch/x86/lib/insn.c | 2 +- arch/xtensa/include/asm/flat.h | 2 +- block/partitions/ldm.h | 2 +- block/partitions/msdos.c | 2 +- block/t10-pi.c | 2 +- crypto/aes_generic.c | 2 +- crypto/blake2b_generic.c | 2 +- crypto/blowfish_generic.c | 2 +- crypto/camellia_generic.c | 2 +- crypto/cast5_generic.c | 2 +- crypto/cast6_generic.c | 2 +- crypto/chacha_generic.c | 2 +- crypto/crc32_generic.c | 2 +- crypto/crc32c_generic.c | 2 +- crypto/crc64_rocksoft_generic.c | 2 +- crypto/ecc.c | 2 +- crypto/michael_mic.c | 2 +- crypto/nhpoly1305.c | 2 +- crypto/poly1305_generic.c | 2 +- crypto/polyval-generic.c | 2 +- crypto/serpent_generic.c | 2 +- crypto/sha256_generic.c | 2 +- crypto/sha3_generic.c | 2 +- crypto/sha512_generic.c | 2 +- crypto/sm3.c | 2 +- crypto/sm3_generic.c | 2 +- crypto/sm4.c | 2 +- crypto/sm4_generic.c | 2 +- crypto/twofish_generic.c | 2 +- crypto/vmac.c | 2 +- crypto/xxhash_generic.c | 2 +- drivers/acpi/apei/apei-base.c | 2 +- drivers/acpi/apei/einj-core.c | 2 +- drivers/acpi/battery.c | 2 +- drivers/acpi/cppc_acpi.c | 2 +- drivers/ata/libata-core.c | 2 +- drivers/ata/libata-sata.c | 2 +- drivers/ata/libata-scsi.c | 2 +- drivers/auxdisplay/ht16k33.c | 2 +- drivers/base/regmap/regmap.c | 2 +- drivers/block/aoe/aoecmd.c | 2 +- drivers/block/aoe/aoenet.c | 2 +- drivers/block/drbd/drbd_nl.c | 2 +- drivers/block/pktcdvd.c | 2 +- drivers/bluetooth/ath3k.c | 2 +- drivers/bluetooth/btbcm.c | 2 +- drivers/bluetooth/btintel.c | 2 +- drivers/bluetooth/btintel_pcie.c | 2 +- drivers/bluetooth/btmtk.c | 2 +- drivers/bluetooth/btmtksdio.c | 2 +- drivers/bluetooth/btmtkuart.c | 2 +- drivers/bluetooth/btnxpuart.c | 2 +- drivers/bluetooth/btrsi.c | 2 +- drivers/bluetooth/btrtl.c | 2 +- drivers/bluetooth/btusb.c | 2 +- drivers/bluetooth/h4_recv.h | 2 +- drivers/bluetooth/hci_bcm4377.c | 2 +- drivers/bluetooth/hci_bcsp.c | 2 +- drivers/bluetooth/hci_h4.c | 2 +- drivers/bluetooth/hci_nokia.c | 2 +- drivers/bluetooth/hci_qca.c | 2 +- drivers/bluetooth/hci_vhci.c | 2 +- drivers/char/tpm/tpm2-sessions.c | 2 +- drivers/char/tpm/tpm2-space.c | 2 +- drivers/clk/clk-si5341.c | 2 +- drivers/comedi/drivers/usbduxsigma.c | 2 +- drivers/counter/104-quad-8.c | 2 +- drivers/counter/i8254.c | 2 +- drivers/cpufreq/cppc_cpufreq.c | 2 +- drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c | 2 +- drivers/crypto/caam/caamalg.c | 2 +- drivers/crypto/caam/caamalg_qi.c | 2 +- drivers/crypto/caam/caamalg_qi2.c | 2 +- drivers/crypto/inside-secure/safexcel_cipher.c | 2 +- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 2 +- drivers/crypto/stm32/stm32-crc32.c | 2 +- drivers/cxl/core/mbox.c | 2 +- drivers/cxl/core/trace.h | 2 +- drivers/cxl/pci.c | 2 +- drivers/cxl/pmem.c | 2 +- drivers/cxl/security.c | 2 +- drivers/firewire/net.c | 2 +- drivers/firmware/arm_scmi/common.h | 2 +- drivers/firmware/arm_scmi/protocols.h | 2 +- drivers/firmware/dmi_scan.c | 2 +- drivers/firmware/efi/fdtparams.c | 2 +- drivers/firmware/efi/libstub/riscv-stub.c | 2 +- drivers/firmware/efi/libstub/riscv.c | 2 +- drivers/firmware/efi/libstub/zboot.c | 2 +- drivers/fpga/microchip-spi.c | 2 +- drivers/fsi/fsi-occ.c | 2 +- drivers/gpu/drm/amd/amdgpu/atom.c | 2 +- drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c | 2 +- drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c | 2 +- drivers/gpu/drm/bridge/samsung-dsim.c | 2 +- drivers/gpu/drm/bridge/sil-sii8620.c | 2 +- drivers/gpu/drm/bridge/tc358775.c | 2 +- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 2 +- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 2 +- drivers/gpu/drm/nouveau/include/nvif/os.h | 2 +- drivers/gpu/drm/radeon/atom.c | 2 +- drivers/gpu/drm/udl/udl_transfer.c | 2 +- drivers/greybus/es2.c | 2 +- drivers/greybus/gb-beagleplay.c | 2 +- drivers/hid/hid-alps.c | 2 +- drivers/hid/hid-core.c | 2 +- drivers/hid/hid-generic.c | 2 +- drivers/hid/hid-goodix-spi.c | 2 +- drivers/hid/hid-google-hammer.c | 2 +- drivers/hid/hid-kye.c | 2 +- drivers/hid/hid-letsketch.c | 2 +- drivers/hid/hid-logitech-dj.c | 2 +- drivers/hid/hid-logitech-hidpp.c | 2 +- drivers/hid/hid-nintendo.c | 2 +- drivers/hid/hid-playstation.c | 2 +- drivers/hid/hid-sony.c | 2 +- drivers/hid/hid-uclogic-params.c | 2 +- drivers/hid/hid-uclogic-rdesc.c | 2 +- drivers/hid/i2c-hid/i2c-hid-core.c | 2 +- drivers/hid/surface-hid/surface_hid.c | 2 +- drivers/hid/surface-hid/surface_hid_core.c | 2 +- drivers/hid/surface-hid/surface_kbd.c | 2 +- drivers/hid/usbhid/hid-core.c | 2 +- drivers/hid/wacom.h | 2 +- drivers/hwmon/adt7310.c | 2 +- drivers/hwmon/aquacomputer_d5next.c | 2 +- drivers/hwmon/asus-ec-sensors.c | 2 +- drivers/hwmon/asus_rog_ryujin.c | 2 +- drivers/hwmon/dell-smm-hwmon.c | 2 +- drivers/hwmon/gigabyte_waterforce.c | 2 +- drivers/hwmon/nzxt-kraken2.c | 2 +- drivers/hwmon/nzxt-kraken3.c | 2 +- drivers/hwmon/nzxt-smart2.c | 2 +- drivers/hwmon/occ/common.c | 2 +- drivers/hwmon/occ/p8_i2c.c | 2 +- drivers/i2c/busses/i2c-nvidia-gpu.c | 2 +- drivers/iio/accel/adxl355_core.c | 2 +- drivers/iio/accel/adxl367.c | 2 +- drivers/iio/accel/adxl380.c | 2 +- drivers/iio/accel/bma400_core.c | 2 +- drivers/iio/accel/bmi088-accel-core.c | 2 +- drivers/iio/accel/dmard09.c | 2 +- drivers/iio/accel/sca3300.c | 2 +- drivers/iio/adc/ad4130.c | 2 +- drivers/iio/adc/ad_sigma_delta.c | 2 +- drivers/iio/adc/axp20x_adc.c | 2 +- drivers/iio/adc/intel_mrfld_adc.c | 2 +- drivers/iio/adc/ltc2497.c | 2 +- drivers/iio/adc/max11100.c | 2 +- drivers/iio/adc/max11410.c | 2 +- drivers/iio/adc/mcp3422.c | 2 +- drivers/iio/adc/mcp3911.c | 2 +- drivers/iio/adc/mt6360-adc.c | 2 +- drivers/iio/adc/pac1921.c | 2 +- drivers/iio/adc/pac1934.c | 2 +- drivers/iio/adc/qcom-spmi-rradc.c | 2 +- drivers/iio/adc/ti-ads124s08.c | 2 +- drivers/iio/adc/ti-ads1298.c | 2 +- drivers/iio/adc/ti-ads131e08.c | 2 +- drivers/iio/adc/ti-tsc2046.c | 2 +- drivers/iio/addac/ad74115.c | 2 +- drivers/iio/addac/ad74413r.c | 2 +- drivers/iio/amplifiers/ada4250.c | 2 +- drivers/iio/cdc/ad7746.c | 2 +- drivers/iio/chemical/bme680_core.c | 2 +- drivers/iio/chemical/pms7003.c | 2 +- drivers/iio/chemical/scd30_i2c.c | 2 +- drivers/iio/chemical/scd30_serial.c | 2 +- drivers/iio/chemical/scd4x.c | 2 +- drivers/iio/chemical/sps30_i2c.c | 2 +- drivers/iio/common/st_sensors/st_sensors_core.c | 2 +- drivers/iio/dac/ad3552r.c | 2 +- drivers/iio/dac/ad5064.c | 2 +- drivers/iio/dac/ad5446.c | 2 +- drivers/iio/dac/ad5449.c | 2 +- drivers/iio/dac/ad5593r.c | 2 +- drivers/iio/dac/ad5624r_spi.c | 2 +- drivers/iio/dac/ad5766.c | 2 +- drivers/iio/dac/ad7293.c | 2 +- drivers/iio/dac/ltc2632.c | 2 +- drivers/iio/dac/mcp4821.c | 2 +- drivers/iio/frequency/adf4377.c | 2 +- drivers/iio/frequency/admv1013.c | 2 +- drivers/iio/frequency/admv1014.c | 2 +- drivers/iio/frequency/admv4420.c | 2 +- drivers/iio/frequency/adrf6780.c | 2 +- drivers/iio/gyro/adis16130.c | 2 +- drivers/iio/health/afe4403.c | 2 +- drivers/iio/humidity/ens210.c | 2 +- drivers/iio/humidity/hdc3020.c | 2 +- drivers/iio/imu/adis.c | 2 +- drivers/iio/imu/bmi323/bmi323_core.c | 2 +- drivers/iio/light/apds9306.c | 2 +- drivers/iio/light/gp2ap020a00f.c | 2 +- drivers/iio/light/ltr390.c | 2 +- drivers/iio/light/ltrf216a.c | 2 +- drivers/iio/light/si1133.c | 2 +- drivers/iio/light/tsl2591.c | 2 +- drivers/iio/light/zopt2201.c | 2 +- drivers/iio/magnetometer/rm3100-core.c | 2 +- drivers/iio/magnetometer/yamaha-yas530.c | 2 +- drivers/iio/pressure/bmp280-core.c | 2 +- drivers/iio/pressure/dlhl60d.c | 2 +- drivers/iio/pressure/hp206c.c | 2 +- drivers/iio/pressure/hsc030pa.c | 2 +- drivers/iio/pressure/mprls0025pa.c | 2 +- drivers/iio/pressure/ms5611_i2c.c | 2 +- drivers/iio/pressure/ms5611_spi.c | 2 +- drivers/iio/pressure/sdp500.c | 2 +- drivers/iio/pressure/st_pressure_core.c | 2 +- drivers/iio/pressure/zpa2326.c | 2 +- drivers/iio/proximity/aw96103.c | 2 +- drivers/iio/proximity/cros_ec_mkbp_proximity.c | 2 +- drivers/iio/proximity/hx9023s.c | 2 +- drivers/iio/proximity/irsd200.c | 2 +- drivers/iio/temperature/ltc2983.c | 2 +- drivers/iio/temperature/max31856.c | 2 +- drivers/iio/temperature/max31865.c | 2 +- drivers/input/joystick/adafruit-seesaw.c | 2 +- drivers/input/joystick/adc-joystick.c | 2 +- drivers/input/joystick/iforce/iforce-main.c | 2 +- drivers/input/joystick/iforce/iforce-packets.c | 2 +- drivers/input/joystick/spaceball.c | 2 +- drivers/input/keyboard/applespi.c | 2 +- drivers/input/keyboard/cros_ec_keyb.c | 2 +- drivers/input/misc/ims-pcu.c | 2 +- drivers/input/misc/iqs7222.c | 2 +- drivers/input/mouse/cyapa_gen3.c | 2 +- drivers/input/mouse/cyapa_gen5.c | 2 +- drivers/input/mouse/cyapa_gen6.c | 2 +- drivers/input/mouse/elan_i2c_core.c | 2 +- drivers/input/mouse/elan_i2c_i2c.c | 2 +- drivers/input/mouse/elantech.c | 2 +- drivers/input/rmi4/rmi_f01.c | 2 +- drivers/input/rmi4/rmi_f34.c | 2 +- drivers/input/rmi4/rmi_f34v7.c | 2 +- drivers/input/tablet/aiptek.c | 2 +- drivers/input/tablet/kbtab.c | 2 +- drivers/input/touchscreen/ads7846.c | 2 +- drivers/input/touchscreen/atmel_mxt_ts.c | 2 +- drivers/input/touchscreen/chipone_icn8505.c | 2 +- drivers/input/touchscreen/cy8ctma140.c | 2 +- drivers/input/touchscreen/cyttsp5.c | 2 +- drivers/input/touchscreen/edt-ft5x06.c | 2 +- drivers/input/touchscreen/eeti_ts.c | 2 +- drivers/input/touchscreen/elants_i2c.c | 2 +- drivers/input/touchscreen/exc3000.c | 2 +- drivers/input/touchscreen/goodix.c | 2 +- drivers/input/touchscreen/goodix_berlin_core.c | 2 +- drivers/input/touchscreen/goodix_berlin_spi.c | 2 +- drivers/input/touchscreen/hideep.c | 2 +- drivers/input/touchscreen/hycon-hy46xx.c | 2 +- drivers/input/touchscreen/hynitron_cstxxx.c | 2 +- drivers/input/touchscreen/ili210x.c | 2 +- drivers/input/touchscreen/ilitek_ts_i2c.c | 2 +- drivers/input/touchscreen/iqs5xx.c | 2 +- drivers/input/touchscreen/iqs7211.c | 2 +- drivers/input/touchscreen/melfas_mip4.c | 2 +- drivers/input/touchscreen/novatek-nvt-ts.c | 2 +- drivers/input/touchscreen/pixcir_i2c_ts.c | 2 +- drivers/input/touchscreen/raydium_i2c_ts.c | 2 +- drivers/input/touchscreen/s6sy761.c | 2 +- drivers/input/touchscreen/silead.c | 2 +- drivers/input/touchscreen/sis_i2c.c | 2 +- drivers/input/touchscreen/surface3_spi.c | 2 +- drivers/input/touchscreen/wacom_i2c.c | 2 +- drivers/input/touchscreen/wdt87xx_i2c.c | 2 +- drivers/input/touchscreen/zet6223.c | 2 +- drivers/input/touchscreen/zforce_ts.c | 2 +- drivers/isdn/hardware/mISDN/avmfritz.c | 2 +- drivers/leds/rgb/leds-mt6370-rgb.c | 2 +- drivers/macintosh/adb-iop.c | 2 +- drivers/md/dm-crypt.c | 2 +- drivers/md/dm-vdo/murmurhash3.c | 2 +- drivers/md/dm-vdo/numeric.h | 2 +- drivers/media/dvb-frontends/mxl5xx.c | 2 +- drivers/media/i2c/ccs/ccs-reg-access.c | 2 +- drivers/media/i2c/hi556.c | 2 +- drivers/media/i2c/hi846.c | 2 +- drivers/media/i2c/hi847.c | 2 +- drivers/media/i2c/imx208.c | 2 +- drivers/media/i2c/imx258.c | 2 +- drivers/media/i2c/imx290.c | 2 +- drivers/media/i2c/imx319.c | 2 +- drivers/media/i2c/imx334.c | 2 +- drivers/media/i2c/imx335.c | 2 +- drivers/media/i2c/imx355.c | 2 +- drivers/media/i2c/imx412.c | 2 +- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/i2c/og01a1b.c | 2 +- drivers/media/i2c/ov01a10.c | 2 +- drivers/media/i2c/ov08x40.c | 2 +- drivers/media/i2c/ov2740.c | 2 +- drivers/media/i2c/ov5670.c | 2 +- drivers/media/i2c/ov5675.c | 2 +- drivers/media/i2c/ov8856.c | 2 +- drivers/media/i2c/ov8858.c | 2 +- drivers/media/i2c/ov9282.c | 2 +- drivers/media/i2c/ov9734.c | 2 +- drivers/media/i2c/thp7312.c | 2 +- drivers/media/i2c/vgxy61.c | 2 +- drivers/media/pci/bt8xx/bttv-cards.c | 2 +- drivers/media/platform/chips-media/coda/coda-jpeg.c | 2 +- drivers/media/platform/renesas/rcar_jpu.c | 2 +- drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c | 2 +- drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c | 2 +- .../media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c | 2 +- .../media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c | 2 +- drivers/media/radio/radio-raremono.c | 2 +- drivers/media/radio/si470x/radio-si470x.h | 2 +- drivers/media/rc/ir_toy.c | 2 +- drivers/media/rc/redrat3.c | 2 +- drivers/media/tuners/xc2028.c | 2 +- drivers/media/tuners/xc4000.c | 2 +- drivers/media/usb/dvb-usb/m920x.c | 2 +- drivers/media/usb/uvc/uvc_driver.c | 2 +- drivers/media/usb/uvc/uvc_video.c | 2 +- drivers/media/v4l2-core/v4l2-cci.c | 2 +- drivers/media/v4l2-core/v4l2-jpeg.c | 2 +- drivers/memstick/host/rtsx_usb_ms.c | 2 +- drivers/mfd/gateworks-gsc.c | 2 +- drivers/mfd/iqs62x.c | 2 +- drivers/mfd/ntxec.c | 2 +- drivers/mfd/rave-sp.c | 2 +- drivers/mfd/si476x-cmd.c | 2 +- drivers/misc/altera-stapl/altera.c | 2 +- drivers/misc/bcm-vk/bcm_vk_sg.c | 2 +- drivers/misc/cardreader/rtsx_pcr.c | 2 +- drivers/misc/lattice-ecp3-config.c | 2 +- drivers/misc/mei/platform-vsc.c | 2 +- drivers/misc/mei/vsc-fw-loader.c | 2 +- drivers/mmc/host/atmel-mci.c | 2 +- drivers/mmc/host/mmc_spi.c | 2 +- drivers/mmc/host/mvsdio.c | 2 +- drivers/mmc/host/rtsx_pci_sdmmc.c | 2 +- drivers/mmc/host/rtsx_usb_sdmmc.c | 2 +- drivers/mtd/nand/raw/intel-nand-controller.c | 2 +- drivers/mtd/nand/raw/marvell_nand.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c | 2 +- drivers/net/can/usb/etas_es58x/es581_4.c | 2 +- drivers/net/can/usb/etas_es58x/es58x_core.c | 2 +- drivers/net/can/usb/etas_es58x/es58x_fd.c | 2 +- drivers/net/can/usb/f81604.c | 2 +- drivers/net/can/usb/mcba_usb.c | 2 +- drivers/net/can/usb/peak_usb/pcan_usb.c | 2 +- drivers/net/dsa/b53/b53_spi.c | 2 +- drivers/net/dsa/microchip/ksz_spi.c | 2 +- drivers/net/ethernet/adi/adin1110.c | 2 +- drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c | 2 +- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 +- drivers/net/ethernet/dec/tulip/de2104x.c | 2 +- drivers/net/ethernet/dec/tulip/eeprom.c | 2 +- drivers/net/ethernet/dec/tulip/tulip.h | 2 +- drivers/net/ethernet/dec/tulip/tulip_core.c | 2 +- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +- drivers/net/ethernet/intel/e100.c | 2 +- drivers/net/ethernet/intel/ice/ice_fw_update.c | 2 +- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 2 +- drivers/net/ethernet/meta/fbnic/fbnic_devlink.c | 2 +- drivers/net/ethernet/netronome/nfp/crypto/ipsec.c | 2 +- drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c | 2 +- drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c | 2 +- drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c | 2 +- drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c | 2 +- drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c | 2 +- drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c | 2 +- drivers/net/ethernet/packetengines/hamachi.c | 2 +- drivers/net/ethernet/packetengines/yellowfin.c | 2 +- drivers/net/ethernet/realtek/r8169_main.c | 2 +- drivers/net/ethernet/smsc/smsc9420.c | 2 +- drivers/net/ieee802154/cc2520.c | 2 +- drivers/net/mctp/mctp-i3c.c | 2 +- drivers/net/phy/air_en8811h.c | 2 +- drivers/net/phy/aquantia/aquantia_firmware.c | 2 +- drivers/net/phy/bcm-phy-ptp.c | 2 +- drivers/net/phy/mscc/mscc_ptp.c | 2 +- drivers/net/ppp/ppp_async.c | 2 +- drivers/net/ppp/ppp_deflate.c | 2 +- drivers/net/ppp/ppp_generic.c | 2 +- drivers/net/ppp/ppp_mppe.c | 2 +- drivers/net/ppp/ppp_synctty.c | 2 +- drivers/net/slip/slhc.c | 2 +- drivers/net/usb/net1080.c | 2 +- drivers/net/usb/sierra_net.c | 2 +- drivers/net/wireless/ath/ath5k/base.c | 2 +- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 2 +- drivers/net/wireless/ath/ath5k/phy.c | 2 +- drivers/net/wireless/ath/ath5k/reset.c | 2 +- drivers/net/wireless/ath/ath6kl/htc_mbox.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- drivers/net/wireless/ath/ath9k/debug.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom_def.c | 2 +- drivers/net/wireless/ath/ath9k/hif_usb.c | 2 +- drivers/net/wireless/ath/ath9k/hw.c | 2 +- drivers/net/wireless/ath/carl9170/mac.c | 2 +- drivers/net/wireless/ath/hw.c | 2 +- drivers/net/wireless/ath/key.c | 2 +- drivers/net/wireless/broadcom/b43/main.c | 2 +- drivers/net/wireless/broadcom/b43legacy/main.c | 2 +- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | 2 +- drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c | 2 +- drivers/net/wireless/intel/iwlegacy/3945.c | 2 +- drivers/net/wireless/intel/iwlegacy/4965.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/led.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/rx.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 2 +- drivers/net/wireless/marvell/libertas/cfg.c | 2 +- drivers/net/wireless/marvell/libertas/cmdresp.c | 2 +- drivers/net/wireless/marvell/mwifiex/cmdevt.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c | 2 +- drivers/net/wireless/mediatek/mt7601u/dma.h | 2 +- drivers/net/wireless/mediatek/mt7601u/eeprom.c | 2 +- drivers/net/wireless/purelifi/plfxlc/usb.c | 2 +- drivers/net/wireless/zydas/zd1211rw/zd_usb.c | 2 +- drivers/nfc/nfcmrvl/fw_dnld.c | 2 +- drivers/nfc/nxp-nci/firmware.c | 2 +- drivers/nfc/nxp-nci/i2c.c | 2 +- drivers/nfc/pn544/i2c.c | 2 +- drivers/nvme/common/auth.c | 2 +- drivers/nvme/host/auth.c | 2 +- drivers/nvme/host/core.c | 2 +- drivers/nvme/host/hwmon.c | 2 +- drivers/nvme/host/pr.c | 2 +- drivers/nvme/host/rdma.c | 2 +- drivers/nvme/host/trace.c | 2 +- drivers/nvme/target/admin-cmd.c | 2 +- drivers/nvme/target/auth.c | 2 +- drivers/nvme/target/rdma.c | 2 +- drivers/nvme/target/trace.c | 2 +- drivers/pci/vpd.c | 2 +- drivers/pcmcia/cistpl.c | 2 +- drivers/peci/controller/peci-aspeed.c | 2 +- drivers/peci/request.c | 2 +- drivers/platform/arm64/acer-aspire1-ec.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 2 +- drivers/platform/chrome/cros_ec_proto_test.c | 2 +- drivers/platform/chrome/wilco_ec/properties.c | 2 +- drivers/platform/cznic/turris-omnia-mcu-gpio.c | 2 +- drivers/platform/cznic/turris-omnia-mcu.h | 2 +- drivers/platform/surface/aggregator/ssh_msgb.h | 2 +- drivers/platform/surface/aggregator/ssh_packet_layer.c | 2 +- drivers/platform/surface/aggregator/ssh_parser.c | 2 +- drivers/platform/surface/aggregator/ssh_request_layer.c | 2 +- drivers/platform/surface/aggregator/trace.h | 2 +- drivers/platform/surface/surface3_power.c | 2 +- drivers/platform/surface/surface_acpi_notify.c | 2 +- drivers/platform/surface/surface_aggregator_tabletsw.c | 2 +- drivers/platform/surface/surface_platform_profile.c | 2 +- drivers/platform/x86/asus-tf103c-dock.c | 2 +- drivers/platform/x86/dell/dell-wmi-ddv.c | 2 +- drivers/platform/x86/msi-wmi-platform.c | 2 +- drivers/platform/x86/quickstart.c | 2 +- drivers/power/supply/axp288_fuel_gauge.c | 2 +- drivers/power/supply/bq27xxx_battery_i2c.c | 2 +- drivers/power/supply/cros_peripheral_charger.c | 2 +- drivers/power/supply/max1720x_battery.c | 2 +- drivers/power/supply/rk817_charger.c | 2 +- drivers/power/supply/surface_battery.c | 2 +- drivers/power/supply/surface_charger.c | 2 +- drivers/ptp/ptp_clockmatrix.c | 2 +- drivers/ptp/ptp_fc3.c | 2 +- drivers/rtc/rtc-max31335.c | 2 +- drivers/rtc/rtc-pm8xxx.c | 2 +- drivers/scsi/aacraid/aachba.c | 2 +- drivers/scsi/csiostor/csio_lnode.c | 2 +- drivers/scsi/csiostor/csio_scsi.c | 2 +- drivers/scsi/cxlflash/lunmgt.c | 2 +- drivers/scsi/cxlflash/main.c | 2 +- drivers/scsi/cxlflash/superpipe.c | 2 +- drivers/scsi/cxlflash/vlun.c | 2 +- drivers/scsi/device_handler/scsi_dh_alua.c | 2 +- drivers/scsi/hpsa.c | 2 +- drivers/scsi/ipr.h | 2 +- drivers/scsi/libfc/fc_disc.c | 2 +- drivers/scsi/libfc/fc_elsct.c | 2 +- drivers/scsi/libfc/fc_encode.h | 2 +- drivers/scsi/libfc/fc_lport.c | 2 +- drivers/scsi/libfc/fc_rport.c | 2 +- drivers/scsi/libiscsi.c | 2 +- drivers/scsi/libsas/sas_expander.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 2 +- drivers/scsi/lpfc/lpfc_nvmet.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 2 +- drivers/scsi/mpi3mr/mpi3mr.h | 2 +- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +- drivers/scsi/mpt3sas/mpt3sas_warpdrive.c | 2 +- drivers/scsi/mvsas/mv_sas.h | 2 +- drivers/scsi/myrb.c | 2 +- drivers/scsi/myrs.c | 2 +- drivers/scsi/qla2xxx/qla_dsd.h | 2 +- drivers/scsi/qla2xxx/qla_target.c | 2 +- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 +- drivers/scsi/scsi.c | 2 +- drivers/scsi/scsi_common.c | 2 +- drivers/scsi/scsi_debug.c | 2 +- drivers/scsi/scsi_error.c | 2 +- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_proto_test.c | 2 +- drivers/scsi/scsi_scan.c | 2 +- drivers/scsi/scsi_trace.c | 2 +- drivers/scsi/scsicam.c | 2 +- drivers/scsi/sd.c | 2 +- drivers/scsi/sd_zbc.c | 2 +- drivers/scsi/ses.c | 2 +- drivers/scsi/smartpqi/smartpqi_init.c | 2 +- drivers/scsi/smartpqi/smartpqi_sas_transport.c | 2 +- drivers/scsi/smartpqi/smartpqi_sis.c | 2 +- drivers/scsi/sr.c | 2 +- drivers/scsi/st.c | 2 +- drivers/soc/qcom/socinfo.c | 2 +- drivers/spi/spi-airoha-snfi.c | 2 +- drivers/spi/spi-dln2.c | 2 +- drivers/spi/spi-npcm-pspi.c | 2 +- drivers/spi/spi-orion.c | 2 +- drivers/spi/spi-rpc-if.c | 2 +- drivers/spi/spi-sh-msiof.c | 2 +- drivers/spi/spi-uniphier.c | 2 +- drivers/spi/spi-xcomm.c | 2 +- drivers/staging/media/av7110/av7110.c | 2 +- drivers/staging/rtl8192e/rtl819x_BAProc.c | 2 +- drivers/staging/rtl8723bs/core/rtw_ap.c | 2 +- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 2 +- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 2 +- drivers/staging/rtl8723bs/core/rtw_recv.c | 2 +- drivers/staging/rtl8723bs/os_dep/recv_linux.c | 2 +- drivers/target/iscsi/cxgbit/cxgbit_target.c | 2 +- drivers/target/iscsi/iscsi_target.c | 2 +- drivers/target/iscsi/iscsi_target_tmr.c | 2 +- drivers/target/sbp/sbp_target.c | 2 +- drivers/target/target_core_alua.c | 2 +- drivers/target/target_core_device.c | 2 +- drivers/target/target_core_fabric_lib.c | 2 +- drivers/target/target_core_file.c | 2 +- drivers/target/target_core_iblock.c | 2 +- drivers/target/target_core_pr.c | 2 +- drivers/target/target_core_pscsi.c | 2 +- drivers/target/target_core_sbc.c | 2 +- drivers/target/target_core_spc.c | 2 +- drivers/target/target_core_transport.c | 2 +- drivers/target/target_core_xcopy.c | 2 +- drivers/target/tcm_fc/tfc_cmd.c | 2 +- drivers/target/tcm_fc/tfc_conf.c | 2 +- drivers/target/tcm_fc/tfc_io.c | 2 +- drivers/target/tcm_fc/tfc_sess.c | 2 +- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 2 +- drivers/tty/serial/max3100.c | 2 +- drivers/tty/vt/vc_screen.c | 2 +- drivers/ufs/core/ufs-mcq.c | 2 +- drivers/ufs/core/ufs-sysfs.c | 2 +- drivers/ufs/core/ufshcd.c | 2 +- drivers/ufs/host/ufs-exynos.c | 2 +- drivers/usb/atm/cxacru.c | 2 +- drivers/usb/atm/ueagle-atm.c | 2 +- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/class/cdc-wdm.c | 2 +- drivers/usb/core/hcd.c | 2 +- drivers/usb/fotg210/fotg210-hcd.c | 2 +- drivers/usb/gadget/composite.c | 2 +- drivers/usb/gadget/function/f_fs.c | 2 +- drivers/usb/gadget/function/f_mass_storage.c | 2 +- drivers/usb/gadget/function/f_printer.c | 2 +- drivers/usb/gadget/function/f_tcm.c | 2 +- drivers/usb/gadget/function/rndis.c | 2 +- drivers/usb/gadget/function/storage_common.h | 2 +- drivers/usb/gadget/function/uvc_video.c | 2 +- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 2 +- drivers/usb/gadget/u_os_desc.h | 2 +- drivers/usb/gadget/udc/bdc/bdc.h | 2 +- drivers/usb/gadget/udc/bdc/bdc_ep.c | 2 +- drivers/usb/gadget/udc/bdc/bdc_udc.c | 2 +- drivers/usb/gadget/udc/cdns2/cdns2-ep0.c | 2 +- drivers/usb/gadget/udc/dummy_hcd.c | 2 +- drivers/usb/gadget/udc/fsl_udc_core.c | 2 +- drivers/usb/gadget/udc/goku_udc.c | 2 +- drivers/usb/gadget/udc/mv_udc_core.c | 2 +- drivers/usb/gadget/udc/net2272.c | 2 +- drivers/usb/gadget/udc/net2280.c | 2 +- drivers/usb/gadget/udc/omap_udc.c | 2 +- drivers/usb/gadget/udc/pxa25x_udc.c | 2 +- drivers/usb/gadget/udc/snps_udc_core.c | 2 +- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/isp1362-hcd.c | 2 +- drivers/usb/host/ohci-da8xx.c | 2 +- drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/oxu210hp-hcd.c | 2 +- drivers/usb/host/sl811-hcd.c | 2 +- drivers/usb/host/xhci-hub.c | 2 +- drivers/usb/host/xhci-pci-renesas.c | 2 +- drivers/usb/isp1760/isp1760-hcd.c | 2 +- drivers/usb/misc/usb-ljca.c | 2 +- drivers/usb/musb/musb_virthub.c | 2 +- drivers/usb/phy/phy-fsl-usb.c | 2 +- drivers/usb/serial/aircable.c | 2 +- drivers/usb/serial/ch341.c | 2 +- drivers/usb/serial/cypress_m8.c | 2 +- drivers/usb/serial/kl5kusb105.c | 2 +- drivers/usb/serial/mct_u232.c | 2 +- drivers/usb/serial/mxuport.c | 2 +- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/quatech2.c | 2 +- drivers/usb/typec/ucsi/ucsi.h | 2 +- drivers/usb/typec/ucsi/ucsi_ccg.c | 2 +- drivers/usb/typec/ucsi/ucsi_stm32g0.c | 2 +- drivers/vhost/scsi.c | 2 +- drivers/video/fbdev/aty/mach64_accel.c | 2 +- drivers/video/fbdev/c2p_iplan2.c | 2 +- drivers/video/fbdev/c2p_planar.c | 2 +- drivers/video/fbdev/matrox/matroxfb_base.h | 2 +- drivers/video/fbdev/metronomefb.c | 2 +- drivers/video/fbdev/udlfb.c | 2 +- drivers/watchdog/ziirave_wdt.c | 2 +- fs/adfs/map.c | 2 +- fs/bcachefs/bset.c | 2 +- fs/bcachefs/inode.c | 2 +- fs/bcachefs/siphash.c | 2 +- fs/bcachefs/varint.c | 2 +- fs/binfmt_flat.c | 2 +- fs/btrfs/accessors.c | 2 +- fs/btrfs/accessors.h | 2 +- fs/btrfs/disk-io.c | 2 +- fs/btrfs/inode.c | 2 +- fs/btrfs/uuid-tree.c | 2 +- fs/ceph/export.c | 2 +- fs/ceph/super.h | 2 +- fs/crypto/keyring.c | 2 +- fs/ecryptfs/crypto.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/ecryptfs/mmap.c | 2 +- fs/erofs/zmap.c | 2 +- fs/exfat/cache.c | 2 +- fs/exfat/fatent.c | 2 +- fs/exfat/nls.c | 2 +- fs/f2fs/dir.c | 2 +- fs/f2fs/recovery.c | 2 +- fs/fat/inode.c | 2 +- fs/hfsplus/wrapper.c | 2 +- fs/hpfs/hpfs_fn.h | 2 +- fs/isofs/isofs.h | 2 +- fs/lockd/mon.c | 2 +- fs/nls/nls_ucs2_utils.c | 2 +- fs/ntfs3/lib/decompress_common.h | 2 +- fs/orangefs/orangefs-kernel.h | 2 +- fs/reiserfs/inode.c | 2 +- fs/reiserfs/reiserfs.h | 2 +- fs/smb/client/cifspdu.h | 2 +- fs/smb/client/compress/lz77.c | 2 +- fs/smb/server/unicode.c | 2 +- fs/xfs/xfs_linux.h | 2 +- include/asm-generic/Kbuild | 1 - include/asm-generic/uaccess.h | 2 +- include/crypto/chacha.h | 2 +- include/crypto/internal/ecc.h | 2 +- include/crypto/internal/poly1305.h | 2 +- include/crypto/sha1_base.h | 2 +- include/crypto/sha256_base.h | 2 +- include/crypto/sha512_base.h | 2 +- include/crypto/sm3_base.h | 2 +- include/crypto/utils.h | 2 +- include/linux/ceph/decode.h | 2 +- include/linux/ceph/libceph.h | 2 +- include/linux/etherdevice.h | 2 +- include/linux/ieee80211.h | 2 +- include/linux/mtd/map.h | 2 +- include/linux/ptp_classify.h | 2 +- include/linux/sunrpc/xdr.h | 2 +- include/linux/tpm.h | 2 +- include/{asm-generic => linux}/unaligned.h | 6 +++--- include/net/bluetooth/l2cap.h | 2 +- include/net/calipso.h | 2 +- include/net/cipso_ipv4.h | 2 +- include/net/ieee80211_radiotap.h | 2 +- include/net/mac80211.h | 2 +- include/net/mac802154.h | 2 +- include/net/netfilter/nf_tables.h | 2 +- include/rdma/ib_hdrs.h | 2 +- include/rdma/iba.h | 2 +- include/scsi/scsi_transport_fc.h | 2 +- include/target/target_core_backend.h | 2 +- kernel/bpf/core.c | 2 +- kernel/debug/gdbstub.c | 2 +- lib/842/842.h | 2 +- lib/crypto/aes.c | 2 +- lib/crypto/blake2s-generic.c | 2 +- lib/crypto/chacha.c | 2 +- lib/crypto/chacha20poly1305-selftest.c | 2 +- lib/crypto/chacha20poly1305.c | 2 +- lib/crypto/curve25519-fiat32.c | 2 +- lib/crypto/curve25519-hacl64.c | 2 +- lib/crypto/des.c | 2 +- lib/crypto/memneq.c | 2 +- lib/crypto/poly1305-donna32.c | 2 +- lib/crypto/poly1305-donna64.c | 2 +- lib/crypto/poly1305.c | 2 +- lib/crypto/sha1.c | 2 +- lib/crypto/sha256.c | 2 +- lib/crypto/utils.c | 2 +- lib/decompress_unlz4.c | 2 +- lib/decompress_unlzo.c | 2 +- lib/hexdump.c | 2 +- lib/lz4/lz4_compress.c | 2 +- lib/lz4/lz4_decompress.c | 2 +- lib/lz4/lz4defs.h | 2 +- lib/lzo/lzo1x_compress.c | 2 +- lib/lzo/lzo1x_decompress_safe.c | 2 +- lib/pldmfw/pldmfw.c | 2 +- lib/random32.c | 2 +- lib/siphash.c | 2 +- lib/string.c | 2 +- lib/vsprintf.c | 2 +- lib/xxhash.c | 2 +- lib/xz/xz_private.h | 2 +- lib/zstd/common/mem.h | 2 +- net/802/garp.c | 2 +- net/802/mrp.c | 2 +- net/batman-adv/distributed-arp-table.c | 2 +- net/bluetooth/bnep/core.c | 2 +- net/bluetooth/coredump.c | 2 +- net/bluetooth/eir.h | 2 +- net/bluetooth/hci_core.c | 2 +- net/bluetooth/hci_event.c | 2 +- net/bluetooth/hci_sock.c | 2 +- net/bluetooth/mgmt.c | 2 +- net/bluetooth/mgmt_util.c | 2 +- net/bluetooth/rfcomm/core.c | 2 +- net/bridge/br_fdb.c | 2 +- net/bridge/br_stp_bpdu.c | 2 +- net/caif/cfrfml.c | 2 +- net/core/drop_monitor.c | 2 +- net/core/filter.c | 2 +- net/core/net-traces.c | 2 +- net/core/netpoll.c | 2 +- net/core/sock.c | 2 +- net/core/tso.c | 2 +- net/dccp/ccids/ccid3.c | 2 +- net/dccp/options.c | 2 +- net/ipv4/cipso_ipv4.c | 2 +- net/ipv4/ip_options.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv6/addrconf.c | 2 +- net/ipv6/calipso.c | 2 +- net/mac80211/key.c | 2 +- net/mac80211/mesh.c | 2 +- net/mac80211/mesh_hwmp.c | 2 +- net/mac80211/michael.c | 2 +- net/mac80211/mlme.c | 2 +- net/mac80211/ocb.c | 2 +- net/mac80211/rx.c | 2 +- net/mac80211/status.c | 2 +- net/mac80211/tkip.c | 2 +- net/mac80211/tx.c | 2 +- net/mac80211/wep.c | 2 +- net/mac80211/wpa.c | 2 +- net/mac802154/rx.c | 2 +- net/mac802154/tx.c | 2 +- net/mptcp/crypto.c | 2 +- net/netfilter/ipvs/ip_vs_ftp.c | 2 +- net/netfilter/ipvs/ip_vs_sync.c | 2 +- net/netfilter/nf_conntrack_proto_tcp.c | 2 +- net/netfilter/nf_synproxy_core.c | 2 +- net/netfilter/nft_byteorder.c | 2 +- net/netfilter/nft_exthdr.c | 2 +- net/phonet/af_phonet.c | 2 +- net/sched/em_cmp.c | 2 +- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 2 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 2 +- net/tls/trace.h | 2 +- net/wireless/radiotap.c | 2 +- net/xfrm/xfrm_user.c | 2 +- security/apparmor/policy_unpack.c | 2 +- security/keys/trusted-keys/trusted_tpm2.c | 2 +- sound/i2c/cs8427.c | 2 +- sound/pci/hda/hda_eld.c | 2 +- sound/pci/hda/tas2781_hda_i2c.c | 2 +- sound/soc/codecs/adau1701.c | 2 +- sound/soc/codecs/adau17x1.c | 2 +- sound/soc/codecs/pcm6240.c | 2 +- sound/soc/codecs/peb2466.c | 2 +- sound/soc/codecs/sigmadsp-i2c.c | 2 +- sound/soc/codecs/tas2781-fmwlib.c | 2 +- sound/soc/codecs/tas2781-i2c.c | 2 +- sound/soc/codecs/tas571x.c | 2 +- sound/soc/codecs/tlv320aic31xx.c | 2 +- sound/soc/codecs/wm5102.c | 2 +- sound/soc/codecs/wm8958-dsp2.c | 2 +- sound/soc/sof/iomem-utils.c | 2 +- sound/soc/sof/sof-utils.c | 2 +- tools/arch/x86/lib/insn.c | 2 +- tools/include/{asm-generic => linux}/unaligned.h | 6 +++--- tools/perf/check-headers.sh | 2 +- tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 2 +- tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c | 2 +- tools/testing/cxl/test/mem.c | 2 +- .../testing/selftests/bpf/progs/test_tcp_custom_syncookie.h | 2 +- 848 files changed, 851 insertions(+), 852 deletions(-) rename include/{asm-generic => linux}/unaligned.h (96%) rename tools/include/{asm-generic => linux}/unaligned.h (97%) diff --git a/Documentation/arch/arm/mem_alignment.rst b/Documentation/arch/arm/mem_alignment.rst index aa22893b62bc..64bd77959300 100644 --- a/Documentation/arch/arm/mem_alignment.rst +++ b/Documentation/arch/arm/mem_alignment.rst @@ -12,7 +12,7 @@ ones. Of course this is a bad idea to rely on the alignment trap to perform unaligned memory access in general. If those access are predictable, you -are better to use the macros provided by include/asm/unaligned.h. The +are better to use the macros provided by include/linux/unaligned.h. The alignment trap can fixup misaligned access for the exception cases, but at a high performance cost. It better be rare. diff --git a/Documentation/core-api/unaligned-memory-access.rst b/Documentation/core-api/unaligned-memory-access.rst index 1ee82419d8aa..5ceeb80eb539 100644 --- a/Documentation/core-api/unaligned-memory-access.rst +++ b/Documentation/core-api/unaligned-memory-access.rst @@ -203,7 +203,7 @@ Avoiding unaligned accesses =========================== The easiest way to avoid unaligned access is to use the get_unaligned() and -put_unaligned() macros provided by the <asm/unaligned.h> header file. +put_unaligned() macros provided by the <linux/unaligned.h> header file. Going back to an earlier example of code that potentially causes unaligned access:: diff --git a/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst b/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst index 29c33e7e0855..fbe0989a8ce5 100644 --- a/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst +++ b/Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst @@ -175,7 +175,7 @@ field2会导致éžå¯¹é½è®¿é—®ï¼Œè¿™å¹¶ä¸æ˜¯ä¸åˆç†çš„ã€‚ä½ ä¼šæœŸæœ›field2 é¿å…éžå¯¹é½è®¿é—® ============== -é¿å…éžå¯¹é½è®¿é—®çš„最简å•æ–¹æ³•æ˜¯ä½¿ç”¨<asm/unaligned.h>头文件æ供的get_unaligned()å’Œ +é¿å…éžå¯¹é½è®¿é—®çš„最简å•æ–¹æ³•æ˜¯ä½¿ç”¨<linux/unaligned.h>头文件æ供的get_unaligned()å’Œ put_unaligned()å®ã€‚ 回到å‰é¢çš„一个å¯èƒ½å¯¼è‡´éžå¯¹é½è®¿é—®çš„代ç 例å:: diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 6afae65e9a8b..a9a38c80c4a7 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -22,7 +22,7 @@ #include <asm/gentrap.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/sysinfo.h> #include <asm/hwrpb.h> #include <asm/mmu_context.h> diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h index 4fdb7350636c..f57cb5a6b624 100644 --- a/arch/arc/include/asm/io.h +++ b/arch/arc/include/asm/io.h @@ -9,7 +9,7 @@ #include <linux/types.h> #include <asm/byteorder.h> #include <asm/page.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #ifdef CONFIG_ISA_ARCV2 #include <asm/barrier.h> diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index 41af02081549..8d2ea2cbd98b 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -18,7 +18,7 @@ #include <linux/kgdb.h> #include <asm/entry.h> #include <asm/setup.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/kprobes.h> #include "unaligned.h" diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 9270d0a713c3..d8969dab12d4 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -19,7 +19,7 @@ #include <linux/uaccess.h> #include <linux/ptrace.h> #include <asm/sections.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/unwind.h> extern char __start_unwind[], __end_unwind[]; diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c index f5b66f4cf45d..21df5e7f51f9 100644 --- a/arch/arm/crypto/aes-ce-glue.c +++ b/arch/arm/crypto/aes-ce-glue.c @@ -8,7 +8,7 @@ #include <asm/hwcap.h> #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <crypto/ctr.h> #include <crypto/internal/simd.h> diff --git a/arch/arm/crypto/crc32-ce-glue.c b/arch/arm/crypto/crc32-ce-glue.c index 4ff18044af07..20b4dff13e3a 100644 --- a/arch/arm/crypto/crc32-ce-glue.c +++ b/arch/arm/crypto/crc32-ce-glue.c @@ -18,7 +18,7 @@ #include <asm/hwcap.h> #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define PMULL_MIN_LEN 64L /* minimum size of buffer * for crc32_pmull_le_16 */ diff --git a/arch/arm/crypto/ghash-ce-glue.c b/arch/arm/crypto/ghash-ce-glue.c index 3ddf05b4234d..3af997082534 100644 --- a/arch/arm/crypto/ghash-ce-glue.c +++ b/arch/arm/crypto/ghash-ce-glue.c @@ -9,7 +9,7 @@ #include <asm/hwcap.h> #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <crypto/gcm.h> #include <crypto/b128ops.h> diff --git a/arch/arm/crypto/poly1305-glue.c b/arch/arm/crypto/poly1305-glue.c index 8482e302c45a..4464ffbf8fd1 100644 --- a/arch/arm/crypto/poly1305-glue.c +++ b/arch/arm/crypto/poly1305-glue.c @@ -8,7 +8,7 @@ #include <asm/hwcap.h> #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/internal/hash.h> #include <crypto/internal/poly1305.h> diff --git a/arch/arm/crypto/sha2-ce-glue.c b/arch/arm/crypto/sha2-ce-glue.c index c62ce89dd3e0..aeac45bfbf9f 100644 --- a/arch/arm/crypto/sha2-ce-glue.c +++ b/arch/arm/crypto/sha2-ce-glue.c @@ -16,7 +16,7 @@ #include <asm/hwcap.h> #include <asm/simd.h> #include <asm/neon.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sha256_glue.h" diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 6c9c16d767cf..f90be312418e 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -12,7 +12,7 @@ #include <linux/string.h> #include <asm/page.h> #include <asm/domain.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/unified.h> #include <asm/pgtable.h> #include <asm/proc-fns.h> diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index f8dd0b3cc8e0..3c6ddb1afdc4 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -22,7 +22,7 @@ #include <asm/cp15.h> #include <asm/system_info.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/opcodes.h> #include "fault.h" diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c index ce9b28e3c7d6..a523b519700f 100644 --- a/arch/arm64/crypto/aes-ce-ccm-glue.c +++ b/arch/arm64/crypto/aes-ce-ccm-glue.c @@ -9,7 +9,7 @@ */ #include <asm/neon.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <crypto/scatterwalk.h> #include <crypto/internal/aead.h> diff --git a/arch/arm64/crypto/aes-ce-glue.c b/arch/arm64/crypto/aes-ce-glue.c index e921823ca103..00b8749013c5 100644 --- a/arch/arm64/crypto/aes-ce-glue.c +++ b/arch/arm64/crypto/aes-ce-glue.c @@ -7,7 +7,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <crypto/algapi.h> #include <crypto/internal/simd.h> diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c index 97331b454ea8..da7b7ec1a664 100644 --- a/arch/arm64/crypto/ghash-ce-glue.c +++ b/arch/arm64/crypto/ghash-ce-glue.c @@ -7,7 +7,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <crypto/gcm.h> #include <crypto/algapi.h> diff --git a/arch/arm64/crypto/poly1305-glue.c b/arch/arm64/crypto/poly1305-glue.c index 9c4bfd62e789..18883ea438f3 100644 --- a/arch/arm64/crypto/poly1305-glue.c +++ b/arch/arm64/crypto/poly1305-glue.c @@ -8,7 +8,7 @@ #include <asm/hwcap.h> #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/internal/hash.h> #include <crypto/internal/poly1305.h> diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c index 1dd93e1fcb39..cbd14f208f83 100644 --- a/arch/arm64/crypto/sha1-ce-glue.c +++ b/arch/arm64/crypto/sha1-ce-glue.c @@ -7,7 +7,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/sha1.h> diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c index 0a44d2e7ee1f..6b4866a88ded 100644 --- a/arch/arm64/crypto/sha2-ce-glue.c +++ b/arch/arm64/crypto/sha2-ce-glue.c @@ -7,7 +7,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/sha2.h> diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-glue.c index 250e1377c481..5662c3ac49e9 100644 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ b/arch/arm64/crypto/sha3-ce-glue.c @@ -12,7 +12,7 @@ #include <asm/hwcap.h> #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/sha3.h> diff --git a/arch/arm64/crypto/sha512-ce-glue.c b/arch/arm64/crypto/sha512-ce-glue.c index f3431fc62315..071f64293227 100644 --- a/arch/arm64/crypto/sha512-ce-glue.c +++ b/arch/arm64/crypto/sha512-ce-glue.c @@ -11,7 +11,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/sha2.h> diff --git a/arch/arm64/crypto/sm3-ce-glue.c b/arch/arm64/crypto/sm3-ce-glue.c index 54bf6ebcfffb..1a71788c4cda 100644 --- a/arch/arm64/crypto/sm3-ce-glue.c +++ b/arch/arm64/crypto/sm3-ce-glue.c @@ -7,7 +7,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/sm3.h> diff --git a/arch/arm64/crypto/sm3-neon-glue.c b/arch/arm64/crypto/sm3-neon-glue.c index 7182ee683f14..8dd71ce79b69 100644 --- a/arch/arm64/crypto/sm3-neon-glue.c +++ b/arch/arm64/crypto/sm3-neon-glue.c @@ -7,7 +7,7 @@ #include <asm/neon.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/sm3.h> diff --git a/arch/loongarch/crypto/crc32-loongarch.c b/arch/loongarch/crypto/crc32-loongarch.c index 3eebea3a7b47..b7d9782827f5 100644 --- a/arch/loongarch/crypto/crc32-loongarch.c +++ b/arch/loongarch/crypto/crc32-loongarch.c @@ -13,7 +13,7 @@ #include <crypto/internal/hash.h> #include <asm/cpu-features.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define _CRC32(crc, value, size, type) \ do { \ diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h index 79a749f4ad04..edff4306fa70 100644 --- a/arch/microblaze/include/asm/flat.h +++ b/arch/microblaze/include/asm/flat.h @@ -8,7 +8,7 @@ #ifndef _ASM_MICROBLAZE_FLAT_H #define _ASM_MICROBLAZE_FLAT_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * Microblaze works a little differently from other arches, because diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index adb6d5b0e6eb..90021c6a8cab 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -16,7 +16,7 @@ #include <linux/libfdt.h> #include <asm/addrspace.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm-generic/vmlinux.lds.h> #include "decompress.h" diff --git a/arch/mips/crypto/crc32-mips.c b/arch/mips/crypto/crc32-mips.c index 2a59b85f88aa..a7a1d43a1b2c 100644 --- a/arch/mips/crypto/crc32-mips.c +++ b/arch/mips/crypto/crc32-mips.c @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/string.h> #include <asm/mipsregs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> diff --git a/arch/mips/crypto/poly1305-glue.c b/arch/mips/crypto/poly1305-glue.c index 867728ee535a..c03ad0bbe69c 100644 --- a/arch/mips/crypto/poly1305-glue.c +++ b/arch/mips/crypto/poly1305-glue.c @@ -5,7 +5,7 @@ * Copyright (C) 2019 Linaro Ltd. <ard.biesheuvel@linaro.org> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/internal/hash.h> #include <crypto/internal/poly1305.h> diff --git a/arch/nios2/kernel/misaligned.c b/arch/nios2/kernel/misaligned.c index 23e0544e117c..2f2862eab3c6 100644 --- a/arch/nios2/kernel/misaligned.c +++ b/arch/nios2/kernel/misaligned.c @@ -23,7 +23,7 @@ #include <linux/seq_file.h> #include <asm/traps.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* instructions we emulate */ #define INST_LDHU 0x0b diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c index d389359e22ac..9c83bd06ef15 100644 --- a/arch/parisc/boot/compressed/misc.c +++ b/arch/parisc/boot/compressed/misc.c @@ -6,7 +6,7 @@ #include <linux/uaccess.h> #include <linux/elf.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/page.h> #include "sizes.h" diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index a111d7362d56..b9b3d527bc90 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -36,7 +36,7 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/traps.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <asm/smp.h> #include <asm/pdc.h> diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index 99897107d800..f4626943633a 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -12,7 +12,7 @@ #include <linux/ratelimit.h> #include <linux/uaccess.h> #include <linux/sysctl.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/hardirq.h> #include <asm/traps.h> #include "unaligned.h" diff --git a/arch/powerpc/crypto/aes-gcm-p10-glue.c b/arch/powerpc/crypto/aes-gcm-p10-glue.c index f62ee54076c0..f66ad56e765f 100644 --- a/arch/powerpc/crypto/aes-gcm-p10-glue.c +++ b/arch/powerpc/crypto/aes-gcm-p10-glue.c @@ -5,7 +5,7 @@ * Copyright 2022- IBM Inc. All rights reserved */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/simd.h> #include <asm/switch_to.h> #include <crypto/aes.h> diff --git a/arch/powerpc/crypto/poly1305-p10-glue.c b/arch/powerpc/crypto/poly1305-p10-glue.c index 95dd708573ee..369686e9370b 100644 --- a/arch/powerpc/crypto/poly1305-p10-glue.c +++ b/arch/powerpc/crypto/poly1305-p10-glue.c @@ -14,7 +14,7 @@ #include <crypto/internal/poly1305.h> #include <crypto/internal/simd.h> #include <linux/cpufeature.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/simd.h> #include <asm/switch_to.h> diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index d95e03b3d3e3..9e297f88adc5 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -19,7 +19,7 @@ #include <uapi/linux/papr_pdsm.h> #include <linux/papr_scm.h> #include <asm/mce.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/perf_event.h> #define BIND_ANY_ADDR (~0ul) diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h index fee4f25555cb..70752c7bc55f 100644 --- a/arch/sh/include/asm/flat.h +++ b/arch/sh/include/asm/flat.h @@ -9,7 +9,7 @@ #ifndef __ASM_SH_FLAT_H #define __ASM_SH_FLAT_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, u32 *addr) diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 45c8ae20d109..a1b54bedc929 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -24,7 +24,7 @@ #include <asm/dwarf.h> #include <asm/unwinder.h> #include <asm/sections.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/stacktrace.h> /* Reserve enough memory for two stack frames */ diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index b9cee98a754e..a469a80840d3 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c @@ -18,7 +18,7 @@ #include <linux/fs.h> #include <linux/string.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/dwarf.h> int apply_relocate_add(Elf32_Shdr *sechdrs, diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c index 688db0dcb97d..913b9a09e885 100644 --- a/arch/sparc/crypto/crc32c_glue.c +++ b/arch/sparc/crypto/crc32c_glue.c @@ -20,7 +20,7 @@ #include <asm/pstate.h> #include <asm/elf.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "opcodes.h" diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 6100819681b5..744e7f31e8ef 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -14,7 +14,7 @@ #include <linux/virtio-uml.h> #include <linux/delay.h> #include <linux/msi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <irq_kern.h> #define MAX_DEVICES 8 diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index 7d9d60e41e4e..1d4b6bbc1b65 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -8,7 +8,7 @@ #define __UM_UACCESS_H #include <asm/elf.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define __under_task_size(addr, size) \ (((unsigned long) (addr) < TASK_SIZE) && \ diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c index d45e9c0c42ac..f110708c8038 100644 --- a/arch/x86/crypto/camellia_glue.c +++ b/arch/x86/crypto/camellia_glue.c @@ -8,7 +8,7 @@ * Copyright (C) 2006 NTT (Nippon Telegraph and Telephone Corporation) */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crypto.h> #include <linux/init.h> #include <linux/module.h> diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index 700ecaee9a08..41bc02e48916 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -19,7 +19,7 @@ #include <crypto/internal/simd.h> #include <asm/cpu_device_id.h> #include <asm/simd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c index 5952ab41c60f..6ffb931b9fb1 100644 --- a/arch/x86/lib/insn.c +++ b/arch/x86/lib/insn.c @@ -13,7 +13,7 @@ #endif #include <asm/inat.h> /*__ignore_sync_check__ */ #include <asm/insn.h> /* __ignore_sync_check__ */ -#include <asm/unaligned.h> /* __ignore_sync_check__ */ +#include <linux/unaligned.h> /* __ignore_sync_check__ */ #include <linux/errno.h> #include <linux/kconfig.h> diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h index ed5870c779f9..4854419dcd86 100644 --- a/arch/xtensa/include/asm/flat.h +++ b/arch/xtensa/include/asm/flat.h @@ -2,7 +2,7 @@ #ifndef __ASM_XTENSA_FLAT_H #define __ASM_XTENSA_FLAT_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, u32 *addr) diff --git a/block/partitions/ldm.h b/block/partitions/ldm.h index 0a747a0c782d..e259180c8914 100644 --- a/block/partitions/ldm.h +++ b/block/partitions/ldm.h @@ -15,7 +15,7 @@ #include <linux/types.h> #include <linux/list.h> #include <linux/fs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/byteorder.h> struct parsed_partitions; diff --git a/block/partitions/msdos.c b/block/partitions/msdos.c index b5d5c229cc3b..073be78ba0b0 100644 --- a/block/partitions/msdos.c +++ b/block/partitions/msdos.c @@ -36,7 +36,7 @@ * the nr_sects and start_sect partition table entries are * at a 2 (mod 4) address. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline sector_t nr_sects(struct msdos_partition *p) { diff --git a/block/t10-pi.c b/block/t10-pi.c index e7052a728966..2d05421f0fa5 100644 --- a/block/t10-pi.c +++ b/block/t10-pi.c @@ -9,7 +9,7 @@ #include <linux/crc-t10dif.h> #include <linux/crc64.h> #include <net/checksum.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "blk.h" struct blk_integrity_iter { diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c index 666474b81c6a..3c66d425c97b 100644 --- a/crypto/aes_generic.c +++ b/crypto/aes_generic.c @@ -54,7 +54,7 @@ #include <linux/types.h> #include <linux/errno.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline u8 byte(const u32 x, const unsigned n) { diff --git a/crypto/blake2b_generic.c b/crypto/blake2b_generic.c index 32e380b714b6..04a712ddfb43 100644 --- a/crypto/blake2b_generic.c +++ b/crypto/blake2b_generic.c @@ -15,7 +15,7 @@ * More information about BLAKE2 can be found at https://blake2.net. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/bitops.h> diff --git a/crypto/blowfish_generic.c b/crypto/blowfish_generic.c index 0e74c7242e77..0146bc762c09 100644 --- a/crypto/blowfish_generic.c +++ b/crypto/blowfish_generic.c @@ -16,7 +16,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/mm.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/types.h> #include <crypto/blowfish.h> diff --git a/crypto/camellia_generic.c b/crypto/camellia_generic.c index c04670cf51ac..197fcf3abc89 100644 --- a/crypto/camellia_generic.c +++ b/crypto/camellia_generic.c @@ -15,7 +15,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/bitops.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static const u32 camellia_sp1110[256] = { 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, diff --git a/crypto/cast5_generic.c b/crypto/cast5_generic.c index 085a1eedae03..f3e57775fa02 100644 --- a/crypto/cast5_generic.c +++ b/crypto/cast5_generic.c @@ -13,7 +13,7 @@ */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <linux/init.h> #include <linux/module.h> diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c index 34f1ab53e3a7..11b725b12f27 100644 --- a/crypto/cast6_generic.c +++ b/crypto/cast6_generic.c @@ -10,7 +10,7 @@ */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <linux/init.h> #include <linux/module.h> diff --git a/crypto/chacha_generic.c b/crypto/chacha_generic.c index 8beea79ab117..ba7fcb47f9aa 100644 --- a/crypto/chacha_generic.c +++ b/crypto/chacha_generic.c @@ -6,7 +6,7 @@ * Copyright (C) 2018 Google LLC */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/internal/chacha.h> #include <crypto/internal/skcipher.h> diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c index a989cb44fd16..d1251663ed66 100644 --- a/crypto/crc32_generic.c +++ b/crypto/crc32_generic.c @@ -7,7 +7,7 @@ * This is crypto api shash wrappers to crc32_le. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc32.h> #include <crypto/internal/hash.h> #include <linux/init.h> diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c index 768614738541..a8c90b3f4c6c 100644 --- a/crypto/crc32c_generic.c +++ b/crypto/crc32c_generic.c @@ -30,7 +30,7 @@ * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <linux/init.h> #include <linux/module.h> diff --git a/crypto/crc64_rocksoft_generic.c b/crypto/crc64_rocksoft_generic.c index 9e812bb26dba..ce0f3059b912 100644 --- a/crypto/crc64_rocksoft_generic.c +++ b/crypto/crc64_rocksoft_generic.c @@ -3,7 +3,7 @@ #include <linux/crc64.h> #include <linux/module.h> #include <crypto/internal/hash.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static int chksum_init(struct shash_desc *desc) { diff --git a/crypto/ecc.c b/crypto/ecc.c index 420decdad7d9..50ad2d4ed672 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -33,7 +33,7 @@ #include <crypto/ecdh.h> #include <crypto/rng.h> #include <crypto/internal/ecc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ratelimit.h> #include "ecc_curve_defs.h" diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c index f4c31049601c..0d14e980d4d6 100644 --- a/crypto/michael_mic.c +++ b/crypto/michael_mic.c @@ -7,7 +7,7 @@ * Copyright (c) 2004 Jouni Malinen <j@w1.fi> */ #include <crypto/internal/hash.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/init.h> #include <linux/module.h> #include <linux/string.h> diff --git a/crypto/nhpoly1305.c b/crypto/nhpoly1305.c index 8a3006c3b51b..a661d4f667cd 100644 --- a/crypto/nhpoly1305.c +++ b/crypto/nhpoly1305.c @@ -30,7 +30,7 @@ * (https://cr.yp.to/mac/poly1305-20050329.pdf) */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/internal/hash.h> #include <crypto/internal/poly1305.h> diff --git a/crypto/poly1305_generic.c b/crypto/poly1305_generic.c index 94af47eb6fa6..e6f29a98725a 100644 --- a/crypto/poly1305_generic.c +++ b/crypto/poly1305_generic.c @@ -17,7 +17,7 @@ #include <linux/crypto.h> #include <linux/kernel.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static int crypto_poly1305_init(struct shash_desc *desc) { diff --git a/crypto/polyval-generic.c b/crypto/polyval-generic.c index 16bfa6925b31..4f98910bcdb5 100644 --- a/crypto/polyval-generic.c +++ b/crypto/polyval-generic.c @@ -44,7 +44,7 @@ * */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/gf128mul.h> #include <crypto/polyval.h> diff --git a/crypto/serpent_generic.c b/crypto/serpent_generic.c index c6bca47931e2..f6ef187be6fe 100644 --- a/crypto/serpent_generic.c +++ b/crypto/serpent_generic.c @@ -11,7 +11,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/errno.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/types.h> #include <crypto/serpent.h> diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index bf147b01e313..b00521f1a6d4 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c @@ -15,7 +15,7 @@ #include <crypto/sha2.h> #include <crypto/sha256_base.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> const u8 sha224_zero_message_hash[SHA224_DIGEST_SIZE] = { 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47, diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c index 3e4069935b53..b103642b56ea 100644 --- a/crypto/sha3_generic.c +++ b/crypto/sha3_generic.c @@ -13,7 +13,7 @@ #include <linux/module.h> #include <linux/types.h> #include <crypto/sha3.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * On some 32-bit architectures (h8300), GCC ends up using diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index be70e76d6d86..ed81813bd420 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c @@ -16,7 +16,7 @@ #include <crypto/sha512_base.h> #include <linux/percpu.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> const u8 sha384_zero_message_hash[SHA384_DIGEST_SIZE] = { 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, diff --git a/crypto/sm3.c b/crypto/sm3.c index d473e358a873..18c2fb73ba16 100644 --- a/crypto/sm3.c +++ b/crypto/sm3.c @@ -9,7 +9,7 @@ */ #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/sm3.h> static const u32 ____cacheline_aligned K[64] = { diff --git a/crypto/sm3_generic.c b/crypto/sm3_generic.c index a215c1c37e73..a2d23a46924e 100644 --- a/crypto/sm3_generic.c +++ b/crypto/sm3_generic.c @@ -17,7 +17,7 @@ #include <crypto/sm3_base.h> #include <linux/bitops.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE] = { 0x1A, 0xB2, 0x1D, 0x83, 0x55, 0xCF, 0xA1, 0x7F, diff --git a/crypto/sm4.c b/crypto/sm4.c index 2c44193bc27e..f4cd7edc11f0 100644 --- a/crypto/sm4.c +++ b/crypto/sm4.c @@ -8,7 +8,7 @@ */ #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/sm4.h> static const u32 ____cacheline_aligned fk[4] = { diff --git a/crypto/sm4_generic.c b/crypto/sm4_generic.c index 560eba37dc55..7df86369ac00 100644 --- a/crypto/sm4_generic.c +++ b/crypto/sm4_generic.c @@ -14,7 +14,7 @@ #include <linux/types.h> #include <linux/errno.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /** * sm4_setkey - Set the SM4 key. diff --git a/crypto/twofish_generic.c b/crypto/twofish_generic.c index 557915e4062d..19f2b365e140 100644 --- a/crypto/twofish_generic.c +++ b/crypto/twofish_generic.c @@ -24,7 +24,7 @@ * Third Edition. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <crypto/twofish.h> #include <linux/module.h> diff --git a/crypto/vmac.c b/crypto/vmac.c index 0a1d8efa6c1a..bd9d70eac22e 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -28,7 +28,7 @@ * Last modified: 17 APR 08, 1700 PDT */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/init.h> #include <linux/types.h> #include <linux/crypto.h> diff --git a/crypto/xxhash_generic.c b/crypto/xxhash_generic.c index 55d1c8a76127..ac206ad4184d 100644 --- a/crypto/xxhash_generic.c +++ b/crypto/xxhash_generic.c @@ -4,7 +4,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/xxhash.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define XXHASH64_BLOCK_SIZE 32 #define XXHASH64_DIGEST_SIZE 8 diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index c7c26872f4ce..9c84f3da7c09 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -28,7 +28,7 @@ #include <linux/interrupt.h> #include <linux/debugfs.h> #include <acpi/apei.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "apei-internal.h" diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index 73903a497d73..5c22720f43cc 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -22,7 +22,7 @@ #include <linux/delay.h> #include <linux/mm.h> #include <linux/platform_device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "apei-internal.h" diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index f4599261cfc3..2c9289ac2824 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -21,7 +21,7 @@ #include <linux/suspend.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/power_supply.h> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 5b06e236aabe..b73b3aa92f3f 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -41,7 +41,7 @@ #include <linux/topology.h> #include <linux/dmi.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <acpi/cppc_acpi.h> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index cdb20a700b55..c085dd81ebe7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -50,7 +50,7 @@ #include <scsi/scsi_host.h> #include <linux/libata.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/cdrom.h> #include <linux/ratelimit.h> #include <linux/leds.h> diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index c8b119a06bb2..9c76fb1ad2ec 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -13,7 +13,7 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_eh.h> #include <linux/libata.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "libata.h" #include "libata-transport.h" diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a4aedf7e1775..f915e3df57a9 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -30,7 +30,7 @@ #include <linux/hdreg.h> #include <linux/uaccess.h> #include <linux/suspend.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ioprio.h> #include <linux/of.h> diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 8a7034b41d50..a816f9e10255 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -25,7 +25,7 @@ #include <linux/map_to_7segment.h> #include <linux/map_to_14segment.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "line-display.h" diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 9ed842d17642..4ded93687c1f 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -17,7 +17,7 @@ #include <linux/delay.h> #include <linux/log2.h> #include <linux/hwspinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define CREATE_TRACE_POINTS #include "trace.h" diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index cc9077b588d7..1ad4eb5c3c8f 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -14,7 +14,7 @@ #include <linux/workqueue.h> #include <linux/kthread.h> #include <net/net_namespace.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/uio.h> #include "aoe.h" diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 923a134fd766..66e617664c14 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -10,7 +10,7 @@ #include <linux/netdevice.h> #include <linux/moduleparam.h> #include <net/net_namespace.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "aoe.h" #define NECODES 5 diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 5d65c9754d83..720fc30e2ecc 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -25,7 +25,7 @@ #include "drbd_protocol.h" #include "drbd_req.h" #include "drbd_state_change.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/drbd_limits.h> #include <linux/kthread.h> diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 499c110465e3..65b96c083b3c 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -71,7 +71,7 @@ #include <scsi/scsi_cmnd.h> #include <scsi/scsi_ioctl.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "pktcdvd" diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ce97b336fbfb..fc796f1dbda9 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -11,7 +11,7 @@ #include <linux/errno.h> #include <linux/firmware.h> #include <linux/usb.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #define VERSION "1.0" diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index f9a7c790d7e2..eef00467905e 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -12,7 +12,7 @@ #include <linux/dmi.h> #include <linux/of.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 1ccbb5157515..438b92967bc3 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -11,7 +11,7 @@ #include <linux/regmap.h> #include <linux/acpi.h> #include <acpi/acpi_bus.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/efi.h> #include <net/bluetooth/bluetooth.h> diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index fda47948c35d..5252125b003f 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -14,7 +14,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index 2b7c80043aa2..9bbf20502163 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -6,7 +6,7 @@ #include <linux/firmware.h> #include <linux/usb.h> #include <linux/iopoll.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 497e4c87f5be..11d33cd7b08f 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -10,7 +10,7 @@ * */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <linux/gpio/consumer.h> #include <linux/init.h> diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c index aa87c3e78871..64e4d835af52 100644 --- a/drivers/bluetooth/btmtkuart.c +++ b/drivers/bluetooth/btmtkuart.c @@ -8,7 +8,7 @@ * */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <linux/clk.h> #include <linux/firmware.h> diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index 7c2030cec10e..5ea0d23e88c0 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -10,7 +10,7 @@ #include <linux/serdev.h> #include <linux/of.h> #include <linux/skbuff.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/firmware.h> #include <linux/string.h> #include <linux/crc8.h> diff --git a/drivers/bluetooth/btrsi.c b/drivers/bluetooth/btrsi.c index 0c91d7635ac3..6c1f584c8a33 100644 --- a/drivers/bluetooth/btrsi.c +++ b/drivers/bluetooth/btrsi.c @@ -17,7 +17,7 @@ #include <linux/kernel.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/rsi_91x.h> #define RSI_DMA_ALIGN 8 diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 2d95b3ea046d..0bcb44cf7b31 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -7,7 +7,7 @@ #include <linux/module.h> #include <linux/firmware.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb.h> #include <net/bluetooth/bluetooth.h> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6c9c761d5b93..f23c8801ad5c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -17,7 +17,7 @@ #include <linux/suspend.h> #include <linux/gpio/consumer.h> #include <linux/debugfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/h4_recv.h b/drivers/bluetooth/h4_recv.h index 647d37ca4cdd..28cf2d8c2d48 100644 --- a/drivers/bluetooth/h4_recv.h +++ b/drivers/bluetooth/h4_recv.h @@ -6,7 +6,7 @@ * Copyright (C) 2015-2018 Intel Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> struct h4_recv_pkt { u8 type; /* Packet type */ diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c index 77a5454a8721..9bce53e49cfa 100644 --- a/drivers/bluetooth/hci_bcm4377.c +++ b/drivers/bluetooth/hci_bcm4377.c @@ -17,7 +17,7 @@ #include <linux/pci.h> #include <linux/printk.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 2a5a27d713f8..76878119d910 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -25,7 +25,7 @@ #include <linux/ioctl.h> #include <linux/skbuff.h> #include <linux/bitrev.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 1d0cdf023243..9070e31a68bf 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -25,7 +25,7 @@ #include <linux/signal.h> #include <linux/ioctl.h> #include <linux/skbuff.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c index 62633d9ba7c4..49bbe4975be4 100644 --- a/drivers/bluetooth/hci_nokia.c +++ b/drivers/bluetooth/hci_nokia.c @@ -20,7 +20,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 678f150229e7..37fddf6055be 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -32,7 +32,7 @@ #include <linux/regulator/consumer.h> #include <linux/serdev.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index aa6af351d02d..7651321d351c 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -9,7 +9,7 @@ */ #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <linux/kernel.h> diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 44f60730cff4..511c67061728 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -71,7 +71,7 @@ #include "tpm.h" #include <linux/random.h> #include <linux/scatterlist.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/kpp.h> #include <crypto/ecdh.h> #include <crypto/hash.h> diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c index 25a66870c165..60354cd53b5c 100644 --- a/drivers/char/tpm/tpm2-space.c +++ b/drivers/char/tpm/tpm2-space.c @@ -12,7 +12,7 @@ */ #include <linux/gfp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "tpm.h" enum tpm2_handle_types { diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 6e8dd7387cfd..5004888c7eca 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -21,7 +21,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SI5341_NUM_INPUTS 4 diff --git a/drivers/comedi/drivers/usbduxsigma.c b/drivers/comedi/drivers/usbduxsigma.c index 2aaeaf44fbe5..3f215ae228b2 100644 --- a/drivers/comedi/drivers/usbduxsigma.c +++ b/drivers/comedi/drivers/usbduxsigma.c @@ -39,7 +39,7 @@ #include <linux/input.h> #include <linux/fcntl.h> #include <linux/compiler.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/comedi/comedi_usb.h> /* timeout for the USB-transfer in ms*/ diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c index ed1f57511955..4a6868b8f58b 100644 --- a/drivers/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -22,7 +22,7 @@ #include <linux/spinlock.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define QUAD8_EXTENT 32 diff --git a/drivers/counter/i8254.c b/drivers/counter/i8254.c index c41e4fdc9601..6d74e8ef92f0 100644 --- a/drivers/counter/i8254.c +++ b/drivers/counter/i8254.c @@ -15,7 +15,7 @@ #include <linux/mutex.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define I8254_COUNTER_REG(_counter) (_counter) #define I8254_CONTROL_REG 0x3 diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 1a5ad184d28f..2b8708475ac7 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -22,7 +22,7 @@ #include <linux/vmalloc.h> #include <uapi/linux/sched/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <acpi/cppc_acpi.h> diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c index f7893e4ac59d..434f2b271012 100644 --- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c +++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c @@ -9,7 +9,7 @@ * You could find the datasheet in Documentation/arch/arm/sunxi.rst */ #include "sun4i-ss.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/scatterlist.h> /* This is a totally arbitrary value */ diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 066f08a3a040..2cfb1b8d8c7c 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -56,7 +56,7 @@ #include "sg_sw_sec4.h" #include "key_gen.h" #include "caamalg_desc.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/aead.h> #include <crypto/internal/engine.h> #include <crypto/internal/skcipher.h> diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index 13347dfecf7a..65f6adb6c673 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -19,7 +19,7 @@ #include "jr.h" #include "caamalg_desc.h" #include <crypto/xts.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/err.h> #include <linux/dma-mapping.h> diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c index 44e1f8f46967..e809d030ab11 100644 --- a/drivers/crypto/caam/caamalg_qi2.c +++ b/drivers/crypto/caam/caamalg_qi2.c @@ -22,7 +22,7 @@ #include <soc/fsl/dpaa2-io.h> #include <soc/fsl/dpaa2-fd.h> #include <crypto/xts.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define CAAM_CRA_PRIORITY 2000 diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c index 42677f7458b7..919e5a2cab95 100644 --- a/drivers/crypto/inside-secure/safexcel_cipher.c +++ b/drivers/crypto/inside-secure/safexcel_cipher.c @@ -5,7 +5,7 @@ * Antoine Tenart <antoine.tenart@free-electrons.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/dmapool.h> diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c index a235e6c300f1..69d6019d8abc 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c @@ -9,7 +9,7 @@ * Some ideas are from marvell/cesa.c and s5p-sss.c driver. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <linux/device.h> #include <linux/err.h> diff --git a/drivers/crypto/stm32/stm32-crc32.c b/drivers/crypto/stm32/stm32-crc32.c index b0cf6d2fd352..e0faddbf8990 100644 --- a/drivers/crypto/stm32/stm32-crc32.c +++ b/drivers/crypto/stm32/stm32-crc32.c @@ -17,7 +17,7 @@ #include <crypto/internal/hash.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "stm32-crc32" #define CHKSUM_DIGEST_SIZE 4 diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 946f8e44455f..5175138c4fb7 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -4,7 +4,7 @@ #include <linux/debugfs.h> #include <linux/ktime.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <cxlpci.h> #include <cxlmem.h> #include <cxl.h> diff --git a/drivers/cxl/core/trace.h b/drivers/cxl/core/trace.h index 9167cfba7f59..8672b42ee4d1 100644 --- a/drivers/cxl/core/trace.h +++ b/drivers/cxl/core/trace.h @@ -8,7 +8,7 @@ #include <linux/tracepoint.h> #include <linux/pci.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <cxl.h> #include <cxlmem.h> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 37164174b5fb..188412d45e0d 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2020 Intel Corporation. All rights reserved. */ -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/moduleparam.h> #include <linux/module.h> diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index a6538a5f5c9f..d2d43a4fc053 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2021 Intel Corporation. All rights reserved. */ #include <linux/libnvdimm.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/module.h> #include <linux/ndctl.h> diff --git a/drivers/cxl/security.c b/drivers/cxl/security.c index 452d1a9b9148..ab793e8577c7 100644 --- a/drivers/cxl/security.c +++ b/drivers/cxl/security.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ #include <linux/libnvdimm.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/module.h> #include <linux/async.h> #include <linux/slab.h> diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 7a4d1a478e33..1bf0e15c1540 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -28,7 +28,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/arp.h> #include <net/firewire.h> diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 6d9227db473f..c4b8e7ff88aa 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -22,7 +22,7 @@ #include <linux/spinlock.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "protocols.h" #include "notify.h" diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 8e95f53bd7b7..aaee57cdcd55 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -22,7 +22,7 @@ #include <linux/spinlock.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0) #define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 23b002e4d4a0..fde0656481cc 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -9,7 +9,7 @@ #include <linux/memblock.h> #include <linux/random.h> #include <asm/dmi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #ifndef SMBIOS_ENTRY_POINT_SCAN_START #define SMBIOS_ENTRY_POINT_SCAN_START 0xF0000 diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c index 0ec83ba58097..b815d2a754ee 100644 --- a/drivers/firmware/efi/fdtparams.c +++ b/drivers/firmware/efi/fdtparams.c @@ -8,7 +8,7 @@ #include <linux/libfdt.h> #include <linux/of_fdt.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> enum { SYSTAB, diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c index c96d6dcee86c..e7d9204baee3 100644 --- a/drivers/firmware/efi/libstub/riscv-stub.c +++ b/drivers/firmware/efi/libstub/riscv-stub.c @@ -7,7 +7,7 @@ #include <asm/efi.h> #include <asm/sections.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "efistub.h" diff --git a/drivers/firmware/efi/libstub/riscv.c b/drivers/firmware/efi/libstub/riscv.c index 8022b104c3e6..f66f33ceb99e 100644 --- a/drivers/firmware/efi/libstub/riscv.c +++ b/drivers/firmware/efi/libstub/riscv.c @@ -7,7 +7,7 @@ #include <linux/libfdt.h> #include <asm/efi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "efistub.h" diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c index 1ceace956758..af23b3c50228 100644 --- a/drivers/firmware/efi/libstub/zboot.c +++ b/drivers/firmware/efi/libstub/zboot.c @@ -3,7 +3,7 @@ #include <linux/efi.h> #include <linux/pe.h> #include <asm/efi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "efistub.h" diff --git a/drivers/fpga/microchip-spi.c b/drivers/fpga/microchip-spi.c index 2a82c726d6e5..6134cea86ac8 100644 --- a/drivers/fpga/microchip-spi.c +++ b/drivers/fpga/microchip-spi.c @@ -3,7 +3,7 @@ * Microchip Polarfire FPGA programming over slave SPI interface. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/fpga/fpga-mgr.h> #include <linux/iopoll.h> diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index f58b158d097c..a6d4c8f123a5 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -20,7 +20,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define OCC_SRAM_BYTES 4096 #define OCC_CMD_DATA_BYTES 4090 diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index 09715b506468..81d195d366ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -27,7 +27,7 @@ #include <linux/slab.h> #include <linux/string_helpers.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/drm_util.h> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index dee640ab1d3a..41f72d458487 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -47,7 +47,7 @@ #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cdns-mhdp8546-core.h" #include "cdns-mhdp8546-hdcp.h" diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c index 5e3b8edcf794..31832ba4017f 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c @@ -9,7 +9,7 @@ #include <linux/io.h> #include <linux/iopoll.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/display/drm_hdcp_helper.h> diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index e7e53a9e42af..430f8adebf9c 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -10,7 +10,7 @@ * Tomasz Figa <t.figa@samsung.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 6bb755e9f0a5..26b8d137bce0 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -6,7 +6,7 @@ * Andrzej Hajda <a.hajda@samsung.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/bridge/mhl.h> #include <drm/drm_bridge.h> diff --git a/drivers/gpu/drm/bridge/tc358775.c b/drivers/gpu/drm/bridge/tc358775.c index 3b7cc3be2ccd..0b4efaca6d68 100644 --- a/drivers/gpu/drm/bridge/tc358775.c +++ b/drivers/gpu/drm/bridge/tc358775.c @@ -19,7 +19,7 @@ #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/display/drm_dp_helper.h> #include <drm/drm_atomic_helper.h> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 84698a0b27a8..582cf4f73a74 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -21,7 +21,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/display/drm_dp_aux_bus.h> #include <drm/display/drm_dp_helper.h> diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index d8951464bd2b..f0e3be0fe420 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -32,7 +32,7 @@ #include <linux/slab.h> #include <linux/string_helpers.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> diff --git a/drivers/gpu/drm/nouveau/include/nvif/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h index a2eaf3929ac3..4a1123b81fee 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/os.h +++ b/drivers/gpu/drm/nouveau/include/nvif/os.h @@ -30,7 +30,7 @@ #include <linux/iommu.h> #include <linux/of_device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <soc/tegra/fuse.h> #include <soc/tegra/pmc.h> diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 5bc3e6b41c34..b31125eb9a65 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -27,7 +27,7 @@ #include <linux/slab.h> #include <linux/string_helpers.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/drm_device.h> #include <drm/drm_util.h> diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index 5ff1037a3453..62224992988f 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c @@ -7,7 +7,7 @@ * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "udl_drv.h" #include "udl_proto.h" diff --git a/drivers/greybus/es2.c b/drivers/greybus/es2.c index 69e46b1dff1f..7630a36ecf81 100644 --- a/drivers/greybus/es2.c +++ b/drivers/greybus/es2.c @@ -12,7 +12,7 @@ #include <linux/debugfs.h> #include <linux/list.h> #include <linux/greybus.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "arpc.h" #include "greybus_trace.h" diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c index 3a1ade84737c..473ac3f2d382 100644 --- a/drivers/greybus/gb-beagleplay.c +++ b/drivers/greybus/gb-beagleplay.c @@ -6,7 +6,7 @@ * Copyright (c) 2023 BeagleBoard.org Foundation */ -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc32.h> #include <linux/gpio/consumer.h> #include <linux/firmware.h> diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c index 669d769ea1dc..ba00f6e6324b 100644 --- a/drivers/hid/hid-alps.c +++ b/drivers/hid/hid-alps.c @@ -8,7 +8,7 @@ #include <linux/input.h> #include <linux/input/mt.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hid-ids.h" /* ALPS Device Product ID */ diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 30de92d0bf0f..612ee6ddfc8d 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -20,7 +20,7 @@ #include <linux/list.h> #include <linux/mm.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/byteorder.h> #include <linux/input.h> #include <linux/wait.h> diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index f9db991d3c5a..d2439399fb35 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c @@ -16,7 +16,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/byteorder.h> #include <linux/hid.h> diff --git a/drivers/hid/hid-goodix-spi.c b/drivers/hid/hid-goodix-spi.c index 0e59663814dd..0f87bf9c67cf 100644 --- a/drivers/hid/hid-goodix-spi.c +++ b/drivers/hid/hid-goodix-spi.c @@ -4,7 +4,7 @@ * * Copyright (C) 2024 Godix, Inc. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/hid.h> #include <linux/interrupt.h> diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index 4e79fafeeafa..22683ec819aa 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c @@ -23,7 +23,7 @@ #include <linux/platform_data/cros_ec_proto.h> #include <linux/platform_device.h> #include <linux/pm_wakeup.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hid-ids.h" #include "hid-vivaldi-common.h" diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index 32344331282f..bd96bfa7af70 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -8,7 +8,7 @@ * Copyright (c) 2023 David Yang */ -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/hid.h> #include <linux/module.h> diff --git a/drivers/hid/hid-letsketch.c b/drivers/hid/hid-letsketch.c index 229820fda960..8602c63ed9c6 100644 --- a/drivers/hid/hid-letsketch.c +++ b/drivers/hid/hid-letsketch.c @@ -41,7 +41,7 @@ #include <linux/timer.h> #include <linux/usb.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hid-ids.h" diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index d9580bc3e19a..34fa71ceec2b 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -13,7 +13,7 @@ #include <linux/kfifo.h> #include <linux/delay.h> #include <linux/usb.h> /* For to_usb_interface for kvm extra intf check */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hid-ids.h" #define DJ_MAX_PAIRED_DEVICES 7 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 0e33fa0eb8db..cf7a6986cf20 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -23,7 +23,7 @@ #include <linux/workqueue.h> #include <linux/atomic.h> #include <linux/fixp-arith.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "usbhid/usbhid.h" #include "hid-ids.h" diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c index 58cd0506e431..55153a2f7988 100644 --- a/drivers/hid/hid-nintendo.c +++ b/drivers/hid/hid-nintendo.c @@ -29,7 +29,7 @@ */ #include "hid-ids.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/kernel.h> diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index 0d90d7ee693c..1468fb11e39d 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -15,7 +15,7 @@ #include <linux/led-class-multicolor.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hid-ids.h" diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index df29c614e490..d2486f3734f0 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -40,7 +40,7 @@ #include <linux/crc32.h> #include <linux/usb.h> #include <linux/timer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hid-ids.h" diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c index 87fd4eb76c70..ef26c7defcf6 100644 --- a/drivers/hid/hid-uclogic-params.c +++ b/drivers/hid/hid-uclogic-params.c @@ -19,7 +19,7 @@ #include "hid-ids.h" #include <linux/ctype.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /** * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c index 964d17e08f26..9b9cbc2aae36 100644 --- a/drivers/hid/hid-uclogic-rdesc.c +++ b/drivers/hid/hid-uclogic-rdesc.c @@ -16,7 +16,7 @@ #include "hid-uclogic-rdesc.h" #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <kunit/visibility.h> /* Fixed WP4030U report descriptor */ diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 2f8a9d3f1e86..be5d342d5d13 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -36,7 +36,7 @@ #include <linux/kernel.h> #include <linux/hid.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <drm/drm_panel.h> diff --git a/drivers/hid/surface-hid/surface_hid.c b/drivers/hid/surface-hid/surface_hid.c index 61e5814b0ad7..eae47e0d95ed 100644 --- a/drivers/hid/surface-hid/surface_hid.c +++ b/drivers/hid/surface-hid/surface_hid.c @@ -8,7 +8,7 @@ * Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/hid.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/hid/surface-hid/surface_hid_core.c b/drivers/hid/surface-hid/surface_hid_core.c index a3e9cceddfac..6690c24f28f0 100644 --- a/drivers/hid/surface-hid/surface_hid_core.c +++ b/drivers/hid/surface-hid/surface_hid_core.c @@ -7,7 +7,7 @@ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/hid.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/hid/surface-hid/surface_kbd.c b/drivers/hid/surface-hid/surface_kbd.c index 8c0cbb2deb11..383200d9121a 100644 --- a/drivers/hid/surface-hid/surface_kbd.c +++ b/drivers/hid/surface-hid/surface_kbd.c @@ -7,7 +7,7 @@ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/hid.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index cb687ea7325c..a9e85bdd4cc6 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -21,7 +21,7 @@ #include <linux/mutex.h> #include <linux/property.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/byteorder.h> #include <linux/input.h> #include <linux/wait.h> diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 77c5fb26cd14..6f1443999d1d 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -89,7 +89,7 @@ #include <linux/usb/input.h> #include <linux/power_supply.h> #include <linux/timer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * Version Information diff --git a/drivers/hwmon/adt7310.c b/drivers/hwmon/adt7310.c index 25281739aa3b..6a834a37bc65 100644 --- a/drivers/hwmon/adt7310.c +++ b/drivers/hwmon/adt7310.c @@ -10,7 +10,7 @@ #include <linux/init.h> #include <linux/regmap.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "adt7x10.h" diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c index 8e55cd2f46f5..34cac27e4dde 100644 --- a/drivers/hwmon/aquacomputer_d5next.c +++ b/drivers/hwmon/aquacomputer_d5next.c @@ -22,7 +22,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/seq_file.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define USB_VENDOR_ID_AQUACOMPUTER 0x0c70 #define USB_PRODUCT_ID_AQUAERO 0xf001 diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index ee396f21fac5..9555366aeaf0 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -34,7 +34,7 @@ #include <linux/sort.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static char *mutex_path_override; diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c index f8b20346a995..e5e93a20723c 100644 --- a/drivers/hwmon/asus_rog_ryujin.c +++ b/drivers/hwmon/asus_rog_ryujin.c @@ -11,7 +11,7 @@ #include <linux/jiffies.h> #include <linux/module.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "asus_rog_ryujin" diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index f9b3a3030f13..f5bdf842040e 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c @@ -38,7 +38,7 @@ #include <linux/wmi.h> #include <linux/i8k.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define I8K_SMM_FN_STATUS 0x0025 #define I8K_SMM_POWER_STATUS 0x0069 diff --git a/drivers/hwmon/gigabyte_waterforce.c b/drivers/hwmon/gigabyte_waterforce.c index 8129d7b3ceaf..27487e215bdd 100644 --- a/drivers/hwmon/gigabyte_waterforce.c +++ b/drivers/hwmon/gigabyte_waterforce.c @@ -11,7 +11,7 @@ #include <linux/jiffies.h> #include <linux/module.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "gigabyte_waterforce" diff --git a/drivers/hwmon/nzxt-kraken2.c b/drivers/hwmon/nzxt-kraken2.c index 7caf387eb144..ed38645a1dc2 100644 --- a/drivers/hwmon/nzxt-kraken2.c +++ b/drivers/hwmon/nzxt-kraken2.c @@ -9,7 +9,7 @@ * Copyright 2019-2021 Jonas Malaco <jonas@protocubo.io> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/hid.h> #include <linux/hwmon.h> #include <linux/jiffies.h> diff --git a/drivers/hwmon/nzxt-kraken3.c b/drivers/hwmon/nzxt-kraken3.c index 00f3ac90a290..d00409bcab93 100644 --- a/drivers/hwmon/nzxt-kraken3.c +++ b/drivers/hwmon/nzxt-kraken3.c @@ -17,7 +17,7 @@ #include <linux/mutex.h> #include <linux/spinlock.h> #include <linux/wait.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define USB_VENDOR_ID_NZXT 0x1e71 #define USB_PRODUCT_ID_X53 0x2007 diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c index df6fa72a6b59..c2d1173f42fe 100644 --- a/drivers/hwmon/nzxt-smart2.c +++ b/drivers/hwmon/nzxt-smart2.c @@ -14,7 +14,7 @@ #include <linux/wait.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * The device has only 3 fan channels/connectors. But all HID reports have diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c index dd690f700d49..9486db249c64 100644 --- a/drivers/hwmon/occ/common.c +++ b/drivers/hwmon/occ/common.c @@ -12,7 +12,7 @@ #include <linux/mutex.h> #include <linux/property.h> #include <linux/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "common.h" diff --git a/drivers/hwmon/occ/p8_i2c.c b/drivers/hwmon/occ/p8_i2c.c index 31159606cec7..5817a099c622 100644 --- a/drivers/hwmon/occ/p8_i2c.c +++ b/drivers/hwmon/occ/p8_i2c.c @@ -8,7 +8,7 @@ #include <linux/jiffies.h> #include <linux/module.h> #include <linux/sched.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "common.h" diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index 9bcaa29a7191..541d808d62d0 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -16,7 +16,7 @@ #include <linux/pm_runtime.h> #include <linux/power_supply.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "i2c-ccgx-ucsi.h" diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index 0c9225d18fb2..eabaefa92f19 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -22,7 +22,7 @@ #include <linux/regmap.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "adxl355.h" diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c index 1c046e96aef9..e790a66d86c7 100644 --- a/drivers/iio/accel/adxl367.c +++ b/drivers/iio/accel/adxl367.c @@ -16,7 +16,7 @@ #include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "adxl367.h" diff --git a/drivers/iio/accel/adxl380.c b/drivers/iio/accel/adxl380.c index 98863e22bb6b..f80527d899be 100644 --- a/drivers/iio/accel/adxl380.c +++ b/drivers/iio/accel/adxl380.c @@ -13,7 +13,7 @@ #include <linux/regmap.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/events.h> diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 89db242f06e0..f4e43c3bbf1a 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -22,7 +22,7 @@ #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> diff --git a/drivers/iio/accel/bmi088-accel-core.c b/drivers/iio/accel/bmi088-accel-core.c index 469a1255d93c..fc1c1613d673 100644 --- a/drivers/iio/accel/bmi088-accel-core.c +++ b/drivers/iio/accel/bmi088-accel-core.c @@ -18,7 +18,7 @@ #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "bmi088-accel.h" diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c index 6644c1fec3e6..4ec70ca6910d 100644 --- a/drivers/iio/accel/dmard09.c +++ b/drivers/iio/accel/dmard09.c @@ -5,7 +5,7 @@ * Copyright (c) 2016, Jelle van der Waa <jelle@vdwaa.nl> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/module.h> #include <linux/i2c.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c index fca77d660625..ca0ce83e42b2 100644 --- a/drivers/iio/accel/sca3300.c +++ b/drivers/iio/accel/sca3300.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/adc/ad4130.c b/drivers/iio/adc/ad4130.c index e134d6497827..de32cc9d18c5 100644 --- a/drivers/iio/adc/ad4130.c +++ b/drivers/iio/adc/ad4130.c @@ -23,7 +23,7 @@ #include <linux/units.h> #include <asm/div64.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index e2bed2d648f2..ea4aabd3960a 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -23,7 +23,7 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/adc/ad_sigma_delta.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define AD_SD_COMM_CHAN_MASK 0x3 diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c index d43c8d124a0c..6c1a5d1b0a83 100644 --- a/drivers/iio/adc/axp20x_adc.c +++ b/drivers/iio/adc/axp20x_adc.c @@ -5,7 +5,7 @@ * Quentin Schulz <quentin.schulz@free-electrons.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/completion.h> #include <linux/interrupt.h> diff --git a/drivers/iio/adc/intel_mrfld_adc.c b/drivers/iio/adc/intel_mrfld_adc.c index 0590a126f321..30733252aa56 100644 --- a/drivers/iio/adc/intel_mrfld_adc.c +++ b/drivers/iio/adc/intel_mrfld_adc.c @@ -25,7 +25,7 @@ #include <linux/iio/iio.h> #include <linux/iio/machine.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define BCOVE_GPADCREQ 0xDC #define BCOVE_GPADCREQ_BUSY BIT(0) diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index f010b2fd1202..eb9d521e86e5 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -14,7 +14,7 @@ #include <linux/mod_devicetable.h> #include <linux/property.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ltc2497.h" diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index 2f07437caec3..520e37f75aac 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/driver.h> diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c index 45368850b220..f0dc4b460903 100644 --- a/drivers/iio/adc/max11410.c +++ b/drivers/iio/adc/max11410.c @@ -15,7 +15,7 @@ #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/sysfs.h> diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index 0778a8fb6866..50834fdcf738 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -19,7 +19,7 @@ #include <linux/mod_devicetable.h> #include <linux/delay.h> #include <linux/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c index d0e77971c5d3..b097f04172c8 100644 --- a/drivers/iio/adc/mcp3911.c +++ b/drivers/iio/adc/mcp3911.c @@ -23,7 +23,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/trigger.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define MCP3911_REG_CHANNEL0 0x00 #define MCP3911_REG_CHANNEL1 0x03 diff --git a/drivers/iio/adc/mt6360-adc.c b/drivers/iio/adc/mt6360-adc.c index e2ec805e834f..83161e6d29b9 100644 --- a/drivers/iio/adc/mt6360-adc.c +++ b/drivers/iio/adc/mt6360-adc.c @@ -16,7 +16,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define MT6360_REG_PMUCHGCTRL3 0x313 #define MT6360_REG_PMUADCCFG 0x356 diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c index 4c2a1c07bc39..36e813d9c73f 100644 --- a/drivers/iio/adc/pac1921.c +++ b/drivers/iio/adc/pac1921.c @@ -5,7 +5,7 @@ * Copyright (C) 2024 Matteo Martelli <matteomartelli3@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/i2c.h> #include <linux/iio/events.h> diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c index 8210728034d0..7ef249d83286 100644 --- a/drivers/iio/adc/pac1934.c +++ b/drivers/iio/adc/pac1934.c @@ -19,7 +19,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * maximum accumulation time should be (17 * 60 * 1000) around 17 minutes@1024 sps diff --git a/drivers/iio/adc/qcom-spmi-rradc.c b/drivers/iio/adc/qcom-spmi-rradc.c index 6aa70b4629a7..63ebaf13ef19 100644 --- a/drivers/iio/adc/qcom-spmi-rradc.c +++ b/drivers/iio/adc/qcom-spmi-rradc.c @@ -20,7 +20,7 @@ #include <linux/types.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/types.h> diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index 14941f384dad..425b48d8986f 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -21,7 +21,7 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Commands */ #define ADS124S08_CMD_NOP 0x00 diff --git a/drivers/iio/adc/ti-ads1298.c b/drivers/iio/adc/ti-ads1298.c index 13cb32125eef..0f9f75baaebb 100644 --- a/drivers/iio/adc/ti-ads1298.c +++ b/drivers/iio/adc/ti-ads1298.c @@ -23,7 +23,7 @@ #include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Commands */ #define ADS1298_CMD_WAKEUP 0x02 diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index 91a427eb0882..31f1f229d97a 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -23,7 +23,7 @@ #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Commands */ #define ADS131E08_CMD_RESET 0x06 diff --git a/drivers/iio/adc/ti-tsc2046.c b/drivers/iio/adc/ti-tsc2046.c index 311d97001249..b56f2503f14c 100644 --- a/drivers/iio/adc/ti-tsc2046.c +++ b/drivers/iio/adc/ti-tsc2046.c @@ -13,7 +13,7 @@ #include <linux/spi/spi.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/trigger_consumer.h> diff --git a/drivers/iio/addac/ad74115.c b/drivers/iio/addac/ad74115.c index 12dc43d487b4..3ee0dd5537c1 100644 --- a/drivers/iio/addac/ad74115.c +++ b/drivers/iio/addac/ad74115.c @@ -16,7 +16,7 @@ #include <linux/spi/spi.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index 2410d72da49b..69c586525d21 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -4,7 +4,7 @@ * Author: Cosmin Tanislav <cosmin.tanislav@analog.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/crc8.h> #include <linux/device.h> diff --git a/drivers/iio/amplifiers/ada4250.c b/drivers/iio/amplifiers/ada4250.c index 4b32d350dc5d..566f0e1c98a5 100644 --- a/drivers/iio/amplifiers/ada4250.c +++ b/drivers/iio/amplifiers/ada4250.c @@ -14,7 +14,7 @@ #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* ADA4250 Register Map */ #define ADA4250_REG_GAIN_MUX 0x00 diff --git a/drivers/iio/cdc/ad7746.c b/drivers/iio/cdc/ad7746.c index d11bc3496dda..ba18dbbe0940 100644 --- a/drivers/iio/cdc/ad7746.c +++ b/drivers/iio/cdc/ad7746.c @@ -16,7 +16,7 @@ #include <linux/stat.h> #include <linux/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c index 5d2e750ca2b9..0b96534c6867 100644 --- a/drivers/iio/chemical/bme680_core.c +++ b/drivers/iio/chemical/bme680_core.c @@ -19,7 +19,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "bme680.h" diff --git a/drivers/iio/chemical/pms7003.c b/drivers/iio/chemical/pms7003.c index 43025866d5b7..d0bd94912e0a 100644 --- a/drivers/iio/chemical/pms7003.c +++ b/drivers/iio/chemical/pms7003.c @@ -5,7 +5,7 @@ * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/completion.h> #include <linux/device.h> #include <linux/errno.h> diff --git a/drivers/iio/chemical/scd30_i2c.c b/drivers/iio/chemical/scd30_i2c.c index bd3b01ded246..b31dfaf52df9 100644 --- a/drivers/iio/chemical/scd30_i2c.c +++ b/drivers/iio/chemical/scd30_i2c.c @@ -13,7 +13,7 @@ #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "scd30.h" diff --git a/drivers/iio/chemical/scd30_serial.c b/drivers/iio/chemical/scd30_serial.c index 2adb76dbb020..55044f07d5a3 100644 --- a/drivers/iio/chemical/scd30_serial.c +++ b/drivers/iio/chemical/scd30_serial.c @@ -15,7 +15,7 @@ #include <linux/serdev.h> #include <linux/string.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "scd30.h" diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c index ca6b20270711..52cad54e8572 100644 --- a/drivers/iio/chemical/scd4x.c +++ b/drivers/iio/chemical/scd4x.c @@ -11,7 +11,7 @@ * https://www.sensirion.com/file/datasheet_scd4x */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc8.h> #include <linux/delay.h> #include <linux/device.h> diff --git a/drivers/iio/chemical/sps30_i2c.c b/drivers/iio/chemical/sps30_i2c.c index 5c31299813ec..1b21b6bcd0e7 100644 --- a/drivers/iio/chemical/sps30_i2c.c +++ b/drivers/iio/chemical/sps30_i2c.c @@ -6,7 +6,7 @@ * * I2C slave address: 0x69 */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc8.h> #include <linux/delay.h> #include <linux/device.h> diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index c69399ac6657..1b4287991d00 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -16,7 +16,7 @@ #include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/common/st_sensors.h> #include "st_sensors_core.h" diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c index bd37d304ca70..7d61b2fe6624 100644 --- a/drivers/iio/dac/ad3552r.c +++ b/drivers/iio/dac/ad3552r.c @@ -5,7 +5,7 @@ * * Copyright 2021 Analog Devices Inc. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 7712dc6be608..905988724f27 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -18,7 +18,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 8103d2cd13f6..708629efc157 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -22,7 +22,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define MODE_PWRDWN_1k 0x1 #define MODE_PWRDWN_100k 0x2 diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index 953fcfa2110b..1c996016756a 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -15,7 +15,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index fae5e5a0e72f..62e1fbb9e910 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -13,7 +13,7 @@ #include <linux/module.h> #include <linux/mod_devicetable.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4) diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 7e6f824de299..9304d0499bae 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -18,7 +18,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ad5624r.h" diff --git a/drivers/iio/dac/ad5766.c b/drivers/iio/dac/ad5766.c index 899894523752..f658ac8086aa 100644 --- a/drivers/iio/dac/ad5766.c +++ b/drivers/iio/dac/ad5766.c @@ -14,7 +14,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/module.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define AD5766_UPPER_WORD_SPI_MASK GENMASK(31, 16) #define AD5766_LOWER_WORD_SPI_MASK GENMASK(15, 0) diff --git a/drivers/iio/dac/ad7293.c b/drivers/iio/dac/ad7293.c index 06f05750d921..1d4032670482 100644 --- a/drivers/iio/dac/ad7293.c +++ b/drivers/iio/dac/ad7293.c @@ -16,7 +16,7 @@ #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define AD7293_R1B BIT(16) #define AD7293_R2B BIT(17) diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c index 3a3c4f4874e4..a4fb2509c950 100644 --- a/drivers/iio/dac/ltc2632.c +++ b/drivers/iio/dac/ltc2632.c @@ -13,7 +13,7 @@ #include <linux/property.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define LTC2632_CMD_WRITE_INPUT_N 0x0 #define LTC2632_CMD_UPDATE_DAC_N 0x1 diff --git a/drivers/iio/dac/mcp4821.c b/drivers/iio/dac/mcp4821.c index 782e8f6b7782..c1a59bbbba3c 100644 --- a/drivers/iio/dac/mcp4821.c +++ b/drivers/iio/dac/mcp4821.c @@ -23,7 +23,7 @@ #include <linux/iio/iio.h> #include <linux/iio/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define MCP4821_ACTIVE_MODE BIT(12) #define MCP4802_SECOND_CHAN BIT(15) diff --git a/drivers/iio/frequency/adf4377.c b/drivers/iio/frequency/adf4377.c index 25fbc2cef1f7..45ceeb828d6b 100644 --- a/drivers/iio/frequency/adf4377.c +++ b/drivers/iio/frequency/adf4377.c @@ -20,7 +20,7 @@ #include <linux/regmap.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* ADF4377 REG0000 Map */ #define ADF4377_0000_SOFT_RESET_R_MSK BIT(7) diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c index c0cd5d9844fe..8ef583680ad0 100644 --- a/drivers/iio/frequency/admv1013.c +++ b/drivers/iio/frequency/admv1013.c @@ -18,7 +18,7 @@ #include <linux/spi/spi.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* ADMV1013 Register Map */ #define ADMV1013_REG_SPI_CONTROL 0x00 diff --git a/drivers/iio/frequency/admv1014.c b/drivers/iio/frequency/admv1014.c index b46b73b89eb7..986b87a72577 100644 --- a/drivers/iio/frequency/admv1014.c +++ b/drivers/iio/frequency/admv1014.c @@ -19,7 +19,7 @@ #include <linux/spi/spi.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* ADMV1014 Register Map */ #define ADMV1014_REG_SPI_CONTROL 0x00 diff --git a/drivers/iio/frequency/admv4420.c b/drivers/iio/frequency/admv4420.c index 863ba8e98c95..3ae462b4f5c9 100644 --- a/drivers/iio/frequency/admv4420.c +++ b/drivers/iio/frequency/admv4420.c @@ -13,7 +13,7 @@ #include <linux/spi/spi.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* ADMV4420 Register Map */ #define ADMV4420_SPI_CONFIG_1 0x00 diff --git a/drivers/iio/frequency/adrf6780.c b/drivers/iio/frequency/adrf6780.c index 3f46032c9275..57ee908fc747 100644 --- a/drivers/iio/frequency/adrf6780.c +++ b/drivers/iio/frequency/adrf6780.c @@ -16,7 +16,7 @@ #include <linux/mod_devicetable.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* ADRF6780 Register Map */ #define ADRF6780_REG_CONTROL 0x00 diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c index 33cde9e6fca5..2535e3c94037 100644 --- a/drivers/iio/gyro/adis16130.c +++ b/drivers/iio/gyro/adis16130.c @@ -12,7 +12,7 @@ #include <linux/iio/iio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ADIS16130_CON 0x0 #define ADIS16130_CON_RD (1 << 6) diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index 85637e8ac45f..13e1dd4dd62c 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -23,7 +23,7 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "afe440x.h" diff --git a/drivers/iio/humidity/ens210.c b/drivers/iio/humidity/ens210.c index e9167574203a..77418d97f30d 100644 --- a/drivers/iio/humidity/ens210.c +++ b/drivers/iio/humidity/ens210.c @@ -22,7 +22,7 @@ #include <linux/module.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* register definitions */ #define ENS210_REG_PART_ID 0x00 diff --git a/drivers/iio/humidity/hdc3020.c b/drivers/iio/humidity/hdc3020.c index a82dcc3da421..ffb25596d3a8 100644 --- a/drivers/iio/humidity/hdc3020.c +++ b/drivers/iio/humidity/hdc3020.c @@ -26,7 +26,7 @@ #include <linux/regulator/consumer.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/events.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 876848b42f69..99410733c1ca 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -13,7 +13,7 @@ #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/imu/adis.h> diff --git a/drivers/iio/imu/bmi323/bmi323_core.c b/drivers/iio/imu/bmi323/bmi323_core.c index 671401ce80dc..beda8d2de53f 100644 --- a/drivers/iio/imu/bmi323/bmi323_core.c +++ b/drivers/iio/imu/bmi323/bmi323_core.c @@ -19,7 +19,7 @@ #include <linux/regulator/consumer.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/events.h> diff --git a/drivers/iio/light/apds9306.c b/drivers/iio/light/apds9306.c index 66a063ea3db4..079e02be1005 100644 --- a/drivers/iio/light/apds9306.c +++ b/drivers/iio/light/apds9306.c @@ -28,7 +28,7 @@ #include <linux/iio/events.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define APDS9306_MAIN_CTRL_REG 0x00 #define APDS9306_ALS_MEAS_RATE_REG 0x04 diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index b3f87dded040..81e718cdeae3 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -43,7 +43,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/events.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/light/ltr390.c b/drivers/iio/light/ltr390.c index 7e58b50f3660..4f6975e63a8f 100644 --- a/drivers/iio/light/ltr390.c +++ b/drivers/iio/light/ltr390.c @@ -27,7 +27,7 @@ #include <linux/iio/iio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define LTR390_MAIN_CTRL 0x00 #define LTR390_ALS_UVS_MEAS_RATE 0x04 diff --git a/drivers/iio/light/ltrf216a.c b/drivers/iio/light/ltrf216a.c index bc8444516689..37eecff571b9 100644 --- a/drivers/iio/light/ltrf216a.c +++ b/drivers/iio/light/ltrf216a.c @@ -26,7 +26,7 @@ #include <linux/iio/iio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define LTRF216A_ALS_RESET_MASK BIT(4) #define LTRF216A_ALS_DATA_STATUS BIT(3) diff --git a/drivers/iio/light/si1133.c b/drivers/iio/light/si1133.c index eeff6cc792f2..44fa152dbd24 100644 --- a/drivers/iio/light/si1133.c +++ b/drivers/iio/light/si1133.c @@ -17,7 +17,7 @@ #include <linux/util_macros.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SI1133_REG_PART_ID 0x00 #define SI1133_REG_REV_ID 0x01 diff --git a/drivers/iio/light/tsl2591.c b/drivers/iio/light/tsl2591.c index 7bdbfe72f0f0..850c2465992f 100644 --- a/drivers/iio/light/tsl2591.c +++ b/drivers/iio/light/tsl2591.c @@ -21,7 +21,7 @@ #include <linux/pm_runtime.h> #include <linux/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/events.h> #include <linux/iio/iio.h> diff --git a/drivers/iio/light/zopt2201.c b/drivers/iio/light/zopt2201.c index 327f94e447af..604be60e92ac 100644 --- a/drivers/iio/light/zopt2201.c +++ b/drivers/iio/light/zopt2201.c @@ -19,7 +19,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ZOPT2201_DRV_NAME "zopt2201" diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c index 0e03a772fa43..baab918b3825 100644 --- a/drivers/iio/magnetometer/rm3100-core.c +++ b/drivers/iio/magnetometer/rm3100-core.c @@ -22,7 +22,7 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/trigger_consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "rm3100.h" diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c index 7b041bb38693..65011a8598d3 100644 --- a/drivers/iio/magnetometer/yamaha-yas530.c +++ b/drivers/iio/magnetometer/yamaha-yas530.c @@ -43,7 +43,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Commonly used registers */ #define YAS5XX_DEVICE_ID 0x80 diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index da379230c837..a8b97b9b0461 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -46,7 +46,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "bmp280.h" diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c index c1cea9d40424..e99e97ea6300 100644 --- a/drivers/iio/pressure/dlhl60d.c +++ b/drivers/iio/pressure/dlhl60d.c @@ -15,7 +15,7 @@ #include <linux/iio/buffer.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Commands */ #define DLH_START_SINGLE 0xAA diff --git a/drivers/iio/pressure/hp206c.c b/drivers/iio/pressure/hp206c.c index 261af1562827..442740941933 100644 --- a/drivers/iio/pressure/hp206c.c +++ b/drivers/iio/pressure/hp206c.c @@ -18,7 +18,7 @@ #include <linux/delay.h> #include <linux/util_macros.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* I2C commands: */ #define HP206C_CMD_SOFT_RST 0x06 diff --git a/drivers/iio/pressure/hsc030pa.c b/drivers/iio/pressure/hsc030pa.c index 1682b90d4557..4e6f10eeabc3 100644 --- a/drivers/iio/pressure/hsc030pa.c +++ b/drivers/iio/pressure/hsc030pa.c @@ -28,7 +28,7 @@ #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hsc030pa.h" diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index 33a15d4c642c..3b6145348c2e 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -26,7 +26,7 @@ #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mprls0025pa.h" diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index 9a0f52321fcb..7e2cb8b6afa2 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -16,7 +16,7 @@ #include <linux/module.h> #include <linux/mod_devicetable.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ms5611.h" diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c index cc9d1f68c53c..87181963a3e3 100644 --- a/drivers/iio/pressure/ms5611_spi.c +++ b/drivers/iio/pressure/ms5611_spi.c @@ -11,7 +11,7 @@ #include <linux/spi/spi.h> #include <linux/mod_devicetable.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ms5611.h" diff --git a/drivers/iio/pressure/sdp500.c b/drivers/iio/pressure/sdp500.c index 6ff32e3fa637..9828c73c4855 100644 --- a/drivers/iio/pressure/sdp500.c +++ b/drivers/iio/pressure/sdp500.c @@ -10,7 +10,7 @@ #include <linux/iio/iio.h> #include <linux/mod_devicetable.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SDP500_CRC8_POLYNOMIAL 0x31 /* x8+x5+x4+1 (normalized to 0x31) */ #define SDP500_READ_SIZE 3 diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 80176e3083af..597bf268ea51 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -14,7 +14,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/common/st_sensors.h> #include "st_pressure.h" diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index dcc87a9015e8..950f8dee2b26 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -64,7 +64,7 @@ #include <linux/iio/trigger.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "zpa2326.h" /* 200 ms should be enough for the longest conversion time in one-shot mode. */ diff --git a/drivers/iio/proximity/aw96103.c b/drivers/iio/proximity/aw96103.c index db9d78e961fd..707ba0a510aa 100644 --- a/drivers/iio/proximity/aw96103.c +++ b/drivers/iio/proximity/aw96103.c @@ -17,7 +17,7 @@ #include <linux/regulator/consumer.h> #include <linux/regmap.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define AW_DATA_PROCESS_FACTOR 1024 #define AW96103_CHIP_ID 0xa961 diff --git a/drivers/iio/proximity/cros_ec_mkbp_proximity.c b/drivers/iio/proximity/cros_ec_mkbp_proximity.c index cff57d851762..c25472b14d4b 100644 --- a/drivers/iio/proximity/cros_ec_mkbp_proximity.c +++ b/drivers/iio/proximity/cros_ec_mkbp_proximity.c @@ -21,7 +21,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> struct cros_ec_mkbp_proximity_data { struct cros_ec_device *ec; diff --git a/drivers/iio/proximity/hx9023s.c b/drivers/iio/proximity/hx9023s.c index 8b9f84400e00..d8fb34060d3d 100644 --- a/drivers/iio/proximity/hx9023s.c +++ b/drivers/iio/proximity/hx9023s.c @@ -29,7 +29,7 @@ #include <linux/units.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/iio/buffer.h> #include <linux/iio/events.h> diff --git a/drivers/iio/proximity/irsd200.c b/drivers/iio/proximity/irsd200.c index 323ac6dac90e..6e96b764fed8 100644 --- a/drivers/iio/proximity/irsd200.c +++ b/drivers/iio/proximity/irsd200.c @@ -5,7 +5,7 @@ * Copyright (C) 2023 Axis Communications AB */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/i2c.h> #include <linux/module.h> diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c index 21f2cfc55bf8..f8ea2219ab48 100644 --- a/drivers/iio/temperature/ltc2983.c +++ b/drivers/iio/temperature/ltc2983.c @@ -22,7 +22,7 @@ #include <linux/spi/spi.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* register map */ #define LTC2983_STATUS_REG 0x0000 diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c index 8307aae2cb45..7ddec5cbe558 100644 --- a/drivers/iio/temperature/max31856.c +++ b/drivers/iio/temperature/max31856.c @@ -16,7 +16,7 @@ #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/util_macros.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <dt-bindings/iio/temperature/thermocouple.h> /* * The MSB of the register value determines whether the following byte will diff --git a/drivers/iio/temperature/max31865.c b/drivers/iio/temperature/max31865.c index 29e23652ba5a..5a6fbe3c80e5 100644 --- a/drivers/iio/temperature/max31865.c +++ b/drivers/iio/temperature/max31865.c @@ -18,7 +18,7 @@ #include <linux/iio/sysfs.h> #include <linux/property.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * The MSB of the register value determines whether the following byte will diff --git a/drivers/input/joystick/adafruit-seesaw.c b/drivers/input/joystick/adafruit-seesaw.c index 5c775ca886a5..c248c15b849d 100644 --- a/drivers/input/joystick/adafruit-seesaw.c +++ b/drivers/input/joystick/adafruit-seesaw.c @@ -15,7 +15,7 @@ * - Add interrupt support */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bits.h> #include <linux/delay.h> #include <linux/i2c.h> diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c index 02713e624df1..ff44f9978b71 100644 --- a/drivers/input/joystick/adc-joystick.c +++ b/drivers/input/joystick/adc-joystick.c @@ -11,7 +11,7 @@ #include <linux/platform_device.h> #include <linux/property.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> struct adc_joystick_axis { u32 code; diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 84b87526b7ba..55e6321adab9 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -6,7 +6,7 @@ * USB/RS232 I-Force joysticks and wheels. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "iforce.h" MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>"); diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 763642c8cee9..08c889a72f6c 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -6,7 +6,7 @@ * USB/RS232 I-Force joysticks and wheels. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "iforce.h" static struct { diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 49101f1c858b..4f2221001a95 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -16,7 +16,7 @@ #include <linux/module.h> #include <linux/input.h> #include <linux/serio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver" diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c index 707c5a8ae736..2c993fa8306a 100644 --- a/drivers/input/keyboard/applespi.c +++ b/drivers/input/keyboard/applespi.c @@ -57,7 +57,7 @@ #include <linux/workqueue.h> #include <asm/barrier.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define CREATE_TRACE_POINTS #include "applespi.h" diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 12eb9df180ee..4c81b20ff6af 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -27,7 +27,7 @@ #include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /** * struct cros_ec_keyb - Structure representing EC keyboard device diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 058f3470b7ae..4215f9b9c2b0 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -17,7 +17,7 @@ #include <linux/types.h> #include <linux/usb/input.h> #include <linux/usb/cdc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IMS_PCU_KEYMAP_LEN 32 diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index 9ca5a743f19f..be80a31de9f8 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -20,7 +20,7 @@ #include <linux/module.h> #include <linux/property.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IQS7222_PROD_NUM 0x00 #define IQS7222_PROD_NUM_A 840 diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c index 60c83bc71d84..fc3fb954523b 100644 --- a/drivers/input/mouse/cyapa_gen3.c +++ b/drivers/input/mouse/cyapa_gen3.c @@ -20,7 +20,7 @@ #include <linux/input/mt.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cyapa.h" diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c index 2e6bcb07257e..3b4439f10635 100644 --- a/drivers/input/mouse/cyapa_gen5.c +++ b/drivers/input/mouse/cyapa_gen5.c @@ -17,7 +17,7 @@ #include <linux/mutex.h> #include <linux/completion.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-itu-t.h> #include <linux/pm_runtime.h> #include "cyapa.h" diff --git a/drivers/input/mouse/cyapa_gen6.c b/drivers/input/mouse/cyapa_gen6.c index 4ffe08fee10c..570c06dcef78 100644 --- a/drivers/input/mouse/cyapa_gen6.c +++ b/drivers/input/mouse/cyapa_gen6.c @@ -17,7 +17,7 @@ #include <linux/mutex.h> #include <linux/completion.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-itu-t.h> #include "cyapa.h" diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index ce96513b34f6..7521981274bd 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -36,7 +36,7 @@ #include <linux/pm_wakeirq.h> #include <linux/property.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "elan_i2c.h" diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c index 13dc097eb6c6..15cf4463b64e 100644 --- a/drivers/input/mouse/elan_i2c_i2c.c +++ b/drivers/input/mouse/elan_i2c_i2c.c @@ -21,7 +21,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/sched.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "elan_i2c.h" diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b4723ea395eb..79ad98cc1e79 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -17,7 +17,7 @@ #include <linux/platform_device.h> #include <linux/serio.h> #include <linux/libps2.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "psmouse.h" #include "elantech.h" #include "elan_i2c.h" diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index cc1d4b424640..47be64284b25 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c @@ -9,7 +9,7 @@ #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/of.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "rmi_driver.h" #define RMI_PRODUCT_ID_LENGTH 10 diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c index 3b3ac71e53dc..e2468bc04a5c 100644 --- a/drivers/input/rmi4/rmi_f34.c +++ b/drivers/input/rmi4/rmi_f34.c @@ -7,7 +7,7 @@ #include <linux/kernel.h> #include <linux/rmi.h> #include <linux/firmware.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitops.h> #include "rmi_driver.h" diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c index 886557b01eba..fd49acc02071 100644 --- a/drivers/input/rmi4/rmi_f34v7.c +++ b/drivers/input/rmi4/rmi_f34v7.c @@ -13,7 +13,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/jiffies.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "rmi_driver.h" #include "rmi_f34.h" diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 2d176fbab251..2b3fbb0455d5 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -63,7 +63,7 @@ #include <linux/module.h> #include <linux/usb/input.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * Aiptek status packet: diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index 38d36d25f6f4..794caa102909 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c @@ -3,7 +3,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/usb/input.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * Pressure-threshold modules param code from Alex Perry <alex.perry@ieee.org> diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index f89c0dd15d8b..607f18af7010 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -30,7 +30,7 @@ #include <linux/spi/ads7846.h> #include <linux/regulator/consumer.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * This code has been heavily tested on a Nokia 770, and lightly diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index cfc92157701f..3ddabc5a2c99 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -26,7 +26,7 @@ #include <linux/slab.h> #include <linux/regulator/consumer.h> #include <linux/gpio/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> #include <media/videobuf2-v4l2.h> diff --git a/drivers/input/touchscreen/chipone_icn8505.c b/drivers/input/touchscreen/chipone_icn8505.c index c1b4fc28fa8d..cde0e4789503 100644 --- a/drivers/input/touchscreen/chipone_icn8505.c +++ b/drivers/input/touchscreen/chipone_icn8505.c @@ -8,7 +8,7 @@ * Hans de Goede <hdegoede@redhat.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/crc32.h> #include <linux/delay.h> diff --git a/drivers/input/touchscreen/cy8ctma140.c b/drivers/input/touchscreen/cy8ctma140.c index 567c9dcaac91..2d4b6e343203 100644 --- a/drivers/input/touchscreen/cy8ctma140.c +++ b/drivers/input/touchscreen/cy8ctma140.c @@ -16,7 +16,7 @@ * same. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/input.h> diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c index 3ca246ab192e..eafe5a9b8964 100644 --- a/drivers/input/touchscreen/cyttsp5.c +++ b/drivers/input/touchscreen/cyttsp5.c @@ -21,7 +21,7 @@ #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define CYTTSP5_NAME "cyttsp5" #define CY_I2C_DATA_SIZE (2 * 256) diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index e70415f189a5..fda49b2fe088 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -32,7 +32,7 @@ #include <linux/slab.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define WORK_REGISTER_THRESHOLD 0x00 #define WORK_REGISTER_REPORT_RATE 0x08 diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 48c69788b84a..87eb18977b71 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -21,7 +21,7 @@ #include <linux/gpio/consumer.h> #include <linux/of.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> struct eeti_ts { struct i2c_client *client; diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c index 365765d40e62..3fd170f75b4a 100644 --- a/drivers/input/touchscreen/elants_i2c.c +++ b/drivers/input/touchscreen/elants_i2c.c @@ -40,7 +40,7 @@ #include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> #include <linux/uuid.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Device, Driver information */ #define DEVICE_NAME "elants_i2c" diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c index 2e77cfb63f32..fdda8412b164 100644 --- a/drivers/input/touchscreen/exc3000.c +++ b/drivers/input/touchscreen/exc3000.c @@ -22,7 +22,7 @@ #include <linux/regulator/consumer.h> #include <linux/sizes.h> #include <linux/timer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define EXC3000_NUM_SLOTS 10 #define EXC3000_SLOTS_PER_FRAME 5 diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 435714f18c23..a3e8a51c9144 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -22,7 +22,7 @@ #include <linux/slab.h> #include <linux/acpi.h> #include <linux/of.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "goodix.h" #define GOODIX_GPIO_INT_NAME "irq" diff --git a/drivers/input/touchscreen/goodix_berlin_core.c b/drivers/input/touchscreen/goodix_berlin_core.c index 0bfca897ce5a..3fc03cf0ca23 100644 --- a/drivers/input/touchscreen/goodix_berlin_core.c +++ b/drivers/input/touchscreen/goodix_berlin_core.c @@ -31,7 +31,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/sizes.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "goodix_berlin.h" diff --git a/drivers/input/touchscreen/goodix_berlin_spi.c b/drivers/input/touchscreen/goodix_berlin_spi.c index a2d80e84391b..0662e87b8692 100644 --- a/drivers/input/touchscreen/goodix_berlin_spi.c +++ b/drivers/input/touchscreen/goodix_berlin_spi.c @@ -7,7 +7,7 @@ * * Based on goodix_ts_berlin driver. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/regmap.h> diff --git a/drivers/input/touchscreen/hideep.c b/drivers/input/touchscreen/hideep.c index 682abbbe5bd6..a73369e15dda 100644 --- a/drivers/input/touchscreen/hideep.c +++ b/drivers/input/touchscreen/hideep.c @@ -17,7 +17,7 @@ #include <linux/input/mt.h> #include <linux/input/touchscreen.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define HIDEEP_TS_NAME "HiDeep Touchscreen" #define HIDEEP_I2C_NAME "hideep_ts" diff --git a/drivers/input/touchscreen/hycon-hy46xx.c b/drivers/input/touchscreen/hycon-hy46xx.c index 2e01d87977c1..b2ff7a45b908 100644 --- a/drivers/input/touchscreen/hycon-hy46xx.c +++ b/drivers/input/touchscreen/hycon-hy46xx.c @@ -15,7 +15,7 @@ #include <linux/regulator/consumer.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define HY46XX_CHKSUM_CODE 0x1 #define HY46XX_FINGER_NUM 0x2 diff --git a/drivers/input/touchscreen/hynitron_cstxxx.c b/drivers/input/touchscreen/hynitron_cstxxx.c index f72834859282..1d8ca90dcda6 100644 --- a/drivers/input/touchscreen/hynitron_cstxxx.c +++ b/drivers/input/touchscreen/hynitron_cstxxx.c @@ -22,7 +22,7 @@ #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/property.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Per chip data */ struct hynitron_ts_chip_data { diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 4573844c3395..260c83dc23a2 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -12,7 +12,7 @@ #include <linux/module.h> #include <linux/sizes.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ILI2XXX_POLL_PERIOD 15 diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c index 5569641f05f6..0dd632724a00 100644 --- a/drivers/input/touchscreen/ilitek_ts_i2c.c +++ b/drivers/input/touchscreen/ilitek_ts_i2c.c @@ -19,7 +19,7 @@ #include <linux/errno.h> #include <linux/acpi.h> #include <linux/input/touchscreen.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ILITEK_TS_NAME "ilitek_ts" diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c index 4d226118f3cc..4ebd7565ae6e 100644 --- a/drivers/input/touchscreen/iqs5xx.c +++ b/drivers/input/touchscreen/iqs5xx.c @@ -26,7 +26,7 @@ #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IQS5XX_FW_FILE_LEN 64 #define IQS5XX_NUM_RETRIES 10 diff --git a/drivers/input/touchscreen/iqs7211.c b/drivers/input/touchscreen/iqs7211.c index f0a56cde899e..c5d447ee6f53 100644 --- a/drivers/input/touchscreen/iqs7211.c +++ b/drivers/input/touchscreen/iqs7211.c @@ -22,7 +22,7 @@ #include <linux/of_device.h> #include <linux/property.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IQS7211_PROD_NUM 0x00 diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c index b99a0e3c4084..a6946e3d8376 100644 --- a/drivers/input/touchscreen/melfas_mip4.c +++ b/drivers/input/touchscreen/melfas_mip4.c @@ -18,7 +18,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define MIP4_DEVICE_NAME "mip4_ts" diff --git a/drivers/input/touchscreen/novatek-nvt-ts.c b/drivers/input/touchscreen/novatek-nvt-ts.c index 1a797e410a3f..0afee41ac9de 100644 --- a/drivers/input/touchscreen/novatek-nvt-ts.c +++ b/drivers/input/touchscreen/novatek-nvt-ts.c @@ -15,7 +15,7 @@ #include <linux/input/touchscreen.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define NVT_TS_TOUCH_START 0x00 #define NVT_TS_TOUCH_SIZE 6 diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 4ede0687beb0..83bf27085ebc 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -5,7 +5,7 @@ * Copyright (C) 2010-2011 Pixcir, Inc. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index 92d75057de2d..f975b53e8825 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -24,7 +24,7 @@ #include <linux/pm_wakeirq.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Slave I2C mode */ #define RM_BOOT_BLDR 0x02 diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c index a529217e748f..e1518a75a51b 100644 --- a/drivers/input/touchscreen/s6sy761.c +++ b/drivers/input/touchscreen/s6sy761.c @@ -4,7 +4,7 @@ // Copyright (c) 2017 Samsung Electronics Co., Ltd. // Copyright (c) 2017 Andi Shyti <andi@etezian.org> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/i2c.h> #include <linux/input/mt.h> diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index 6a42b27c4599..5ccc96764742 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -24,7 +24,7 @@ #include <linux/irq.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SILEAD_TS_NAME "silead_ts" diff --git a/drivers/input/touchscreen/sis_i2c.c b/drivers/input/touchscreen/sis_i2c.c index 2023c6df416f..a625f2ad809d 100644 --- a/drivers/input/touchscreen/sis_i2c.c +++ b/drivers/input/touchscreen/sis_i2c.c @@ -15,7 +15,7 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SIS_I2C_NAME "sis_i2c_ts" diff --git a/drivers/input/touchscreen/surface3_spi.c b/drivers/input/touchscreen/surface3_spi.c index 7efbcd0fde4f..6074b7730e86 100644 --- a/drivers/input/touchscreen/surface3_spi.c +++ b/drivers/input/touchscreen/surface3_spi.c @@ -18,7 +18,7 @@ #include <linux/spi/spi.h> #include <linux/acpi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SURFACE3_PACKET_SIZE 264 diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index 486230985bf0..fd97a83f5664 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c @@ -13,7 +13,7 @@ #include <linux/slab.h> #include <linux/irq.h> #include <linux/interrupt.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Bitmasks (for data[3]) */ #define WACOM_TIP_SWITCH BIT(0) diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c index 698fc7e0ee7f..27941245e962 100644 --- a/drivers/input/touchscreen/wdt87xx_i2c.c +++ b/drivers/input/touchscreen/wdt87xx_i2c.c @@ -20,7 +20,7 @@ #include <linux/firmware.h> #include <linux/input/mt.h> #include <linux/acpi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define WDT87XX_NAME "wdt87xx_i2c" #define WDT87XX_FW_NAME "wdt87xx_fw.bin" diff --git a/drivers/input/touchscreen/zet6223.c b/drivers/input/touchscreen/zet6223.c index 27333fded9a9..943634ba9cd9 100644 --- a/drivers/input/touchscreen/zet6223.c +++ b/drivers/input/touchscreen/zet6223.c @@ -11,7 +11,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ZET6223_MAX_FINGERS 16 #define ZET6223_MAX_PKT_SIZE (3 + 4 * ZET6223_MAX_FINGERS) diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 4b8c4ebfff96..df42fdf36ae3 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -22,7 +22,7 @@ #include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define WAIT_TIMEOUT msecs_to_jiffies(1000) diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index 509b362d6465..044e4961376c 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -13,7 +13,7 @@ #include <linux/delay.h> #include <linux/mISDNhw.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ipac.h" diff --git a/drivers/leds/rgb/leds-mt6370-rgb.c b/drivers/leds/rgb/leds-mt6370-rgb.c index 359ef00498b4..10a0b5b45227 100644 --- a/drivers/leds/rgb/leds-mt6370-rgb.c +++ b/drivers/leds/rgb/leds-mt6370-rgb.c @@ -21,7 +21,7 @@ #include <linux/regmap.h> #include <linux/util_macros.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> enum { MT6370_LED_ISNK1 = 0, diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index 2633bc254935..126dd1cfba8e 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c @@ -19,7 +19,7 @@ #include <asm/macints.h> #include <asm/mac_iop.h> #include <asm/adb_iop.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/adb.h> diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 5228b03b6fe0..1ae2c71bb383 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -28,7 +28,7 @@ #include <linux/rbtree.h> #include <linux/ctype.h> #include <asm/page.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/hash.h> #include <crypto/md5.h> #include <crypto/skcipher.h> diff --git a/drivers/md/dm-vdo/murmurhash3.c b/drivers/md/dm-vdo/murmurhash3.c index 3a989efae142..13008b089206 100644 --- a/drivers/md/dm-vdo/murmurhash3.c +++ b/drivers/md/dm-vdo/murmurhash3.c @@ -8,7 +8,7 @@ #include "murmurhash3.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline u64 rotl64(u64 x, s8 r) { diff --git a/drivers/md/dm-vdo/numeric.h b/drivers/md/dm-vdo/numeric.h index dc8c400b21d2..f568dc59e6f1 100644 --- a/drivers/md/dm-vdo/numeric.h +++ b/drivers/md/dm-vdo/numeric.h @@ -6,7 +6,7 @@ #ifndef UDS_NUMERIC_H #define UDS_NUMERIC_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c index 91e9c378397c..930da176e5bf 100644 --- a/drivers/media/dvb-frontends/mxl5xx.c +++ b/drivers/media/dvb-frontends/mxl5xx.c @@ -21,7 +21,7 @@ #include <linux/mutex.h> #include <linux/vmalloc.h> #include <asm/div64.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/dvb_frontend.h> #include "mxl5xx.h" diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c index ed79075505e6..a696a0ec8ff5 100644 --- a/drivers/media/i2c/ccs/ccs-reg-access.c +++ b/drivers/media/i2c/ccs/ccs-reg-access.c @@ -9,7 +9,7 @@ * Contact: Sakari Ailus <sakari.ailus@linux.intel.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/i2c.h> diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index b440f386f062..f31f9886c924 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2019 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c index 52d9ca68a86c..172772decd3d 100644 --- a/drivers/media/i2c/hi846.c +++ b/drivers/media/i2c/hi846.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2021 Purism SPC -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> diff --git a/drivers/media/i2c/hi847.c b/drivers/media/i2c/hi847.c index 72c60747a839..546833f5b5f5 100644 --- a/drivers/media/i2c/hi847.c +++ b/drivers/media/i2c/hi847.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/delay.h> #include <linux/i2c.h> diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c index 639e05340dbb..2184c90f7864 100644 --- a/drivers/media/i2c/imx208.c +++ b/drivers/media/i2c/imx208.c @@ -8,7 +8,7 @@ #include <linux/pm_runtime.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IMX208_REG_MODE_SELECT 0x0100 #define IMX208_MODE_STANDBY 0x00 diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index 1a99eaaff21a..9e30fce1f223 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -12,7 +12,7 @@ #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IMX258_REG_MODE_SELECT CCI_REG8(0x0100) #define IMX258_MODE_STANDBY 0x00 diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index 4150e6e4b9a6..458905dfb3e1 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -18,7 +18,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/media-entity.h> #include <media/v4l2-cci.h> diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index 8fe3933f3146..dd1b4ff983dc 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (C) 2018 Intel Corporation -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/i2c.h> #include <linux/module.h> diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index 40863d87d341..a544fc3df39c 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -4,7 +4,7 @@ * * Copyright (C) 2021 Intel Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 54a1de53d497..fcfd1d851bd4 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -4,7 +4,7 @@ * * Copyright (C) 2021 Intel Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 0dd25eeea60b..b2dce67c0b6b 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (C) 2018 Intel Corporation -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/i2c.h> #include <linux/module.h> diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c index 7d1f7af0a9df..0bfe3046fcc8 100644 --- a/drivers/media/i2c/imx412.c +++ b/drivers/media/i2c/imx412.c @@ -4,7 +4,7 @@ * * Copyright (C) 2021 Intel Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index b37a2aaf8ac0..c84e1e0e6109 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -35,7 +35,7 @@ * Copyright (C) 2011 Andy Walls <awalls@md.metrocast.net> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c index e906435fc49a..78d5d406e4b7 100644 --- a/drivers/media/i2c/og01a1b.c +++ b/drivers/media/i2c/og01a1b.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov01a10.c b/drivers/media/i2c/ov01a10.c index 5606437f37d0..0b9fb1ddbe59 100644 --- a/drivers/media/i2c/ov01a10.c +++ b/drivers/media/i2c/ov01a10.c @@ -3,7 +3,7 @@ * Copyright (c) 2023 Intel Corporation. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/bitfield.h> diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 48df077522ad..7ead3c720e0e 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/i2c.h> #include <linux/module.h> diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index c48dbcde9877..bd0b2f0f0d45 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2020 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 2aee85965cf7..f051045d340f 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2017 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index 5b5127f8953f..2833b14ee139 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2019 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index 6ffe10e57b5b..3b94338f55ed 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2019 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c index 174c65f76886..326f50a5ab51 100644 --- a/drivers/media/i2c/ov8858.c +++ b/drivers/media/i2c/ov8858.c @@ -5,7 +5,7 @@ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c index 251a4b534914..9f52af6f047f 100644 --- a/drivers/media/i2c/ov9282.c +++ b/drivers/media/i2c/ov9282.c @@ -4,7 +4,7 @@ * * Copyright (C) 2021 Intel Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c index d99728597431..bf9e2adbff34 100644 --- a/drivers/media/i2c/ov9734.c +++ b/drivers/media/i2c/ov9734.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2020 Intel Corporation. -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/delay.h> #include <linux/i2c.h> diff --git a/drivers/media/i2c/thp7312.c b/drivers/media/i2c/thp7312.c index 75225ff5eff6..c77440ff098c 100644 --- a/drivers/media/i2c/thp7312.c +++ b/drivers/media/i2c/thp7312.c @@ -4,7 +4,7 @@ * Copyright (C) 2023 Ideas on Board Oy */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/media/i2c/vgxy61.c b/drivers/media/i2c/vgxy61.c index 30378e962016..409d2d4ffb4b 100644 --- a/drivers/media/i2c/vgxy61.c +++ b/drivers/media/i2c/vgxy61.c @@ -16,7 +16,7 @@ #include <linux/regulator/consumer.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/mipi-csi2.h> #include <media/v4l2-async.h> diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index 867c1308de23..365b04e5ae4d 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -24,7 +24,7 @@ #include <linux/firmware.h> #include <net/checksum.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/io.h> #include "bttvp.h" diff --git a/drivers/media/platform/chips-media/coda/coda-jpeg.c b/drivers/media/platform/chips-media/coda/coda-jpeg.c index ba8f41002917..5746892658b1 100644 --- a/drivers/media/platform/chips-media/coda/coda-jpeg.c +++ b/drivers/media/platform/chips-media/coda/coda-jpeg.c @@ -5,7 +5,7 @@ * Copyright (C) 2014 Philipp Zabel, Pengutronix */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/irqreturn.h> #include <linux/kernel.h> #include <linux/ktime.h> diff --git a/drivers/media/platform/renesas/rcar_jpu.c b/drivers/media/platform/renesas/rcar_jpu.c index fff349e45067..e50fe7525a73 100644 --- a/drivers/media/platform/renesas/rcar_jpu.c +++ b/drivers/media/platform/renesas/rcar_jpu.c @@ -14,7 +14,7 @@ * 3) V4L2_CID_JPEG_ACTIVE_MARKER */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/interrupt.h> diff --git a/drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c b/drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c index 9aea331e1a3c..e0d6bd0a6e44 100644 --- a/drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c @@ -5,7 +5,7 @@ * Copyright (C) 2018 Rockchip Electronics Co., Ltd. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <media/v4l2-mem2mem.h> #include "hantro.h" diff --git a/drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c b/drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c index 12d69503d6ba..86cc1a07026f 100644 --- a/drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c +++ b/drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c @@ -5,7 +5,7 @@ * Copyright (C) 2018 Rockchip Electronics Co., Ltd. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-mem2mem.h> #include "hantro_jpeg.h" #include "hantro.h" diff --git a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c index 8395c4d48dd0..61621b1be8a2 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c @@ -22,7 +22,7 @@ * zigzag, nor linear. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-mem2mem.h> #include "hantro_jpeg.h" #include "hantro.h" diff --git a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c index b66737fab46b..50a3a3eeaa00 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c @@ -5,7 +5,7 @@ * Copyright (C) 2018 Rockchip Electronics Co., Ltd. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <media/v4l2-mem2mem.h> #include "hantro.h" diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c index c3180d53c282..64c7452c05b5 100644 --- a/drivers/media/radio/radio-raremono.c +++ b/drivers/media/radio/radio-raremono.c @@ -12,7 +12,7 @@ #include <linux/hid.h> #include <linux/mutex.h> #include <linux/videodev2.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-ctrls.h> diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index e57ab54a27fc..2915c0023fcd 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -26,7 +26,7 @@ #include <media/v4l2-ctrls.h> #include <media/v4l2-event.h> #include <media/v4l2-device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c index 69e630d85262..533faa117517 100644 --- a/drivers/media/rc/ir_toy.c +++ b/drivers/media/rc/ir_toy.c @@ -12,7 +12,7 @@ * Copyright (C) 2011 Peter Kooiman <pkooiman@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/completion.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 9f2947af33aa..d89a4cfe3c89 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -31,7 +31,7 @@ * -- */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/device.h> #include <linux/leds.h> #include <linux/module.h> diff --git a/drivers/media/tuners/xc2028.c b/drivers/media/tuners/xc2028.c index 352b8a3679b7..8e6638e5f688 100644 --- a/drivers/media/tuners/xc2028.c +++ b/drivers/media/tuners/xc2028.c @@ -14,7 +14,7 @@ #include <media/tuner.h> #include <linux/mutex.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "tuner-i2c.h" #include "xc2028.h" #include "xc2028-types.h" diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c index 29bc63021c5a..3cf54d776d36 100644 --- a/drivers/media/tuners/xc4000.c +++ b/drivers/media/tuners/xc4000.c @@ -16,7 +16,7 @@ #include <linux/dvb/frontend.h> #include <linux/i2c.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/dvb_frontend.h> diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c index c88a202daf5f..a2054b1b100f 100644 --- a/drivers/media/usb/dvb-usb/m920x.c +++ b/drivers/media/usb/dvb-usb/m920x.c @@ -17,7 +17,7 @@ #include <media/tuner.h> #include "tuner-simple.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* debug */ static int dvb_usb_m920x_debug; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index f0febdc08c2d..0fac689c6350 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -19,7 +19,7 @@ #include <linux/videodev2.h> #include <linux/vmalloc.h> #include <linux/wait.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index cd9c29532fb0..e00f38dd07d9 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -18,7 +18,7 @@ #include <linux/vmalloc.h> #include <linux/wait.h> #include <linux/atomic.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-common.h> diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c index 1ff94affbaf3..e9ecf4785946 100644 --- a/drivers/media/v4l2-core/v4l2-cci.c +++ b/drivers/media/v4l2-core/v4l2-cci.c @@ -12,7 +12,7 @@ #include <linux/regmap.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-cci.h> diff --git a/drivers/media/v4l2-core/v4l2-jpeg.c b/drivers/media/v4l2-core/v4l2-jpeg.c index b8bece739d07..6e2647323522 100644 --- a/drivers/media/v4l2-core/v4l2-jpeg.c +++ b/drivers/media/v4l2-core/v4l2-jpeg.c @@ -9,7 +9,7 @@ * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c index 246876ac713c..ffdd8de9ec5d 100644 --- a/drivers/memstick/host/rtsx_usb_ms.c +++ b/drivers/memstick/host/rtsx_usb_ms.c @@ -19,7 +19,7 @@ #include <linux/mutex.h> #include <linux/sched.h> #include <linux/completion.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> struct rtsx_usb_ms { struct platform_device *pdev; diff --git a/drivers/mfd/gateworks-gsc.c b/drivers/mfd/gateworks-gsc.c index 6ca867b8f5f1..a3301502ce6a 100644 --- a/drivers/mfd/gateworks-gsc.c +++ b/drivers/mfd/gateworks-gsc.c @@ -20,7 +20,7 @@ #include <linux/platform_device.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * The GSC suffers from an errata where occasionally during diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c index 1b465590567c..ee017617d1d1 100644 --- a/drivers/mfd/iqs62x.c +++ b/drivers/mfd/iqs62x.c @@ -31,7 +31,7 @@ #include <linux/property.h> #include <linux/regmap.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define IQS62X_PROD_NUM 0x00 diff --git a/drivers/mfd/ntxec.c b/drivers/mfd/ntxec.c index 4416cd37e539..08c68de0f01b 100644 --- a/drivers/mfd/ntxec.c +++ b/drivers/mfd/ntxec.c @@ -21,7 +21,7 @@ #include <linux/reboot.h> #include <linux/regmap.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define NTXEC_REG_VERSION 0x00 #define NTXEC_REG_POWEROFF 0x50 diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c index ef326d6d566e..c1b78d127a26 100644 --- a/drivers/mfd/rave-sp.c +++ b/drivers/mfd/rave-sp.c @@ -21,7 +21,7 @@ #include <linux/of_platform.h> #include <linux/sched.h> #include <linux/serdev.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * UART protocol using following entities: diff --git a/drivers/mfd/si476x-cmd.c b/drivers/mfd/si476x-cmd.c index c9a0ec084aa8..3bb2decfebd3 100644 --- a/drivers/mfd/si476x-cmd.c +++ b/drivers/mfd/si476x-cmd.c @@ -20,7 +20,7 @@ #include <linux/mfd/si476x-core.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define msb(x) ((u8)((u16) x >> 8)) #define lsb(x) ((u8)((u16) x & 0x00FF)) diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index 587427b73914..bbe3967c3a4c 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -9,7 +9,7 @@ * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ctype.h> #include <linux/string.h> #include <linux/firmware.h> diff --git a/drivers/misc/bcm-vk/bcm_vk_sg.c b/drivers/misc/bcm-vk/bcm_vk_sg.c index 2e9daaf3e492..d309216ee181 100644 --- a/drivers/misc/bcm-vk/bcm_vk_sg.c +++ b/drivers/misc/bcm-vk/bcm_vk_sg.c @@ -9,7 +9,7 @@ #include <linux/vmalloc.h> #include <asm/page.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <uapi/linux/misc/bcm_vk.h> diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index 117b3c24f910..be3d4e0e50cc 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -19,7 +19,7 @@ #include <linux/mfd/core.h> #include <linux/rtsx_pci.h> #include <linux/mmc/card.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/pm.h> #include <linux/pm_runtime.h> diff --git a/drivers/misc/lattice-ecp3-config.c b/drivers/misc/lattice-ecp3-config.c index bac4df2e5231..93949df3bcff 100644 --- a/drivers/misc/lattice-ecp3-config.c +++ b/drivers/misc/lattice-ecp3-config.c @@ -11,7 +11,7 @@ #include <linux/spi/spi.h> #include <linux/platform_device.h> #include <linux/delay.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define FIRMWARE_NAME "lattice-ecp3.bit" diff --git a/drivers/misc/mei/platform-vsc.c b/drivers/misc/mei/platform-vsc.c index d02f6e881139..20a11b299bcd 100644 --- a/drivers/misc/mei/platform-vsc.c +++ b/drivers/misc/mei/platform-vsc.c @@ -19,7 +19,7 @@ #include <linux/types.h> #include <asm-generic/bug.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include "mei_dev.h" #include "vsc-tp.h" diff --git a/drivers/misc/mei/vsc-fw-loader.c b/drivers/misc/mei/vsc-fw-loader.c index 084d0205f97d..9f129bc641f6 100644 --- a/drivers/misc/mei/vsc-fw-loader.c +++ b/drivers/misc/mei/vsc-fw-loader.c @@ -15,7 +15,7 @@ #include <linux/string_helpers.h> #include <linux/types.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include "vsc-tp.h" diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 6490df54a6f5..cdbd2edf4b2e 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -37,7 +37,7 @@ #include <asm/cacheflush.h> #include <asm/io.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ATMCI_MAX_NR_SLOTS 2 diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index c9caa1ece7ef..8fee7052f2ef 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -26,7 +26,7 @@ #include <linux/spi/spi.h> #include <linux/spi/mmc_spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* NOTES: diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index af7f21888e27..d859b1a3ab71 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -22,7 +22,7 @@ #include <linux/mmc/slot-gpio.h> #include <linux/sizes.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mvsdio.h" diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 7dfe7c4e0077..20e79109be16 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -20,7 +20,7 @@ #include <linux/mmc/sdio.h> #include <linux/mmc/card.h> #include <linux/rtsx_pci.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/pm_runtime.h> struct realtek_pci_sdmmc { diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index ded9b6849e35..4e86f0a705b6 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -21,7 +21,7 @@ #include <linux/pm_runtime.h> #include <linux/rtsx_usb.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \ defined(CONFIG_MMC_REALTEK_USB_MODULE)) diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index 78174c463b36..f0f0522b2fa2 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -22,7 +22,7 @@ #include <linux/slab.h> #include <linux/types.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define EBU_CLC 0x000 #define EBU_CLC_RST 0x00000000u diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 26648b72e691..aa113a5d88c8 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -84,7 +84,7 @@ #include <linux/slab.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 3e7526274e34..3bc56517fe7a 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -12,7 +12,7 @@ // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> // -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/clk.h> #include <linux/device.h> diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c index 65150e762007..8c5be8d1c519 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c @@ -8,7 +8,7 @@ #include "mcp251xfd.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> static const struct regmap_config mcp251xfd_regmap_crc; diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c index 83c18035b2a2..e684991fa391 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c @@ -12,7 +12,7 @@ // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> // -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mcp251xfd.h" #include "mcp251xfd-ram.h" diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c index b1de8052a45c..747ae3e8a768 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c @@ -12,7 +12,7 @@ // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> // -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include "mcp251xfd.h" diff --git a/drivers/net/can/usb/etas_es58x/es581_4.c b/drivers/net/can/usb/etas_es58x/es581_4.c index 4151b18fd045..1888ca1de7b6 100644 --- a/drivers/net/can/usb/etas_es58x/es581_4.c +++ b/drivers/net/can/usb/etas_es58x/es581_4.c @@ -9,7 +9,7 @@ * Copyright (c) 2020-2022 Vincent Mailhol <mailhol.vincent@wanadoo.fr> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/units.h> diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 5e3a72b7c469..71f24dc0a927 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -10,7 +10,7 @@ * Copyright (c) 2020-2022 Vincent Mailhol <mailhol.vincent@wanadoo.fr> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc16.h> #include <linux/ethtool.h> #include <linux/kernel.h> diff --git a/drivers/net/can/usb/etas_es58x/es58x_fd.c b/drivers/net/can/usb/etas_es58x/es58x_fd.c index fa87b0b78e3e..84ffa1839bac 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_fd.c +++ b/drivers/net/can/usb/etas_es58x/es58x_fd.c @@ -11,7 +11,7 @@ * Copyright (c) 2020-2022 Vincent Mailhol <mailhol.vincent@wanadoo.fr> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/units.h> diff --git a/drivers/net/can/usb/f81604.c b/drivers/net/can/usb/f81604.c index ec8cef7fd2d5..bc0c8903fe77 100644 --- a/drivers/net/can/usb/f81604.c +++ b/drivers/net/can/usb/f81604.c @@ -13,7 +13,7 @@ #include <linux/can/error.h> #include <linux/can/platform/sja1000.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> /* vendor and product id */ #define F81604_VENDOR_ID 0x2c42 diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c index 47619e9cb005..41c0a1c399bf 100644 --- a/drivers/net/can/usb/mcba_usb.c +++ b/drivers/net/can/usb/mcba_usb.c @@ -6,7 +6,7 @@ * This driver is inspired by the 4.6.2 version of net/can/usb/usb_8dev.c */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/can.h> #include <linux/can/dev.h> #include <linux/can/error.h> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index b211b6e283a2..c75df1755b3b 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -8,7 +8,7 @@ * * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ethtool.h> #include <linux/module.h> diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 308f15d3832e..467da057579e 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -16,7 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/kernel.h> diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c index e3e341431f09..1c6652f2b9fe 100644 --- a/drivers/net/dsa/microchip/ksz_spi.c +++ b/drivers/net/dsa/microchip/ksz_spi.c @@ -6,7 +6,7 @@ * Tristram Ha <Tristram.Ha@microchip.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/kernel.h> diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c index 3431a7e62b0d..a98b3139606a 100644 --- a/drivers/net/ethernet/adi/adin1110.c +++ b/drivers/net/ethernet/adi/adin1110.c @@ -26,7 +26,7 @@ #include <net/switchdev.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ADIN1110_PHY_ID 0x1 diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c index 484fc2b5626f..ca163c8e3729 100644 --- a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c +++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #define pr_fmt(fmt) "bcmasp_ethtool: " fmt -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <linux/ethtool.h> #include <linux/netdevice.h> #include <linux/platform_device.h> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index c7e7dac057a3..f7be886570d8 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -37,7 +37,7 @@ #include <linux/phy.h> #include <linux/platform_data/bcmgenet.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "bcmgenet.h" diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c index cd3dc4b89518..0a161a4db242 100644 --- a/drivers/net/ethernet/dec/tulip/de2104x.c +++ b/drivers/net/ethernet/dec/tulip/de2104x.c @@ -49,7 +49,7 @@ #include <asm/io.h> #include <asm/irq.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>"); MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver"); diff --git a/drivers/net/ethernet/dec/tulip/eeprom.c b/drivers/net/ethernet/dec/tulip/eeprom.c index d5657ff15e3c..71ff9e6db209 100644 --- a/drivers/net/ethernet/dec/tulip/eeprom.c +++ b/drivers/net/ethernet/dec/tulip/eeprom.c @@ -13,7 +13,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include "tulip.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> diff --git a/drivers/net/ethernet/dec/tulip/tulip.h b/drivers/net/ethernet/dec/tulip/tulip.h index bd786dfbc066..5e010e1fa6f7 100644 --- a/drivers/net/ethernet/dec/tulip/tulip.h +++ b/drivers/net/ethernet/dec/tulip/tulip.h @@ -23,7 +23,7 @@ #include <linux/pci.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index ecfad43df45a..27e01d780cd0 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -23,7 +23,7 @@ #include <linux/delay.h> #include <linux/mii.h> #include <linux/crc32.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/uaccess.h> #ifdef CONFIG_SPARC diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index 11b14555802c..8f6b0bf48139 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* Copyright 2017-2019 NXP */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/mdio.h> #include <linux/module.h> #include <linux/fsl/enetc_mdio.h> diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index aa139b67a55b..3a5bbda235cb 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -146,7 +146,7 @@ #include <linux/string.h> #include <linux/firmware.h> #include <linux/rtnetlink.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRV_NAME "e100" diff --git a/drivers/net/ethernet/intel/ice/ice_fw_update.c b/drivers/net/ethernet/intel/ice/ice_fw_update.c index f81db6c107c8..2702a0da5c3e 100644 --- a/drivers/net/ethernet/intel/ice/ice_fw_update.c +++ b/drivers/net/ethernet/intel/ice/ice_fw_update.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2018-2019, Intel Corporation. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/uuid.h> #include <linux/crc32.h> #include <linux/pldmfw.h> diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c index ea0884186d76..c06e5ad18b01 100644 --- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c +++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c @@ -10,7 +10,7 @@ #include <linux/of_reserved_mem.h> #include <linux/mfd/syscon.h> #include <linux/soc/mediatek/mtk_wed.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mtk_wed_regs.h" #include "mtk_wed_wo.h" diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c b/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c index ef05ae8f5039..0072d612215e 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) Meta Platforms, Inc. and affiliates. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/pci.h> #include <linux/types.h> #include <net/devlink.h> diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c index cc54faca2283..515069d5637b 100644 --- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c +++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c @@ -6,7 +6,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/netdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ktime.h> #include <net/xfrm.h> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c index 3f10c5365c80..7c2200b49ce4 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c @@ -15,7 +15,7 @@ * abstraction builds upon this BAR interface. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/kref.h> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index a8286d0032d1..669f9f8fb507 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -9,7 +9,7 @@ * Rolf Neugebauer <rolf.neugebauer@netronome.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/ioport.h> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c index 508ae6b571ca..addf02c63b1a 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c @@ -9,7 +9,7 @@ * Rolf Neugebauer <rolf.neugebauer@netronome.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/delay.h> #include <linux/kernel.h> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c index f05dd34ab89f..cfa4db5d3f85 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c @@ -15,7 +15,7 @@ */ #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/delay.h> #include <linux/log2.h> #include <linux/kernel.h> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c index df0234a338a8..0bd6477292a6 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c @@ -7,7 +7,7 @@ * Jason McMullan <jason.mcmullan@netronome.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/delay.h> #include <linux/firmware.h> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c index 2260c2403a83..68862ac062d2 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c @@ -10,7 +10,7 @@ * Francois H. Theron <francois.theron@netronome.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c index 1cc001087193..a36d422b5173 100644 --- a/drivers/net/ethernet/packetengines/hamachi.c +++ b/drivers/net/ethernet/packetengines/hamachi.c @@ -163,7 +163,7 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; #include <linux/uaccess.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/io.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/cache.h> static const char version[] = diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c index 640ac01689fb..c0515dc63246 100644 --- a/drivers/net/ethernet/packetengines/yellowfin.c +++ b/drivers/net/ethernet/packetengines/yellowfin.c @@ -102,7 +102,7 @@ static int gx_fix; #include <linux/bitops.h> #include <linux/uaccess.h> #include <asm/processor.h> /* Processor type for cache alignment. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/io.h> /* These identify the driver base version and may not be removed. */ diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 305ec19ccef1..0cc9baaecb1b 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -28,7 +28,7 @@ #include <linux/bitfield.h> #include <linux/prefetch.h> #include <linux/ipv6.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/ip6_checksum.h> #include <net/netdev_queues.h> diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index 15cb96c2506d..f30d4b17c7fb 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -18,7 +18,7 @@ #include <linux/crc32.h> #include <linux/slab.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "smsc9420.h" #define DRV_NAME "smsc9420" diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index a94d8dd71aad..2b7034193a00 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -16,7 +16,7 @@ #include <linux/skbuff.h> #include <linux/ieee802154.h> #include <linux/crc-ccitt.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac802154.h> #include <net/cfg802154.h> diff --git a/drivers/net/mctp/mctp-i3c.c b/drivers/net/mctp/mctp-i3c.c index 8e989c157caa..1bc87a062686 100644 --- a/drivers/net/mctp/mctp-i3c.c +++ b/drivers/net/mctp/mctp-i3c.c @@ -13,7 +13,7 @@ #include <linux/i3c/device.h> #include <linux/i3c/master.h> #include <linux/if_arp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mctp.h> #include <net/mctpdevice.h> diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c index 3cdc8c6b30b6..8d076b9609fd 100644 --- a/drivers/net/phy/air_en8811h.c +++ b/drivers/net/phy/air_en8811h.c @@ -15,7 +15,7 @@ #include <linux/firmware.h> #include <linux/property.h> #include <linux/wordpart.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define EN8811H_PHY_ID 0x03a2a411 diff --git a/drivers/net/phy/aquantia/aquantia_firmware.c b/drivers/net/phy/aquantia/aquantia_firmware.c index dac6464b5fe2..dab3af80593f 100644 --- a/drivers/net/phy/aquantia/aquantia_firmware.c +++ b/drivers/net/phy/aquantia/aquantia_firmware.c @@ -6,7 +6,7 @@ #include <linux/crc-itu-t.h> #include <linux/nvmem-consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "aquantia.h" diff --git a/drivers/net/phy/bcm-phy-ptp.c b/drivers/net/phy/bcm-phy-ptp.c index 874a1b64b115..208e8f561e06 100644 --- a/drivers/net/phy/bcm-phy-ptp.c +++ b/drivers/net/phy/bcm-phy-ptp.c @@ -4,7 +4,7 @@ * Copyright (C) 2022 Jonathan Lemon <jonathan.lemon@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/mii.h> #include <linux/phy.h> #include <linux/ptp_classify.h> diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c index c1ddae36a2ae..738a8822fcf0 100644 --- a/drivers/net/phy/mscc/mscc_ptp.c +++ b/drivers/net/phy/mscc/mscc_ptp.c @@ -15,7 +15,7 @@ #include <linux/ptp_classify.h> #include <linux/ptp_clock_kernel.h> #include <linux/udp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mscc.h" #include "mscc_ptp.h" diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index c33c3db3cc08..a940b9a67107 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -29,7 +29,7 @@ #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/uaccess.h> #include <asm/string.h> diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c index 4d2ff63f2ee2..d93aeacc0dba 100644 --- a/drivers/net/ppp/ppp_deflate.c +++ b/drivers/net/ppp/ppp_deflate.c @@ -16,7 +16,7 @@ #include <linux/ppp-comp.h> #include <linux/zlib.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * State for a Deflate (de)compressor. diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 4b2971e2bf48..453f8437afe8 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -44,7 +44,7 @@ #include <linux/mutex.h> #include <linux/slab.h> #include <linux/file.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/slhc_vj.h> #include <linux/atomic.h> #include <linux/refcount.h> diff --git a/drivers/net/ppp/ppp_mppe.c b/drivers/net/ppp/ppp_mppe.c index 208f6e24f37c..bcc1eaedf58f 100644 --- a/drivers/net/ppp/ppp_mppe.c +++ b/drivers/net/ppp/ppp_mppe.c @@ -56,7 +56,7 @@ #include <linux/ppp_defs.h> #include <linux/ppp-comp.h> #include <linux/scatterlist.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ppp_mppe.h" diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 45bf59ac8f57..644e99fc3623 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -43,7 +43,7 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/refcount.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/uaccess.h> #define PPP_VERSION "2.4.2" diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index 18df7ca66198..252cd757d3a2 100644 --- a/drivers/net/slip/slhc.c +++ b/drivers/net/slip/slhc.c @@ -77,7 +77,7 @@ #include <linux/timer.h> #include <linux/uaccess.h> #include <net/checksum.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static unsigned char *encode(unsigned char *cp, unsigned short n); static long decode(unsigned char **cpp); diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index b0c0c9dd6a02..5d4a1fd2b524 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c @@ -17,7 +17,7 @@ #include <linux/usb/usbnet.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 673d3aa83792..3d239b8d1a1b 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -30,7 +30,7 @@ static const char driver_name[] = "sierra_net"; #include <linux/usb/cdc.h> #include <net/ip.h> #include <net/udp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb/usbnet.h> #define SWI_USB_REQUEST_GET_FW_ATTR 0x06 diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index abe41330fb69..4d88b02ffa79 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -59,7 +59,7 @@ #include <net/cfg80211.h> #include <net/ieee80211_radiotap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac80211.h> #include "base.h" diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index eea4bda77608..d81b2ad0b095 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -44,7 +44,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ath5k.h" #include "base.h" diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 3f4ce4e9c532..90e0859a8e50 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -24,7 +24,7 @@ * Protocol Control Unit Functions * \*********************************/ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ath5k.h" #include "reg.h" diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 7ee4e1616f45..4825f9cb9cb8 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -27,7 +27,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/sort.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ath5k.h" #include "reg.h" diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 9fdb5283b39c..c67f163c0858 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -25,7 +25,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/pci.h> /* To determine if a card is pci-e */ #include <linux/log2.h> diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index fb5144e2d86c..f8a94d764be6 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -21,7 +21,7 @@ #include "hif-ops.h" #include "trace.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 944f46cdf34c..73c38a6b4880 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include "hw.h" #include "ar9003_phy.h" diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 51abc470125b..eff894958a73 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -17,7 +17,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ath9k.h" diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 27b860b0c769..3e16cfe059f3 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hw.h" #include "ar9002_phy.h" diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index d85472ee4d85..c139ac49ccf6 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hw.h" #include "ar9002_phy.h" diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 84b31caf8ca6..5ba467cb7425 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hw.h" #include "ar9002_phy.h" diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index a3733c9b484e..7265766cddbd 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "htc.h" MODULE_FIRMWARE(HTC_7010_MODULE_FW); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 04a4b9ea61c3..c3a6368bfc68 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -21,7 +21,7 @@ #include <linux/bitops.h> #include <linux/etherdevice.h> #include <linux/gpio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hw.h" #include "hw-ops.h" diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index 6cdbee5beb07..20ceed0dd4be 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -36,7 +36,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "carl9170.h" #include "cmd.h" diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index 85955572a705..b301e6fbce6c 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c @@ -15,7 +15,7 @@ */ #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ath.h" #include "reg.h" diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 21a93fec284d..0ae436bd9b66 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -16,7 +16,7 @@ */ #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac80211.h> #include "ath.h" diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 8e56dcf9309d..25b4ef9d3c9a 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -30,7 +30,7 @@ #include <linux/io.h> #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "b43.h" #include "main.h" diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index 441d6440671b..2370a2e6a2e3 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -27,7 +27,7 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> #include <net/dst.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "b43legacy.h" #include "main.h" diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h index 9ca1b2aadcb5..eed439b84010 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h @@ -7,7 +7,7 @@ #ifndef FWEH_H_ #define FWEH_H_ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/skbuff.h> #include <linux/if_ether.h> #include <linux/if.h> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index ce482a3877e9..5dee54819fbd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -16,7 +16,7 @@ #include <linux/kthread.h> #include <linux/io.h> #include <linux/random.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <soc.h> #include <chipcommon.h> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 1461dc453ac2..7b936668c1b6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -23,7 +23,7 @@ #include <linux/bcma/bcma.h> #include <linux/debugfs.h> #include <linux/vmalloc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <defs.h> #include <brcmu_wifi.h> #include <brcmu_utils.h> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c index 2f8908074303..08841b9a5b81 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c @@ -3,7 +3,7 @@ * Copyright (c) 2019 Broadcom */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/math.h> #include <linux/string.h> diff --git a/drivers/net/wireless/intel/iwlegacy/3945.c b/drivers/net/wireless/intel/iwlegacy/3945.c index e95800b77f6b..14d2331ee6cb 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945.c +++ b/drivers/net/wireless/intel/iwlegacy/3945.c @@ -20,7 +20,7 @@ #include <linux/netdevice.h> #include <linux/firmware.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac80211.h> #include "common.h" diff --git a/drivers/net/wireless/intel/iwlegacy/4965.c b/drivers/net/wireless/intel/iwlegacy/4965.c index c34729f576cd..b63e29590b04 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965.c +++ b/drivers/net/wireless/intel/iwlegacy/4965.c @@ -20,7 +20,7 @@ #include <linux/units.h> #include <net/mac80211.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "common.h" #include "4965.h" diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c index 71f67a019cf6..5ca85d90a8d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -13,7 +13,7 @@ #include <linux/netdevice.h> #include <net/mac80211.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "iwl-io.h" #include "iwl-trans.h" #include "iwl-modparams.h" diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c index e9d2717362cf..7f67e602940c 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c @@ -13,7 +13,7 @@ #include <linux/slab.h> #include <linux/sched.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "iwl-trans.h" #include "iwl-io.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 047c020f8efa..1a0b5f8d4339 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -4,7 +4,7 @@ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include "iwl-trans.h" diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c index b700c213d10c..afe9bcd3ad46 100644 --- a/drivers/net/wireless/marvell/libertas/cfg.c +++ b/drivers/net/wireless/marvell/libertas/cfg.c @@ -15,7 +15,7 @@ #include <linux/slab.h> #include <linux/ieee80211.h> #include <net/cfg80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "decl.h" #include "cfg.h" diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/marvell/libertas/cmdresp.c index 74cb7551f427..f2aa659e7714 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -8,7 +8,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/sched.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/cfg80211.h> #include "cfg.h" diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c index 7894102f03eb..1cff001bdc51 100644 --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -5,7 +5,7 @@ * Copyright 2011-2020 NXP */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "decl.h" #include "ioctl.h" #include "util.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c index bcd24c9072ec..4de45a56812d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c @@ -10,7 +10,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mt76x0.h" #include "eeprom.h" #include "../mt76x02_phy.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c index 5d402cf2951c..a5e3392c0b48 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c @@ -4,7 +4,7 @@ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mt76x02_eeprom.h" diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c index 1fe5f5a02f93..156b16c17b2b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c @@ -5,7 +5,7 @@ #include <linux/module.h> #include <linux/of.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mt76x2.h" #include "eeprom.h" diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.h b/drivers/net/wireless/mediatek/mt7601u/dma.h index 81e559ec1c7b..cda9c267516e 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.h +++ b/drivers/net/wireless/mediatek/mt7601u/dma.h @@ -7,7 +7,7 @@ #ifndef __MT7601U_DMA_H #define __MT7601U_DMA_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/skbuff.h> #define MT_DMA_HDR_LEN 4 diff --git a/drivers/net/wireless/mediatek/mt7601u/eeprom.c b/drivers/net/wireless/mediatek/mt7601u/eeprom.c index 625bebe60538..d4d31a546556 100644 --- a/drivers/net/wireless/mediatek/mt7601u/eeprom.c +++ b/drivers/net/wireless/mediatek/mt7601u/eeprom.c @@ -8,7 +8,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mt7601u.h" #include "eeprom.h" #include "mac.h" diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c index 15334940287d..56d1139ba8bc 100644 --- a/drivers/net/wireless/purelifi/plfxlc/usb.c +++ b/drivers/net/wireless/purelifi/plfxlc/usb.c @@ -16,7 +16,7 @@ #include <linux/string.h> #include <linux/module.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/sysfs.h> #include "mac.h" diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c index a8a94edf2a70..9ae10f65f2af 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -17,7 +17,7 @@ #include <linux/workqueue.h> #include <linux/module.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "zd_def.h" #include "zd_mac.h" diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c index e83f65596a88..93094418fd24 100644 --- a/drivers/nfc/nfcmrvl/fw_dnld.c +++ b/drivers/nfc/nfcmrvl/fw_dnld.c @@ -6,7 +6,7 @@ */ #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/firmware.h> #include <linux/nfc.h> #include <net/nfc/nci.h> diff --git a/drivers/nfc/nxp-nci/firmware.c b/drivers/nfc/nxp-nci/firmware.c index 119bf305c642..381b5bb75477 100644 --- a/drivers/nfc/nxp-nci/firmware.c +++ b/drivers/nfc/nxp-nci/firmware.c @@ -13,7 +13,7 @@ #include <linux/completion.h> #include <linux/firmware.h> #include <linux/nfc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nxp-nci.h" diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c index a8aced0b8010..049662ffdf97 100644 --- a/drivers/nfc/nxp-nci/i2c.c +++ b/drivers/nfc/nxp-nci/i2c.c @@ -19,7 +19,7 @@ #include <linux/module.h> #include <linux/nfc.h> #include <linux/gpio/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/nfc/nfc.h> diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index e2a6575b9ff7..a0dfb3f98d5a 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c @@ -17,7 +17,7 @@ #include <linux/firmware.h> #include <linux/gpio/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/nfc/hci.h> #include <net/nfc/llc.h> diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c index a3455f1d67fa..9b7126e1a19d 100644 --- a/drivers/nvme/common/auth.c +++ b/drivers/nvme/common/auth.c @@ -8,7 +8,7 @@ #include <linux/base64.h> #include <linux/prandom.h> #include <linux/scatterlist.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/hash.h> #include <crypto/dh.h> #include <linux/nvme.h> diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c index 371e14f0a203..5ea0e21709da 100644 --- a/drivers/nvme/host/auth.c +++ b/drivers/nvme/host/auth.c @@ -6,7 +6,7 @@ #include <linux/crc32.h> #include <linux/base64.h> #include <linux/prandom.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/hash.h> #include <crypto/dh.h> #include "nvme.h" diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ba6508455e18..43d73d31c66f 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -22,7 +22,7 @@ #include <linux/nvme_ioctl.h> #include <linux/pm_qos.h> #include <linux/ratelimit.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nvme.h" #include "fabrics.h" diff --git a/drivers/nvme/host/hwmon.c b/drivers/nvme/host/hwmon.c index 8df73a0b3980..89a1a1043d63 100644 --- a/drivers/nvme/host/hwmon.c +++ b/drivers/nvme/host/hwmon.c @@ -6,7 +6,7 @@ #include <linux/hwmon.h> #include <linux/units.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nvme.h" diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c index 7347ddf85f00..dc7922f22600 100644 --- a/drivers/nvme/host/pr.c +++ b/drivers/nvme/host/pr.c @@ -5,7 +5,7 @@ */ #include <linux/blkdev.h> #include <linux/pr.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nvme.h" diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index c8fd0e8f0237..24a2759798d0 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -18,7 +18,7 @@ #include <linux/mutex.h> #include <linux/scatterlist.h> #include <linux/nvme.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> diff --git a/drivers/nvme/host/trace.c b/drivers/nvme/host/trace.c index 0288315f0050..87c437fc070d 100644 --- a/drivers/nvme/host/trace.c +++ b/drivers/nvme/host/trace.c @@ -4,7 +4,7 @@ * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "trace.h" static const char *nvme_trace_delete_sq(struct trace_seq *p, u8 *cdw10) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 954d4c074770..081f0473cd9e 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -9,7 +9,7 @@ #include <linux/part_stat.h> #include <generated/utsrelease.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nvmet.h" u32 nvmet_get_log_page_len(struct nvme_command *cmd) diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c index 7897d02c681d..29f8639cfe7f 100644 --- a/drivers/nvme/target/auth.c +++ b/drivers/nvme/target/auth.c @@ -15,7 +15,7 @@ #include <linux/ctype.h> #include <linux/random.h> #include <linux/nvme-auth.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nvmet.h" diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index 1b6264fa5803..ade285308450 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -16,7 +16,7 @@ #include <linux/string.h> #include <linux/wait.h> #include <linux/inet.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> diff --git a/drivers/nvme/target/trace.c b/drivers/nvme/target/trace.c index 8d1806a82887..9a3548179a8e 100644 --- a/drivers/nvme/target/trace.c +++ b/drivers/nvme/target/trace.c @@ -4,7 +4,7 @@ * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "trace.h" static const char *nvmet_trace_admin_identify(struct trace_seq *p, u8 *cdw10) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 485a642b9304..e4300f5f304f 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -9,7 +9,7 @@ #include <linux/delay.h> #include <linux/export.h> #include <linux/sched/signal.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "pci.h" #define PCI_VPD_LRDT_TAG_SIZE 3 diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 948b763dc451..d018f36f3a89 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -23,7 +23,7 @@ #include <linux/io.h> #include <linux/security.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <pcmcia/ss.h> #include <pcmcia/cisreg.h> diff --git a/drivers/peci/controller/peci-aspeed.c b/drivers/peci/controller/peci-aspeed.c index de7046e6b9c4..b93eb6f43b98 100644 --- a/drivers/peci/controller/peci-aspeed.c +++ b/drivers/peci/controller/peci-aspeed.c @@ -2,7 +2,7 @@ // Copyright (c) 2012-2017 ASPEED Technology Inc. // Copyright (c) 2018-2021 Intel Corporation -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include <linux/clk.h> diff --git a/drivers/peci/request.c b/drivers/peci/request.c index 8d6dd7b6b559..87eefe66743f 100644 --- a/drivers/peci/request.c +++ b/drivers/peci/request.c @@ -8,7 +8,7 @@ #include <linux/slab.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "internal.h" diff --git a/drivers/platform/arm64/acer-aspire1-ec.c b/drivers/platform/arm64/acer-aspire1-ec.c index dbb1cce13965..2df42406430d 100644 --- a/drivers/platform/arm64/acer-aspire1-ec.c +++ b/drivers/platform/arm64/acer-aspire1-ec.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2024, Nikita Travkin <nikita@trvn.ru> */ -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <drm/drm_bridge.h> #include <linux/bits.h> #include <linux/delay.h> diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 73f75958e15c..5c9a53dffcf9 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -10,7 +10,7 @@ #include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cros_ec_trace.h" diff --git a/drivers/platform/chrome/cros_ec_proto_test.c b/drivers/platform/chrome/cros_ec_proto_test.c index 7ca9895a0065..3f281996a686 100644 --- a/drivers/platform/chrome/cros_ec_proto_test.c +++ b/drivers/platform/chrome/cros_ec_proto_test.c @@ -5,7 +5,7 @@ #include <kunit/test.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> diff --git a/drivers/platform/chrome/wilco_ec/properties.c b/drivers/platform/chrome/wilco_ec/properties.c index c2bf4c95c5d2..9951c8db04da 100644 --- a/drivers/platform/chrome/wilco_ec/properties.c +++ b/drivers/platform/chrome/wilco_ec/properties.c @@ -8,7 +8,7 @@ #include <linux/platform_data/wilco-ec.h> #include <linux/string.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Operation code; what the EC should do with the property */ enum ec_property_op { diff --git a/drivers/platform/cznic/turris-omnia-mcu-gpio.c b/drivers/platform/cznic/turris-omnia-mcu-gpio.c index 91da56a704c7..88e208d45882 100644 --- a/drivers/platform/cznic/turris-omnia-mcu-gpio.c +++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c @@ -20,7 +20,7 @@ #include <linux/sysfs.h> #include <linux/types.h> #include <linux/workqueue.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/turris-omnia-mcu-interface.h> #include "turris-omnia-mcu.h" diff --git a/drivers/platform/cznic/turris-omnia-mcu.h b/drivers/platform/cznic/turris-omnia-mcu.h index fed0d357fea3..57ef5d350043 100644 --- a/drivers/platform/cznic/turris-omnia-mcu.h +++ b/drivers/platform/cznic/turris-omnia-mcu.h @@ -18,7 +18,7 @@ #include <linux/watchdog.h> #include <linux/workqueue.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> struct i2c_client; struct rtc_device; diff --git a/drivers/platform/surface/aggregator/ssh_msgb.h b/drivers/platform/surface/aggregator/ssh_msgb.h index 438873e06098..80aa568a0759 100644 --- a/drivers/platform/surface/aggregator/ssh_msgb.h +++ b/drivers/platform/surface/aggregator/ssh_msgb.h @@ -8,7 +8,7 @@ #ifndef _SURFACE_AGGREGATOR_SSH_MSGB_H #define _SURFACE_AGGREGATOR_SSH_MSGB_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/types.h> #include <linux/surface_aggregator/controller.h> diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c index d726b1a86319..6081b0146d5f 100644 --- a/drivers/platform/surface/aggregator/ssh_packet_layer.c +++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c @@ -5,7 +5,7 @@ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <linux/error-injection.h> #include <linux/jiffies.h> diff --git a/drivers/platform/surface/aggregator/ssh_parser.c b/drivers/platform/surface/aggregator/ssh_parser.c index a6f668694365..6cfda85d3b33 100644 --- a/drivers/platform/surface/aggregator/ssh_parser.c +++ b/drivers/platform/surface/aggregator/ssh_parser.c @@ -5,7 +5,7 @@ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/compiler.h> #include <linux/device.h> #include <linux/types.h> diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.c b/drivers/platform/surface/aggregator/ssh_request_layer.c index 90634dcacabf..879ca9ee7ff6 100644 --- a/drivers/platform/surface/aggregator/ssh_request_layer.c +++ b/drivers/platform/surface/aggregator/ssh_request_layer.c @@ -5,7 +5,7 @@ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <linux/completion.h> #include <linux/error-injection.h> diff --git a/drivers/platform/surface/aggregator/trace.h b/drivers/platform/surface/aggregator/trace.h index 55cc61bba1da..caf7d3cb5d8b 100644 --- a/drivers/platform/surface/aggregator/trace.h +++ b/drivers/platform/surface/aggregator/trace.h @@ -13,7 +13,7 @@ #include <linux/surface_aggregator/serial_hub.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/tracepoint.h> TRACE_DEFINE_ENUM(SSH_FRAME_TYPE_DATA_SEQ); diff --git a/drivers/platform/surface/surface3_power.c b/drivers/platform/surface/surface3_power.c index 4c0f92562a79..1ee5239269ae 100644 --- a/drivers/platform/surface/surface3_power.c +++ b/drivers/platform/surface/surface3_power.c @@ -40,7 +40,7 @@ #include <linux/slab.h> #include <linux/types.h> #include <linux/uuid.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SURFACE_3_POLL_INTERVAL (2 * HZ) #define SURFACE_3_STRLEN 10 diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c index 20f3870915d2..14a9d8a267cb 100644 --- a/drivers/platform/surface/surface_acpi_notify.c +++ b/drivers/platform/surface/surface_acpi_notify.c @@ -11,7 +11,7 @@ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/delay.h> #include <linux/jiffies.h> diff --git a/drivers/platform/surface/surface_aggregator_tabletsw.c b/drivers/platform/surface/surface_aggregator_tabletsw.c index c0a1a5869246..ffa36ed92897 100644 --- a/drivers/platform/surface/surface_aggregator_tabletsw.c +++ b/drivers/platform/surface/surface_aggregator_tabletsw.c @@ -5,7 +5,7 @@ * Copyright (C) 2022 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/input.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/platform/surface/surface_platform_profile.c b/drivers/platform/surface/surface_platform_profile.c index 3de864bc6610..08db878f1d7d 100644 --- a/drivers/platform/surface/surface_platform_profile.c +++ b/drivers/platform/surface/surface_platform_profile.c @@ -6,7 +6,7 @@ * Copyright (C) 2021-2022 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_profile.h> diff --git a/drivers/platform/x86/asus-tf103c-dock.c b/drivers/platform/x86/asus-tf103c-dock.c index b441d8ca72d3..ca4670d0dc67 100644 --- a/drivers/platform/x86/asus-tf103c-dock.c +++ b/drivers/platform/x86/asus-tf103c-dock.c @@ -26,7 +26,7 @@ #include <linux/module.h> #include <linux/pm.h> #include <linux/workqueue.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static bool fnlock; module_param(fnlock, bool, 0644); diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c index 0b2299f7a2de..e75cd6e1efe6 100644 --- a/drivers/platform/x86/dell/dell-wmi-ddv.c +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c @@ -31,7 +31,7 @@ #include <acpi/battery.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "dell-wmi-ddv" diff --git a/drivers/platform/x86/msi-wmi-platform.c b/drivers/platform/x86/msi-wmi-platform.c index 436fb91a47db..9b5c7f8c79b0 100644 --- a/drivers/platform/x86/msi-wmi-platform.c +++ b/drivers/platform/x86/msi-wmi-platform.c @@ -22,7 +22,7 @@ #include <linux/types.h> #include <linux/wmi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "msi-wmi-platform" diff --git a/drivers/platform/x86/quickstart.c b/drivers/platform/x86/quickstart.c index df496c7e7171..8d540a1c8602 100644 --- a/drivers/platform/x86/quickstart.c +++ b/drivers/platform/x86/quickstart.c @@ -26,7 +26,7 @@ #include <linux/sysfs.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "quickstart" diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index 95d9a35243c2..a3d71fc72064 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c @@ -21,7 +21,7 @@ #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/iio/consumer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/iosf_mbi.h> #define PS_STAT_VBUS_TRIGGER (1 << 0) diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c index c1737f964840..ba0d22d90429 100644 --- a/drivers/power/supply/bq27xxx_battery_i2c.c +++ b/drivers/power/supply/bq27xxx_battery_i2c.c @@ -9,7 +9,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/power/bq27xxx_battery.h> diff --git a/drivers/power/supply/cros_peripheral_charger.c b/drivers/power/supply/cros_peripheral_charger.c index d406f2a78449..962a6fd29832 100644 --- a/drivers/power/supply/cros_peripheral_charger.c +++ b/drivers/power/supply/cros_peripheral_charger.c @@ -15,7 +15,7 @@ #include <linux/slab.h> #include <linux/stringify.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRV_NAME "cros-ec-pchg" #define PCHG_DIR_PREFIX "peripheral" diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c index 2bc3dce963a3..33105419e242 100644 --- a/drivers/power/supply/max1720x_battery.c +++ b/drivers/power/supply/max1720x_battery.c @@ -14,7 +14,7 @@ #include <linux/power_supply.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Nonvolatile registers */ #define MAX1720X_NXTABLE0 0x80 diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c index a3d377a32b49..57b6ddefad28 100644 --- a/drivers/power/supply/rk817_charger.c +++ b/drivers/power/supply/rk817_charger.c @@ -8,7 +8,7 @@ * Chris Morgan <macromorgan@hotmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/devm-helpers.h> #include <linux/mfd/rk808.h> #include <linux/irq.h> diff --git a/drivers/power/supply/surface_battery.c b/drivers/power/supply/surface_battery.c index 196d290dc596..ebd1edde28f1 100644 --- a/drivers/power/supply/surface_battery.c +++ b/drivers/power/supply/surface_battery.c @@ -6,7 +6,7 @@ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/power/supply/surface_charger.c b/drivers/power/supply/surface_charger.c index 7a6c62d6f883..90b823848c99 100644 --- a/drivers/power/supply/surface_charger.c +++ b/drivers/power/supply/surface_charger.c @@ -6,7 +6,7 @@ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> diff --git a/drivers/ptp/ptp_clockmatrix.c b/drivers/ptp/ptp_clockmatrix.c index 209a45a76e6b..b6f1941308b1 100644 --- a/drivers/ptp/ptp_clockmatrix.c +++ b/drivers/ptp/ptp_clockmatrix.c @@ -17,7 +17,7 @@ #include <linux/of.h> #include <linux/mfd/rsmu.h> #include <linux/mfd/idt8a340_reg.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ptp_private.h" #include "ptp_clockmatrix.h" diff --git a/drivers/ptp/ptp_fc3.c b/drivers/ptp/ptp_fc3.c index 6ef982862e27..e14e149b746e 100644 --- a/drivers/ptp/ptp_fc3.c +++ b/drivers/ptp/ptp_fc3.c @@ -18,7 +18,7 @@ #include <linux/bitfield.h> #include <linux/mfd/rsmu.h> #include <linux/mfd/idtRC38xxx_reg.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ptp_private.h" #include "ptp_fc3.h" diff --git a/drivers/rtc/rtc-max31335.c b/drivers/rtc/rtc-max31335.c index 9a456f537d3b..3fbcf5f6b92f 100644 --- a/drivers/rtc/rtc-max31335.c +++ b/drivers/rtc/rtc-max31335.c @@ -8,7 +8,7 @@ * */ -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <linux/bcd.h> #include <linux/bitfield.h> #include <linux/bitops.h> diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index f6b779c12ca7..c32fba550c8e 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -17,7 +17,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* RTC_CTRL register bit fields */ #define PM8xxx_RTC_ENABLE BIT(7) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index ec3834bda111..abf6a82b74af 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -27,7 +27,7 @@ #include <linux/uaccess.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index 5b3ffefae476..6cc1d53165a0 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -38,7 +38,7 @@ #include <linux/utsname.h> #include <scsi/scsi_device.h> #include <scsi/scsi_transport_fc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/fc/fc_els.h> #include <scsi/fc/fc_fs.h> #include <scsi/fc/fc_gs.h> diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 05e1a63e00c3..8329f0cab4e7 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -41,7 +41,7 @@ #include <linux/compiler.h> #include <linux/export.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/page.h> #include <scsi/scsi.h> #include <scsi/scsi_device.h> diff --git a/drivers/scsi/cxlflash/lunmgt.c b/drivers/scsi/cxlflash/lunmgt.c index 52405c6462f8..962c797fda07 100644 --- a/drivers/scsi/cxlflash/lunmgt.c +++ b/drivers/scsi/cxlflash/lunmgt.c @@ -8,7 +8,7 @@ * Copyright (C) 2015 IBM Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/interrupt.h> #include <linux/pci.h> diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index e4b45b7e3277..60d62b93d624 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -13,7 +13,7 @@ #include <linux/module.h> #include <linux/pci.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 2d356fe2457a..b375509d1470 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -13,7 +13,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/syscalls.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index 35326e311991..32e807703377 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -11,7 +11,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/syscalls.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/bitsperlong.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 4eb0837298d4..1bf5948d1188 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -8,7 +8,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_proto.h> #include <scsi/scsi_dbg.h> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index e044ed09d7e0..0c49414c1f35 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -51,7 +51,7 @@ #include <linux/jiffies.h> #include <linux/percpu-defs.h> #include <linux/percpu.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/div64.h> #include "hpsa_cmd.h" #include "hpsa.h" diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b2b643c6dbbe..fde7145835de 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -13,7 +13,7 @@ #ifndef _IPR_H #define _IPR_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/types.h> #include <linux/completion.h> #include <linux/list.h> diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 384f48ff64d7..60d621ad0024 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -26,7 +26,7 @@ #include <linux/export.h> #include <linux/list.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/fc/fc_gs.h> diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c index 8d3006edbe12..4fa18a317f77 100644 --- a/drivers/scsi/libfc/fc_elsct.c +++ b/drivers/scsi/libfc/fc_elsct.c @@ -10,7 +10,7 @@ */ #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/fc/fc_gs.h> #include <scsi/fc/fc_ns.h> #include <scsi/fc/fc_els.h> diff --git a/drivers/scsi/libfc/fc_encode.h b/drivers/scsi/libfc/fc_encode.h index 6b7e4ca6b7b5..02e31db31d68 100644 --- a/drivers/scsi/libfc/fc_encode.h +++ b/drivers/scsi/libfc/fc_encode.h @@ -7,7 +7,7 @@ #ifndef _FC_ENCODE_H_ #define _FC_ENCODE_H_ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/utsname.h> #include <scsi/fc/fc_ms.h> diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index ab06e9aeb613..310fa5add5f0 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -79,7 +79,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/fc/fc_gs.h> diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 308cb4872f96..c25979d96808 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -55,7 +55,7 @@ #include <linux/export.h> #include <linux/rculist.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/libfc.h> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 0fda8905eabd..2b1bf990a9dc 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -15,7 +15,7 @@ #include <linux/slab.h> #include <linux/sched/signal.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/tcp.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 4e6bb3d0f163..2b8004eb6f1b 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -11,7 +11,7 @@ #include <linux/scatterlist.h> #include <linux/blkdev.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sas_internal.h" diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index d70da2736c94..fec23c723730 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -24,7 +24,7 @@ #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/delay.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-t10dif.h> #include <net/checksum.h> diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 0cef5d089f34..55c3e2c2bf8f 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -24,7 +24,7 @@ #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/delay.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-t10dif.h> #include <net/checksum.h> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 0eaede8275da..11c974bffa72 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -25,7 +25,7 @@ #include <linux/interrupt.h> #include <linux/export.h> #include <linux/delay.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/t10-pi.h> #include <linux/crc-t10dif.h> #include <linux/blk-cgroup.h> diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 4ecf5284c0fc..8e75e2e279a4 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -29,7 +29,7 @@ #include <linux/uio.h> #include <linux/slab.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/fs.h> #include <linux/compat.h> #include <linux/blkdev.h> diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index fcb0fa31536b..14eeac08660f 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -31,7 +31,7 @@ #include <linux/uaccess.h> #include <linux/utsname.h> #include <linux/workqueue.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_dbg.h> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 728cced42b0e..f2a55aa5fe65 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -54,7 +54,7 @@ #include <linux/interrupt.h> #include <linux/raid_class.h> #include <linux/blk-mq-pci.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mpt3sas_base.h" diff --git a/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c index 1d64e5056a8a..2b04f0852dec 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c +++ b/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c @@ -42,7 +42,7 @@ #include <linux/module.h> #include <linux/errno.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mpt3sas_base.h" diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 68df771e2975..19b01f7c4767 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -23,7 +23,7 @@ #include <linux/irq.h> #include <linux/slab.h> #include <linux/vmalloc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/libsas.h> #include <scsi/scsi.h> #include <scsi/scsi_tcq.h> diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index bfc2b835e612..a7e64b867c8e 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -16,7 +16,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/raid_class.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_device.h> diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 3392feb15cb4..1469d0c54e45 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -17,7 +17,7 @@ #include <linux/interrupt.h> #include <linux/pci.h> #include <linux/raid_class.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_device.h> diff --git a/drivers/scsi/qla2xxx/qla_dsd.h b/drivers/scsi/qla2xxx/qla_dsd.h index 20788054b91b..52e060f83b37 100644 --- a/drivers/scsi/qla2xxx/qla_dsd.h +++ b/drivers/scsi/qla2xxx/qla_dsd.h @@ -1,7 +1,7 @@ #ifndef _QLA_DSD_H_ #define _QLA_DSD_H_ -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* 32-bit data segment descriptor (8 bytes) */ struct dsd32 { diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index d7551b1443e4..11eadb3bd36e 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -23,7 +23,7 @@ #include <linux/delay.h> #include <linux/list.h> #include <linux/workqueue.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 7e7460a747a4..ceaf1c7b1d17 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -24,7 +24,7 @@ #include <linux/string.h> #include <linux/configfs.h> #include <linux/ctype.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_host.h> #include <target/target_core_base.h> #include <target/target_core_fabric.h> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index ee69bd35889d..a77e0499b738 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -55,7 +55,7 @@ #include <linux/notifier.h> #include <linux/cpu.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index 04749fde1636..e1a2a62b6910 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c @@ -9,7 +9,7 @@ #include <linux/errno.h> #include <linux/module.h> #include <uapi/linux/pr.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_common.h> MODULE_DESCRIPTION("SCSI functions used by both the initiator and the target code"); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d95f417e24c0..de15fc0df104 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -47,7 +47,7 @@ #include <net/checksum.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 612489afe8d2..10154d78e336 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -48,7 +48,7 @@ #include <trace/events/scsi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * These should *probably* be handled by the host itself. diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0561b318dade..adee6f60c966 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -23,7 +23,7 @@ #include <linux/blk-mq.h> #include <linux/blk-integrity.h> #include <linux/ratelimit.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/scsi_proto_test.c b/drivers/scsi/scsi_proto_test.c index 7fa0a78a2ad1..c093389edabb 100644 --- a/drivers/scsi/scsi_proto_test.c +++ b/drivers/scsi/scsi_proto_test.c @@ -3,7 +3,7 @@ * Copyright 2023 Google LLC */ #include <kunit/test.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_proto.h> static void test_scsi_proto(struct kunit *test) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index c0b72199b4fa..042329b74c6e 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -35,7 +35,7 @@ #include <linux/spinlock.h> #include <linux/async.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/scsi_trace.c b/drivers/scsi/scsi_trace.c index 3e47c4472a80..b3baae91e7a2 100644 --- a/drivers/scsi/scsi_trace.c +++ b/drivers/scsi/scsi_trace.c @@ -5,7 +5,7 @@ */ #include <linux/kernel.h> #include <linux/trace_seq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <trace/events/scsi.h> #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index dd69342bbe78..19e6c3852d50 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c @@ -18,7 +18,7 @@ #include <linux/blkdev.h> #include <linux/pagemap.h> #include <linux/msdos_partition.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsicam.h> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 41e2dfa2d67d..ca4bc0ac76ad 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -57,7 +57,7 @@ #include <linux/pr.h> #include <linux/t10-pi.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index c8b9654d30f0..ee2b74238758 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -13,7 +13,7 @@ #include <linux/sched/mm.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index e22c7f5e652b..2c61624cb4b0 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -9,7 +9,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/enclosure.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 7fd5a8c813dc..870f37b70546 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -25,7 +25,7 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_eh.h> #include <scsi/scsi_transport_sas.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "smartpqi.h" #include "smartpqi_sis.h" diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index a981d0377948..93e96705754e 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -14,7 +14,7 @@ #include <scsi/scsi_host.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_transport_sas.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "smartpqi.h" static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port) diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index ca1df36b83f7..ae5a264d062d 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -14,7 +14,7 @@ #include <linux/delay.h> #include <linux/pci.h> #include <scsi/scsi_device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "smartpqi.h" #include "smartpqi_sis.h" diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 3f491019103e..198bec87bb8e 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -52,7 +52,7 @@ #include <linux/pm_runtime.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_dbg.h> diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index d50bad3a2ce9..beb88f25dbb9 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -46,7 +46,7 @@ static const char *verstr = "20160209"; #include <linux/uaccess.h> #include <asm/dma.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_dbg.h> diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 24c3971f2ef1..64fc4f41da77 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -17,7 +17,7 @@ #include <linux/sys_soc.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <dt-bindings/arm/qcom,ids.h> diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c index 94458df53eae..1369691a997b 100644 --- a/drivers/spi/spi-airoha-snfi.c +++ b/drivers/spi/spi-airoha-snfi.c @@ -23,7 +23,7 @@ #include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* SPI */ #define REG_SPI_CTRL_BASE 0x1FA10000 diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c index d319dc357fef..4ba1d9245c9f 100644 --- a/drivers/spi/spi-dln2.c +++ b/drivers/spi/spi-dln2.c @@ -12,7 +12,7 @@ #include <linux/mfd/dln2.h> #include <linux/spi/spi.h> #include <linux/pm_runtime.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DLN2_SPI_MODULE_ID 0x02 #define DLN2_SPI_CMD(cmd) DLN2_CMD(cmd, DLN2_SPI_MODULE_ID) diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c index a7feb20b06ee..30aa37b0c3b8 100644 --- a/drivers/spi/spi-npcm-pspi.c +++ b/drivers/spi/spi-npcm-pspi.c @@ -12,7 +12,7 @@ #include <linux/spi/spi.h> #include <linux/reset.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/regmap.h> #include <linux/mfd/syscon.h> diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index eee9ff4bfa5b..4730e4ba8901 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -18,7 +18,7 @@ #include <linux/of_address.h> #include <linux/clk.h> #include <linux/sizes.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_NAME "orion_spi" diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c index b468a95972bf..c24dad51a0e9 100644 --- a/drivers/spi/spi-rpc-if.c +++ b/drivers/spi/spi-rpc-if.c @@ -14,7 +14,7 @@ #include <memory/renesas-rpc-if.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static void rpcif_spi_mem_prepare(struct spi_device *spi_dev, const struct spi_mem_op *spi_op, diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 6f12e4fb2e2e..3519656515ea 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -27,7 +27,7 @@ #include <linux/spi/sh_msiof.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SH_MSIOF_FLAG_FIXED_DTDL_200 BIT(0) diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c index 4a18cf896194..07b155980e71 100644 --- a/drivers/spi/spi-uniphier.c +++ b/drivers/spi/spi-uniphier.c @@ -15,7 +15,7 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SSI_TIMEOUT_MS 2000 #define SSI_POLL_TIMEOUT_US 200 diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c index 846f00e23b71..3bd0149d8f4e 100644 --- a/drivers/spi/spi-xcomm.c +++ b/drivers/spi/spi-xcomm.c @@ -12,7 +12,7 @@ #include <linux/i2c.h> #include <linux/gpio/driver.h> #include <linux/spi/spi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define SPI_XCOMM_SETTINGS_LEN_OFFSET 10 #define SPI_XCOMM_SETTINGS_3WIRE BIT(6) diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c index 728b3892a20c..bc9a2a40afcb 100644 --- a/drivers/staging/media/av7110/av7110.c +++ b/drivers/staging/media/av7110/av7110.c @@ -32,7 +32,7 @@ #include <linux/i2c.h> #include <linux/kthread.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/byteorder.h> #include <linux/dvb/frontend.h> diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 834329886ea2..c400d4f8ff9a 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -5,7 +5,7 @@ * Contact Information: wlanfae <wlanfae@realtek.com> */ #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/etherdevice.h> #include "rtllib.h" #include "rtl819x_BA.h" diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c index e55b4f7e0aef..a6dc88dd4ba1 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ap.c +++ b/drivers/staging/rtl8723bs/core/rtw_ap.c @@ -6,7 +6,7 @@ ******************************************************************************/ #include <drv_types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> void init_mlme_ap_info(struct adapter *padapter) { diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index 5a76069a8222..0ed420f3d096 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -7,7 +7,7 @@ #include <drv_types.h> #include <linux/of.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; u16 RTW_WPA_VERSION = 1; diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index bbdd5fce28a1..4d4bec47d187 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -8,7 +8,7 @@ #include <rtw_wifi_regd.h> #include <hal_btcoex.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static struct mlme_handler mlme_sta_tbl[] = { {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index b30f026789b6..a389ba5ecc6f 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -8,7 +8,7 @@ #include <linux/jiffies.h> #include <rtw_recv.h> #include <net/cfg80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; diff --git a/drivers/staging/rtl8723bs/os_dep/recv_linux.c b/drivers/staging/rtl8723bs/os_dep/recv_linux.c index 746f45cf9aac..ca808ded61ac 100644 --- a/drivers/staging/rtl8723bs/os_dep/recv_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/recv_linux.c @@ -7,7 +7,7 @@ #include <drv_types.h> #include <linux/jiffies.h> #include <net/cfg80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> void rtw_os_free_recvframe(union recv_frame *precvframe) { diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c index acfc39683c87..3698f2eb097e 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_target.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c @@ -7,7 +7,7 @@ #include <linux/kthread.h> #include <linux/sched/signal.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/tcp.h> #include <target/target_core_base.h> #include <target/target_core_fabric.h> diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 1d25e64b068a..6002283cbeba 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -17,7 +17,7 @@ #include <linux/idr.h> #include <linux/delay.h> #include <linux/sched/signal.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/inet.h> #include <net/ipv6.h> #include <scsi/scsi_proto.h> diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index 9c4aa01b6351..f60b156ede12 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -8,7 +8,7 @@ * ******************************************************************************/ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_proto.h> #include <scsi/iscsi_proto.h> #include <target/target_core_base.h> diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index b604fcae21e1..3b89b5a70331 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -23,7 +23,7 @@ #include <target/target_core_base.h> #include <target/target_core_backend.h> #include <target/target_core_fabric.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sbp_target.h" diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 01751faad386..10250aca5a81 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -19,7 +19,7 @@ #include <linux/file.h> #include <linux/fs.h> #include <scsi/scsi_proto.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #include <target/target_core_backend.h> diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index bf4892544cfd..7d43d92c44d4 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -21,7 +21,7 @@ #include <linux/in.h> #include <linux/export.h> #include <linux/t10-pi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/sock.h> #include <net/tcp.h> #include <scsi/scsi_common.h> diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index 6600ae44f29d..43f47e3aa448 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -21,7 +21,7 @@ #include <linux/ctype.h> #include <linux/spinlock.h> #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_proto.h> diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 94e6cd4e7e43..2d78ef74633c 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -22,7 +22,7 @@ #include <linux/uio.h> #include <linux/scatterlist.h> #include <scsi/scsi_proto.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #include <target/target_core_backend.h> diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index a3e09adc4e76..c8dc92a7d63e 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -26,7 +26,7 @@ #include <linux/pr.h> #include <scsi/scsi_proto.h> #include <scsi/scsi_common.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #include <target/target_core_backend.h> diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 80b7d85030d0..4f4ad6af416c 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -19,7 +19,7 @@ #include <linux/fcntl.h> #include <linux/fs.h> #include <scsi/scsi_proto.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #include <target/target_core_backend.h> diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index f98ebb18666b..440e07b1d5cd 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -20,7 +20,7 @@ #include <linux/cdrom.h> #include <linux/ratelimit.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 6a02561cc20c..fe8beb7dbab1 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -12,7 +12,7 @@ #include <linux/ratelimit.h> #include <linux/crc-t10dif.h> #include <linux/t10-pi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_proto.h> #include <scsi/scsi_tcq.h> diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 50290abc07bc..ea14a3835681 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_proto.h> #include <scsi/scsi_common.h> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 73d0d6133ac8..05d29201b730 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -22,7 +22,7 @@ #include <linux/module.h> #include <linux/ratelimit.h> #include <linux/vmalloc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/sock.h> #include <net/tcp.h> #include <scsi/scsi_proto.h> diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 4128631c9dfd..877ce58c0a70 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -19,7 +19,7 @@ #include <linux/configfs.h> #include <linux/ratelimit.h> #include <scsi/scsi_proto.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #include <target/target_core_backend.h> diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 21783cd71c15..34ab628809e8 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -16,7 +16,7 @@ #include <linux/configfs.h> #include <linux/ctype.h> #include <linux/hash.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_tcq.h> #include <scsi/libfc.h> diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 5ee03d1cba2b..639fc358ed0f 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -25,7 +25,7 @@ #include <linux/configfs.h> #include <linux/kernel.h> #include <linux/ctype.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/libfc.h> #include <target/target_core_base.h> diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c index bbe2e29612fa..45329284f52f 100644 --- a/drivers/target/tcm_fc/tfc_io.c +++ b/drivers/target/tcm_fc/tfc_io.c @@ -26,7 +26,7 @@ #include <linux/ctype.h> #include <linux/hash.h> #include <linux/ratelimit.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/libfc.h> #include <target/target_core_base.h> diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 593540da9346..d6afaba52ea5 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -19,7 +19,7 @@ #include <linux/rcupdate.h> #include <linux/rculist.h> #include <linux/kref.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/libfc.h> #include <target/target_core_base.h> diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index 7c9f4023babc..5e94a45eba3e 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -18,7 +18,7 @@ #include <linux/regmap.h> #include <linux/thermal.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "../thermal_hwmon.h" diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index fda63918d1eb..cde5f1c86353 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -32,7 +32,7 @@ #include <linux/tty.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define MAX3100_C (1<<14) #define MAX3100_D (0<<14) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index da33c6c4691c..79b33d998d43 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -48,7 +48,7 @@ #include <linux/uaccess.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define HEADER_SIZE 4u #define CON_BUF_SIZE (IS_ENABLED(CONFIG_BASE_SMALL) ? 256 : PAGE_SIZE) diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 5891cdacd0b3..8402151330fe 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -7,7 +7,7 @@ * Can Guo <quic_cang@quicinc.com> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/platform_device.h> diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index fe313800aed0..265f21133b63 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -4,7 +4,7 @@ #include <linux/err.h> #include <linux/string.h> #include <linux/bitfield.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <ufs/ufs.h> #include <ufs/unipro.h> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 24a32e2fd75e..fc55fdab526b 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -36,7 +36,7 @@ #include "ufs-fault-injection.h" #include "ufs_bsg.h" #include "ufshcd-crypto.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define CREATE_TRACE_POINTS #include "ufs_trace.h" diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index 9ec318ef52bf..5867e6338562 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -8,7 +8,7 @@ * */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <linux/arm-smccc.h> #include <linux/clk.h> diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 8f3b9a0a38e1..0dd85d2635b9 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -24,7 +24,7 @@ #include <linux/device.h> #include <linux/firmware.h> #include <linux/mutex.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "usbatm.h" diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 16703815be0c..e8e43c38aa1b 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -25,7 +25,7 @@ #include <linux/slab.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "usbatm.h" diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 605fea461102..6b37d1c47fce 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -35,7 +35,7 @@ #include <linux/usb.h> #include <linux/usb/cdc.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/idr.h> #include <linux/list.h> diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 6830be4419e2..86ee39db013f 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -26,7 +26,7 @@ #include <linux/usb/cdc.h> #include <linux/wwan.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb/cdc-wdm.h> #define DRIVER_AUTHOR "Oliver Neukum" diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1ff7d901fede..500dc35e6477 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -24,7 +24,7 @@ #include <linux/mutex.h> #include <asm/irq.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/platform_device.h> #include <linux/workqueue.h> #include <linux/pm_runtime.h> diff --git a/drivers/usb/fotg210/fotg210-hcd.c b/drivers/usb/fotg210/fotg210-hcd.c index 8c5aaf860635..3d404d19a205 100644 --- a/drivers/usb/fotg210/fotg210-hcd.c +++ b/drivers/usb/fotg210/fotg210-hcd.c @@ -36,7 +36,7 @@ #include <asm/byteorder.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "fotg210.h" diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f45d5bedda68..f25dd2cb5d03 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -19,7 +19,7 @@ #include <linux/usb/composite.h> #include <linux/usb/otg.h> #include <linux/usb/webusb.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "u_os_desc.h" diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index c626bb73ea59..2920f8000bbd 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -28,7 +28,7 @@ #include <linux/sched/signal.h> #include <linux/uio.h> #include <linux/vmalloc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb/ccid.h> #include <linux/usb/composite.h> diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index e11d8c0edf06..08e0d1c511e8 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -188,7 +188,7 @@ #include <linux/freezer.h> #include <linux/module.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index ef2ffde625c3..d295ade8fa67 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -37,7 +37,7 @@ #include <linux/io.h> #include <linux/irq.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb/ch9.h> #include <linux/usb/composite.h> diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 90906d714736..15bb3aa12aa8 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -19,7 +19,7 @@ #include <scsi/scsi_tcq.h> #include <target/target_core_base.h> #include <target/target_core_fabric.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "tcm.h" #include "u_tcm.h" diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 12c5d9cf450c..afd75d72412c 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -31,7 +31,7 @@ #include <asm/io.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "u_rndis.h" diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index 0a544a82cbf8..ced5d2b09234 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h @@ -5,7 +5,7 @@ #include <linux/device.h> #include <linux/usb/storage.h> #include <scsi/scsi.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #ifndef DEBUG #undef VERBOSE_DEBUG diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index a9edd60fbbf7..57a851151225 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -12,7 +12,7 @@ #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/usb/video.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <media/v4l2-dev.h> diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 40870227999a..fc1e06246d9d 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -19,7 +19,7 @@ #include <scsi/scsi_tcq.h> #include <target/target_core_base.h> #include <target/target_core_fabric.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "u_tcm.h" diff --git a/drivers/usb/gadget/u_os_desc.h b/drivers/usb/gadget/u_os_desc.h index 5d7d35c8cc31..f8b9f0faa9b1 100644 --- a/drivers/usb/gadget/u_os_desc.h +++ b/drivers/usb/gadget/u_os_desc.h @@ -13,7 +13,7 @@ #ifndef __U_OS_DESC_H__ #define __U_OS_DESC_H__ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/nls.h> #define USB_EXT_PROP_DW_SIZE 0 diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h index 8d00b1239f21..2f4abf6f8f77 100644 --- a/drivers/usb/gadget/udc/bdc/bdc.h +++ b/drivers/usb/gadget/udc/bdc/bdc.h @@ -20,7 +20,7 @@ #include <linux/debugfs.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define BRCM_BDC_NAME "bdc" #define BRCM_BDC_DESC "Broadcom USB Device Controller driver" diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index fa88f210ecd5..f995cfa9b99e 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -30,7 +30,7 @@ #include <linux/pm.h> #include <linux/io.h> #include <linux/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/platform_device.h> #include <linux/usb/composite.h> diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c index 53ffaf4e2e37..23826fd7a8e6 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_udc.c +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c @@ -29,7 +29,7 @@ #include <linux/pm.h> #include <linux/io.h> #include <linux/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/platform_device.h> #include "bdc.h" diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-ep0.c b/drivers/usb/gadget/udc/cdns2/cdns2-ep0.c index fa12a5d46f2e..a5a9d395fd0d 100644 --- a/drivers/usb/gadget/udc/cdns2/cdns2-ep0.c +++ b/drivers/usb/gadget/udc/cdns2/cdns2-ep0.c @@ -8,7 +8,7 @@ */ #include <linux/usb/composite.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cdns2-gadget.h" #include "cdns2-trace.h" diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index ff7bee78bcc4..8820d9924448 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -42,7 +42,7 @@ #include <asm/byteorder.h> #include <linux/io.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_DESC "USB Host+Gadget Emulator" #define DRIVER_VERSION "02 May 2005" diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 3432ebfae978..0cabd4eee6ac 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -39,7 +39,7 @@ #include <asm/byteorder.h> #include <asm/io.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/dma.h> #include "fsl_usb2_udc.h" diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index 5ffb3d5c635b..b860c2e76449 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -40,7 +40,7 @@ #include <asm/byteorder.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "goku_udc.h" diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 78308b64955d..71012b282891 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -30,7 +30,7 @@ #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/platform_data/mv_usb.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "mv_udc.h" diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 19bbc38f3d35..9230db57dab7 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -28,7 +28,7 @@ #include <linux/usb/gadget.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "net2272.h" diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 1b929c519cd7..b2903e4bbf54 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -56,7 +56,7 @@ #include <asm/byteorder.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DRIVER_DESC "PLX NET228x/USB338x USB Peripheral Controller" #define DRIVER_VERSION "2005 Sept 27/v3.0" diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index e13b8ec8ef8a..61a45e4657d5 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -36,7 +36,7 @@ #include <asm/byteorder.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/mach-types.h> #include <linux/omap-dma.h> diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 1ac26cb49ecf..7c96fc9f680f 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -38,7 +38,7 @@ #include <asm/byteorder.h> #include <asm/dma.h> #include <asm/mach-types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index 2fc5d4d277bc..cd89532adec2 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -33,7 +33,7 @@ #include <linux/prefetch.h> #include <linux/moduleparam.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "amd5536udc.h" static void udc_setup_endpoints(struct udc *dev); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 802bfafb1012..cbc0b86fcc36 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -32,7 +32,7 @@ #include <asm/byteorder.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #if defined(CONFIG_PPC_PS3) #include <asm/firmware.h> diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index a52c3d858f3e..31059c8f94e6 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -83,7 +83,7 @@ #include <asm/irq.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static int dbg_level; #ifdef ISP1362_DEBUG diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index d9adae53466b..d2b67da76762 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -22,7 +22,7 @@ #include <linux/regulator/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ohci.h" diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 5cec7640e913..9b24181fee60 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -44,7 +44,7 @@ #include <asm/io.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/byteorder.h> diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 3f871fe62b90..ca3859463ba1 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -27,7 +27,7 @@ #include <linux/iopoll.h> #include <asm/irq.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/irq.h> #include <linux/platform_device.h> diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 2b871540bb50..92f2d1238448 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -54,7 +54,7 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sl811.h" diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index d27c30ac17fd..8d774f19271e 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -10,7 +10,7 @@ #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitfield.h> #include "xhci.h" diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c index 30cc5a1380a5..65fc9319d5e7 100644 --- a/drivers/usb/host/xhci-pci-renesas.c +++ b/drivers/usb/host/xhci-pci-renesas.c @@ -6,7 +6,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "xhci.h" #include "xhci-trace.h" diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index 0e5e4cb74c87..add2d2e3b61b 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -27,7 +27,7 @@ #include <linux/iopoll.h> #include <linux/mm.h> #include <linux/timer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/cacheflush.h> #include "isp1760-core.h" diff --git a/drivers/usb/misc/usb-ljca.c b/drivers/usb/misc/usb-ljca.c index 1a8d5e80b9ae..01ceafc4ab78 100644 --- a/drivers/usb/misc/usb-ljca.c +++ b/drivers/usb/misc/usb-ljca.c @@ -18,7 +18,7 @@ #include <linux/usb.h> #include <linux/usb/ljca.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* command flags */ #define LJCA_ACK_FLAG BIT(0) diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 2b2164e028b3..ce6f25a9650b 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -14,7 +14,7 @@ #include <linux/time.h> #include <linux/timer.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "musb_core.h" diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index 1ebbf189a535..c5c6b818998e 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -27,7 +27,7 @@ #include <linux/platform_device.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "phy-fsl-usb.h" diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index aa517242d060..2a76f1f0ee4f 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -35,7 +35,7 @@ * */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/tty.h> #include <linux/slab.h> #include <linux/module.h> diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 02945ccf531d..d10e4c4848a0 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -19,7 +19,7 @@ #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/serial.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define DEFAULT_BAUD_RATE 9600 #define DEFAULT_TIMEOUT 1000 diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index ce9134bb30f3..e29569d65991 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -36,7 +36,7 @@ #include <linux/kfifo.h> #include <linux/delay.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cypress_m8.h" diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a2c0bebc041f..d36155b6d2bf 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -39,7 +39,7 @@ #include <linux/tty_flip.h> #include <linux/module.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include "kl5kusb105.h" diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index e5a139ed5d90..2bce8cc03aca 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -26,7 +26,7 @@ #include <linux/module.h> #include <linux/spinlock.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/serial.h> diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c index 57e4f2b215d8..ad5fdf55a02e 100644 --- a/drivers/usb/serial/mxuport.c +++ b/drivers/usb/serial/mxuport.c @@ -25,7 +25,7 @@ #include <linux/uaccess.h> #include <linux/usb.h> #include <linux/usb/serial.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Definitions for the vendor ID and device ID */ #define MX_USBSERIAL_VID 0x110A diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ab48f8875249..ad41363e3cea 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -24,7 +24,7 @@ #include <linux/uaccess.h> #include <linux/usb.h> #include <linux/usb/serial.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "pl2303.h" diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 4167a45d1be3..a317bdbd00ad 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -9,7 +9,7 @@ * */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/tty.h> diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 4a017eb6a65b..1cf5aad4c23a 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -11,7 +11,7 @@ #include <linux/usb/typec.h> #include <linux/usb/pd.h> #include <linux/usb/role.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index b3ec799fc873..ba58d11907bc 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -18,7 +18,7 @@ #include <linux/pm_runtime.h> #include <linux/usb/typec_dp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ucsi.h" enum enum_fw_mode { diff --git a/drivers/usb/typec/ucsi/ucsi_stm32g0.c b/drivers/usb/typec/ucsi/ucsi_stm32g0.c index ddbec2b78c8e..6923fad31d79 100644 --- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c +++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c @@ -12,7 +12,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ucsi.h" diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 006ffacf1c56..7db9bbdfb038 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -27,7 +27,7 @@ #include <linux/miscdevice.h> #include <linux/blk_types.h> #include <linux/bio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi_common.h> #include <scsi/scsi_proto.h> #include <target/target_core_base.h> diff --git a/drivers/video/fbdev/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index e4b2c89baee2..826fb04de64c 100644 --- a/drivers/video/fbdev/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -5,7 +5,7 @@ */ #include <linux/delay.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/fb.h> #include <video/mach64.h> #include "atyfb.h" diff --git a/drivers/video/fbdev/c2p_iplan2.c b/drivers/video/fbdev/c2p_iplan2.c index 19156dc6158c..cfd2361f24b1 100644 --- a/drivers/video/fbdev/c2p_iplan2.c +++ b/drivers/video/fbdev/c2p_iplan2.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "c2p.h" #include "c2p_core.h" diff --git a/drivers/video/fbdev/c2p_planar.c b/drivers/video/fbdev/c2p_planar.c index 22c8c1b6db60..819c82a98ac0 100644 --- a/drivers/video/fbdev/c2p_planar.c +++ b/drivers/video/fbdev/c2p_planar.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "c2p.h" #include "c2p_core.h" diff --git a/drivers/video/fbdev/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h index c93c69bbcd57..a6437c40fc57 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.h +++ b/drivers/video/fbdev/matrox/matroxfb_base.h @@ -44,7 +44,7 @@ #include <linux/kd.h> #include <asm/io.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #if defined(CONFIG_PPC_PMAC) #include "../macmodes.h" diff --git a/drivers/video/fbdev/metronomefb.c b/drivers/video/fbdev/metronomefb.c index 130394616a7c..c15353a356b6 100644 --- a/drivers/video/fbdev/metronomefb.c +++ b/drivers/video/fbdev/metronomefb.c @@ -37,7 +37,7 @@ #include <video/metronomefb.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Display specific information */ #define DPY_W 832 diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index 1514ddac4caf..71ac9e36f67c 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -23,7 +23,7 @@ #include <linux/vmalloc.h> #include <linux/slab.h> #include <linux/delay.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <video/udlfb.h> #include "edid.h" diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index 5ed33df68e9a..775838346bb5 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c @@ -20,7 +20,7 @@ #include <linux/types.h> #include <linux/watchdog.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ZIIRAVE_TIMEOUT_MIN 3 #define ZIIRAVE_TIMEOUT_MAX 255 diff --git a/fs/adfs/map.c b/fs/adfs/map.c index a81de80c45c1..a0ce272b4098 100644 --- a/fs/adfs/map.c +++ b/fs/adfs/map.c @@ -6,7 +6,7 @@ */ #include <linux/slab.h> #include <linux/statfs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "adfs.h" /* diff --git a/fs/bcachefs/bset.c b/fs/bcachefs/bset.c index d1f6092624d8..9a4a83d6fd2d 100644 --- a/fs/bcachefs/bset.c +++ b/fs/bcachefs/bset.c @@ -13,7 +13,7 @@ #include "trace.h" #include "util.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/console.h> #include <linux/random.h> #include <linux/prefetch.h> diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c index 753c208896c3..f414c69acc44 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -20,7 +20,7 @@ #include <linux/random.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define x(name, ...) #name, const char * const bch2_inode_opts[] = { diff --git a/fs/bcachefs/siphash.c b/fs/bcachefs/siphash.c index dc1a27cc31cd..a1cc44e66c7e 100644 --- a/fs/bcachefs/siphash.c +++ b/fs/bcachefs/siphash.c @@ -45,7 +45,7 @@ */ #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitops.h> #include <linux/string.h> diff --git a/fs/bcachefs/varint.c b/fs/bcachefs/varint.c index a9ebcd82c602..6a78553d9b0c 100644 --- a/fs/bcachefs/varint.c +++ b/fs/bcachefs/varint.c @@ -3,7 +3,7 @@ #include <linux/bitops.h> #include <linux/math.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #ifdef CONFIG_VALGRIND #include <valgrind/memcheck.h> diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index cd6d5bbb4b9d..390808ce935d 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -39,7 +39,7 @@ #include <linux/vmalloc.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/cacheflush.h> #include <asm/page.h> #include <asm/flat.h> diff --git a/fs/btrfs/accessors.c b/fs/btrfs/accessors.c index 79026917db19..e3716516ca38 100644 --- a/fs/btrfs/accessors.c +++ b/fs/btrfs/accessors.c @@ -3,7 +3,7 @@ * Copyright (C) 2007 Oracle. All rights reserved. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "messages.h" #include "extent_io.h" #include "fs.h" diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h index b2eb9cde2c5d..7a7e0ef69973 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -3,7 +3,7 @@ #ifndef BTRFS_ACCESSORS_H #define BTRFS_ACCESSORS_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/stddef.h> #include <linux/types.h> #include <linux/align.h> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 25d768e67e37..831fb901683c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -17,7 +17,7 @@ #include <linux/error-injection.h> #include <linux/crc32c.h> #include <linux/sched/mm.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/hash.h> #include "ctree.h" #include "disk-io.h" diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index edac499fd83d..9122afcb712c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -32,7 +32,7 @@ #include <linux/migrate.h> #include <linux/sched/mm.h> #include <linux/iomap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/fsverity.h> #include "misc.h" #include "ctree.h" diff --git a/fs/btrfs/uuid-tree.c b/fs/btrfs/uuid-tree.c index c6399513c66f..aca2861f2187 100644 --- a/fs/btrfs/uuid-tree.c +++ b/fs/btrfs/uuid-tree.c @@ -5,7 +5,7 @@ #include <linux/kthread.h> #include <linux/uuid.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "messages.h" #include "ctree.h" #include "transaction.h" diff --git a/fs/ceph/export.c b/fs/ceph/export.c index a79f163ae4ed..44451749c544 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -3,7 +3,7 @@ #include <linux/exportfs.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "super.h" #include "mds_client.h" diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2508aa8950b7..037eac35a9e0 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -5,7 +5,7 @@ #include <linux/ceph/ceph_debug.h> #include <linux/ceph/osd_client.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/backing-dev.h> #include <linux/completion.h> #include <linux/exportfs.h> diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index 6681a71625f0..206835e31efa 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -18,7 +18,7 @@ * information about these ioctls. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/skcipher.h> #include <linux/key-type.h> #include <linux/random.h> diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index d39a1a69fecc..827278525fd9 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -21,7 +21,7 @@ #include <linux/file.h> #include <linux/scatterlist.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/xattr.h> #include "ecryptfs_kernel.h" diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5ed1e4cf6c0b..cbdf82f0183f 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -21,7 +21,7 @@ #include <linux/posix_acl.h> #include <linux/posix_acl_xattr.h> #include <linux/fileattr.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ecryptfs_kernel.h" static int lock_parent(struct dentry *dentry, diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 287e5d407f08..ceda5555971a 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -19,7 +19,7 @@ #include <linux/scatterlist.h> #include <linux/slab.h> #include <linux/xattr.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ecryptfs_kernel.h" /* diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index e980e29873a5..1253a8456e59 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -4,7 +4,7 @@ * https://www.huawei.com/ */ #include "internal.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <trace/events/erofs.h> struct z_erofs_maprecorder { diff --git a/fs/exfat/cache.c b/fs/exfat/cache.c index 7cc200d89821..d5ce0ae660ba 100644 --- a/fs/exfat/cache.c +++ b/fs/exfat/cache.c @@ -11,7 +11,7 @@ */ #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/buffer_head.h> #include "exfat_raw.h" diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c index 56b870d9cc0d..773c320d68f3 100644 --- a/fs/exfat/fatent.c +++ b/fs/exfat/fatent.c @@ -4,7 +4,7 @@ */ #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/buffer_head.h> #include <linux/blkdev.h> diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c index 1ac011088ce7..d47896a89596 100644 --- a/fs/exfat/nls.c +++ b/fs/exfat/nls.c @@ -6,7 +6,7 @@ #include <linux/string.h> #include <linux/slab.h> #include <linux/buffer_head.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "exfat_raw.h" #include "exfat_fs.h" diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 1136539a57a8..47a5c806cf16 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -5,7 +5,7 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com/ */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/fs.h> #include <linux/f2fs_fs.h> #include <linux/sched/signal.h> diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 9756f0f2b7f7..e4d81b8705d1 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -5,7 +5,7 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com/ */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/fs.h> #include <linux/f2fs_fs.h> #include <linux/sched/mm.h> diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 75722bbd6b5f..3852bb66358c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -19,7 +19,7 @@ #include <linux/uio.h> #include <linux/blkdev.h> #include <linux/backing-dev.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/random.h> #include <linux/iversion.h> #include "fat.h" diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index ce9346099c72..9592ffcb44e5 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c @@ -12,7 +12,7 @@ #include <linux/fs.h> #include <linux/blkdev.h> #include <linux/cdrom.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hfsplus_fs.h" #include "hfsplus_raw.h" diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index f5a2476c47bf..237c1c23e855 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -21,7 +21,7 @@ #include <linux/slab.h> #include <linux/sched/signal.h> #include <linux/blkdev.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "hpfs.h" diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index dcdc191ed183..2d55207c9a99 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h @@ -3,7 +3,7 @@ #include <linux/buffer_head.h> #include <linux/exportfs.h> #include <linux/iso_fs.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> enum isofs_file_format { isofs_file_normal = 0, diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 87a0f207df0b..b8fc732e1c67 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -18,7 +18,7 @@ #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "netns.h" diff --git a/fs/nls/nls_ucs2_utils.c b/fs/nls/nls_ucs2_utils.c index d4564b79d7bf..b81c298e4966 100644 --- a/fs/nls/nls_ucs2_utils.c +++ b/fs/nls/nls_ucs2_utils.c @@ -13,7 +13,7 @@ #include <linux/fs.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "nls_ucs2_utils.h" MODULE_DESCRIPTION("NLS UCS-2"); diff --git a/fs/ntfs3/lib/decompress_common.h b/fs/ntfs3/lib/decompress_common.h index dd7ced000d0e..f0cad9c4a289 100644 --- a/fs/ntfs3/lib/decompress_common.h +++ b/fs/ntfs3/lib/decompress_common.h @@ -12,7 +12,7 @@ #include <linux/compiler.h> #include <linux/types.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* "Force inline" macro (not required, but helpful for performance) */ diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index e2df7eeadc7a..3d4b883a7660 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -53,7 +53,7 @@ #include <linux/exportfs.h> #include <linux/hashtable.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "orangefs-dev-proto.h" diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 72c53129c952..d39ee5f6c075 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -12,7 +12,7 @@ #include <linux/highmem.h> #include <linux/slab.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/buffer_head.h> #include <linux/mpage.h> #include <linux/writeback.h> diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index f0e1f29f20ee..12fc20af8e17 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h @@ -11,7 +11,7 @@ #include <linux/sched.h> #include <linux/bug.h> #include <linux/workqueue.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitops.h> #include <linux/proc_fs.h> #include <linux/buffer_head.h> diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h index c3b6263060b0..409b43adb20d 100644 --- a/fs/smb/client/cifspdu.h +++ b/fs/smb/client/cifspdu.h @@ -10,7 +10,7 @@ #define _CIFSPDU_H #include <net/sock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "../common/smbfsctl.h" #define CIFS_PROT 0 diff --git a/fs/smb/client/compress/lz77.c b/fs/smb/client/compress/lz77.c index 553e253ada29..96e8a8057a77 100644 --- a/fs/smb/client/compress/lz77.c +++ b/fs/smb/client/compress/lz77.c @@ -9,7 +9,7 @@ #include <linux/slab.h> #include <linux/sizes.h> #include <linux/count_zeros.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "lz77.h" diff --git a/fs/smb/server/unicode.c b/fs/smb/server/unicode.c index 43ed29ee44ea..217106ff7b82 100644 --- a/fs/smb/server/unicode.c +++ b/fs/smb/server/unicode.c @@ -8,7 +8,7 @@ */ #include <linux/fs.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "glob.h" #include "unicode.h" #include "smb_common.h" diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 54a098fe7285..9a2221b4aa21 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -69,7 +69,7 @@ typedef __u32 xfs_nlink_t; #include <asm/param.h> #include <linux/uaccess.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "xfs_fs.h" #include "xfs_stats.h" diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild index 620b6da429d4..1b43c3a77012 100644 --- a/include/asm-generic/Kbuild +++ b/include/asm-generic/Kbuild @@ -58,7 +58,6 @@ mandatory-y += tlbflush.h mandatory-y += topology.h mandatory-y += trace_clock.h mandatory-y += uaccess.h -mandatory-y += unaligned.h mandatory-y += vermagic.h mandatory-y += vga.h mandatory-y += video.h diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index a5be9e61a2a2..b276f783494c 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -11,7 +11,7 @@ #include <asm-generic/access_ok.h> #ifdef CONFIG_UACCESS_MEMCPY -#include <asm/unaligned.h> +#include <linux/unaligned.h> static __always_inline int __get_user_fn(size_t size, const void __user *from, void *to) diff --git a/include/crypto/chacha.h b/include/crypto/chacha.h index b3ea73b81944..5bae6a55b333 100644 --- a/include/crypto/chacha.h +++ b/include/crypto/chacha.h @@ -15,7 +15,7 @@ #ifndef _CRYPTO_CHACHA_H #define _CRYPTO_CHACHA_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/types.h> /* 32-bit stream position, then 96-bit nonce (RFC7539 convention) */ diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h index 0717a53ae732..065f00e4bf40 100644 --- a/include/crypto/internal/ecc.h +++ b/include/crypto/internal/ecc.h @@ -27,7 +27,7 @@ #define _CRYPTO_ECC_H #include <crypto/ecc_curve.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* One digit is u64 qword. */ #define ECC_CURVE_NIST_P192_DIGITS 3 diff --git a/include/crypto/internal/poly1305.h b/include/crypto/internal/poly1305.h index 196aa769f296..e614594f88c1 100644 --- a/include/crypto/internal/poly1305.h +++ b/include/crypto/internal/poly1305.h @@ -6,7 +6,7 @@ #ifndef _CRYPTO_INTERNAL_POLY1305_H #define _CRYPTO_INTERNAL_POLY1305_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/types.h> #include <crypto/poly1305.h> diff --git a/include/crypto/sha1_base.h b/include/crypto/sha1_base.h index 2e0e7c3827d1..0c342ed0d038 100644 --- a/include/crypto/sha1_base.h +++ b/include/crypto/sha1_base.h @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> typedef void (sha1_block_fn)(struct sha1_state *sst, u8 const *src, int blocks); diff --git a/include/crypto/sha256_base.h b/include/crypto/sha256_base.h index ab904d82236f..e0418818d63c 100644 --- a/include/crypto/sha256_base.h +++ b/include/crypto/sha256_base.h @@ -9,7 +9,7 @@ #define _CRYPTO_SHA256_BASE_H #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/sha2.h> #include <linux/string.h> diff --git a/include/crypto/sha512_base.h b/include/crypto/sha512_base.h index b370b3340b16..679916a84cb2 100644 --- a/include/crypto/sha512_base.h +++ b/include/crypto/sha512_base.h @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> typedef void (sha512_block_fn)(struct sha512_state *sst, u8 const *src, int blocks); diff --git a/include/crypto/sm3_base.h b/include/crypto/sm3_base.h index 2f3a32ab97bb..b33ed39c2bce 100644 --- a/include/crypto/sm3_base.h +++ b/include/crypto/sm3_base.h @@ -14,7 +14,7 @@ #include <linux/crypto.h> #include <linux/module.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> typedef void (sm3_block_fn)(struct sm3_state *sst, u8 const *src, int blocks); diff --git a/include/crypto/utils.h b/include/crypto/utils.h index acbb917a00c6..2594f45777b5 100644 --- a/include/crypto/utils.h +++ b/include/crypto/utils.h @@ -7,7 +7,7 @@ #ifndef _CRYPTO_UTILS_H #define _CRYPTO_UTILS_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/compiler_attributes.h> #include <linux/types.h> diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h index 04f3ace5787b..8fc1aed64113 100644 --- a/include/linux/ceph/decode.h +++ b/include/linux/ceph/decode.h @@ -6,7 +6,7 @@ #include <linux/bug.h> #include <linux/slab.h> #include <linux/time.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ceph/types.h> diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 4497d0a6772c..15fb566d3f46 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -4,7 +4,7 @@ #include <linux/ceph/ceph_debug.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/backing-dev.h> #include <linux/completion.h> #include <linux/exportfs.h> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 30114c25ad12..ecf203f01034 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -21,7 +21,7 @@ #include <linux/netdevice.h> #include <linux/random.h> #include <linux/crc32.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/bitsperlong.h> #ifdef __KERNEL__ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 30cef3b940eb..456bca45ff05 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -20,7 +20,7 @@ #include <linux/etherdevice.h> #include <linux/bitfield.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * DS bit usage diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index b4fa92a6e44b..1b56796f6cb3 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -15,7 +15,7 @@ #include <linux/kernel.h> #include <linux/io.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/barrier.h> #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h index 1b5a953c6bbc..3a74f69e0b59 100644 --- a/include/linux/ptp_classify.h +++ b/include/linux/ptp_classify.h @@ -10,7 +10,7 @@ #ifndef _PTP_CLASSIFY_H_ #define _PTP_CLASSIFY_H_ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/ip.h> #include <linux/ktime.h> #include <linux/skbuff.h> diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 2f8dc47f1eb0..5f775e104f9a 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -13,7 +13,7 @@ #include <linux/uio.h> #include <asm/byteorder.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/scatterlist.h> struct bio_vec; diff --git a/include/linux/tpm.h b/include/linux/tpm.h index e93ee8d936a9..587b96b4418e 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -537,7 +537,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, int rc); void tpm2_end_auth_session(struct tpm_chip *chip); #else -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline int tpm2_start_auth_session(struct tpm_chip *chip) { diff --git a/include/asm-generic/unaligned.h b/include/linux/unaligned.h similarity index 96% rename from include/asm-generic/unaligned.h rename to include/linux/unaligned.h index 95acdd70b3b2..4a9651017e3c 100644 --- a/include/asm-generic/unaligned.h +++ b/include/linux/unaligned.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ASM_GENERIC_UNALIGNED_H -#define __ASM_GENERIC_UNALIGNED_H +#ifndef __LINUX_UNALIGNED_H +#define __LINUX_UNALIGNED_H /* * This is the most generic implementation of unaligned accesses @@ -143,4 +143,4 @@ static inline u64 get_unaligned_be48(const void *p) return __get_unaligned_be48(p); } -#endif /* __ASM_GENERIC_UNALIGNED_H */ +#endif /* __LINUX_UNALIGNED_H */ diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 313d0b972e06..d9c767cf773d 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -27,7 +27,7 @@ #ifndef __L2CAP_H #define __L2CAP_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> /* L2CAP defaults */ diff --git a/include/net/calipso.h b/include/net/calipso.h index f8667a3fda9e..76b9e08c10c2 100644 --- a/include/net/calipso.h +++ b/include/net/calipso.h @@ -25,7 +25,7 @@ #include <net/netlabel.h> #include <net/request_sock.h> #include <linux/refcount.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* known doi values */ #define CALIPSO_DOI_UNKNOWN 0x00000000 diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index c9111bb2f59b..d6780d7903f4 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h @@ -28,7 +28,7 @@ #include <net/request_sock.h> #include <linux/atomic.h> #include <linux/refcount.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* known doi values */ #define CIPSO_V4_DOI_UNKNOWN 0x00000000 diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index 91762faecc13..02fbc036f34e 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h @@ -18,7 +18,7 @@ #define __RADIOTAP_H #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /** * struct ieee80211_radiotap_header - base radiotap header diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 954dff901b69..333e0fae6796 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -22,7 +22,7 @@ #include <net/cfg80211.h> #include <net/codel.h> #include <net/ieee80211_radiotap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /** * DOC: Introduction diff --git a/include/net/mac802154.h b/include/net/mac802154.h index 1b5488fa2ff0..d72006a85f02 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -7,7 +7,7 @@ #ifndef NET_MAC802154_H #define NET_MAC802154_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/af_ieee802154.h> #include <linux/ieee802154.h> #include <linux/skbuff.h> diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 49708e7e1339..91ae20cb7648 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -2,7 +2,7 @@ #ifndef _NET_NF_TABLES_H #define _NET_NF_TABLES_H -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/list.h> #include <linux/netfilter.h> #include <linux/netfilter/nfnetlink.h> diff --git a/include/rdma/ib_hdrs.h b/include/rdma/ib_hdrs.h index 8ae07c0ecdf7..1c4c1a69937a 100644 --- a/include/rdma/ib_hdrs.h +++ b/include/rdma/ib_hdrs.h @@ -7,7 +7,7 @@ #define IB_HDRS_H #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <rdma/ib_verbs.h> #define IB_SEQ_NAK (3 << 29) diff --git a/include/rdma/iba.h b/include/rdma/iba.h index 6a1115b02a0d..dcae154edc26 100644 --- a/include/rdma/iba.h +++ b/include/rdma/iba.h @@ -7,7 +7,7 @@ #include <linux/kernel.h> #include <linux/bitfield.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static inline u32 _iba_get8(const u8 *ptr) { diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 8e6c60090c62..d02b55261307 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -12,7 +12,7 @@ #include <linux/sched.h> #include <linux/bsg-lib.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_netlink.h> #include <scsi/scsi_host.h> diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 739df993aa5e..4063a701081b 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -3,7 +3,7 @@ #define TARGET_CORE_BACKEND_H #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #define TRANSPORT_FLAG_PASSTHROUGH 0x1 diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 4e07cc057d6f..5e77c58e0601 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -40,7 +40,7 @@ #include <linux/execmem.h> #include <asm/barrier.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* Registers */ #define BPF_R0 regs[BPF_REG_0] diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index 9d34d2364b5a..f625172d4b67 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c @@ -33,7 +33,7 @@ #include <linux/reboot.h> #include <linux/uaccess.h> #include <asm/cacheflush.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "debug_core.h" #define KGDB_MAX_THREAD_QUERY 17 diff --git a/lib/842/842.h b/lib/842/842.h index 7b1f581a2907..f9e8a5dd790f 100644 --- a/lib/842/842.h +++ b/lib/842/842.h @@ -78,7 +78,7 @@ #include <linux/kernel.h> #include <linux/bitops.h> #include <linux/crc32.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/sw842.h> diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index 827fe89922ff..eafe14d021f5 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -6,7 +6,7 @@ #include <crypto/aes.h> #include <linux/crypto.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * Emit the sbox as volatile const to prevent the compiler from doing diff --git a/lib/crypto/blake2s-generic.c b/lib/crypto/blake2s-generic.c index 3b6dcfdd9628..09682136b57c 100644 --- a/lib/crypto/blake2s-generic.c +++ b/lib/crypto/blake2s-generic.c @@ -14,7 +14,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/bug.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static const u8 blake2s_sigma[10][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, diff --git a/lib/crypto/chacha.c b/lib/crypto/chacha.c index b748fd3d256e..3cdda3b5ee06 100644 --- a/lib/crypto/chacha.c +++ b/lib/crypto/chacha.c @@ -10,7 +10,7 @@ #include <linux/export.h> #include <linux/bitops.h> #include <linux/string.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/chacha.h> static void chacha_permute(u32 *x, int nrounds) diff --git a/lib/crypto/chacha20poly1305-selftest.c b/lib/crypto/chacha20poly1305-selftest.c index fa43deda2660..2ea61c28be4f 100644 --- a/lib/crypto/chacha20poly1305-selftest.c +++ b/lib/crypto/chacha20poly1305-selftest.c @@ -7,7 +7,7 @@ #include <crypto/chacha.h> #include <crypto/poly1305.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bug.h> #include <linux/init.h> #include <linux/mm.h> diff --git a/lib/crypto/chacha20poly1305.c b/lib/crypto/chacha20poly1305.c index fa6a9440fc95..a839c0ac60b2 100644 --- a/lib/crypto/chacha20poly1305.c +++ b/lib/crypto/chacha20poly1305.c @@ -13,7 +13,7 @@ #include <crypto/poly1305.h> #include <crypto/scatterwalk.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/mm.h> diff --git a/lib/crypto/curve25519-fiat32.c b/lib/crypto/curve25519-fiat32.c index 2fde0ec33dbd..2e0ba634e299 100644 --- a/lib/crypto/curve25519-fiat32.c +++ b/lib/crypto/curve25519-fiat32.c @@ -10,7 +10,7 @@ * with 128-bit integer types. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/curve25519.h> #include <linux/string.h> diff --git a/lib/crypto/curve25519-hacl64.c b/lib/crypto/curve25519-hacl64.c index c40e5d913234..c4204133afb7 100644 --- a/lib/crypto/curve25519-hacl64.c +++ b/lib/crypto/curve25519-hacl64.c @@ -10,7 +10,7 @@ * integer types. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/curve25519.h> #include <linux/string.h> diff --git a/lib/crypto/des.c b/lib/crypto/des.c index 9518658b97cf..d3423b34a8e9 100644 --- a/lib/crypto/des.c +++ b/lib/crypto/des.c @@ -17,7 +17,7 @@ #include <linux/string.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/des.h> #include <crypto/internal/des.h> diff --git a/lib/crypto/memneq.c b/lib/crypto/memneq.c index 243d8677cc51..a2afd10349c9 100644 --- a/lib/crypto/memneq.c +++ b/lib/crypto/memneq.c @@ -59,7 +59,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/algapi.h> #include <linux/module.h> diff --git a/lib/crypto/poly1305-donna32.c b/lib/crypto/poly1305-donna32.c index 7fb71845cc84..0a4a2d99e365 100644 --- a/lib/crypto/poly1305-donna32.c +++ b/lib/crypto/poly1305-donna32.c @@ -7,7 +7,7 @@ */ #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/poly1305.h> void poly1305_core_setkey(struct poly1305_core_key *key, diff --git a/lib/crypto/poly1305-donna64.c b/lib/crypto/poly1305-donna64.c index 988702c9b3b2..530287531b2e 100644 --- a/lib/crypto/poly1305-donna64.c +++ b/lib/crypto/poly1305-donna64.c @@ -7,7 +7,7 @@ */ #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/internal/poly1305.h> void poly1305_core_setkey(struct poly1305_core_key *key, diff --git a/lib/crypto/poly1305.c b/lib/crypto/poly1305.c index 5d8378d23e95..6e80214ebad8 100644 --- a/lib/crypto/poly1305.c +++ b/lib/crypto/poly1305.c @@ -10,7 +10,7 @@ #include <crypto/internal/poly1305.h> #include <linux/kernel.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> void poly1305_init_generic(struct poly1305_desc_ctx *desc, const u8 key[POLY1305_KEY_SIZE]) diff --git a/lib/crypto/sha1.c b/lib/crypto/sha1.c index 6d2922747cab..ebb60519ae93 100644 --- a/lib/crypto/sha1.c +++ b/lib/crypto/sha1.c @@ -12,7 +12,7 @@ #include <linux/bitops.h> #include <linux/string.h> #include <crypto/sha1.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * If you have 32 registers or more, the compiler can (and should) diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c index 3f42d203c7bc..04c1f2557e6c 100644 --- a/lib/crypto/sha256.c +++ b/lib/crypto/sha256.c @@ -11,7 +11,7 @@ * Copyright (c) 2014 Red Hat Inc. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/sha256_base.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/lib/crypto/utils.c b/lib/crypto/utils.c index 373364141408..87da2a6dd161 100644 --- a/lib/crypto/utils.c +++ b/lib/crypto/utils.c @@ -5,7 +5,7 @@ * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/utils.h> #include <linux/module.h> diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c index e6327391b6b6..c0dbb3cea915 100644 --- a/lib/decompress_unlz4.c +++ b/lib/decompress_unlz4.c @@ -16,7 +16,7 @@ #include <linux/decompress/mm.h> #include <linux/compiler.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* * Note: Uncompressed chunk size is used in the compressor side diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c index 64c1358500ce..57a9e93743e1 100644 --- a/lib/decompress_unlzo.c +++ b/lib/decompress_unlzo.c @@ -28,7 +28,7 @@ #include <linux/decompress/mm.h> #include <linux/compiler.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static const unsigned char lzop_magic[] = { 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a }; diff --git a/lib/hexdump.c b/lib/hexdump.c index 06833d404398..c3db7c3a7643 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/minmax.h> #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> const char hex_asc[] = "0123456789abcdef"; EXPORT_SYMBOL(hex_asc); diff --git a/lib/lz4/lz4_compress.c b/lib/lz4/lz4_compress.c index 90bb67994688..b0bbeeb74b9e 100644 --- a/lib/lz4/lz4_compress.c +++ b/lib/lz4/lz4_compress.c @@ -37,7 +37,7 @@ #include "lz4defs.h" #include <linux/module.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static const int LZ4_minLength = (MFLIMIT + 1); static const int LZ4_64Klimit = ((64 * KB) + (MFLIMIT - 1)); diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c index 59fe69a63800..0e31e6da5ce7 100644 --- a/lib/lz4/lz4_decompress.c +++ b/lib/lz4/lz4_decompress.c @@ -38,7 +38,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /*-***************************** * Decompression functions diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h index 330aa539b46e..cb358d6bde5a 100644 --- a/lib/lz4/lz4defs.h +++ b/lib/lz4/lz4defs.h @@ -35,7 +35,7 @@ * Sven Schmidt <4sschmid@informatik.uni-hamburg.de> */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/bitops.h> #include <linux/string.h> /* memset, memcpy */ diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c index 9d31e7126606..47d6d43ea957 100644 --- a/lib/lzo/lzo1x_compress.c +++ b/lib/lzo/lzo1x_compress.c @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/lzo.h> #include "lzodefs.h" diff --git a/lib/lzo/lzo1x_decompress_safe.c b/lib/lzo/lzo1x_decompress_safe.c index 7892a40cf765..c94f4928e188 100644 --- a/lib/lzo/lzo1x_decompress_safe.c +++ b/lib/lzo/lzo1x_decompress_safe.c @@ -16,7 +16,7 @@ #include <linux/module.h> #include <linux/kernel.h> #endif -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/lzo.h> #include "lzodefs.h" diff --git a/lib/pldmfw/pldmfw.c b/lib/pldmfw/pldmfw.c index 54e1809a38fd..6e1581b9a616 100644 --- a/lib/pldmfw/pldmfw.c +++ b/lib/pldmfw/pldmfw.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2018-2019, Intel Corporation. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc32.h> #include <linux/device.h> #include <linux/firmware.h> diff --git a/lib/random32.c b/lib/random32.c index 32060b852668..0a5a0e3600c8 100644 --- a/lib/random32.c +++ b/lib/random32.c @@ -40,7 +40,7 @@ #include <linux/sched.h> #include <linux/bitops.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /** * prandom_u32_state - seeded pseudo-random number generator. diff --git a/lib/siphash.c b/lib/siphash.c index 15bc5b6f368c..9e4e88752d2e 100644 --- a/lib/siphash.c +++ b/lib/siphash.c @@ -10,7 +10,7 @@ */ #include <linux/siphash.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 #include <linux/dcache.h> diff --git a/lib/string.c b/lib/string.c index 966da44bfc86..76327b51e36f 100644 --- a/lib/string.c +++ b/lib/string.c @@ -27,7 +27,7 @@ #include <asm/page.h> #include <asm/rwonce.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/word-at-a-time.h> #ifndef __HAVE_ARCH_STRNCASECMP diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 09f022ba1c05..c5e2ec9303c5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -51,7 +51,7 @@ #include <asm/page.h> /* for PAGE_SIZE */ #include <asm/byteorder.h> /* cpu_to_le16 */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/string_helpers.h> #include "kstrtox.h" diff --git a/lib/xxhash.c b/lib/xxhash.c index d5bb9ff10607..b5bd567aa6b3 100644 --- a/lib/xxhash.c +++ b/lib/xxhash.c @@ -38,7 +38,7 @@ * - xxHash source repository: https://github.com/Cyan4973/xxHash */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/errno.h> #include <linux/compiler.h> #include <linux/kernel.h> diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h index 5f1294a1408c..8409784b1639 100644 --- a/lib/xz/xz_private.h +++ b/lib/xz/xz_private.h @@ -12,7 +12,7 @@ #ifdef __KERNEL__ # include <linux/xz.h> # include <linux/kernel.h> -# include <asm/unaligned.h> +# include <linux/unaligned.h> /* XZ_PREBOOT may be defined only via decompress_unxz.c. */ # ifndef XZ_PREBOOT # include <linux/slab.h> diff --git a/lib/zstd/common/mem.h b/lib/zstd/common/mem.h index 1d9cc03924ca..c22a2e69bf46 100644 --- a/lib/zstd/common/mem.h +++ b/lib/zstd/common/mem.h @@ -15,7 +15,7 @@ /*-**************************************** * Dependencies ******************************************/ -#include <asm/unaligned.h> /* get_unaligned, put_unaligned* */ +#include <linux/unaligned.h> /* get_unaligned, put_unaligned* */ #include <linux/compiler.h> /* inline */ #include <linux/swab.h> /* swab32, swab64 */ #include <linux/types.h> /* size_t, ptrdiff_t */ diff --git a/net/802/garp.c b/net/802/garp.c index 6a743d004301..27f0ab146026 100644 --- a/net/802/garp.c +++ b/net/802/garp.c @@ -16,7 +16,7 @@ #include <net/llc.h> #include <net/llc_pdu.h> #include <net/garp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static unsigned int garp_join_time __read_mostly = 200; module_param(garp_join_time, uint, 0644); diff --git a/net/802/mrp.c b/net/802/mrp.c index 3154d7409493..e0c96d0da8d5 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c @@ -16,7 +16,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <net/mrp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> static unsigned int mrp_join_time __read_mostly = 200; module_param(mrp_join_time, uint, 0644); diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 4c7e85534324..801eff8a40e5 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -7,7 +7,7 @@ #include "distributed-arp-table.h" #include "main.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/atomic.h> #include <linux/bitops.h> #include <linux/byteorder/generic.h> diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ec45f77fce21..a3bc0934cc13 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -29,7 +29,7 @@ #include <linux/kthread.h> #include <linux/file.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/l2cap.h> diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c index ec97a4bab1c9..c18df3a08607 100644 --- a/net/bluetooth/coredump.c +++ b/net/bluetooth/coredump.c @@ -5,7 +5,7 @@ #include <linux/devcoredump.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/net/bluetooth/eir.h b/net/bluetooth/eir.h index 0df19f2f4af9..5c89a05e8b29 100644 --- a/net/bluetooth/eir.h +++ b/net/bluetooth/eir.h @@ -5,7 +5,7 @@ * Copyright (C) 2021 Intel Corporation */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> void eir_create(struct hci_dev *hdev, u8 *data); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d6976db02c06..41db06bb6171 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -33,7 +33,7 @@ #include <linux/property.h> #include <linux/suspend.h> #include <linux/wait.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 1c82dcdf6e8f..9e0f5a41f207 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -25,7 +25,7 @@ /* Bluetooth HCI event handling. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crypto.h> #include <crypto/algapi.h> diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 69c2ba1e843e..2272e1849ebd 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -27,7 +27,7 @@ #include <linux/export.h> #include <linux/utsname.h> #include <linux/sched.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index e4f564d6f6fb..96fccfa5b006 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -25,7 +25,7 @@ /* Bluetooth HCI Management interface */ #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c index 0115f783bde8..17ab909a7c07 100644 --- a/net/bluetooth/mgmt_util.c +++ b/net/bluetooth/mgmt_util.c @@ -21,7 +21,7 @@ SOFTWARE IS DISCLAIMED. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 1d34d8497033..ad5177e3a69b 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -28,7 +28,7 @@ #include <linux/module.h> #include <linux/debugfs.h> #include <linux/kthread.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index ad7a42b505ef..642b8ccaae8e 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -18,7 +18,7 @@ #include <linux/random.h> #include <linux/slab.h> #include <linux/atomic.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/if_vlan.h> #include <net/switchdev.h> #include <trace/events/bridge.h> diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 0e4572f31330..7895489ac6fe 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c @@ -17,7 +17,7 @@ #include <net/llc.h> #include <net/llc_pdu.h> #include <net/stp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "br_private.h" #include "br_private_stp.h" diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index 7b0af33bdb97..3c335057f255 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -9,7 +9,7 @@ #include <linux/stddef.h> #include <linux/spinlock.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/caif/caif_layer.h> #include <net/caif/cfsrvl.h> #include <net/caif/cfpkt.h> diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 2e0ae3328232..6efd4cccc9dd 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -37,7 +37,7 @@ #include <trace/events/napi.h> #include <trace/events/devlink.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define TRACE_ON 1 #define TRACE_OFF 0 diff --git a/net/core/filter.c b/net/core/filter.c index cd3524cb326b..bd0d08bf76bb 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -42,7 +42,7 @@ #include <linux/errno.h> #include <linux/timer.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/filter.h> #include <linux/ratelimit.h> #include <linux/seccomp.h> diff --git a/net/core/net-traces.c b/net/core/net-traces.c index 6aef976bc1da..f2fa34b1d78d 100644 --- a/net/core/net-traces.c +++ b/net/core/net-traces.c @@ -23,7 +23,7 @@ #include <linux/net_dropmon.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <asm/bitops.h> #define CREATE_TRACE_POINTS diff --git a/net/core/netpoll.c b/net/core/netpoll.c index ca52cbe0f63c..aa49b92e9194 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -34,7 +34,7 @@ #include <net/addrconf.h> #include <net/ndisc.h> #include <net/ip6_checksum.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <trace/events/napi.h> #include <linux/kconfig.h> diff --git a/net/core/sock.c b/net/core/sock.c index fe87f9bd8f16..039be95c40cf 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -85,7 +85,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/capability.h> #include <linux/errno.h> #include <linux/errqueue.h> diff --git a/net/core/tso.c b/net/core/tso.c index e00796e3b146..6df997b9076e 100644 --- a/net/core/tso.c +++ b/net/core/tso.c @@ -3,7 +3,7 @@ #include <linux/if_vlan.h> #include <net/ip.h> #include <net/tso.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso, int size, bool is_last) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index ca8670f78ac6..f349d16dd8f6 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -22,7 +22,7 @@ #include "../dccp.h" #include "ccid3.h" -#include <asm/unaligned.h> +#include <linux/unaligned.h> #ifdef CONFIG_IP_DCCP_CCID3_DEBUG static bool ccid3_debug; diff --git a/net/dccp/options.c b/net/dccp/options.c index d24cad05001e..db62d4767024 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -10,7 +10,7 @@ #include <linux/dccp.h> #include <linux/module.h> #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/skbuff.h> diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 8cc0e2f4159d..740af8541d2f 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -37,7 +37,7 @@ #include <net/cipso_ipv4.h> #include <linux/atomic.h> #include <linux/bug.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* List of available DOI definitions */ /* XXX - This currently assumes a minimal number of different DOIs in use, diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index a9e22a098872..68aedb8877b9 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -17,7 +17,7 @@ #include <linux/slab.h> #include <linux/types.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/skbuff.h> #include <linux/ip.h> #include <linux/icmp.h> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9f314dfa1490..cc05ec1faac8 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -75,7 +75,7 @@ #include <net/proto_memory.h> #include <net/inet_common.h> #include <linux/ipsec.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/errqueue.h> #include <trace/events/tcp.h> #include <linux/jump_label_ratelimit.h> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d680beb91b0a..94dceac52884 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -85,7 +85,7 @@ #include <linux/netconf.h> #include <linux/random.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index eb8ee1e9373a..dbcea9fee626 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -29,7 +29,7 @@ #include <net/calipso.h> #include <linux/atomic.h> #include <linux/bug.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/crc-ccitt.h> /* Maximium size of the calipso option including diff --git a/net/mac80211/key.c b/net/mac80211/key.c index eecdd2265eaa..6fac3ba00d88 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -18,7 +18,7 @@ #include <linux/slab.h> #include <linux/export.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ieee80211_i.h" #include "driver-ops.h" #include "debugfs_key.h" diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index f94e4be0be12..640239f4425b 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -7,7 +7,7 @@ */ #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ieee80211_i.h" #include "mesh.h" #include "wme.h" diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 024f48db6b05..579d0f24ac9d 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -7,7 +7,7 @@ #include <linux/slab.h> #include <linux/etherdevice.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "wme.h" #include "mesh.h" diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c index a57502d9ffec..8a1afc93e749 100644 --- a/net/mac80211/michael.c +++ b/net/mac80211/michael.c @@ -6,7 +6,7 @@ #include <linux/types.h> #include <linux/bitops.h> #include <linux/ieee80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "michael.h" diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 735e78adb0db..0303972c23e4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -23,7 +23,7 @@ #include <linux/slab.h> #include <linux/export.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ieee80211_i.h" #include "driver-ops.h" diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c index 9ef14e475c90..f4c51e4a1e29 100644 --- a/net/mac80211/ocb.c +++ b/net/mac80211/ocb.c @@ -16,7 +16,7 @@ #include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ieee80211_i.h" #include "driver-ops.h" diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 59ad24a71141..694b43091fec 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -22,7 +22,7 @@ #include <kunit/visibility.h> #include <net/mac80211.h> #include <net/ieee80211_radiotap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ieee80211_i.h" #include "driver-ops.h" diff --git a/net/mac80211/status.c b/net/mac80211/status.c index d1cf987de13b..b41b867f43b2 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -11,7 +11,7 @@ #include <linux/export.h> #include <linux/etherdevice.h> #include <net/mac80211.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "ieee80211_i.h" #include "rate.h" #include "mesh.h" diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index e7f57bb18f6e..880a1fa8705a 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -9,7 +9,7 @@ #include <linux/types.h> #include <linux/netdevice.h> #include <linux/export.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac80211.h> #include "driver-ops.h" diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a9ee86982259..0ff8b56f5807 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -24,7 +24,7 @@ #include <net/mac80211.h> #include <net/codel.h> #include <net/codel_impl.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/fq_impl.h> #include <net/gso.h> diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 5c01e121481a..93b8668079a7 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -16,7 +16,7 @@ #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac80211.h> #include "ieee80211_i.h" diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 047a33797020..293afa3f57c5 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -12,7 +12,7 @@ #include <linux/compiler.h> #include <linux/ieee80211.h> #include <linux/gfp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac80211.h> #include <crypto/aes.h> #include <crypto/utils.h> diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index e40a988d6c80..aac359b5c71d 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -13,7 +13,7 @@ #include <linux/module.h> #include <linux/netdevice.h> #include <linux/crc-ccitt.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/mac802154.h> #include <net/ieee802154_netdev.h> diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 6fbed5bb5c3e..337d6faf0d2a 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -12,7 +12,7 @@ #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/crc-ccitt.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/rtnetlink.h> #include <net/ieee802154_netdev.h> diff --git a/net/mptcp/crypto.c b/net/mptcp/crypto.c index a8931349933c..b08ba959ac4f 100644 --- a/net/mptcp/crypto.c +++ b/net/mptcp/crypto.c @@ -22,7 +22,7 @@ #include <linux/kernel.h> #include <crypto/sha2.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "protocol.h" diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index f53899d12416..d8a284999544 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -35,7 +35,7 @@ #include <linux/gfp.h> #include <net/protocol.h> #include <net/tcp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/ip_vs.h> diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index be74c0906dda..3402675bf521 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -51,7 +51,7 @@ #include <linux/kernel.h> #include <linux/sched/signal.h> -#include <asm/unaligned.h> /* Used for ntoh_seq and hton_seq */ +#include <linux/unaligned.h> /* Used for ntoh_seq and hton_seq */ #include <net/ip.h> #include <net/sock.h> diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index ae493599a3ef..0c1d086e96cb 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -14,7 +14,7 @@ #include <linux/skbuff.h> #include <linux/ipv6.h> #include <net/ip6_checksum.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/tcp.h> diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index 5b140c12b7df..3fa3f5dfb264 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -5,7 +5,7 @@ #include <linux/module.h> #include <linux/skbuff.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/tcp.h> #include <net/netns/generic.h> #include <linux/proc_fs.h> diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c index 2f82a444d21b..af9206a3afd1 100644 --- a/net/netfilter/nft_byteorder.c +++ b/net/netfilter/nft_byteorder.c @@ -5,7 +5,7 @@ * Development of this code funded by Astaro AG (http://www.astaro.com/) */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index 6bfd33516241..b8d03364566c 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -5,7 +5,7 @@ * Development of this code funded by Astaro AG (http://www.astaro.com/) */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/kernel.h> #include <linux/netlink.h> #include <linux/netfilter.h> diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 2b582da1e88c..a27efa4faa4e 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -13,7 +13,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/sock.h> #include <linux/if_phonet.h> diff --git a/net/sched/em_cmp.c b/net/sched/em_cmp.c index c90ad7ea26b4..64b637f18bc7 100644 --- a/net/sched/em_cmp.c +++ b/net/sched/em_cmp.c @@ -10,7 +10,7 @@ #include <linux/kernel.h> #include <linux/skbuff.h> #include <linux/tc_ematch/tc_em_cmp.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <net/pkt_cls.h> static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp) diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index d72953f29258..ae3fb9bc8a21 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -94,7 +94,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index bb5436b719e0..96154a2367a1 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -100,7 +100,7 @@ */ #include <linux/spinlock.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> diff --git a/net/tls/trace.h b/net/tls/trace.h index 9ba5f600ea43..2d8ce4ff3265 100644 --- a/net/tls/trace.h +++ b/net/tls/trace.h @@ -7,7 +7,7 @@ #if !defined(_TLS_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #define _TLS_TRACE_H_ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/tracepoint.h> struct sock; diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index ae2e1a896461..b7e3e46ec16d 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -18,7 +18,7 @@ #include <linux/export.h> #include <net/cfg80211.h> #include <net/ieee80211_radiotap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> /* function prototypes and related defs are in include/net/cfg80211.h */ diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 55f039ec3d59..2b10a45ff124 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -33,7 +33,7 @@ #if IS_ENABLED(CONFIG_IPV6) #include <linux/in6.h> #endif -#include <asm/unaligned.h> +#include <linux/unaligned.h> static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type, struct netlink_ext_ack *extack) diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 5a570235427d..3483c595f999 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -13,7 +13,7 @@ * All policy is validated before it is used. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <kunit/visibility.h> #include <linux/ctype.h> #include <linux/errno.h> diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c index 8b7dd73d94c1..024be262702f 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -14,7 +14,7 @@ #include <keys/trusted-type.h> #include <keys/trusted_tpm.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "tpm2key.asn1.h" diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index 29a1a7a0d050..46f081268348 100644 --- a/sound/i2c/cs8427.c +++ b/sound/i2c/cs8427.c @@ -10,7 +10,7 @@ #include <linux/init.h> #include <linux/bitrev.h> #include <linux/module.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <sound/core.h> #include <sound/control.h> #include <sound/pcm.h> diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 1d108ed5c6f2..301730432375 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <sound/core.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <sound/hda_chmap.h> #include <sound/hda_codec.h> #include "hda_local.h" diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index f58f434e7110..7232b0a9c677 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -7,7 +7,7 @@ // Author: Shenghao Ding <shenghao-ding@ti.com> // Current maintainer: Baojun Xu <baojun.xu@ti.com> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/acpi.h> #include <linux/crc8.h> #include <linux/crc32.h> diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 8bd6067df7f7..291249e0a2a3 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -21,7 +21,7 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sigmadsp.h" #include "adau1701.h" diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index f2932713b4de..4dcc984761e0 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -19,7 +19,7 @@ #include <linux/i2c.h> #include <linux/spi/spi.h> #include <linux/regmap.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sigmadsp.h" #include "adau17x1.h" diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c index 6641e7c1ddf4..5d99877f8839 100644 --- a/sound/soc/codecs/pcm6240.c +++ b/sound/soc/codecs/pcm6240.c @@ -12,7 +12,7 @@ // Author: Shenghao Ding <shenghao-ding@ti.com> // -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/firmware.h> #include <linux/gpio.h> #include <linux/i2c.h> diff --git a/sound/soc/codecs/peb2466.c b/sound/soc/codecs/peb2466.c index 74b628ae1964..bb9ca6354ae1 100644 --- a/sound/soc/codecs/peb2466.c +++ b/sound/soc/codecs/peb2466.c @@ -6,7 +6,7 @@ // // Author: Herve Codina <herve.codina@bootlin.com> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/clk.h> #include <linux/firmware.h> #include <linux/gpio/consumer.h> diff --git a/sound/soc/codecs/sigmadsp-i2c.c b/sound/soc/codecs/sigmadsp-i2c.c index cb4c491078c2..07c9d89ab24a 100644 --- a/sound/soc/codecs/sigmadsp-i2c.c +++ b/sound/soc/codecs/sigmadsp-i2c.c @@ -9,7 +9,7 @@ #include <linux/i2c.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "sigmadsp.h" diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 3de0132c345d..ae360c97fe1e 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -20,7 +20,7 @@ #include <sound/soc.h> #include <sound/tlv.h> #include <sound/tas2781.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define ERROR_PRAM_CRCCHK 0x0000000 #define ERROR_YRAM_CRCCHK 0x0000001 diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index d0ba7cbe03a8..12d093437ba9 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -31,7 +31,7 @@ #include <sound/tlv.h> #include <sound/tas2563-tlv.h> #include <sound/tas2781-tlv.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #define X2563_CL_STT_VAL(xreg, xval) \ { .reg = xreg, \ diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index f249e93e2a4e..6c6e7ae07d80 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -27,7 +27,7 @@ #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/tlv.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "tas571x.h" diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 187d68e8688c..d81ab9c25c29 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -12,7 +12,7 @@ * and mono/stereo Class-D speaker driver. */ -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 651f1319204d..9fc7a8325724 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -25,7 +25,7 @@ #include <linux/mfd/arizona/core.h> #include <linux/mfd/arizona/registers.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "arizona.h" #include "wm5102.h" diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 7878c7a58ff1..d08419b108fe 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -25,7 +25,7 @@ #include <linux/mfd/wm8994/pdata.h> #include <linux/mfd/wm8994/gpio.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "wm8994.h" diff --git a/sound/soc/sof/iomem-utils.c b/sound/soc/sof/iomem-utils.c index cd9cb54e7b23..f6cb79082672 100644 --- a/sound/soc/sof/iomem-utils.c +++ b/sound/soc/sof/iomem-utils.c @@ -10,7 +10,7 @@ #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/platform_device.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <sound/soc.h> #include <sound/sof.h> #include "sof-priv.h" diff --git a/sound/soc/sof/sof-utils.c b/sound/soc/sof/sof-utils.c index 44608682e9f8..f70089317b8c 100644 --- a/sound/soc/sof/sof-utils.c +++ b/sound/soc/sof/sof-utils.c @@ -8,7 +8,7 @@ // Author: Keyon Jie <yang.jie@linux.intel.com> // -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/device.h> #include <sound/memalloc.h> diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c index a43b37346a22..ab5cdc3337da 100644 --- a/tools/arch/x86/lib/insn.c +++ b/tools/arch/x86/lib/insn.c @@ -13,7 +13,7 @@ #endif #include "../include/asm/inat.h" /* __ignore_sync_check__ */ #include "../include/asm/insn.h" /* __ignore_sync_check__ */ -#include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */ +#include "../include/linux/unaligned.h" /* __ignore_sync_check__ */ #include <linux/errno.h> #include <linux/kconfig.h> diff --git a/tools/include/asm-generic/unaligned.h b/tools/include/linux/unaligned.h similarity index 97% rename from tools/include/asm-generic/unaligned.h rename to tools/include/linux/unaligned.h index cdd2fd078027..bc0633bc4650 100644 --- a/tools/include/asm-generic/unaligned.h +++ b/tools/include/linux/unaligned.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ASM_GENERIC_UNALIGNED_H -#define __ASM_GENERIC_UNALIGNED_H +#ifndef __LINUX_UNALIGNED_H +#define __LINUX_UNALIGNED_H /* * This is the most generic implementation of unaligned accesses @@ -154,4 +154,4 @@ static inline u64 get_unaligned_be48(const void *p) } #pragma GCC diagnostic pop -#endif /* __ASM_GENERIC_UNALIGNED_H */ +#endif /* __LINUX_UNALIGNED_H */ diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 714c78e5da07..5d4f74b30102 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -163,7 +163,7 @@ check arch/x86/lib/memcpy_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/ex check arch/x86/lib/memset_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memset_\(erms\|orig\))"' check arch/x86/include/asm/amd-ibs.h '-I "^#include [<\"]\(asm/\)*msr-index.h"' check arch/arm64/include/asm/cputype.h '-I "^#include [<\"]\(asm/\)*sysreg.h"' -check include/asm-generic/unaligned.h '-I "^#include <linux/unaligned/packed_struct.h>" -I "^#include <asm/byteorder.h>" -I "^#pragma GCC diagnostic"' +check include/linux/unaligned.h '-I "^#include <linux/unaligned/packed_struct.h>" -I "^#include <asm/byteorder.h>" -I "^#pragma GCC diagnostic"' check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common\(-tools\)*.h>"' check include/uapi/linux/mman.h '-I "^#include <\(uapi/\)*asm/mman.h>"' check include/linux/build_bug.h '-I "^#\(ifndef\|endif\)\( \/\/\)* static_assert$"' diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c index 7bf607d0f6d8..4cef10a83962 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c @@ -11,7 +11,7 @@ #include <linux/bitops.h> #include <stdarg.h> #include <linux/kernel.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include "arm-spe-pkt-decoder.h" diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c index bccb988a7a44..94fb16cf9e0c 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c @@ -10,7 +10,7 @@ #include <byteswap.h> #include <linux/kernel.h> #include <linux/compiler.h> -#include <asm-generic/unaligned.h> +#include <linux/unaligned.h> #include "intel-pt-pkt-decoder.h" diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c index ccdd6a504222..ad5c4c18c5c6 100644 --- a/tools/testing/cxl/test/mem.c +++ b/tools/testing/cxl/test/mem.c @@ -9,7 +9,7 @@ #include <linux/sizes.h> #include <linux/bits.h> #include <cxl/mailbox.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <crypto/sha2.h> #include <cxlmem.h> diff --git a/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.h b/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.h index f8b1b7e68d2e..34024de6337e 100644 --- a/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.h +++ b/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.h @@ -22,7 +22,7 @@ __builtin_memcpy(b, __tmp, sizeof(a)); \ } while (0) -/* asm-generic/unaligned.h */ +/* linux/unaligned.h */ #define __get_unaligned_t(type, ptr) ({ \ const struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr); \ __pptr->x; \ -- GitLab From e9f49feefb4b13b36441aae51649a67a8389bd40 Mon Sep 17 00:00:00 2001 From: Shen Lichuan <shenlichuan@vivo.com> Date: Wed, 25 Sep 2024 14:55:43 +0800 Subject: [PATCH 636/970] smb: client: Correct typos in multiple comments across various files Fixed some confusing typos that were currently identified witch codespell, the details are as follows: -in the code comments: fs/smb/client/cifsacl.h:58: inheritence ==> inheritance fs/smb/client/cifsencrypt.c:242: origiginal ==> original fs/smb/client/cifsfs.c:164: referece ==> reference fs/smb/client/cifsfs.c:292: ned ==> need fs/smb/client/cifsglob.h:779: initital ==> initial fs/smb/client/cifspdu.h:784: altetnative ==> alternative fs/smb/client/cifspdu.h:2409: conrol ==> control fs/smb/client/cifssmb.c:1218: Expirement ==> Experiment fs/smb/client/cifssmb.c:3021: conver ==> convert fs/smb/client/cifssmb.c:3998: asterik ==> asterisk fs/smb/client/file.c:2505: useable ==> usable fs/smb/client/fs_context.h:263: timemout ==> timeout fs/smb/client/misc.c:257: responsbility ==> responsibility fs/smb/client/netmisc.c:1006: divisable ==> divisible fs/smb/client/readdir.c:556: endianess ==> endianness fs/smb/client/readdir.c:818: bu ==> by fs/smb/client/smb2ops.c:2180: snaphots ==> snapshots fs/smb/client/smb2ops.c:3586: otions ==> options fs/smb/client/smb2pdu.c:2979: timestaps ==> timestamps fs/smb/client/smb2pdu.c:4574: memmory ==> memory fs/smb/client/smb2transport.c:699: origiginal ==> original fs/smb/client/smbdirect.c:222: happenes ==> happens fs/smb/client/smbdirect.c:1347: registartions ==> registrations fs/smb/client/smbdirect.h:114: accoutning ==> accounting Signed-off-by: Shen Lichuan <shenlichuan@vivo.com> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/cifsacl.h | 2 +- fs/smb/client/cifsencrypt.c | 2 +- fs/smb/client/cifsfs.c | 4 ++-- fs/smb/client/cifsglob.h | 2 +- fs/smb/client/cifspdu.h | 4 ++-- fs/smb/client/cifssmb.c | 6 +++--- fs/smb/client/file.c | 2 +- fs/smb/client/fs_context.h | 2 +- fs/smb/client/misc.c | 2 +- fs/smb/client/netmisc.c | 2 +- fs/smb/client/readdir.c | 4 ++-- fs/smb/client/smb2ops.c | 4 ++-- fs/smb/client/smb2pdu.c | 4 ++-- fs/smb/client/smb2transport.c | 2 +- fs/smb/client/smbdirect.c | 4 ++-- fs/smb/client/smbdirect.h | 2 +- 16 files changed, 24 insertions(+), 24 deletions(-) diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h index 6529478b7f48..31b51a8fc256 100644 --- a/fs/smb/client/cifsacl.h +++ b/fs/smb/client/cifsacl.h @@ -55,7 +55,7 @@ struct smb3_sd { #define ACL_CONTROL_SI 0x0800 /* SACL Auto-Inherited */ #define ACL_CONTROL_DI 0x0400 /* DACL Auto-Inherited */ #define ACL_CONTROL_SC 0x0200 /* SACL computed through inheritance */ -#define ACL_CONTROL_DC 0x0100 /* DACL computed through inheritence */ +#define ACL_CONTROL_DC 0x0100 /* DACL computed through inheritance */ #define ACL_CONTROL_SS 0x0080 /* Create server ACL */ #define ACL_CONTROL_DT 0x0040 /* DACL provided by trusted source */ #define ACL_CONTROL_SD 0x0020 /* SACL defaulted */ diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index 464e6ccdfa5f..7a43daacc815 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -239,7 +239,7 @@ int cifs_verify_signature(struct smb_rqst *rqst, cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n", cifs_pdu->Command); - /* save off the origiginal signature so we can modify the smb and check + /* save off the original signature so we can modify the smb and check its signature against what the server sent */ memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8); diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 33e286001015..000e1ef3beea 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -161,7 +161,7 @@ __u32 cifs_lock_secret; /* * Bumps refcount for cifs super block. - * Note that it should be only called if a referece to VFS super block is + * Note that it should be only called if a reference to VFS super block is * already held, e.g. in open-type syscalls context. Otherwise it can race with * atomic_dec_and_test in deactivate_locked_super. */ @@ -289,7 +289,7 @@ static void cifs_kill_sb(struct super_block *sb) struct cifs_sb_info *cifs_sb = CIFS_SB(sb); /* - * We ned to release all dentries for the cached directories + * We need to release all dentries for the cached directories * before we kill the sb. */ if (cifs_sb->root) { diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 589438b867a9..5041b1ffc244 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -775,7 +775,7 @@ struct TCP_Server_Info { } compression; __u16 signing_algorithm; __le16 cipher_type; - /* save initital negprot hash */ + /* save initial negprot hash */ __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; bool signing_negotiated; /* true if valid signing context rcvd from server */ bool posix_ext_supported; diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h index c3b6263060b0..ff694dca4248 100644 --- a/fs/smb/client/cifspdu.h +++ b/fs/smb/client/cifspdu.h @@ -781,7 +781,7 @@ typedef struct smb_com_logoff_andx_rsp { __u16 ByteCount; } __attribute__((packed)) LOGOFF_ANDX_RSP; -typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on +typedef union smb_com_tree_disconnect { /* as an alternative can use flag on tree_connect PDU to effect disconnect */ /* tdis is probably simplest SMB PDU */ struct { @@ -2406,7 +2406,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */ __le64 cifs_uid; /* or gid */ } __attribute__((packed)); -struct cifs_posix_acl { /* access conrol list (ACL) */ +struct cifs_posix_acl { /* access control list (ACL) */ __le16 version; __le16 access_entry_count; /* access ACL - count of entries */ __le16 default_entry_count; /* default ACL - count of entries */ diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index 131f20b91c3e..c6f15dbe860a 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -1215,7 +1215,7 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, req->CreateDisposition = cpu_to_le32(disposition); req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); - /* BB Expirement with various impersonation levels and verify */ + /* BB Experiment with various impersonation levels and verify */ req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY; @@ -3018,7 +3018,7 @@ static void cifs_init_ace(struct cifs_posix_ace *cifs_ace, /** * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format - * @parm_data: ACLs in cifs format to conver to + * @parm_data: ACLs in cifs format to convert to * @acl: ACLs in POSIX ACL format to convert from * @acl_type: the type of POSIX ACLs stored in @acl * @@ -3995,7 +3995,7 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, remap); - /* We can not add the asterik earlier in case + /* We can not add the asterisk earlier in case it got remapped to 0xF03A as if it were part of the directory name instead of a wildcard */ name_len *= 2; diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 78b59c4ef3ce..a58a3333ecc3 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -2502,7 +2502,7 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, } } } - /* couldn't find useable FH with same pid, try any available */ + /* couldn't find usable FH with same pid, try any available */ if (!any_available) { any_available = true; goto refind_writable; diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h index 69f9d938b336..890d6d9d4a59 100644 --- a/fs/smb/client/fs_context.h +++ b/fs/smb/client/fs_context.h @@ -260,7 +260,7 @@ struct smb3_fs_context { unsigned int min_offload; unsigned int retrans; bool sockopt_tcp_nodelay:1; - /* attribute cache timemout for files and directories in jiffies */ + /* attribute cache timeout for files and directories in jiffies */ unsigned long acregmax; unsigned long acdirmax; /* timeout for deferred close of files in jiffies */ diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index 054f10ebf65a..4373dd64b66d 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -254,7 +254,7 @@ free_rsp_buf(int resp_buftype, void *rsp) } /* NB: MID can not be set if treeCon not passed in, in that - case it is responsbility of caller to set the mid */ + case it is responsibility of caller to set the mid */ void header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , const struct cifs_tcon *treeCon, int word_count diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c index 1b52e6ac431c..2a8d71221e5e 100644 --- a/fs/smb/client/netmisc.c +++ b/fs/smb/client/netmisc.c @@ -1003,7 +1003,7 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) year is 2**7, the last year is 1980+127, which means we need only consider 2 special case years, ie the years 2000 and 2100, and only adjust for the lack of leap year for the year 2100, as 2000 was a - leap year (divisable by 400) */ + leap year (divisible by 400) */ if (year >= 120) /* the year 2100 */ days = days - 1; /* do not count leap year for the year 2100 */ diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index ebe1cb30e18e..b3a8f9c6fcff 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -553,7 +553,7 @@ static void cifs_fill_dirent_std(struct cifs_dirent *de, const FIND_FILE_STANDARD_INFO *info) { de->name = &info->FileName[0]; - /* one byte length, no endianess conversion */ + /* one byte length, no endianness conversion */ de->namelen = info->FileNameLength; de->resume_key = info->ResumeKey; } @@ -815,7 +815,7 @@ static bool emit_cached_dirents(struct cached_dirents *cde, * However, this sequence of ->pos values may have holes * in it, for example dot-dirs returned from the server * are suppressed. - * Handle this bu forcing ctx->pos to be the same as the + * Handle this by forcing ctx->pos to be the same as the * ->pos of the current dirent we emit from the cache. * This means that when we emit these entries from the cache * we now emit them with the same ->pos value as in the diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index cd6ff224015a..6b385fce3f2a 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2177,7 +2177,7 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, NULL, 0 /* no input data */, max_response_size, (char **)&retbuf, &ret_data_len); - cifs_dbg(FYI, "enum snaphots ioctl returned %d and ret buflen is %d\n", + cifs_dbg(FYI, "enum snapshots ioctl returned %d and ret buflen is %d\n", rc, ret_data_len); if (rc) return rc; @@ -3588,7 +3588,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, /* * At this point, we are trying to fallocate an internal * regions of a sparse file. Since smb2 does not have a - * fallocate command we have two otions on how to emulate this. + * fallocate command we have two options on how to emulate this. * We can either turn the entire file to become non-sparse * which we only do if the fallocate is for virtually * the whole file, or we can overwrite the region with zeroes diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 02828b9c3cb3..b2f16a7b696d 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -2986,7 +2986,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId); - /* Eventually save off posix specific response info and timestaps */ + /* Eventually save off posix specific response info and timestamps */ err_free_rsp_buf: free_rsp_buf(resp_buftype, rsp); @@ -4581,7 +4581,7 @@ smb2_readv_callback(struct mid_q_entry *mid) } #ifdef CONFIG_CIFS_SMB_DIRECT /* - * If this rdata has a memmory registered, the MR can be freed + * If this rdata has a memory registered, the MR can be freed * MR needs to be freed as soon as I/O finishes to prevent deadlock * because they have limited number and are used for future I/Os */ diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index c8bf0000f73b..b486b14bb330 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -696,7 +696,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) shdr->Command); /* - * Save off the origiginal signature so we can modify the smb and check + * Save off the original signature so we can modify the smb and check * our calculated signature against what the server sent. */ memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE); diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index 0c64b37e2660..b0b7254661e9 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -219,7 +219,7 @@ static int smbd_conn_upcall( case RDMA_CM_EVENT_DEVICE_REMOVAL: case RDMA_CM_EVENT_DISCONNECTED: - /* This happenes when we fail the negotiation */ + /* This happens when we fail the negotiation */ if (info->transport_status == SMBD_NEGOTIATE_FAILED) { info->transport_status = SMBD_DISCONNECTED; wake_up(&info->conn_wait); @@ -1344,7 +1344,7 @@ void smbd_destroy(struct TCP_Server_Info *server) * are not locked by srv_mutex. It is possible some processes are * blocked on transport srv_mutex while holding memory registration. * Release the transport srv_mutex to allow them to hit the failure - * path when sending data, and then release memory registartions. + * path when sending data, and then release memory registrations. */ log_rdma_event(INFO, "freeing mr list\n"); wake_up_interruptible_all(&info->wait_mr); diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h index 83f239f376f0..c08e3665150d 100644 --- a/fs/smb/client/smbdirect.h +++ b/fs/smb/client/smbdirect.h @@ -111,7 +111,7 @@ struct smbd_connection { /* Used by transport to wait until all MRs are returned */ wait_queue_head_t wait_for_mr_cleanup; - /* Activity accoutning */ + /* Activity accounting */ atomic_t send_pending; wait_queue_head_t wait_send_pending; wait_queue_head_t wait_post_send; -- GitLab From 17bd3bd82f9f79f3feba15476c2b2c95a9b11ff8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau <nbd@nbd.name> Date: Thu, 26 Sep 2024 10:53:14 +0200 Subject: [PATCH 637/970] net: gso: fix tcp fraglist segmentation after pull from frag_list Detect tcp gso fraglist skbs with corrupted geometry (see below) and pass these to skb_segment instead of skb_segment_list, as the first can segment them correctly. Valid SKB_GSO_FRAGLIST skbs - consist of two or more segments - the head_skb holds the protocol headers plus first gso_size - one or more frag_list skbs hold exactly one segment - all but the last must be gso_size Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can modify these skbs, breaking these invariants. In extreme cases they pull all data into skb linear. For TCP, this causes a NULL ptr deref in __tcpv4_gso_segment_list_csum at tcp_hdr(seg->next). Detect invalid geometry due to pull, by checking head_skb size. Don't just drop, as this may blackhole a destination. Convert to be able to pass to regular skb_segment. Approach and description based on a patch by Willem de Bruijn. Link: https://lore.kernel.org/netdev/20240428142913.18666-1-shiming.cheng@mediatek.com/ Link: https://lore.kernel.org/netdev/20240922150450.3873767-1-willemdebruijn.kernel@gmail.com/ Fixes: bee88cd5bd83 ("net: add support for segmenting TCP fraglist GSO packets") Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20240926085315.51524-1-nbd@nbd.name Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- net/ipv4/tcp_offload.c | 10 ++++++++-- net/ipv6/tcpv6_offload.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index e4ad3311e148..2308665b51c5 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c @@ -101,8 +101,14 @@ static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb, if (!pskb_may_pull(skb, sizeof(struct tcphdr))) return ERR_PTR(-EINVAL); - if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) - return __tcp4_gso_segment_list(skb, features); + if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) { + struct tcphdr *th = tcp_hdr(skb); + + if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size) + return __tcp4_gso_segment_list(skb, features); + + skb->ip_summed = CHECKSUM_NONE; + } if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { const struct iphdr *iph = ip_hdr(skb); diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index 23971903e66d..a45bf17cb2a1 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c @@ -159,8 +159,14 @@ static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, if (!pskb_may_pull(skb, sizeof(*th))) return ERR_PTR(-EINVAL); - if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) - return __tcp6_gso_segment_list(skb, features); + if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) { + struct tcphdr *th = tcp_hdr(skb); + + if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size) + return __tcp6_gso_segment_list(skb, features); + + skb->ip_summed = CHECKSUM_NONE; + } if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { const struct ipv6hdr *ipv6h = ipv6_hdr(skb); -- GitLab From 49d14b54a527289d09a9480f214b8c586322310a Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@google.com> Date: Thu, 26 Sep 2024 16:58:36 +0000 Subject: [PATCH 638/970] net: test for not too small csum_start in virtio_net_hdr_to_skb() syzbot was able to trigger this warning [1], after injecting a malicious packet through af_packet, setting skb->csum_start and thus the transport header to an incorrect value. We can at least make sure the transport header is after the end of the network header (with a estimated minimal size). [1] [ 67.873027] skb len=4096 headroom=16 headlen=14 tailroom=0 mac=(-1,-1) mac_len=0 net=(16,-6) trans=10 shinfo(txflags=0 nr_frags=1 gso(size=0 type=0 segs=0)) csum(0xa start=10 offset=0 ip_summed=3 complete_sw=0 valid=0 level=0) hash(0x0 sw=0 l4=0) proto=0x0800 pkttype=0 iif=0 priority=0x0 mark=0x0 alloc_cpu=10 vlan_all=0x0 encapsulation=0 inner(proto=0x0000, mac=0, net=0, trans=0) [ 67.877172] dev name=veth0_vlan feat=0x000061164fdd09e9 [ 67.877764] sk family=17 type=3 proto=0 [ 67.878279] skb linear: 00000000: 00 00 10 00 00 00 00 00 0f 00 00 00 08 00 [ 67.879128] skb frag: 00000000: 0e 00 07 00 00 00 28 00 08 80 1c 00 04 00 00 02 [ 67.879877] skb frag: 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.880647] skb frag: 00000020: 00 00 02 00 00 00 08 00 1b 00 00 00 00 00 00 00 [ 67.881156] skb frag: 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.881753] skb frag: 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.882173] skb frag: 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.882790] skb frag: 00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.883171] skb frag: 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.883733] skb frag: 00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.884206] skb frag: 00000090: 00 00 00 00 00 00 00 00 00 00 69 70 76 6c 61 6e [ 67.884704] skb frag: 000000a0: 31 00 00 00 00 00 00 00 00 00 2b 00 00 00 00 00 [ 67.885139] skb frag: 000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.885677] skb frag: 000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.886042] skb frag: 000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.886408] skb frag: 000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.887020] skb frag: 000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 67.887384] skb frag: 00000100: 00 00 [ 67.887878] ------------[ cut here ]------------ [ 67.887908] offset (-6) >= skb_headlen() (14) [ 67.888445] WARNING: CPU: 10 PID: 2088 at net/core/dev.c:3332 skb_checksum_help (net/core/dev.c:3332 (discriminator 2)) [ 67.889353] Modules linked in: macsec macvtap macvlan hsr wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 libchacha poly1305_x86_64 dummy bridge sr_mod cdrom evdev pcspkr i2c_piix4 9pnet_virtio 9p 9pnet netfs [ 67.890111] CPU: 10 UID: 0 PID: 2088 Comm: b363492833 Not tainted 6.11.0-virtme #1011 [ 67.890183] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 67.890309] RIP: 0010:skb_checksum_help (net/core/dev.c:3332 (discriminator 2)) [ 67.891043] Call Trace: [ 67.891173] <TASK> [ 67.891274] ? __warn (kernel/panic.c:741) [ 67.891320] ? skb_checksum_help (net/core/dev.c:3332 (discriminator 2)) [ 67.891333] ? report_bug (lib/bug.c:180 lib/bug.c:219) [ 67.891348] ? handle_bug (arch/x86/kernel/traps.c:239) [ 67.891363] ? exc_invalid_op (arch/x86/kernel/traps.c:260 (discriminator 1)) [ 67.891372] ? asm_exc_invalid_op (./arch/x86/include/asm/idtentry.h:621) [ 67.891388] ? skb_checksum_help (net/core/dev.c:3332 (discriminator 2)) [ 67.891399] ? skb_checksum_help (net/core/dev.c:3332 (discriminator 2)) [ 67.891416] ip_do_fragment (net/ipv4/ip_output.c:777 (discriminator 1)) [ 67.891448] ? __ip_local_out (./include/linux/skbuff.h:1146 ./include/net/l3mdev.h:196 ./include/net/l3mdev.h:213 net/ipv4/ip_output.c:113) [ 67.891459] ? __pfx_ip_finish_output2 (net/ipv4/ip_output.c:200) [ 67.891470] ? ip_route_output_flow (./arch/x86/include/asm/preempt.h:84 (discriminator 13) ./include/linux/rcupdate.h:96 (discriminator 13) ./include/linux/rcupdate.h:871 (discriminator 13) net/ipv4/route.c:2625 (discriminator 13) ./include/net/route.h:141 (discriminator 13) net/ipv4/route.c:2852 (discriminator 13)) [ 67.891484] ipvlan_process_v4_outbound (drivers/net/ipvlan/ipvlan_core.c:445 (discriminator 1)) [ 67.891581] ipvlan_queue_xmit (drivers/net/ipvlan/ipvlan_core.c:542 drivers/net/ipvlan/ipvlan_core.c:604 drivers/net/ipvlan/ipvlan_core.c:670) [ 67.891596] ipvlan_start_xmit (drivers/net/ipvlan/ipvlan_main.c:227) [ 67.891607] dev_hard_start_xmit (./include/linux/netdevice.h:4916 ./include/linux/netdevice.h:4925 net/core/dev.c:3588 net/core/dev.c:3604) [ 67.891620] __dev_queue_xmit (net/core/dev.h:168 (discriminator 25) net/core/dev.c:4425 (discriminator 25)) [ 67.891630] ? skb_copy_bits (./include/linux/uaccess.h:233 (discriminator 1) ./include/linux/uaccess.h:260 (discriminator 1) ./include/linux/highmem-internal.h:230 (discriminator 1) net/core/skbuff.c:3018 (discriminator 1)) [ 67.891645] ? __pskb_pull_tail (net/core/skbuff.c:2848 (discriminator 4)) [ 67.891655] ? skb_partial_csum_set (net/core/skbuff.c:5657) [ 67.891666] ? virtio_net_hdr_to_skb.constprop.0 (./include/linux/skbuff.h:2791 (discriminator 3) ./include/linux/skbuff.h:2799 (discriminator 3) ./include/linux/virtio_net.h:109 (discriminator 3)) [ 67.891684] packet_sendmsg (net/packet/af_packet.c:3145 (discriminator 1) net/packet/af_packet.c:3177 (discriminator 1)) [ 67.891700] ? _raw_spin_lock_bh (./arch/x86/include/asm/atomic.h:107 (discriminator 4) ./include/linux/atomic/atomic-arch-fallback.h:2170 (discriminator 4) ./include/linux/atomic/atomic-instrumented.h:1302 (discriminator 4) ./include/asm-generic/qspinlock.h:111 (discriminator 4) ./include/linux/spinlock.h:187 (discriminator 4) ./include/linux/spinlock_api_smp.h:127 (discriminator 4) kernel/locking/spinlock.c:178 (discriminator 4)) [ 67.891716] __sys_sendto (net/socket.c:730 (discriminator 1) net/socket.c:745 (discriminator 1) net/socket.c:2210 (discriminator 1)) [ 67.891734] ? do_sock_setsockopt (net/socket.c:2335) [ 67.891747] ? __sys_setsockopt (./include/linux/file.h:34 net/socket.c:2355) [ 67.891761] __x64_sys_sendto (net/socket.c:2222 (discriminator 1) net/socket.c:2218 (discriminator 1) net/socket.c:2218 (discriminator 1)) [ 67.891772] do_syscall_64 (arch/x86/entry/common.c:52 (discriminator 1) arch/x86/entry/common.c:83 (discriminator 1)) [ 67.891785] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) Fixes: 9181d6f8a2bb ("net: add more sanity check in virtio_net_hdr_to_skb()") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20240926165836.3797406-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- include/linux/virtio_net.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 276ca543ef44..02a9f4dc594d 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -103,8 +103,10 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, if (!skb_partial_csum_set(skb, start, off)) return -EINVAL; + if (skb_transport_offset(skb) < nh_min_len) + return -EINVAL; - nh_min_len = max_t(u32, nh_min_len, skb_transport_offset(skb)); + nh_min_len = skb_transport_offset(skb); p_off = nh_min_len + thlen; if (!pskb_may_pull(skb, p_off)) return -EINVAL; -- GitLab From 8ed7cf66f4841bcc8c15a89be0732b933703b51c Mon Sep 17 00:00:00 2001 From: Hangbin Liu <liuhangbin@gmail.com> Date: Fri, 27 Sep 2024 12:13:49 +0800 Subject: [PATCH 639/970] selftests: rds: move include.sh to TEST_FILES The include.sh file is generated for inclusion and should not be executable. Otherwise, it will be added to kselftest-list.txt. Additionally, add the executable bit for test.py at the same time to ensure proper functionality. Fixes: 3ade6ce1255e ("selftests: rds: add testing infrastructure") Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> Link: https://patch.msgid.link/20240927041349.81216-1-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- tools/testing/selftests/net/rds/Makefile | 3 ++- tools/testing/selftests/net/rds/test.py | 0 2 files changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 tools/testing/selftests/net/rds/test.py diff --git a/tools/testing/selftests/net/rds/Makefile b/tools/testing/selftests/net/rds/Makefile index da9714bc7aad..cf30307a829b 100644 --- a/tools/testing/selftests/net/rds/Makefile +++ b/tools/testing/selftests/net/rds/Makefile @@ -4,9 +4,10 @@ all: @echo mk_build_dir="$(shell pwd)" > include.sh TEST_PROGS := run.sh \ - include.sh \ test.py +TEST_FILES := include.sh + EXTRA_CLEAN := /tmp/rds_logs include ../../lib.mk diff --git a/tools/testing/selftests/net/rds/test.py b/tools/testing/selftests/net/rds/test.py old mode 100644 new mode 100755 -- GitLab From aec7291003df78cb71fd461d7b672912bde55807 Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@google.com> Date: Fri, 27 Sep 2024 07:45:53 +0000 Subject: [PATCH 640/970] ppp: do not assume bh is held in ppp_channel_bridge_input() Networking receive path is usually handled from BH handler. However, some protocols need to acquire the socket lock, and packets might be stored in the socket backlog is the socket was owned by a user process. In this case, release_sock(), __release_sock(), and sk_backlog_rcv() might call the sk->sk_backlog_rcv() handler in process context. sybot caught ppp was not considering this case in ppp_channel_bridge_input() : WARNING: inconsistent lock state 6.11.0-rc7-syzkaller-g5f5673607153 #0 Not tainted -------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. ksoftirqd/1/24 [HC0[0]:SC1[1]:HE1:SE0] takes: ffff0000db7f11e0 (&pch->downl){+.?.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline] ffff0000db7f11e0 (&pch->downl){+.?.}-{2:2}, at: ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2272 [inline] ffff0000db7f11e0 (&pch->downl){+.?.}-{2:2}, at: ppp_input+0x16c/0x854 drivers/net/ppp/ppp_generic.c:2304 {SOFTIRQ-ON-W} state was registered at: lock_acquire+0x240/0x728 kernel/locking/lockdep.c:5759 __raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline] _raw_spin_lock+0x48/0x60 kernel/locking/spinlock.c:154 spin_lock include/linux/spinlock.h:351 [inline] ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2272 [inline] ppp_input+0x16c/0x854 drivers/net/ppp/ppp_generic.c:2304 pppoe_rcv_core+0xfc/0x314 drivers/net/ppp/pppoe.c:379 sk_backlog_rcv include/net/sock.h:1111 [inline] __release_sock+0x1a8/0x3d8 net/core/sock.c:3004 release_sock+0x68/0x1b8 net/core/sock.c:3558 pppoe_sendmsg+0xc8/0x5d8 drivers/net/ppp/pppoe.c:903 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg net/socket.c:745 [inline] __sys_sendto+0x374/0x4f4 net/socket.c:2204 __do_sys_sendto net/socket.c:2216 [inline] __se_sys_sendto net/socket.c:2212 [inline] __arm64_sys_sendto+0xd8/0xf8 net/socket.c:2212 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:712 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 irq event stamp: 282914 hardirqs last enabled at (282914): [<ffff80008b42e30c>] __raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:151 [inline] hardirqs last enabled at (282914): [<ffff80008b42e30c>] _raw_spin_unlock_irqrestore+0x38/0x98 kernel/locking/spinlock.c:194 hardirqs last disabled at (282913): [<ffff80008b42e13c>] __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:108 [inline] hardirqs last disabled at (282913): [<ffff80008b42e13c>] _raw_spin_lock_irqsave+0x2c/0x7c kernel/locking/spinlock.c:162 softirqs last enabled at (282904): [<ffff8000801f8e88>] softirq_handle_end kernel/softirq.c:400 [inline] softirqs last enabled at (282904): [<ffff8000801f8e88>] handle_softirqs+0xa3c/0xbfc kernel/softirq.c:582 softirqs last disabled at (282909): [<ffff8000801fbdf8>] run_ksoftirqd+0x70/0x158 kernel/softirq.c:928 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&pch->downl); <Interrupt> lock(&pch->downl); *** DEADLOCK *** 1 lock held by ksoftirqd/1/24: #0: ffff80008f74dfa0 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x10/0x4c include/linux/rcupdate.h:325 stack backtrace: CPU: 1 UID: 0 PID: 24 Comm: ksoftirqd/1 Not tainted 6.11.0-rc7-syzkaller-g5f5673607153 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 Call trace: dump_backtrace+0x1b8/0x1e4 arch/arm64/kernel/stacktrace.c:319 show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:326 __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0xe4/0x150 lib/dump_stack.c:119 dump_stack+0x1c/0x28 lib/dump_stack.c:128 print_usage_bug+0x698/0x9ac kernel/locking/lockdep.c:4000 mark_lock_irq+0x980/0xd2c mark_lock+0x258/0x360 kernel/locking/lockdep.c:4677 __lock_acquire+0xf48/0x779c kernel/locking/lockdep.c:5096 lock_acquire+0x240/0x728 kernel/locking/lockdep.c:5759 __raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline] _raw_spin_lock+0x48/0x60 kernel/locking/spinlock.c:154 spin_lock include/linux/spinlock.h:351 [inline] ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2272 [inline] ppp_input+0x16c/0x854 drivers/net/ppp/ppp_generic.c:2304 ppp_async_process+0x98/0x150 drivers/net/ppp/ppp_async.c:495 tasklet_action_common+0x318/0x3f4 kernel/softirq.c:785 tasklet_action+0x68/0x8c kernel/softirq.c:811 handle_softirqs+0x2e4/0xbfc kernel/softirq.c:554 run_ksoftirqd+0x70/0x158 kernel/softirq.c:928 smpboot_thread_fn+0x4b0/0x90c kernel/smpboot.c:164 kthread+0x288/0x310 kernel/kthread.c:389 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860 Fixes: 4cf476ced45d ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls") Reported-by: syzbot+bd8d55ee2acd0a71d8ce@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/66f661e2.050a0220.38ace9.000f.GAE@google.com/T/#u Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Tom Parkin <tparkin@katalix.com> Cc: James Chapman <jchapman@katalix.com> Link: https://patch.msgid.link/20240927074553.341910-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- drivers/net/ppp/ppp_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 4b2971e2bf48..0d5cd705decb 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -2269,7 +2269,7 @@ static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb) if (!pchb) goto out_rcu; - spin_lock(&pchb->downl); + spin_lock_bh(&pchb->downl); if (!pchb->chan) { /* channel got unregistered */ kfree_skb(skb); @@ -2281,7 +2281,7 @@ static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb) kfree_skb(skb); outl: - spin_unlock(&pchb->downl); + spin_unlock_bh(&pchb->downl); out_rcu: rcu_read_unlock(); -- GitLab From c283782fc5d60c4d8169137c6f955aa3553d3b3d Mon Sep 17 00:00:00 2001 From: Hui Wang <hui.wang@canonical.com> Date: Fri, 27 Sep 2024 19:46:10 +0800 Subject: [PATCH 641/970] net: phy: realtek: Check the index value in led_hw_control_get Just like rtl8211f_led_hw_is_supported() and rtl8211f_led_hw_control_set(), the rtl8211f_led_hw_control_get() also needs to check the index value, otherwise the caller is likely to get an incorrect rules. Fixes: 17784801d888 ("net: phy: realtek: Add support for PHY LEDs on RTL8211F") Signed-off-by: Hui Wang <hui.wang@canonical.com> Reviewed-by: Marek Vasut <marex@denx.de> Link: https://patch.msgid.link/20240927114610.1278935-1-hui.wang@canonical.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- drivers/net/phy/realtek.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 25e5bfbb6f89..c15d2f66ef0d 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -527,6 +527,9 @@ static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index, { int val; + if (index >= RTL8211F_LED_COUNT) + return -EINVAL; + val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR); if (val < 0) return val; -- GitLab From 3c97fe4f9fbc2bbc555b51268a9556e61cd3ca4e Mon Sep 17 00:00:00 2001 From: Dan Carpenter <dan.carpenter@linaro.org> Date: Sat, 28 Sep 2024 13:04:01 +0300 Subject: [PATCH 642/970] net: ethernet: ti: am65-cpsw: Fix forever loop in cleanup code This error handling has a typo. It should i++ instead of i--. In the original code the error handling will loop until it crashes. Fixes: da70d184a8c3 ("net: ethernet: ti: am65-cpsw: Introduce multi queue Rx") Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> Reviewed-by: Alexander Sverdlin <alexander.sverdlin@siemens.com> Reviewed-by: Roger Quadros <rogerq@kernel.org> Link: https://patch.msgid.link/8e7960cc-415d-48d7-99ce-f623022ec7b5@stanley.mountain Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index cbe99017cbfa..d253727b160f 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -763,7 +763,7 @@ static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common) k3_udma_glue_disable_rx_chn(rx_chn->rx_chn); fail_rx: - for (i = 0; i < common->rx_ch_num_flows; i--) + for (i = 0; i < common->rx_ch_num_flows; i++) k3_udma_glue_reset_rx_chn(rx_chn->rx_chn, i, &rx_chn->flows[i], am65_cpsw_nuss_rx_cleanup, 0); -- GitLab From b04c4d9eb4f25b950b33218e33b04c94e7445e51 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn <willemb@google.com> Date: Sun, 29 Sep 2024 02:18:20 -0400 Subject: [PATCH 643/970] vrf: revert "vrf: Remove unnecessary RCU-bh critical section" This reverts commit 504fc6f4f7f681d2a03aa5f68aad549d90eab853. dev_queue_xmit_nit is expected to be called with BH disabled. __dev_queue_xmit has the following: /* Disable soft irqs for various locks below. Also * stops preemption for RCU. */ rcu_read_lock_bh(); VRF must follow this invariant. The referenced commit removed this protection. Which triggered a lockdep warning: ================================ WARNING: inconsistent lock state 6.11.0 #1 Tainted: G W -------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. btserver/134819 [HC0[0]:SC0[0]:HE1:SE1] takes: ffff8882da30c118 (rlock-AF_PACKET){+.?.}-{2:2}, at: tpacket_rcv+0x863/0x3b30 {IN-SOFTIRQ-W} state was registered at: lock_acquire+0x19a/0x4f0 _raw_spin_lock+0x27/0x40 packet_rcv+0xa33/0x1320 __netif_receive_skb_core.constprop.0+0xcb0/0x3a90 __netif_receive_skb_list_core+0x2c9/0x890 netif_receive_skb_list_internal+0x610/0xcc0 [...] other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(rlock-AF_PACKET); <Interrupt> lock(rlock-AF_PACKET); *** DEADLOCK *** Call Trace: <TASK> dump_stack_lvl+0x73/0xa0 mark_lock+0x102e/0x16b0 __lock_acquire+0x9ae/0x6170 lock_acquire+0x19a/0x4f0 _raw_spin_lock+0x27/0x40 tpacket_rcv+0x863/0x3b30 dev_queue_xmit_nit+0x709/0xa40 vrf_finish_direct+0x26e/0x340 [vrf] vrf_l3_out+0x5f4/0xe80 [vrf] __ip_local_out+0x51e/0x7a0 [...] Fixes: 504fc6f4f7f6 ("vrf: Remove unnecessary RCU-bh critical section") Link: https://lore.kernel.org/netdev/20240925185216.1990381-1-greearb@candelatech.com/ Reported-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Willem de Bruijn <willemb@google.com> Cc: stable@vger.kernel.org Reviewed-by: Ido Schimmel <idosch@nvidia.com> Tested-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20240929061839.1175300-1-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- drivers/net/vrf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 4d8ccaf9a2b4..4087f72f0d2b 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -608,7 +608,9 @@ static void vrf_finish_direct(struct sk_buff *skb) eth_zero_addr(eth->h_dest); eth->h_proto = skb->protocol; + rcu_read_lock_bh(); dev_queue_xmit_nit(skb, vrf_dev); + rcu_read_unlock_bh(); skb_pull(skb, ETH_HLEN); } -- GitLab From 555f45d24ba7cd5527716553031641cdebbe76c7 Mon Sep 17 00:00:00 2001 From: Ido Schimmel <idosch@nvidia.com> Date: Sun, 29 Sep 2024 15:36:40 +0300 Subject: [PATCH 644/970] bridge: mcast: Fail MDB get request on empty entry When user space deletes a port from an MDB entry, the port is removed synchronously. If this was the last port in the entry and the entry is not joined by the host itself, then the entry is scheduled for deletion via a timer. The above means that it is possible for the MDB get netlink request to retrieve an empty entry which is scheduled for deletion. This is problematic as after deleting the last port in an entry, user space cannot rely on a non-zero return code from the MDB get request as an indication that the port was successfully removed. Fix by returning an error when the entry's port list is empty and the entry is not joined by the host. Fixes: 68b380a395a7 ("bridge: mcast: Add MDB get support") Reported-by: Jamie Bainbridge <jamie.bainbridge@gmail.com> Closes: https://lore.kernel.org/netdev/c92569919307749f879b9482b0f3e125b7d9d2e3.1726480066.git.jamie.bainbridge@gmail.com/ Tested-by: Jamie Bainbridge <jamie.bainbridge@gmail.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/20240929123640.558525-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- net/bridge/br_mdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index bc37e47ad829..1a52a0bca086 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -1674,7 +1674,7 @@ int br_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid, u32 seq, spin_lock_bh(&br->multicast_lock); mp = br_mdb_ip_get(br, &group); - if (!mp) { + if (!mp || (!mp->ports && !mp->host_joined)) { NL_SET_ERR_MSG_MOD(extack, "MDB entry not found"); err = -ENOENT; goto unlock; -- GitLab From a1e40ac5b5e9077fe1f7ae0eb88034db0f9ae1ab Mon Sep 17 00:00:00 2001 From: Willem de Bruijn <willemb@google.com> Date: Tue, 1 Oct 2024 13:17:46 -0400 Subject: [PATCH 645/970] gso: fix udp gso fraglist segmentation after pull from frag_list Detect gso fraglist skbs with corrupted geometry (see below) and pass these to skb_segment instead of skb_segment_list, as the first can segment them correctly. Valid SKB_GSO_FRAGLIST skbs - consist of two or more segments - the head_skb holds the protocol headers plus first gso_size - one or more frag_list skbs hold exactly one segment - all but the last must be gso_size Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can modify these skbs, breaking these invariants. In extreme cases they pull all data into skb linear. For UDP, this causes a NULL ptr deref in __udpv4_gso_segment_list_csum at udp_hdr(seg->next)->dest. Detect invalid geometry due to pull, by checking head_skb size. Don't just drop, as this may blackhole a destination. Convert to be able to pass to regular skb_segment. Link: https://lore.kernel.org/netdev/20240428142913.18666-1-shiming.cheng@mediatek.com/ Fixes: 9fd1ff5d2ac7 ("udp: Support UDP fraglist GRO/GSO.") Signed-off-by: Willem de Bruijn <willemb@google.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20241001171752.107580-1-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- net/ipv4/udp_offload.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index d842303587af..a5be6e4ed326 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -296,8 +296,26 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, return NULL; } - if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) - return __udp_gso_segment_list(gso_skb, features, is_ipv6); + if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) { + /* Detect modified geometry and pass those to skb_segment. */ + if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size) + return __udp_gso_segment_list(gso_skb, features, is_ipv6); + + /* Setup csum, as fraglist skips this in udp4_gro_receive. */ + gso_skb->csum_start = skb_transport_header(gso_skb) - gso_skb->head; + gso_skb->csum_offset = offsetof(struct udphdr, check); + gso_skb->ip_summed = CHECKSUM_PARTIAL; + + uh = udp_hdr(gso_skb); + if (is_ipv6) + uh->check = ~udp_v6_check(gso_skb->len, + &ipv6_hdr(gso_skb)->saddr, + &ipv6_hdr(gso_skb)->daddr, 0); + else + uh->check = ~udp_v4_check(gso_skb->len, + ip_hdr(gso_skb)->saddr, + ip_hdr(gso_skb)->daddr, 0); + } skb_pull(gso_skb, sizeof(*uh)); -- GitLab From fa7dfeae041c91e425db9fbb95fb3f57b821c386 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori <fujita.tomonori@gmail.com> Date: Thu, 26 Sep 2024 12:14:03 +0000 Subject: [PATCH 646/970] net: phy: qt2025: Fix warning: unused import DeviceId Fix the following warning when the driver is compiled as built-in: warning: unused import: `DeviceId` --> drivers/net/phy/qt2025.rs:18:5 | 18 | DeviceId, Driver, | ^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default device_table in module_phy_driver macro is defined only when the driver is built as a module. Use phy::DeviceId in the macro instead of importing `DeviceId` since `phy` is always used. Fixes: fd3eaad826da ("net: phy: add Applied Micro QT2025 PHY driver") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202409190717.i135rfVo-lkp@intel.com/ Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Trevor Gross <tmgross@umich.edu> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Reviewed-by: Fiona Behrens <me@kloenk.dev> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://patch.msgid.link/20240926121404.242092-1-fujita.tomonori@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- drivers/net/phy/qt2025.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/qt2025.rs b/drivers/net/phy/qt2025.rs index 28d8981f410b..1ab065798175 100644 --- a/drivers/net/phy/qt2025.rs +++ b/drivers/net/phy/qt2025.rs @@ -15,7 +15,7 @@ use kernel::net::phy::{ self, reg::{Mmd, C45}, - DeviceId, Driver, + Driver, }; use kernel::prelude::*; use kernel::sizes::{SZ_16K, SZ_8K}; @@ -23,7 +23,7 @@ kernel::module_phy_driver! { drivers: [PhyQT2025], device_table: [ - DeviceId::new_with_driver::<PhyQT2025>(), + phy::DeviceId::new_with_driver::<PhyQT2025>(), ], name: "qt2025_phy", author: "FUJITA Tomonori <fujita.tomonori@gmail.com>", -- GitLab From abaa6d4f6ab8371c5b73afb726ff1c012526e999 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Tue, 1 Oct 2024 17:43:36 -0400 Subject: [PATCH 647/970] bcachefs: Fix return type of dirent_points_to_inode_nowarn() we're returning an error code now, not a bool Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 0d8b782b63fb..c6c98ee87ec9 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -28,8 +28,8 @@ static bool inode_points_to_dirent(struct bch_inode_unpacked *inode, inode->bi_dir_offset == d.k->p.offset; } -static bool dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d, - struct bch_inode_unpacked *inode) +static int dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d, + struct bch_inode_unpacked *inode) { if (d.v->d_type == DT_SUBVOL ? le32_to_cpu(d.v->d_child_subvol) == inode->bi_subvol -- GitLab From 3b1425a4eb4e9750db8620c26e39390411eea185 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Wed, 2 Oct 2024 21:31:31 -0400 Subject: [PATCH 648/970] bcachefs: Fix bch2_inode_is_open() check Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index c6c98ee87ec9..351de61c7ed1 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1106,7 +1106,7 @@ static int check_inode(struct btree_trans *trans, if (ret) goto err; } else { - if (fsck_err_on(bch2_inode_is_open(c, k.k->p), + if (fsck_err_on(!bch2_inode_is_open(c, k.k->p), trans, inode_unlinked_and_not_open, "inode %llu%u unlinked and not open", u.bi_inum, u.bi_snapshot)) { -- GitLab From d28786606a51620df7b7a3e7231338d9bc081656 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Wed, 2 Oct 2024 21:35:38 -0400 Subject: [PATCH 649/970] bcachefs: Fix trans_commit disk accounting revert We only are applying JSET_ENTRY_TYPE_write_buffer_keys, revert path was missed. Fixes: a3581ca35d2b ("bcachefs: Fix BCH_TRANS_COMMIT_skip_accounting_apply") Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/btree_trans_commit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c index 1a74a1a252ee..9bf471fa4361 100644 --- a/fs/bcachefs/btree_trans_commit.c +++ b/fs/bcachefs/btree_trans_commit.c @@ -832,7 +832,8 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags, for (struct jset_entry *entry2 = trans->journal_entries; entry2 != entry; entry2 = vstruct_next(entry2)) - if (jset_entry_is_key(entry2) && entry2->start->k.type == KEY_TYPE_accounting) { + if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys && + entry2->start->k.type == KEY_TYPE_accounting) { struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start); bch2_accounting_neg(a); -- GitLab From 537e9e7527a7334c93257c347d32daf0da0c6a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 4 Apr 2024 23:33:26 +0300 Subject: [PATCH 650/970] drm/client: s/drm_connector_has_preferred_mode/drm_connector_preferred_mode/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the "has" from drm_connector_has_preferred_mode() to better describe what it does. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240404203336.10454-3-ville.syrjala@linux.intel.com Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/drm_client_modeset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index cee5eafbfb81..1a689a0a25d5 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -145,7 +145,7 @@ drm_connector_fallback_non_tiled_mode(struct drm_connector *connector) } static struct drm_display_mode * -drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height) +drm_connector_preferred_mode(struct drm_connector *connector, int width, int height) { struct drm_display_mode *mode; @@ -441,7 +441,7 @@ static bool drm_client_target_preferred(struct drm_device *dev, drm_dbg_kms(dev, "[CONNECTOR:%d:%s] looking for preferred mode, tile %d\n", connector->base.id, connector->name, connector->tile_group ? connector->tile_group->id : 0); - modes[i] = drm_connector_has_preferred_mode(connector, width, height); + modes[i] = drm_connector_preferred_mode(connector, width, height); } /* No preferred modes, pick one off the list */ if (!modes[i] && !list_empty(&connector->modes)) { @@ -531,7 +531,7 @@ static int drm_client_pick_crtcs(struct drm_client_dev *client, my_score++; if (connector->cmdline_mode.specified) my_score++; - if (drm_connector_has_preferred_mode(connector, width, height)) + if (drm_connector_preferred_mode(connector, width, height)) my_score++; /* @@ -686,7 +686,7 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, "[CONNECTOR:%d:%s] looking for preferred mode, has tile: %s\n", connector->base.id, connector->name, str_yes_no(connector->has_tile)); - modes[i] = drm_connector_has_preferred_mode(connector, width, height); + modes[i] = drm_connector_preferred_mode(connector, width, height); } /* No preferred mode marked by the EDID? Are there any modes? */ -- GitLab From 90c6b18727ebb2dccfc829088c50acee6100903d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 4 Apr 2024 23:33:27 +0300 Subject: [PATCH 651/970] drm/client: Use drm_mode_destroy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefer drm_mode_destroy() over bare kfree(), for consistency and setting a good example. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240404203336.10454-4-ville.syrjala@linux.intel.com Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/drm_client_modeset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 1a689a0a25d5..d62b31d934a3 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -331,7 +331,7 @@ static bool drm_client_target_cloned(struct drm_device *dev, if (!modes[i]) can_clone = false; } - kfree(dmt_mode); + drm_mode_destroy(dev, dmt_mode); if (can_clone) { drm_dbg_kms(dev, "can clone using 1024x768\n"); @@ -878,7 +878,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, break; } - kfree(modeset->mode); + drm_mode_destroy(dev, modeset->mode); modeset->mode = drm_mode_duplicate(dev, mode); if (!modeset->mode) { ret = -ENOMEM; -- GitLab From cbc1e8696fbea0010a73bf93534c712f9ad177db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 4 Apr 2024 23:33:32 +0300 Subject: [PATCH 652/970] drm/client: Extract drm_connector_first_mode() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a consistent method for picking the first mode from the connnector's mode list. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240404203336.10454-9-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/drm_client_modeset.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index d62b31d934a3..251f94313717 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -159,6 +159,12 @@ drm_connector_preferred_mode(struct drm_connector *connector, int width, int hei return NULL; } +static struct drm_display_mode *drm_connector_first_mode(struct drm_connector *connector) +{ + return list_first_entry_or_null(&connector->modes, + struct drm_display_mode, head); +} + static struct drm_display_mode *drm_connector_pick_cmdline_mode(struct drm_connector *connector) { struct drm_cmdline_mode *cmdline_mode; @@ -444,10 +450,8 @@ static bool drm_client_target_preferred(struct drm_device *dev, modes[i] = drm_connector_preferred_mode(connector, width, height); } /* No preferred modes, pick one off the list */ - if (!modes[i] && !list_empty(&connector->modes)) { - list_for_each_entry(modes[i], &connector->modes, head) - break; - } + if (!modes[i]) + modes[i] = drm_connector_first_mode(connector); /* * In case of tiled mode if all tiles not present fallback to * first available non tiled mode. @@ -693,9 +697,7 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, if (!modes[i] && !list_empty(&connector->modes)) { drm_dbg_kms(dev, "[CONNECTOR:%d:%s] using first listed mode\n", connector->base.id, connector->name); - modes[i] = list_first_entry(&connector->modes, - struct drm_display_mode, - head); + modes[i] = drm_connector_first_mode(connector); } /* last resort: use current mode */ -- GitLab From cffa8e83df9fe525afad1e1099097413f9174f57 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi <rodrigo.vivi@intel.com> Date: Thu, 12 Sep 2024 17:45:07 -0400 Subject: [PATCH 653/970] drm/xe: Restore pci state upon resume The pci state was saved, but not restored. Restore right after the power state transition request like every other driver. v2: Use right fixes tag, since this was there initialy, but accidentally removed. Fixes: f6761c68c0ac ("drm/xe/display: Improve s2idle handling.") Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912214507.456897-1-rodrigo.vivi@intel.com Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> (cherry picked from commit ec2d1539e159f53eae708e194c449cfefa004994) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 937c3e064f0d..5e962e72c97e 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -924,6 +924,8 @@ static int xe_pci_resume(struct device *dev) if (err) return err; + pci_restore_state(pdev); + err = pci_enable_device(pdev); if (err) return err; -- GitLab From 790533e44bfc7af929842fccd9674c9f424d4627 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Tue, 24 Sep 2024 16:09:48 +0100 Subject: [PATCH 654/970] drm/xe/guc_submit: add missing locking in wedged_fini Any non-wedged queue can have a zero refcount here and can be running concurrently with an async queue destroy, therefore dereferencing the queue ptr to check wedge status after the lookup can trigger UAF if queue is not wedged. Fix this by keeping the submission_state lock held around the check to postpone the free and make the check safe, before dropping again around the put() to avoid the deadlock. Fixes: 8ed9aaae39f3 ("drm/xe: Force wedged state and block GT reset upon any GPU hang") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924150947.118433-2-matthew.auld@intel.com (cherry picked from commit d28af0b6b9580b9f90c265a7da0315b0ad20bbfd) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_guc_submit.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index fbbe6a487bbb..715c761dc7d6 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -290,9 +290,15 @@ static void guc_submit_wedged_fini(void *arg) struct xe_exec_queue *q; unsigned long index; - xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) - if (exec_queue_wedged(q)) + mutex_lock(&guc->submission_state.lock); + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { + if (exec_queue_wedged(q)) { + mutex_unlock(&guc->submission_state.lock); xe_exec_queue_put(q); + mutex_lock(&guc->submission_state.lock); + } + } + mutex_unlock(&guc->submission_state.lock); } static const struct xe_exec_queue_ops guc_exec_queue_ops; -- GitLab From 2d2be279f1ca9e7288282d4214f16eea8a727cdb Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Mon, 23 Sep 2024 15:56:48 +0100 Subject: [PATCH 655/970] drm/xe: fix UAF around queue destruction We currently do stuff like queuing the final destruction step on a random system wq, which will outlive the driver instance. With bad timing we can teardown the driver with one or more work workqueue still being alive leading to various UAF splats. Add a fini step to ensure user queues are properly torn down. At this point GuC should already be nuked so queue itself should no longer be referenced from hw pov. v2 (Matt B) - Looks much safer to use a waitqueue and then just wait for the xa_array to become empty before triggering the drain. Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2317 Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240923145647.77707-2-matthew.auld@intel.com (cherry picked from commit 861108666cc0e999cffeab6aff17b662e68774e3) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_device.c | 6 +++++- drivers/gpu/drm/xe/xe_device_types.h | 3 +++ drivers/gpu/drm/xe/xe_guc_submit.c | 26 +++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_guc_types.h | 2 ++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 70d4e4d46c3c..74e593caf87c 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -298,6 +298,9 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy) if (xe->unordered_wq) destroy_workqueue(xe->unordered_wq); + if (xe->destroy_wq) + destroy_workqueue(xe->destroy_wq); + ttm_device_fini(&xe->ttm); } @@ -363,8 +366,9 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0); xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0); xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0); + xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0); if (!xe->ordered_wq || !xe->unordered_wq || - !xe->preempt_fence_wq) { + !xe->preempt_fence_wq || !xe->destroy_wq) { /* * Cleanup done in xe_device_destroy via * drmm_add_action_or_reset register above diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index ec7eb7811126..24c8c2d20676 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -396,6 +396,9 @@ struct xe_device { /** @unordered_wq: used to serialize unordered work, mostly display */ struct workqueue_struct *unordered_wq; + /** @destroy_wq: used to serialize user destroy work, like queue */ + struct workqueue_struct *destroy_wq; + /** @tiles: device tiles */ struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE]; diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 715c761dc7d6..98a6a385a796 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -276,10 +276,26 @@ static struct workqueue_struct *get_submit_wq(struct xe_guc *guc) } #endif +static void xe_guc_submit_fini(struct xe_guc *guc) +{ + struct xe_device *xe = guc_to_xe(guc); + struct xe_gt *gt = guc_to_gt(guc); + int ret; + + ret = wait_event_timeout(guc->submission_state.fini_wq, + xa_empty(&guc->submission_state.exec_queue_lookup), + HZ * 5); + + drain_workqueue(xe->destroy_wq); + + xe_gt_assert(gt, ret); +} + static void guc_submit_fini(struct drm_device *drm, void *arg) { struct xe_guc *guc = arg; + xe_guc_submit_fini(guc); xa_destroy(&guc->submission_state.exec_queue_lookup); free_submit_wq(guc); } @@ -351,6 +367,8 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) xa_init(&guc->submission_state.exec_queue_lookup); + init_waitqueue_head(&guc->submission_state.fini_wq); + primelockdep(guc); return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc); @@ -367,6 +385,9 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa xe_guc_id_mgr_release_locked(&guc->submission_state.idm, q->guc->id, q->width); + + if (xa_empty(&guc->submission_state.exec_queue_lookup)) + wake_up(&guc->submission_state.fini_wq); } static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) @@ -1274,13 +1295,16 @@ static void __guc_exec_queue_fini_async(struct work_struct *w) static void guc_exec_queue_fini_async(struct xe_exec_queue *q) { + struct xe_guc *guc = exec_queue_to_guc(q); + struct xe_device *xe = guc_to_xe(guc); + INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async); /* We must block on kernel engines so slabs are empty on driver unload */ if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q)) __guc_exec_queue_fini_async(&q->guc->fini_async); else - queue_work(system_wq, &q->guc->fini_async); + queue_work(xe->destroy_wq, &q->guc->fini_async); } static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q) diff --git a/drivers/gpu/drm/xe/xe_guc_types.h b/drivers/gpu/drm/xe/xe_guc_types.h index 546ac6350a31..69046f698271 100644 --- a/drivers/gpu/drm/xe/xe_guc_types.h +++ b/drivers/gpu/drm/xe/xe_guc_types.h @@ -81,6 +81,8 @@ struct xe_guc { #endif /** @submission_state.enabled: submission is enabled */ bool enabled; + /** @submission_state.fini_wq: submit fini wait queue */ + wait_queue_head_t fini_wq; } submission_state; /** @hwconfig: Hardware config state */ struct { -- GitLab From cb58977016d1b25781743e5fbe6a545493785e37 Mon Sep 17 00:00:00 2001 From: He Lugang <helugang@uniontech.com> Date: Wed, 11 Sep 2024 18:22:15 +0800 Subject: [PATCH 656/970] drm/xe: use devm_add_action_or_reset() helper Use devm_add_action_or_reset() to release resources in case of failure, because the cleanup function will be automatically called. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: He Lugang <helugang@uniontech.com> Link: https://patchwork.freedesktop.org/patch/msgid/9631BC17D1E028A2+20240911102215.84865-1-helugang@uniontech.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> (cherry picked from commit fdc81c43f0c14ace6383024a02585e3fcbd1ceba) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_gt_freq.c | 4 ++-- drivers/gpu/drm/xe/xe_gt_sysfs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c index 68a5778b4319..ab76973f3e1e 100644 --- a/drivers/gpu/drm/xe/xe_gt_freq.c +++ b/drivers/gpu/drm/xe/xe_gt_freq.c @@ -237,11 +237,11 @@ int xe_gt_freq_init(struct xe_gt *gt) if (!gt->freq) return -ENOMEM; - err = devm_add_action(xe->drm.dev, freq_fini, gt->freq); + err = sysfs_create_files(gt->freq, freq_attrs); if (err) return err; - err = sysfs_create_files(gt->freq, freq_attrs); + err = devm_add_action_or_reset(xe->drm.dev, freq_fini, gt->freq); if (err) return err; diff --git a/drivers/gpu/drm/xe/xe_gt_sysfs.c b/drivers/gpu/drm/xe/xe_gt_sysfs.c index a05c3699e8b9..ec2b8246204b 100644 --- a/drivers/gpu/drm/xe/xe_gt_sysfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sysfs.c @@ -51,5 +51,5 @@ int xe_gt_sysfs_init(struct xe_gt *gt) gt->sysfs = &kg->base; - return devm_add_action(xe->drm.dev, gt_sysfs_fini, gt); + return devm_add_action_or_reset(xe->drm.dev, gt_sysfs_fini, gt); } -- GitLab From d1ef967126e295d36201e79ec64efdba31710353 Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Tue, 17 Sep 2024 22:44:36 -0700 Subject: [PATCH 657/970] drm/xe: Convert to USM lock to rwsem Remove contention from GPU fault path for ASID->VM lookup. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918054436.1971839-1-matthew.brost@intel.com (cherry picked from commit 1378c633a3fbfeb344c486ffda0e920a21e62712) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_device.c | 4 +--- drivers/gpu/drm/xe/xe_device_types.h | 2 +- drivers/gpu/drm/xe/xe_gt_pagefault.c | 8 ++++---- drivers/gpu/drm/xe/xe_vm.c | 8 ++++---- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 74e593caf87c..fb7ac06aeef8 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -339,9 +339,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, init_waitqueue_head(&xe->ufence_wq); - err = drmm_mutex_init(&xe->drm, &xe->usm.lock); - if (err) - goto err; + init_rwsem(&xe->usm.lock); xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC); diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 24c8c2d20676..00e370dcf4a9 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -369,7 +369,7 @@ struct xe_device { /** @usm.next_asid: next ASID, used to cyclical alloc asids */ u32 next_asid; /** @usm.lock: protects UM state */ - struct mutex lock; + struct rw_semaphore lock; } usm; /** @pinned: pinned BO state */ diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c index 00af059a8971..5c3af2bb5402 100644 --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c @@ -198,13 +198,13 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) return -EFAULT; /* ASID to VM */ - mutex_lock(&xe->usm.lock); + down_read(&xe->usm.lock); vm = xa_load(&xe->usm.asid_to_vm, pf->asid); if (vm && xe_vm_in_fault_mode(vm)) xe_vm_get(vm); else vm = NULL; - mutex_unlock(&xe->usm.lock); + up_read(&xe->usm.lock); if (!vm) return -EINVAL; @@ -549,11 +549,11 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc) return -EINVAL; /* ASID to VM */ - mutex_lock(&xe->usm.lock); + down_read(&xe->usm.lock); vm = xa_load(&xe->usm.asid_to_vm, acc->asid); if (vm) xe_vm_get(vm); - mutex_unlock(&xe->usm.lock); + up_read(&xe->usm.lock); if (!vm || !xe_vm_in_fault_mode(vm)) return -EINVAL; diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 7acd5fc9d032..a3d7cb7cfd22 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1613,7 +1613,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) up_write(&vm->lock); - mutex_lock(&xe->usm.lock); + down_write(&xe->usm.lock); if (vm->usm.asid) { void *lookup; @@ -1623,7 +1623,7 @@ void xe_vm_close_and_put(struct xe_vm *vm) lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); xe_assert(xe, lookup == vm); } - mutex_unlock(&xe->usm.lock); + up_write(&xe->usm.lock); for_each_tile(tile, xe, id) xe_range_fence_tree_fini(&vm->rftree[id]); @@ -1772,11 +1772,11 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, goto err_close_and_put; if (xe->info.has_asid) { - mutex_lock(&xe->usm.lock); + down_write(&xe->usm.lock); err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, XA_LIMIT(1, XE_MAX_ASID - 1), &xe->usm.next_asid, GFP_KERNEL); - mutex_unlock(&xe->usm.lock); + up_write(&xe->usm.lock); if (err < 0) goto err_free_id; -- GitLab From 0f18ac78aa974660a948dafcc45f4dc6e2c5858d Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Wed, 18 Sep 2024 09:05:03 -0700 Subject: [PATCH 658/970] drm/xe: Use helper for ASID -> VM in GPU faults and access counters Normalize both code paths with a helper. Fixes a possible leak access counter path too. Suggested-by: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918160503.2021315-1-matthew.brost@intel.com (cherry picked from commit dc0dce6d63d22e8319e27b6a41be7368376f9471) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_gt_pagefault.c | 39 +++++++++++++++------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c b/drivers/gpu/drm/xe/xe_gt_pagefault.c index 5c3af2bb5402..79c426dc2505 100644 --- a/drivers/gpu/drm/xe/xe_gt_pagefault.c +++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c @@ -185,6 +185,21 @@ static int handle_vma_pagefault(struct xe_tile *tile, struct pagefault *pf, return err; } +static struct xe_vm *asid_to_vm(struct xe_device *xe, u32 asid) +{ + struct xe_vm *vm; + + down_read(&xe->usm.lock); + vm = xa_load(&xe->usm.asid_to_vm, asid); + if (vm && xe_vm_in_fault_mode(vm)) + xe_vm_get(vm); + else + vm = ERR_PTR(-EINVAL); + up_read(&xe->usm.lock); + + return vm; +} + static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) { struct xe_device *xe = gt_to_xe(gt); @@ -197,16 +212,9 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf) if (pf->trva_fault) return -EFAULT; - /* ASID to VM */ - down_read(&xe->usm.lock); - vm = xa_load(&xe->usm.asid_to_vm, pf->asid); - if (vm && xe_vm_in_fault_mode(vm)) - xe_vm_get(vm); - else - vm = NULL; - up_read(&xe->usm.lock); - if (!vm) - return -EINVAL; + vm = asid_to_vm(xe, pf->asid); + if (IS_ERR(vm)) + return PTR_ERR(vm); /* * TODO: Change to read lock? Using write lock for simplicity. @@ -548,14 +556,9 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc) if (acc->access_type != ACC_TRIGGER) return -EINVAL; - /* ASID to VM */ - down_read(&xe->usm.lock); - vm = xa_load(&xe->usm.asid_to_vm, acc->asid); - if (vm) - xe_vm_get(vm); - up_read(&xe->usm.lock); - if (!vm || !xe_vm_in_fault_mode(vm)) - return -EINVAL; + vm = asid_to_vm(xe, acc->asid); + if (IS_ERR(vm)) + return PTR_ERR(vm); down_read(&vm->lock); -- GitLab From 7929ffce0f8b9c76cb5c2a67d1966beaed20ab61 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:15 -0300 Subject: [PATCH 659/970] drm/xe/mcr: Use Xe2_LPM steering tables for Xe2_HPM According to Bspec, Xe2 steering tables must be used for Xe2_HPM, just as it is with Xe2_LPM. Update our driver to reflect that. Bspec: 71186 Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-2-gustavo.sousa@intel.com (cherry picked from commit 21ae035ae5c33ef176f4062bd9d4aa973dde240b) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_gt_mcr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index 7d7bd0be6233..c834f64b0178 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -439,7 +439,7 @@ void xe_gt_mcr_init(struct xe_gt *gt) if (gt->info.type == XE_GT_TYPE_MEDIA) { drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13); - if (MEDIA_VER(xe) >= 20) { + if (MEDIA_VERx100(xe) >= 1301) { gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table; } else { -- GitLab From 3bf90935aafc750c838c8831e96c3ac36cfd48d5 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:16 -0300 Subject: [PATCH 660/970] drm/xe/xe2: Extend performance tuning to media GT With exception of "Tuning: L3 cache - media", we are currently applying recommended performance tuning settings only for the primary GT. Let's also implement them for the media GT when applicable. According to our spec, media GT registers CCCHKNREG1 and L3SQCREG* exist only in Xe2_LPM and their offsets do not match their primary GT counterparts. Furthermore, the range where CCCHKNREG1 belongs is not listed as a multicast range on the media GT. As such, we need to have Xe2_LPM-specific definitions for those registers and apply the setting only for that specific IP. Both Xe2_HPM and Xe2_LPM contain STATELESS_COMPRESSION_CTRL and the offset on the media GT matches the one on the primary one. So we can simply have a copy of "Tuning: Stateless compression control" for the media GT. v2: - Fix implementation with respect to multicast vs non-multicast registers. (Matt) - Add missing XE2LPM_CCCHKNREG1 on second action of "Tuning: Compression Overfetch - media". v3: - STATELESS_COMPRESSION_CTRL on Xe2_HPM is also a multicast register, do not define a XE2HPM_STATELESS_COMPRESSION_CTRL register. (Tejas) Bspec: 72161 Cc: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-3-gustavo.sousa@intel.com (cherry picked from commit e1f813947ccf2326cfda4558b7d31430d7860c4b) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 6 ++++++ drivers/gpu/drm/xe/xe_tuning.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 660ff42e45a6..5a1d4639e916 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -169,6 +169,8 @@ #define XEHP_SLICE_COMMON_ECO_CHICKEN1 XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED) #define MSC_MSAA_REODER_BUF_BYPASS_DISABLE REG_BIT(14) +#define XE2LPM_CCCHKNREG1 XE_REG(0x82a8) + #define VF_PREEMPTION XE_REG(0x83a4, XE_REG_OPTION_MASKED) #define PREEMPTION_VERTEX_COUNT REG_GENMASK(15, 0) @@ -391,6 +393,10 @@ #define SCRATCH1LPFC XE_REG(0xb474) #define EN_L3_RW_CCS_CACHE_FLUSH REG_BIT(0) +#define XE2LPM_L3SQCREG2 XE_REG_MCR(0xb604) + +#define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) + #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) #define XE2_TDF_CTRL XE_REG(0xb418) diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index faa1bf42e50e..c798ae1b3f75 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -42,20 +42,40 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { XE_RTP_ACTIONS(CLR(CCCHKNREG1, ENCOMPPERFFIX), SET(CCCHKNREG1, L3CMPCTRL)) }, + { XE_RTP_NAME("Tuning: Compression Overfetch - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(CLR(XE2LPM_CCCHKNREG1, ENCOMPPERFFIX), + SET(XE2LPM_CCCHKNREG1, L3CMPCTRL)) + }, { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(SET(L3SQCREG3, COMPPWOVERFETCHEN)) }, + { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3 - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG3, COMPPWOVERFETCHEN)) + }, { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(SET(L3SQCREG2, COMPMEMRD256BOVRFETCHEN)) }, + { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG2, + COMPMEMRD256BOVRFETCHEN)) + }, { XE_RTP_NAME("Tuning: Stateless compression control"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)), XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) }, + { XE_RTP_NAME("Tuning: Stateless compression control - media"), + XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, 2000)), + XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, + REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) + }, + {} }; -- GitLab From 6ef5a04221aaeb858d1a825b2ecb7e200cac80f8 Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Fri, 20 Sep 2024 18:13:18 -0300 Subject: [PATCH 661/970] drm/xe/xe2: Add performance tuning for L3 cache flushing A recommended performance tuning for LNL related to L3 cache flushing was recently introduced in Bspec. Implement it. Unlike the other existing tuning settings, we limit this one for LNL only, since there is no info about whether this would be applicable to other platforms yet. In the future we can come back and use IP version ranges if applicable. v2: - Fix reference to Bspec. (Sai Teja, Tejas) - Use correct register name for "Tuning: L3 RW flush all Cache". (Sai Teja) - Use SCRATCH3_LBCF (with the underscore) for better readability. v3: - Limit setting to LNL only. (Matt) Bspec: 72161 Cc: Sai Teja Pottumuttu <sai.teja.pottumuttu@intel.com> Cc: Tejas Upadhyay <tejas.upadhyay@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240920211459.255181-5-gustavo.sousa@intel.com (cherry picked from commit 876253165f3eaaacacb8c8bed16a9df4b6081479) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 5 +++++ drivers/gpu/drm/xe/xe_tuning.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 5a1d4639e916..ac9c437e103d 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -380,6 +380,9 @@ #define L3SQCREG3 XE_REG_MCR(0xb108) #define COMPPWOVERFETCHEN REG_BIT(28) +#define SCRATCH3_LBCF XE_REG_MCR(0xb154) +#define RWFLUSHALLEN REG_BIT(17) + #define XEHP_L3SQCREG5 XE_REG_MCR(0xb158) #define L3_PWM_TIMER_INIT_VAL_MASK REG_GENMASK(9, 0) @@ -397,6 +400,8 @@ #define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) +#define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) + #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) #define XE2_TDF_CTRL XE_REG(0xb418) diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index c798ae1b3f75..0d5e04158917 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -75,6 +75,14 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT, REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0))) }, + { XE_RTP_NAME("Tuning: L3 RW flush all Cache"), + XE_RTP_RULES(GRAPHICS_VERSION(2004)), + XE_RTP_ACTIONS(SET(SCRATCH3_LBCF, RWFLUSHALLEN)) + }, + { XE_RTP_NAME("Tuning: L3 RW flush all cache - media"), + XE_RTP_RULES(MEDIA_VERSION(2000)), + XE_RTP_ACTIONS(SET(XE2LPM_SCRATCH3_LBCF, RWFLUSHALLEN)) + }, {} }; -- GitLab From 1b30f87e088b499eb74298db256da5c98e8276e2 Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Wed, 24 Jul 2024 16:59:19 -0700 Subject: [PATCH 662/970] drm/xe: Resume TDR after GT reset Not starting the TDR after GT reset on exec queue which have been restarted can lead to jobs being able to be run forever. Fix this by restarting the TDR. Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240724235919.1917216-1-matthew.brost@intel.com (cherry picked from commit 8ec5a4e5ce97d6ee9f5eb5b4ce4cfc831976fdec) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_gpu_scheduler.c | 5 +++++ drivers/gpu/drm/xe/xe_gpu_scheduler.h | 2 ++ drivers/gpu/drm/xe/xe_guc_submit.c | 1 + 3 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.c b/drivers/gpu/drm/xe/xe_gpu_scheduler.c index c518d1d16d82..50361b4638f9 100644 --- a/drivers/gpu/drm/xe/xe_gpu_scheduler.c +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.c @@ -90,6 +90,11 @@ void xe_sched_submission_stop(struct xe_gpu_scheduler *sched) cancel_work_sync(&sched->work_process_msg); } +void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched) +{ + drm_sched_resume_timeout(&sched->base, sched->base.timeout); +} + void xe_sched_add_msg(struct xe_gpu_scheduler *sched, struct xe_sched_msg *msg) { diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.h b/drivers/gpu/drm/xe/xe_gpu_scheduler.h index cee9c6809fc0..5ad5629a6c60 100644 --- a/drivers/gpu/drm/xe/xe_gpu_scheduler.h +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.h @@ -22,6 +22,8 @@ void xe_sched_fini(struct xe_gpu_scheduler *sched); void xe_sched_submission_start(struct xe_gpu_scheduler *sched); void xe_sched_submission_stop(struct xe_gpu_scheduler *sched); +void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched); + void xe_sched_add_msg(struct xe_gpu_scheduler *sched, struct xe_sched_msg *msg); void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched, diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 98a6a385a796..80062e1d3f66 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1826,6 +1826,7 @@ static void guc_exec_queue_start(struct xe_exec_queue *q) } xe_sched_submission_start(sched); + xe_sched_submission_resume_tdr(sched); } int xe_guc_submit_start(struct xe_guc *guc) -- GitLab From 9e3c85ddea7a473ed57b6cdfef2dfd468356fc91 Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Fri, 20 Sep 2024 18:17:12 -0700 Subject: [PATCH 663/970] drm/xe: Clean up VM / exec queue file lock usage. Both the VM / exec queue file lock protect the lookup and reference to the object, nothing more. These locks are not intended anything else underneath them. XA have their own locking too, so no need to take the VM / exec queue file lock aside from when doing a lookup and reference get. Add some kernel doc to make this clear and cleanup a few typos too. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240921011712.2681510-1-matthew.brost@intel.com (cherry picked from commit fe4f5d4b661666a45b48fe7f95443f8fefc09c8c) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_device.c | 2 -- drivers/gpu/drm/xe/xe_device_types.h | 14 +++++++++++--- drivers/gpu/drm/xe/xe_drm_client.c | 9 ++++++++- drivers/gpu/drm/xe/xe_exec_queue.c | 2 -- drivers/gpu/drm/xe/xe_vm.c | 4 ---- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index fb7ac06aeef8..5a63d135ba96 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -171,10 +171,8 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file) xe_exec_queue_kill(q); xe_exec_queue_put(q); } - mutex_lock(&xef->vm.lock); xa_for_each(&xef->vm.xa, idx, vm) xe_vm_close_and_put(vm); - mutex_unlock(&xef->vm.lock); xe_file_put(xef); diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 00e370dcf4a9..09d731a9125c 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -570,15 +570,23 @@ struct xe_file { struct { /** @vm.xe: xarray to store VMs */ struct xarray xa; - /** @vm.lock: protects file VM state */ + /** + * @vm.lock: Protects VM lookup + reference and removal a from + * file xarray. Not an intended to be an outer lock which does + * thing while being held. + */ struct mutex lock; } vm; /** @exec_queue: Submission exec queue state for file */ struct { - /** @exec_queue.xe: xarray to store engines */ + /** @exec_queue.xa: xarray to store exece queues */ struct xarray xa; - /** @exec_queue.lock: protects file engine state */ + /** + * @exec_queue.lock: Protects exec queue lookup + reference and + * removal a frommfile xarray. Not an intended to be an outer + * lock which does thing while being held. + */ struct mutex lock; } exec_queue; diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c index c4add8b38bbd..fb52a23e28f8 100644 --- a/drivers/gpu/drm/xe/xe_drm_client.c +++ b/drivers/gpu/drm/xe/xe_drm_client.c @@ -283,8 +283,15 @@ static void show_run_ticks(struct drm_printer *p, struct drm_file *file) /* Accumulate all the exec queues from this client */ mutex_lock(&xef->exec_queue.lock); - xa_for_each(&xef->exec_queue.xa, i, q) + xa_for_each(&xef->exec_queue.xa, i, q) { + xe_exec_queue_get(q); + mutex_unlock(&xef->exec_queue.lock); + xe_exec_queue_update_run_ticks(q); + + mutex_lock(&xef->exec_queue.lock); + xe_exec_queue_put(q); + } mutex_unlock(&xef->exec_queue.lock); /* Get the total GPU cycles */ diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 7f28b7fc68d5..7743ebdcbf4b 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -635,9 +635,7 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data, } } - mutex_lock(&xef->exec_queue.lock); err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); - mutex_unlock(&xef->exec_queue.lock); if (err) goto kill_exec_queue; diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index a3d7cb7cfd22..31fe31db3fdc 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1765,9 +1765,7 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, if (IS_ERR(vm)) return PTR_ERR(vm); - mutex_lock(&xef->vm.lock); err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); - mutex_unlock(&xef->vm.lock); if (err) goto err_close_and_put; @@ -1799,9 +1797,7 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, return 0; err_free_id: - mutex_lock(&xef->vm.lock); xa_erase(&xef->vm.xa, id); - mutex_unlock(&xef->vm.lock); err_close_and_put: xe_vm_close_and_put(vm); -- GitLab From 74231870cf4976f69e83aa24f48edb16619f652f Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 25 Sep 2024 08:14:27 +0100 Subject: [PATCH 664/970] drm/xe/vm: move xa_alloc to prevent UAF Evil user can guess the next id of the vm before the ioctl completes and then call vm destroy ioctl to trigger UAF since create ioctl is still referencing the same vm. Move the xa_alloc all the way to the end to prevent this. v2: - Rebase Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925071426.144015-3-matthew.auld@intel.com (cherry picked from commit dcfd3971327f3ee92765154baebbaece833d3ca9) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_vm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 31fe31db3fdc..ce9dca4d4e87 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1765,10 +1765,6 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, if (IS_ERR(vm)) return PTR_ERR(vm); - err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); - if (err) - goto err_close_and_put; - if (xe->info.has_asid) { down_write(&xe->usm.lock); err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, @@ -1776,12 +1772,11 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, &xe->usm.next_asid, GFP_KERNEL); up_write(&xe->usm.lock); if (err < 0) - goto err_free_id; + goto err_close_and_put; vm->usm.asid = asid; } - args->vm_id = id; vm->xef = xe_file_get(xef); /* Record BO memory for VM pagetable created against client */ @@ -1794,10 +1789,15 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); #endif + /* user id alloc must always be last in ioctl to prevent UAF */ + err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL); + if (err) + goto err_close_and_put; + + args->vm_id = id; + return 0; -err_free_id: - xa_erase(&xef->vm.xa, id); err_close_and_put: xe_vm_close_and_put(vm); -- GitLab From 67801fa67b94ebd0e4da7a77ac2d9f321b75fbe0 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 25 Sep 2024 08:14:28 +0100 Subject: [PATCH 665/970] drm/xe/queue: move xa_alloc to prevent UAF Evil user can guess the next id of the queue before the ioctl completes and then call queue destroy ioctl to trigger UAF since create ioctl is still referencing the same queue. Move the xa_alloc all the way to the end to prevent this. v2: - Rebase Fixes: 2149ded63079 ("drm/xe: Fix use after free when client stats are captured") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925071426.144015-4-matthew.auld@intel.com (cherry picked from commit 16536582ddbebdbdf9e1d7af321bbba2bf955a87) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_exec_queue.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 7743ebdcbf4b..d098d2dd1b2d 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -635,12 +635,14 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data, } } + q->xef = xe_file_get(xef); + + /* user id alloc must always be last in ioctl to prevent UAF */ err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); if (err) goto kill_exec_queue; args->exec_queue_id = id; - q->xef = xe_file_get(xef); return 0; -- GitLab From 8135f1c09dd2eecee7cb637f7ec9a29e57300eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= <jose.souza@intel.com> Date: Tue, 24 Sep 2024 14:37:13 -0700 Subject: [PATCH 666/970] drm/xe/oa: Don't reset OAC_CONTEXT_ENABLE on OA stream close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesa testing on Xe2+ revealed that when OA metrics are collected for an exec_queue, after the OA stream is closed, future batch buffers submitted on that exec_queue do not complete. Not resetting OAC_CONTEXT_ENABLE on OA stream close resolves these hangs and should not have any adverse effects. v2: Make the change that we don't reset the bit clearer (Ashutosh) Also make the same fix for OAC as OAR (Ashutosh) Bspec: 60314 Fixes: 2f4a730fcd2d ("drm/xe/oa: Add OAR support") Fixes: 14e077f8006d ("drm/xe/oa: Add OAC support") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2821 Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Cc: stable@vger.kernel.org Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240924213713.3497992-1-ashutosh.dixit@intel.com (cherry picked from commit 0c8650b09a365f4a31fca1d1d1e9d99c56071128) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_oa.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index eae38a49ee8e..2804f14f8f29 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -709,8 +709,7 @@ static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable) { RING_CONTEXT_CONTROL(stream->hwe->mmio_base), regs_offset + CTX_CONTEXT_CONTROL, - _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, - enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE), }, }; struct xe_oa_reg reg_lri = { OAR_OACONTROL, oacontrol }; @@ -742,10 +741,8 @@ static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable) { RING_CONTEXT_CONTROL(stream->hwe->mmio_base), regs_offset + CTX_CONTEXT_CONTROL, - _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE, - enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) | - _MASKED_FIELD(CTX_CTRL_RUN_ALONE, - enable ? CTX_CTRL_RUN_ALONE : 0), + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) | + _MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0), }, }; struct xe_oa_reg reg_lri = { OAC_OACONTROL, oacontrol }; -- GitLab From 7257d9c9a3c6cfe26c428e9b7ae21d61f2f55a79 Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 27 Sep 2024 09:13:08 -0700 Subject: [PATCH 667/970] drm/xe: Prevent null pointer access in xe_migrate_copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xe_migrate_copy designed to copy content of TTM resources. When source resource is null, it will trigger a NULL pointer dereference in xe_migrate_copy. To avoid this situation, update lacks source flag to true for this case, the flag will trigger xe_migrate_clear rather than xe_migrate_copy. Issue trace: <7> [317.089847] xe 0000:00:02.0: [drm:xe_migrate_copy [xe]] Pass 14, sizes: 4194304 & 4194304 <7> [317.089945] xe 0000:00:02.0: [drm:xe_migrate_copy [xe]] Pass 15, sizes: 4194304 & 4194304 <1> [317.128055] BUG: kernel NULL pointer dereference, address: 0000000000000010 <1> [317.128064] #PF: supervisor read access in kernel mode <1> [317.128066] #PF: error_code(0x0000) - not-present page <6> [317.128069] PGD 0 P4D 0 <4> [317.128071] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI <4> [317.128074] CPU: 1 UID: 0 PID: 1440 Comm: kunit_try_catch Tainted: G U N 6.11.0-rc7-xe #1 <4> [317.128078] Tainted: [U]=USER, [N]=TEST <4> [317.128080] Hardware name: Intel Corporation Lunar Lake Client Platform/LNL-M LP5 RVP1, BIOS LNLMFWI1.R00.3221.D80.2407291239 07/29/2024 <4> [317.128082] RIP: 0010:xe_migrate_copy+0x66/0x13e0 [xe] <4> [317.128158] Code: 00 00 48 89 8d e0 fe ff ff 48 8b 40 10 4c 89 85 c8 fe ff ff 44 88 8d bd fe ff ff 65 48 8b 3c 25 28 00 00 00 48 89 7d d0 31 ff <8b> 79 10 48 89 85 a0 fe ff ff 48 8b 00 48 89 b5 d8 fe ff ff 83 ff <4> [317.128162] RSP: 0018:ffffc9000167f9f0 EFLAGS: 00010246 <4> [317.128164] RAX: ffff8881120d8028 RBX: ffff88814d070428 RCX: 0000000000000000 <4> [317.128166] RDX: ffff88813cb99c00 RSI: 0000000004000000 RDI: 0000000000000000 <4> [317.128168] RBP: ffffc9000167fbb8 R08: ffff88814e7b1f08 R09: 0000000000000001 <4> [317.128170] R10: 0000000000000001 R11: 0000000000000001 R12: ffff88814e7b1f08 <4> [317.128172] R13: ffff88814e7b1f08 R14: ffff88813cb99c00 R15: 0000000000000001 <4> [317.128174] FS: 0000000000000000(0000) GS:ffff88846f280000(0000) knlGS:0000000000000000 <4> [317.128176] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4> [317.128178] CR2: 0000000000000010 CR3: 000000011f676004 CR4: 0000000000770ef0 <4> [317.128180] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <4> [317.128182] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 <4> [317.128184] PKRU: 55555554 <4> [317.128185] Call Trace: <4> [317.128187] <TASK> <4> [317.128189] ? show_regs+0x67/0x70 <4> [317.128194] ? __die_body+0x20/0x70 <4> [317.128196] ? __die+0x2b/0x40 <4> [317.128198] ? page_fault_oops+0x15f/0x4e0 <4> [317.128203] ? do_user_addr_fault+0x3fb/0x970 <4> [317.128205] ? lock_acquire+0xc7/0x2e0 <4> [317.128209] ? exc_page_fault+0x87/0x2b0 <4> [317.128212] ? asm_exc_page_fault+0x27/0x30 <4> [317.128216] ? xe_migrate_copy+0x66/0x13e0 [xe] <4> [317.128263] ? __lock_acquire+0xb9d/0x26f0 <4> [317.128265] ? __lock_acquire+0xb9d/0x26f0 <4> [317.128267] ? sg_free_append_table+0x20/0x80 <4> [317.128271] ? lock_acquire+0xc7/0x2e0 <4> [317.128273] ? mark_held_locks+0x4d/0x80 <4> [317.128275] ? trace_hardirqs_on+0x1e/0xd0 <4> [317.128278] ? _raw_spin_unlock_irqrestore+0x31/0x60 <4> [317.128281] ? __pm_runtime_resume+0x60/0xa0 <4> [317.128284] xe_bo_move+0x682/0xc50 [xe] <4> [317.128315] ? lock_is_held_type+0xaa/0x120 <4> [317.128318] ttm_bo_handle_move_mem+0xe5/0x1a0 [ttm] <4> [317.128324] ttm_bo_validate+0xd1/0x1a0 [ttm] <4> [317.128328] shrink_test_run_device+0x721/0xc10 [xe] <4> [317.128360] ? find_held_lock+0x31/0x90 <4> [317.128363] ? lock_release+0xd1/0x2a0 <4> [317.128365] ? __pfx_kunit_generic_run_threadfn_adapter+0x10/0x10 [kunit] <4> [317.128370] xe_bo_shrink_kunit+0x11/0x20 [xe] <4> [317.128397] kunit_try_run_case+0x6e/0x150 [kunit] <4> [317.128400] ? trace_hardirqs_on+0x1e/0xd0 <4> [317.128402] ? _raw_spin_unlock_irqrestore+0x31/0x60 <4> [317.128404] kunit_generic_run_threadfn_adapter+0x1e/0x40 [kunit] <4> [317.128407] kthread+0xf5/0x130 <4> [317.128410] ? __pfx_kthread+0x10/0x10 <4> [317.128412] ret_from_fork+0x39/0x60 <4> [317.128415] ? __pfx_kthread+0x10/0x10 <4> [317.128416] ret_from_fork_asm+0x1a/0x30 <4> [317.128420] </TASK> Fixes: 266c85885263 ("drm/xe/xe2: Handle flat ccs move for igfx.") Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240927161308.862323-2-zhanjun.dong@intel.com (cherry picked from commit 59a1c9c7e1d02b43b415ea92627ce095b7c79e47) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_bo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index f379df3a12bf..e5f51fd23c65 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -680,8 +680,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict, tt_has_data = ttm && (ttm_tt_is_populated(ttm) || (ttm->page_flags & TTM_TT_FLAG_SWAPPED)); - move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared) : - (!mem_type_is_vram(old_mem_type) && !tt_has_data); + move_lacks_source = !old_mem || (handle_system_ccs ? (!bo->ccs_cleared) : + (!mem_type_is_vram(old_mem_type) && !tt_has_data)); needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) || (!ttm && ttm_bo->type == ttm_bo_type_device); -- GitLab From a6f3b2527375c786f2eff77d3ee8b805bcfe026d Mon Sep 17 00:00:00 2001 From: Matthew Brost <matthew.brost@intel.com> Date: Fri, 27 Sep 2024 16:22:28 -0700 Subject: [PATCH 668/970] drm/xe: Fix memory leak when aborting binds Make sure to call xe_pt_update_ops_fini in xe_pt_update_ops_abort to free any memory the bind allocated. Caught by kmemleak when running Vulkan CTS tests on LNL. The leak seems to happen only when there's some kind of failure happening, like the lack of memory. Example output: unreferenced object 0xffff9120bdf62000 (size 8192): comm "deqp-vk", pid 115008, jiffies 4310295728 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 1b 05 f9 28 01 00 00 40 ...........(...@ 00 00 00 00 00 00 00 00 1b 15 f9 28 01 00 00 40 ...........(...@ backtrace (crc 7a56be79): [<ffffffff86dd81f0>] __kmalloc_cache_noprof+0x310/0x3d0 [<ffffffffc08e8211>] xe_pt_new_shared.constprop.0+0x81/0xb0 [xe] [<ffffffffc08e8309>] xe_pt_insert_entry+0xb9/0x140 [xe] [<ffffffffc08eab6d>] xe_pt_stage_bind_entry+0x12d/0x5b0 [xe] [<ffffffffc08ecbca>] xe_pt_walk_range+0xea/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08e9eff>] xe_pt_stage_bind.constprop.0+0x25f/0x580 [xe] [<ffffffffc08eb21a>] bind_op_prepare+0xea/0x6e0 [xe] [<ffffffffc08ebab8>] xe_pt_update_ops_prepare+0x1c8/0x440 [xe] [<ffffffffc08ffbf3>] ops_execute+0x143/0x850 [xe] [<ffffffffc0900b64>] vm_bind_ioctl_ops_execute+0x244/0x800 [xe] [<ffffffffc0906467>] xe_vm_bind_ioctl+0x1877/0x2370 [xe] [<ffffffffc05e92b3>] drm_ioctl_kernel+0xb3/0x110 [drm] unreferenced object 0xffff9120bdf72000 (size 8192): comm "deqp-vk", pid 115008, jiffies 4310295728 hex dump (first 32 bytes): 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk backtrace (crc 23b2f0b5): [<ffffffff86dd81f0>] __kmalloc_cache_noprof+0x310/0x3d0 [<ffffffffc08e8211>] xe_pt_new_shared.constprop.0+0x81/0xb0 [xe] [<ffffffffc08e8453>] xe_pt_stage_unbind_post_descend+0xb3/0x150 [xe] [<ffffffffc08ecd26>] xe_pt_walk_range+0x246/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08eccea>] xe_pt_walk_range+0x20a/0x280 [xe] [<ffffffffc08ece31>] xe_pt_walk_shared+0xc1/0x110 [xe] [<ffffffffc08e7b2a>] xe_pt_stage_unbind+0x9a/0xd0 [xe] [<ffffffffc08e913d>] unbind_op_prepare+0xdd/0x270 [xe] [<ffffffffc08eb9f6>] xe_pt_update_ops_prepare+0x106/0x440 [xe] [<ffffffffc08ffbf3>] ops_execute+0x143/0x850 [xe] [<ffffffffc0900b64>] vm_bind_ioctl_ops_execute+0x244/0x800 [xe] [<ffffffffc0906467>] xe_vm_bind_ioctl+0x1877/0x2370 [xe] [<ffffffffc05e92b3>] drm_ioctl_kernel+0xb3/0x110 [drm] [<ffffffffc05e95a0>] drm_ioctl+0x280/0x4e0 [drm] Reported-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2877 Fixes: a708f6501c69 ("drm/xe: Update PT layer with better error handling") Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240927232228.3255246-1-matthew.brost@intel.com (cherry picked from commit 63e0695597a044c96bf369e4d8ba031291449d95) Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> --- drivers/gpu/drm/xe/xe_pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c index d6353e8969f0..f27f579f4d85 100644 --- a/drivers/gpu/drm/xe/xe_pt.c +++ b/drivers/gpu/drm/xe/xe_pt.c @@ -2188,5 +2188,5 @@ void xe_pt_update_ops_abort(struct xe_tile *tile, struct xe_vma_ops *vops) pt_op->num_entries); } - xe_bo_put_commit(&vops->pt_update_ops[tile->id].deferred); + xe_pt_update_ops_fini(tile, vops); } -- GitLab From d278a9de5e1837edbe57b2f1f95a104ff6c84846 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela <perex@perex.cz> Date: Wed, 2 Oct 2024 21:46:49 +0200 Subject: [PATCH 669/970] ALSA: core: add isascii() check to card ID generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card identifier should contain only safe ASCII characters. The isalnum() returns true also for characters for non-ASCII characters. Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4135 Link: https://lore.kernel.org/linux-sound/yk3WTvKkwheOon_LzZlJ43PPInz6byYfBzpKkbasww1yzuiMRqn7n6Y8vZcXB-xwFCu_vb8hoNjv7DTNwH5TWjpEuiVsyn9HPCEXqwF4120=@protonmail.com/ Cc: stable@vger.kernel.org Reported-by: Barnabás PÅ‘cze <pobrn@protonmail.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz> Link: https://patch.msgid.link/20241002194649.1944696-1-perex@perex.cz Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/core/init.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sound/core/init.c b/sound/core/init.c index b92aa7103589..114fb87de990 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -654,13 +654,19 @@ void snd_card_free(struct snd_card *card) } EXPORT_SYMBOL(snd_card_free); +/* check, if the character is in the valid ASCII range */ +static inline bool safe_ascii_char(char c) +{ + return isascii(c) && isalnum(c); +} + /* retrieve the last word of shortname or longname */ static const char *retrieve_id_from_card_name(const char *name) { const char *spos = name; while (*name) { - if (isspace(*name) && isalnum(name[1])) + if (isspace(*name) && safe_ascii_char(name[1])) spos = name + 1; name++; } @@ -687,12 +693,12 @@ static void copy_valid_id_string(struct snd_card *card, const char *src, { char *id = card->id; - while (*nid && !isalnum(*nid)) + while (*nid && !safe_ascii_char(*nid)) nid++; if (isdigit(*nid)) *id++ = isalpha(*src) ? *src : 'D'; while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) { - if (isalnum(*nid)) + if (safe_ascii_char(*nid)) *id++ = *nid; nid++; } @@ -787,7 +793,7 @@ static ssize_t id_store(struct device *dev, struct device_attribute *attr, for (idx = 0; idx < copy; idx++) { c = buf[idx]; - if (!isalnum(c) && c != '_' && c != '-') + if (!safe_ascii_char(c) && c != '_' && c != '-') return -EINVAL; } memcpy(buf1, buf, copy); -- GitLab From 6b0bde5d8d4078ca5feec72fd2d828f0e5cf115d Mon Sep 17 00:00:00 2001 From: Jan Lalinsky <lalinsky@c4.cz> Date: Thu, 3 Oct 2024 05:08:11 +0200 Subject: [PATCH 670/970] ALSA: usb-audio: Add native DSD support for Luxman D-08u Add native DSD support for Luxman D-08u DAC, by adding the PID/VID 1852:5062. This makes DSD playback work, and also sound quality when playing PCM files is improved, crackling sounds are gone. Signed-off-by: Jan Lalinsky <lalinsky@c4.cz> Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20241003030811.2655735-1-lalinsky@c4.cz Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index c7a9c50a65bb..e6278a245795 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2221,6 +2221,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DISABLE_AUTOSUSPEND), DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ QUIRK_FLAG_DISABLE_AUTOSUSPEND), + DEVICE_FLG(0x1852, 0x5062, /* Luxman D-08u */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */ -- GitLab From 3e8800273c4b473342e2dbffa83a87f651d811c7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Thu, 3 Oct 2024 09:24:18 +0200 Subject: [PATCH 671/970] ALSA: hda: Add missing parameter description for snd_hdac_stream_timecounter_init() Add the missing description for the new parameter "start" of snd_hdac_stream_timecounter_init() in the previous patch. Fixes: df5215618fbe ("ALSA: hda: fix trigger_tstamp_latched") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202410031300.ecLmATNd-lkp@intel.com/ Link: https://patch.msgid.link/20241003072420.8932-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/hda/hdac_stream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 0411a8fe9d6f..2670792f43b4 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -657,6 +657,7 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, * snd_hdac_stream_timecounter_init - initialize time counter * @azx_dev: HD-audio core stream (master stream) * @streams: bit flags of streams to set up + * @start: true for PCM trigger start, false for other cases * * Initializes the time counter of streams marked by the bit flags (each * bit corresponds to the stream index). -- GitLab From 7264745d55422dbe53b5e75ddec622ab5d1290cb Mon Sep 17 00:00:00 2001 From: Thorsten Blum <thorsten.blum@toblux.com> Date: Thu, 12 Sep 2024 17:39:24 +0200 Subject: [PATCH 672/970] ceph: use struct_size() helper in __ceph_pool_perm_get() Use struct_size() to calculate the number of bytes to be allocated. Signed-off-by: Thorsten Blum <thorsten.blum@toblux.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> --- fs/ceph/addr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 53fef258c2bc..1d97a53d1b29 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -2145,7 +2145,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, } pool_ns_len = pool_ns ? pool_ns->len : 0; - perm = kmalloc(sizeof(*perm) + pool_ns_len + 1, GFP_NOFS); + perm = kmalloc(struct_size(perm, pool_ns, pool_ns_len + 1), GFP_NOFS); if (!perm) { err = -ENOMEM; goto out_unlock; -- GitLab From ccda9910d8490f4fb067131598e4b2e986faa5a0 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly <pdonnell@redhat.com> Date: Wed, 2 Oct 2024 21:05:12 -0400 Subject: [PATCH 673/970] ceph: fix cap ref leak via netfs init_request Log recovered from a user's cluster: <7>[ 5413.970692] ceph: get_cap_refs 00000000958c114b ret 1 got Fr <7>[ 5413.970695] ceph: start_read 00000000958c114b, no cache cap ... <7>[ 5473.934609] ceph: my wanted = Fr, used = Fr, dirty - <7>[ 5473.934616] ceph: revocation: pAsLsXsFr -> pAsLsXs (revoking Fr) <7>[ 5473.934632] ceph: __ceph_caps_issued 00000000958c114b cap 00000000f7784259 issued pAsLsXs <7>[ 5473.934638] ceph: check_caps 10000000e68.fffffffffffffffe file_want - used Fr dirty - flushing - issued pAsLsXs revoking Fr retain pAsLsXsFsr AUTHONLY NOINVAL FLUSH_FORCE The MDS subsequently complains that the kernel client is late releasing caps. Approximately, a series of changes to this code by commits 49870056005c ("ceph: convert ceph_readpages to ceph_readahead"), 2de160417315 ("netfs: Change ->init_request() to return an error code") and a5c9dc445139 ("ceph: Make ceph_init_request() check caps on readahead") resulted in subtle resource cleanup to be missed. The main culprit is the change in error handling in 2de160417315 which meant that a failure in init_request() would no longer cause cleanup to be called. That would prevent the ceph_put_cap_refs() call which would cleanup the leaked cap ref. Cc: stable@vger.kernel.org Fixes: a5c9dc445139 ("ceph: Make ceph_init_request() check caps on readahead") Link: https://tracker.ceph.com/issues/67008 Signed-off-by: Patrick Donnelly <pdonnell@redhat.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> --- fs/ceph/addr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 1d97a53d1b29..c2a9e2cc03de 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -489,8 +489,11 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file) rreq->io_streams[0].sreq_max_len = fsc->mount_options->rsize; out: - if (ret < 0) + if (ret < 0) { + if (got) + ceph_put_cap_refs(ceph_inode(inode), got); kfree(priv); + } return ret; } -- GitLab From 52789ce35c55ccd30c4b67b9cc5b2af55e0122ea Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Tue, 1 Oct 2024 09:43:47 +0100 Subject: [PATCH 674/970] drm/xe/ct: prevent UAF in send_recv() Ensure we serialize with completion side to prevent UAF with fence going out of scope on the stack, since we have no clue if it will fire after the timeout before we can erase from the xa. Also we have some dependent loads and stores for which we need the correct ordering, and we lack the needed barriers. Fix this by grabbing the ct->lock after the wait, which is also held by the completion side. v2 (Badal): - Also print done after acquiring the lock and seeing timeout. Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Badal Nilawar <badal.nilawar@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241001084346.98516-5-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_guc_ct.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 4b95f75b1546..44263b3cd8c7 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -903,16 +903,26 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len, } ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ); + + /* + * Ensure we serialize with completion side to prevent UAF with fence going out of scope on + * the stack, since we have no clue if it will fire after the timeout before we can erase + * from the xa. Also we have some dependent loads and stores below for which we need the + * correct ordering, and we lack the needed barriers. + */ + mutex_lock(&ct->lock); if (!ret) { - xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x", - g2h_fence.seqno, action[0]); + xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x, done %s", + g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done)); xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); + mutex_unlock(&ct->lock); return -ETIME; } if (g2h_fence.retry) { xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n", action[0], g2h_fence.reason); + mutex_unlock(&ct->lock); goto retry; } if (g2h_fence.fail) { @@ -921,7 +931,12 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len, ret = -EIO; } - return ret > 0 ? response_buffer ? g2h_fence.response_len : g2h_fence.response_data : ret; + if (ret > 0) + ret = response_buffer ? g2h_fence.response_len : g2h_fence.response_data; + + mutex_unlock(&ct->lock); + + return ret; } /** -- GitLab From 1aa4b7864707886fa40d959483591f3d3937fa28 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Tue, 1 Oct 2024 09:43:48 +0100 Subject: [PATCH 675/970] drm/xe/ct: fix xa_store() error checking Looks like we are meant to use xa_err() to extract the error encoded in the ptr. Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Badal Nilawar <badal.nilawar@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241001084346.98516-6-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_guc_ct.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 44263b3cd8c7..d3de2e6d690f 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -667,16 +667,12 @@ static int __guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, num_g2h = 1; if (g2h_fence_needs_alloc(g2h_fence)) { - void *ptr; - g2h_fence->seqno = next_ct_seqno(ct, true); - ptr = xa_store(&ct->fence_lookup, - g2h_fence->seqno, - g2h_fence, GFP_ATOMIC); - if (IS_ERR(ptr)) { - ret = PTR_ERR(ptr); + ret = xa_err(xa_store(&ct->fence_lookup, + g2h_fence->seqno, g2h_fence, + GFP_ATOMIC)); + if (ret) goto out; - } } seqno = g2h_fence->seqno; @@ -879,14 +875,11 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len, retry_same_fence: ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence); if (unlikely(ret == -ENOMEM)) { - void *ptr; - /* Retry allocation /w GFP_KERNEL */ - ptr = xa_store(&ct->fence_lookup, - g2h_fence.seqno, - &g2h_fence, GFP_KERNEL); - if (IS_ERR(ptr)) - return PTR_ERR(ptr); + ret = xa_err(xa_store(&ct->fence_lookup, g2h_fence.seqno, + &g2h_fence, GFP_KERNEL)); + if (ret) + return ret; goto retry_same_fence; } else if (unlikely(ret)) { -- GitLab From f040327238b1a8311598c40ac94464e77fff368c Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Tue, 1 Oct 2024 09:43:49 +0100 Subject: [PATCH 676/970] drm/xe/guc_submit: fix xa_store() error checking Looks like we are meant to use xa_err() to extract the error encoded in the ptr. Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Badal Nilawar <badal.nilawar@intel.com> Cc: <stable@vger.kernel.org> # v6.8+ Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241001084346.98516-7-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_guc_submit.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 80062e1d3f66..8a5c21a87977 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -393,7 +393,6 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) { int ret; - void *ptr; int i; /* @@ -413,12 +412,10 @@ static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q) q->guc->id = ret; for (i = 0; i < q->width; ++i) { - ptr = xa_store(&guc->submission_state.exec_queue_lookup, - q->guc->id + i, q, GFP_NOWAIT); - if (IS_ERR(ptr)) { - ret = PTR_ERR(ptr); + ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup, + q->guc->id + i, q, GFP_NOWAIT)); + if (ret) goto err_release; - } } return 0; -- GitLab From 11bfc4a2cfeaa012113d9b64fc30a5e6e742fc19 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Tue, 1 Oct 2024 09:43:50 +0100 Subject: [PATCH 677/970] drm/xe/ct: drop irq usage of xa_erase() Unclear why disabling interrupts is needed here. Nothing seems to be touching fence_lookup and its corresponding lock from an irq so there should be no risk of deadlock. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Badal Nilawar <badal.nilawar@intel.com> Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241001084346.98516-8-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_guc_ct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index d3de2e6d690f..3fd1d4e97528 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -890,7 +890,7 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len, goto retry_same_fence; if (!g2h_fence_needs_alloc(&g2h_fence)) - xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); + xa_erase(&ct->fence_lookup, g2h_fence.seqno); return ret; } @@ -907,7 +907,7 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len, if (!ret) { xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x, done %s", g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done)); - xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); + xa_erase(&ct->fence_lookup, g2h_fence.seqno); mutex_unlock(&ct->lock); return -ETIME; } -- GitLab From a0ffa68c70b367358b2672cdab6fa5bc4c40de2c Mon Sep 17 00:00:00 2001 From: Eddie James <eajames@linux.ibm.com> Date: Wed, 25 Sep 2024 10:55:23 -0500 Subject: [PATCH 678/970] net/ncsi: Disable the ncsi work before freeing the associated structure The work function can run after the ncsi device is freed, resulting in use-after-free bugs or kernel panic. Fixes: 2d283bdd079c ("net/ncsi: Resource management") Signed-off-by: Eddie James <eajames@linux.ibm.com> Link: https://patch.msgid.link/20240925155523.1017097-1-eajames@linux.ibm.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/ncsi/ncsi-manage.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index 5ecf611c8820..5cf55bde366d 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c @@ -1954,6 +1954,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd) list_del_rcu(&ndp->node); spin_unlock_irqrestore(&ncsi_dev_lock, flags); + disable_work_sync(&ndp->work); + kfree(ndp); } EXPORT_SYMBOL_GPL(ncsi_unregister_dev); -- GitLab From f7a4874d977bf4202ad575031222e78809a36292 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" <djwong@kernel.org> Date: Wed, 2 Oct 2024 08:00:40 -0700 Subject: [PATCH 679/970] iomap: don't bother unsharing delalloc extents If unshare encounters a delalloc reservation in the srcmap, that means that the file range isn't shared because delalloc reservations cannot be reflinked. Therefore, don't try to unshare them. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20241002150040.GB21853@frogsfrogsfrogs Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/iomap/buffered-io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 11ea747228ae..c1c559e0cc07 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1321,7 +1321,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) return length; /* - * Don't bother with holes or unwritten extents. + * Don't bother with delalloc reservations, holes or unwritten extents. * * Note that we use srcmap directly instead of iomap_iter_srcmap as * unsharing requires providing a separate source map, and the presence @@ -1330,6 +1330,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) * fork for XFS. */ if (iter->srcmap.type == IOMAP_HOLE || + iter->srcmap.type == IOMAP_DELALLOC || iter->srcmap.type == IOMAP_UNWRITTEN) return length; -- GitLab From a311a08a4237241fb5b9d219d3e33346de6e83e0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" <djwong@kernel.org> Date: Wed, 2 Oct 2024 08:02:13 -0700 Subject: [PATCH 680/970] iomap: constrain the file range passed to iomap_file_unshare File contents can only be shared (i.e. reflinked) below EOF, so it makes no sense to try to unshare ranges beyond EOF. Constrain the file range parameters here so that we don't have to do that in the callers. Fixes: 5f4e5752a8a3 ("fs: add iomap_file_dirty") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20241002150213.GC21853@frogsfrogsfrogs Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Christian Brauner <brauner@kernel.org> --- fs/dax.c | 6 +++++- fs/iomap/buffered-io.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index becb4a6920c6..c62acd2812f8 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1305,11 +1305,15 @@ int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len, struct iomap_iter iter = { .inode = inode, .pos = pos, - .len = len, .flags = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX, }; + loff_t size = i_size_read(inode); int ret; + if (pos < 0 || pos >= size) + return 0; + + iter.len = min(len, size - pos); while ((ret = iomap_iter(&iter, ops)) > 0) iter.processed = dax_unshare_iter(&iter); return ret; diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index c1c559e0cc07..78ebd265f425 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1375,11 +1375,15 @@ iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len, struct iomap_iter iter = { .inode = inode, .pos = pos, - .len = len, .flags = IOMAP_WRITE | IOMAP_UNSHARE, }; + loff_t size = i_size_read(inode); int ret; + if (pos < 0 || pos >= size) + return 0; + + iter.len = min(len, size - pos); while ((ret = iomap_iter(&iter, ops)) > 0) iter.processed = iomap_unshare_iter(&iter); return ret; -- GitLab From b63ad06ddddfe792f93df0c24adb66622bd7b8c9 Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Mon, 30 Sep 2024 11:39:54 -0400 Subject: [PATCH 681/970] doc: net: napi: Update documentation for napi_schedule_irqoff Since commit 8380c81d5c4f ("net: Treat __napi_schedule_irqoff() as __napi_schedule() on PREEMPT_RT"), napi_schedule_irqoff will do the right thing if IRQs are threaded. Therefore, there is no need to use IRQF_NO_THREAD. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://patch.msgid.link/20240930153955.971657-1-sean.anderson@linux.dev Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- Documentation/networking/napi.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/napi.rst b/Documentation/networking/napi.rst index 7bf7b95c4f7a..dfa5d549be9c 100644 --- a/Documentation/networking/napi.rst +++ b/Documentation/networking/napi.rst @@ -144,9 +144,8 @@ IRQ should only be unmasked after a successful call to napi_complete_done(): napi_schedule_irqoff() is a variant of napi_schedule() which takes advantage of guarantees given by being invoked in IRQ context (no need to -mask interrupts). Note that PREEMPT_RT forces all interrupts -to be threaded so the interrupt may need to be marked ``IRQF_NO_THREAD`` -to avoid issues on real-time kernel configurations. +mask interrupts). napi_schedule_irqoff() will fall back to napi_schedule() if +IRQs are threaded (such as if ``PREEMPT_RT`` is enabled). Instance to queue mapping ------------------------- -- GitLab From c6929644c1e0d6108e57061d427eb966e1746351 Mon Sep 17 00:00:00 2001 From: Ravikanth Tuniki <ravikanth.tuniki@amd.com> Date: Tue, 1 Oct 2024 00:43:35 +0530 Subject: [PATCH 682/970] dt-bindings: net: xlnx,axi-ethernet: Add missing reg minItems Add missing reg minItems as based on current binding document only ethernet MAC IO space is a supported configuration. There is a bug in schema, current examples contain 64-bit addressing as well as 32-bit addressing. The schema validation does pass incidentally considering one 64-bit reg address as two 32-bit reg address entries. If we change axi_ethernet_eth1 example node reg addressing to 32-bit schema validation reports: Documentation/devicetree/bindings/net/xlnx,axi-ethernet.example.dtb: ethernet@40000000: reg: [[1073741824, 262144]] is too short To fix it add missing reg minItems constraints and to make things clearer stick to 32-bit addressing in examples. Fixes: cbb1ca6d5f9a ("dt-bindings: net: xlnx,axi-ethernet: convert bindings document to yaml") Signed-off-by: Ravikanth Tuniki <ravikanth.tuniki@amd.com> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> Acked-by: Conor Dooley <conor.dooley@microchip.com> Link: https://patch.msgid.link/1727723615-2109795-1-git-send-email-radhey.shyam.pandey@amd.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml b/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml index bbe89ea9590c..e95c21628281 100644 --- a/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml +++ b/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml @@ -34,6 +34,7 @@ properties: and length of the AXI DMA controller IO space, unless axistream-connected is specified, in which case the reg attribute of the node referenced by it is used. + minItems: 1 maxItems: 2 interrupts: @@ -181,7 +182,7 @@ examples: clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk"; clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>; phy-mode = "mii"; - reg = <0x00 0x40000000 0x00 0x40000>; + reg = <0x40000000 0x40000>; xlnx,rxcsum = <0x2>; xlnx,rxmem = <0x800>; xlnx,txcsum = <0x2>; -- GitLab From 8beee4d8dee76b67c75dc91fd8185d91e845c160 Mon Sep 17 00:00:00 2001 From: Xin Long <lucien.xin@gmail.com> Date: Mon, 30 Sep 2024 16:49:51 -0400 Subject: [PATCH 683/970] sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start In sctp_listen_start() invoked by sctp_inet_listen(), it should set the sk_state back to CLOSED if sctp_autobind() fails due to whatever reason. Otherwise, next time when calling sctp_inet_listen(), if sctp_sk(sk)->reuse is already set via setsockopt(SCTP_REUSE_PORT), sctp_sk(sk)->bind_hash will be dereferenced as sk_state is LISTENING, which causes a crash as bind_hash is NULL. KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:sctp_inet_listen+0x7f0/0xa20 net/sctp/socket.c:8617 Call Trace: <TASK> __sys_listen_socket net/socket.c:1883 [inline] __sys_listen+0x1b7/0x230 net/socket.c:1894 __do_sys_listen net/socket.c:1902 [inline] Fixes: 5e8f3f703ae4 ("sctp: simplify sctp listening code") Reported-by: syzbot+f4e0f821e3a3b7cee51d@syzkaller.appspotmail.com Signed-off-by: Xin Long <lucien.xin@gmail.com> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Link: https://patch.msgid.link/a93e655b3c153dc8945d7a812e6d8ab0d52b7aa0.1727729391.git.lucien.xin@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/sctp/socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 32f76f1298da..078bcb3858c7 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -8557,8 +8557,10 @@ static int sctp_listen_start(struct sock *sk, int backlog) */ inet_sk_set_state(sk, SCTP_SS_LISTENING); if (!ep->base.bind_addr.port) { - if (sctp_autobind(sk)) + if (sctp_autobind(sk)) { + inet_sk_set_state(sk, SCTP_SS_CLOSED); return -EAGAIN; + } } else { if (sctp_get_port(sk, inet_sk(sk)->inet_num)) { inet_sk_set_state(sk, SCTP_SS_CLOSED); -- GitLab From 91b2c42c214f570efaff80a666e30b8f6ce4f12b Mon Sep 17 00:00:00 2001 From: Francois Dugast <francois.dugast@intel.com> Date: Fri, 27 Sep 2024 17:12:06 +0200 Subject: [PATCH 684/970] drm/xe: Use fault injection infrastructure to find issues at probe time The kernel fault injection infrastructure is used to test proper error handling during probe. The return code of the functions using ALLOW_ERROR_INJECTION() can be conditionnally modified at runtime by tuning some debugfs entries. This requires CONFIG_FUNCTION_ERROR_INJECTION (among others). One way to use fault injection at probe time by making each of those functions fail one at a time is: FAILTYPE=fail_function DEVICE="0000:00:08.0" # depends on the system ERRNO=-12 # -ENOMEM, can depend on the function echo N > /sys/kernel/debug/$FAILTYPE/task-filter echo 100 > /sys/kernel/debug/$FAILTYPE/probability echo 0 > /sys/kernel/debug/$FAILTYPE/interval echo -1 > /sys/kernel/debug/$FAILTYPE/times echo 0 > /sys/kernel/debug/$FAILTYPE/space echo 1 > /sys/kernel/debug/$FAILTYPE/verbose modprobe xe echo $DEVICE > /sys/bus/pci/drivers/xe/unbind grep -oP "^.* \[xe\]" /sys/kernel/debug/$FAILTYPE/injectable | \ cut -d ' ' -f 1 | while read -r FUNCTION ; do echo "Injecting fault in $FUNCTION" echo "" > /sys/kernel/debug/$FAILTYPE/inject echo $FUNCTION > /sys/kernel/debug/$FAILTYPE/inject printf %#x $ERRNO > /sys/kernel/debug/$FAILTYPE/$FUNCTION/retval echo $DEVICE > /sys/bus/pci/drivers/xe/bind done rmmod xe It will also be integrated into IGT for systematic execution by CI. v2: Wrappers are not needed in the cases covered by this patch, so remove them and use ALLOW_ERROR_INJECTION() directly. v3: Document the use of fault injection at probe time in xe_pci_probe and refer to it where ALLOW_ERROR_INJECTION() is used. Signed-off-by: Francois Dugast <francois.dugast@intel.com> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240927151207.399354-1-francois.dugast@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_device.c | 3 +++ drivers/gpu/drm/xe/xe_ggtt.c | 2 ++ drivers/gpu/drm/xe/xe_guc_ads.c | 3 +++ drivers/gpu/drm/xe/xe_guc_ct.c | 2 ++ drivers/gpu/drm/xe/xe_guc_log.c | 3 +++ drivers/gpu/drm/xe/xe_guc_relay.c | 2 ++ drivers/gpu/drm/xe/xe_pci.c | 19 +++++++++++++++++++ drivers/gpu/drm/xe/xe_pm.c | 2 ++ drivers/gpu/drm/xe/xe_sriov.c | 3 +++ drivers/gpu/drm/xe/xe_tile.c | 3 +++ drivers/gpu/drm/xe/xe_uc_fw.c | 2 ++ drivers/gpu/drm/xe/xe_wa.c | 2 ++ drivers/gpu/drm/xe/xe_wopcm.c | 3 +++ 13 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 8e9b551c7033..ad70a1bdd476 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -6,6 +6,7 @@ #include "xe_device.h" #include <linux/delay.h> +#include <linux/fault-inject.h> #include <linux/units.h> #include <drm/drm_aperture.h> @@ -382,6 +383,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, err: return ERR_PTR(err); } +ALLOW_ERROR_INJECTION(xe_device_create, ERRNO); /* See xe_pci_probe() */ static bool xe_driver_flr_disabled(struct xe_device *xe) { @@ -550,6 +552,7 @@ static int wait_for_lmem_ready(struct xe_device *xe) return 0; } +ALLOW_ERROR_INJECTION(wait_for_lmem_ready, ERRNO); /* See xe_pci_probe() */ static void update_device_info(struct xe_device *xe) { diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index f68af56c3f86..47bfd9d2635d 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -5,6 +5,7 @@ #include "xe_ggtt.h" +#include <linux/fault-inject.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/sizes.h> @@ -264,6 +265,7 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt) return 0; } +ALLOW_ERROR_INJECTION(xe_ggtt_init_early, ERRNO); /* See xe_pci_probe() */ static void xe_ggtt_invalidate(struct xe_ggtt *ggtt); diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c index 66d4e5e95abd..04485461aa20 100644 --- a/drivers/gpu/drm/xe/xe_guc_ads.c +++ b/drivers/gpu/drm/xe/xe_guc_ads.c @@ -5,6 +5,8 @@ #include "xe_guc_ads.h" +#include <linux/fault-inject.h> + #include <drm/drm_managed.h> #include <generated/xe_wa_oob.h> @@ -418,6 +420,7 @@ int xe_guc_ads_init(struct xe_guc_ads *ads) return 0; } +ALLOW_ERROR_INJECTION(xe_guc_ads_init, ERRNO); /* See xe_pci_probe() */ /** * xe_guc_ads_init_post_hwconfig - initialize ADS post hwconfig load diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 3fd1d4e97528..5aef2be2d027 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -8,6 +8,7 @@ #include <linux/bitfield.h> #include <linux/circ_buf.h> #include <linux/delay.h> +#include <linux/fault-inject.h> #include <kunit/static_stub.h> @@ -209,6 +210,7 @@ int xe_guc_ct_init(struct xe_guc_ct *ct) ct->state = XE_GUC_CT_STATE_DISABLED; return 0; } +ALLOW_ERROR_INJECTION(xe_guc_ct_init, ERRNO); /* See xe_pci_probe() */ #define desc_read(xe_, guc_ctb__, field_) \ xe_map_rd_field(xe_, &guc_ctb__->desc, 0, \ diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index a37ee3419428..651543721ce5 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -5,6 +5,8 @@ #include "xe_guc_log.h" +#include <linux/fault-inject.h> + #include <drm/drm_managed.h> #include "xe_bo.h" @@ -96,3 +98,4 @@ int xe_guc_log_init(struct xe_guc_log *log) return 0; } +ALLOW_ERROR_INJECTION(xe_guc_log_init, ERRNO); /* See xe_pci_probe() */ diff --git a/drivers/gpu/drm/xe/xe_guc_relay.c b/drivers/gpu/drm/xe/xe_guc_relay.c index ade6162dc259..8f62de026724 100644 --- a/drivers/gpu/drm/xe/xe_guc_relay.c +++ b/drivers/gpu/drm/xe/xe_guc_relay.c @@ -5,6 +5,7 @@ #include <linux/bitfield.h> #include <linux/delay.h> +#include <linux/fault-inject.h> #include <drm/drm_managed.h> @@ -355,6 +356,7 @@ int xe_guc_relay_init(struct xe_guc_relay *relay) return drmm_add_action_or_reset(&xe->drm, __fini_relay, relay); } +ALLOW_ERROR_INJECTION(xe_guc_relay_init, ERRNO); /* See xe_pci_probe() */ static u32 to_relay_error(int err) { diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index edaeefd2d648..af7b2f2ff13a 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -765,6 +765,25 @@ static void xe_pci_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +/* + * Probe the PCI device, initialize various parts of the driver. + * + * Fault injection is used to test the error paths of some initialization + * functions called either directly from xe_pci_probe() or indirectly for + * example through xe_device_probe(). Those functions use the kernel fault + * injection capabilities infrastructure, see + * Documentation/fault-injection/fault-injection.rst for details. The macro + * ALLOW_ERROR_INJECTION() is used to conditionally skip function execution + * at runtime and use a provided return value. The first requirement for + * error injectable functions is proper handling of the error code by the + * caller for recovery, which is always the case here. The second + * requirement is that no state is changed before the first error return. + * It is not strictly fullfilled for all initialization functions using the + * ALLOW_ERROR_INJECTION() macro but this is acceptable because for those + * error cases at probe time, the error code is simply propagated up by the + * caller. Therefore there is no consequence on those specific callers when + * function error injection skips the whole function. + */ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { const struct xe_device_desc *desc = (const void *)ent->driver_data; diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c index 33eb039053e4..40f7c844ed44 100644 --- a/drivers/gpu/drm/xe/xe_pm.c +++ b/drivers/gpu/drm/xe/xe_pm.c @@ -5,6 +5,7 @@ #include "xe_pm.h" +#include <linux/fault-inject.h> #include <linux/pm_runtime.h> #include <drm/drm_managed.h> @@ -263,6 +264,7 @@ int xe_pm_init_early(struct xe_device *xe) return 0; } +ALLOW_ERROR_INJECTION(xe_pm_init_early, ERRNO); /* See xe_pci_probe() */ /** * xe_pm_init - Initialize Xe Power Management diff --git a/drivers/gpu/drm/xe/xe_sriov.c b/drivers/gpu/drm/xe/xe_sriov.c index 69a066ef20c0..ef10782af656 100644 --- a/drivers/gpu/drm/xe/xe_sriov.c +++ b/drivers/gpu/drm/xe/xe_sriov.c @@ -3,6 +3,8 @@ * Copyright © 2023 Intel Corporation */ +#include <linux/fault-inject.h> + #include <drm/drm_managed.h> #include "regs/xe_regs.h" @@ -119,6 +121,7 @@ int xe_sriov_init(struct xe_device *xe) return drmm_add_action_or_reset(&xe->drm, fini_sriov, xe); } +ALLOW_ERROR_INJECTION(xe_sriov_init, ERRNO); /* See xe_pci_probe() */ /** * xe_sriov_print_info - Print basic SR-IOV information. diff --git a/drivers/gpu/drm/xe/xe_tile.c b/drivers/gpu/drm/xe/xe_tile.c index dda5268507d8..07cf7cfe4abd 100644 --- a/drivers/gpu/drm/xe/xe_tile.c +++ b/drivers/gpu/drm/xe/xe_tile.c @@ -3,6 +3,8 @@ * Copyright © 2023 Intel Corporation */ +#include <linux/fault-inject.h> + #include <drm/drm_managed.h> #include "xe_device.h" @@ -129,6 +131,7 @@ int xe_tile_init_early(struct xe_tile *tile, struct xe_device *xe, u8 id) return 0; } +ALLOW_ERROR_INJECTION(xe_tile_init_early, ERRNO); /* See xe_pci_probe() */ static int tile_ttm_mgr_init(struct xe_tile *tile) { diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c index d339f636f4d5..fb0eda3d5682 100644 --- a/drivers/gpu/drm/xe/xe_uc_fw.c +++ b/drivers/gpu/drm/xe/xe_uc_fw.c @@ -4,6 +4,7 @@ */ #include <linux/bitfield.h> +#include <linux/fault-inject.h> #include <linux/firmware.h> #include <drm/drm_managed.h> @@ -796,6 +797,7 @@ int xe_uc_fw_init(struct xe_uc_fw *uc_fw) return err; } +ALLOW_ERROR_INJECTION(xe_uc_fw_init, ERRNO); /* See xe_pci_probe() */ static u32 uc_fw_ggtt_offset(struct xe_uc_fw *uc_fw) { diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 22c148b1e996..94ea76b098ed 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -8,6 +8,7 @@ #include <drm/drm_managed.h> #include <kunit/visibility.h> #include <linux/compiler_types.h> +#include <linux/fault-inject.h> #include <generated/xe_wa_oob.h> @@ -850,6 +851,7 @@ int xe_wa_init(struct xe_gt *gt) return 0; } +ALLOW_ERROR_INJECTION(xe_wa_init, ERRNO); /* See xe_pci_probe() */ void xe_wa_dump(struct xe_gt *gt, struct drm_printer *p) { diff --git a/drivers/gpu/drm/xe/xe_wopcm.c b/drivers/gpu/drm/xe/xe_wopcm.c index 93c82825d896..ada0d0aa6b74 100644 --- a/drivers/gpu/drm/xe/xe_wopcm.c +++ b/drivers/gpu/drm/xe/xe_wopcm.c @@ -5,6 +5,8 @@ #include "xe_wopcm.h" +#include <linux/fault-inject.h> + #include "regs/xe_guc_regs.h" #include "xe_device.h" #include "xe_force_wake.h" @@ -268,3 +270,4 @@ int xe_wopcm_init(struct xe_wopcm *wopcm) return ret; } +ALLOW_ERROR_INJECTION(xe_wopcm_init, ERRNO); /* See xe_pci_probe() */ -- GitLab From bc41d57fab2b3b8faa6699ee3ed824620777356f Mon Sep 17 00:00:00 2001 From: Vignesh Raman <vignesh.raman@collabora.com> Date: Mon, 30 Sep 2024 15:22:47 +0530 Subject: [PATCH 685/970] docs/gpu: ci: update flake tests requirements Update the documentation to specify linking to a relevant GitLab issue or email report for each new flake entry. Added specific GitLab issue urls for amdgpu, i915, msm and xe driver. Acked-by: Maxime Ripard <mripard@kernel.org> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #intel and xe Acked-by: Abhinav Kumar <quic_abhinavk@quicinc.com> # msm Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> # msm Signed-off-by: Vignesh Raman <vignesh.raman@collabora.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Helen Koike <helen.koike@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930095255.2071586-1-vignesh.raman@collabora.com --- Documentation/gpu/automated_testing.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/gpu/automated_testing.rst b/Documentation/gpu/automated_testing.rst index 2d5a28866afe..6d7c6086034d 100644 --- a/Documentation/gpu/automated_testing.rst +++ b/Documentation/gpu/automated_testing.rst @@ -68,19 +68,25 @@ known to behave unreliably. These tests won't cause a job to fail regardless of the result. They will still be run. Each new flake entry must be associated with a link to the email reporting the -bug to the author of the affected driver, the board name or Device Tree name of -the board, the first kernel version affected, the IGT version used for tests, -and an approximation of the failure rate. +bug to the author of the affected driver or the relevant GitLab issue. The entry +must also include the board name or Device Tree name, the first kernel version +affected, the IGT version used for tests, and an approximation of the failure rate. They should be provided under the following format:: - # Bug Report: $LORE_OR_PATCHWORK_URL + # Bug Report: $LORE_URL_OR_GITLAB_ISSUE # Board Name: broken-board.dtb # Linux Version: 6.6-rc1 # IGT Version: 1.28-gd2af13d9f # Failure Rate: 100 flaky-test +Use the appropriate link below to create a GitLab issue: +amdgpu driver: https://gitlab.freedesktop.org/drm/amd/-/issues +i915 driver: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues +msm driver: https://gitlab.freedesktop.org/drm/msm/-/issues +xe driver: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues + drivers/gpu/drm/ci/${DRIVER_NAME}-${HW_REVISION}-skips.txt ----------------------------------------------------------- -- GitLab From e2a8910af01653c1c268984855629d71fb81f404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> Date: Sun, 29 Sep 2024 12:22:40 +0200 Subject: [PATCH 686/970] cifs: Fix buffer overflow when parsing NFS reparse points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ReparseDataLength is sum of the InodeType size and DataBuffer size. So to get DataBuffer size it is needed to subtract InodeType's size from ReparseDataLength. Function cifs_strndup_from_utf16() is currentlly accessing buf->DataBuffer at position after the end of the buffer because it does not subtract InodeType size from the length. Fix this problem and correctly subtract variable len. Member InodeType is present only when reparse buffer is large enough. Check for ReparseDataLength before accessing InodeType to prevent another invalid memory access. Major and minor rdev values are present also only when reparse buffer is large enough. Check for reparse buffer size before calling reparse_mkdev(). Fixes: d5ecebc4900d ("smb3: Allow query of symlinks stored as reparse points") Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/reparse.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 3b48a093cfb1..8ea7a848aa39 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -320,9 +320,16 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, unsigned int len; u64 type; + len = le16_to_cpu(buf->ReparseDataLength); + if (len < sizeof(buf->InodeType)) { + cifs_dbg(VFS, "srv returned malformed nfs buffer\n"); + return -EIO; + } + + len -= sizeof(buf->InodeType); + switch ((type = le64_to_cpu(buf->InodeType))) { case NFS_SPECFILE_LNK: - len = le16_to_cpu(buf->ReparseDataLength); data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer, len, true, cifs_sb->local_nls); @@ -482,12 +489,18 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, u32 tag = data->reparse.tag; if (tag == IO_REPARSE_TAG_NFS && buf) { + if (le16_to_cpu(buf->ReparseDataLength) < sizeof(buf->InodeType)) + return false; switch (le64_to_cpu(buf->InodeType)) { case NFS_SPECFILE_CHR: + if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8) + return false; fattr->cf_mode |= S_IFCHR; fattr->cf_rdev = reparse_mkdev(buf->DataBuffer); break; case NFS_SPECFILE_BLK: + if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8) + return false; fattr->cf_mode |= S_IFBLK; fattr->cf_rdev = reparse_mkdev(buf->DataBuffer); break; -- GitLab From 556ac52bb1e76cc28fd30aa117b42989965b3efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> Date: Sat, 28 Sep 2024 23:59:47 +0200 Subject: [PATCH 687/970] cifs: Validate content of NFS reparse point buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symlink target location stored in DataBuffer is encoded in UTF-16. So check that symlink DataBuffer length is non-zero and even number. And check that DataBuffer does not contain UTF-16 null codepoint because Linux cannot process symlink with null byte. DataBuffer for char and block devices is 8 bytes long as it contains two 32-bit numbers (major and minor). Add check for this. DataBuffer buffer for sockets and fifos zero-length. Add checks for this. Signed-off-by: Pali Rohár <pali@kernel.org> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/reparse.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 8ea7a848aa39..f0cfcf32de19 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -330,6 +330,18 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, switch ((type = le64_to_cpu(buf->InodeType))) { case NFS_SPECFILE_LNK: + if (len == 0 || (len % 2)) { + cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n"); + return -EIO; + } + /* + * Check that buffer does not contain UTF-16 null codepoint + * because Linux cannot process symlink with null byte. + */ + if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) { + cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n"); + return -EIO; + } data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer, len, true, cifs_sb->local_nls); @@ -341,8 +353,19 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, break; case NFS_SPECFILE_CHR: case NFS_SPECFILE_BLK: + /* DataBuffer for block and char devices contains two 32-bit numbers */ + if (len != 8) { + cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type); + return -EIO; + } + break; case NFS_SPECFILE_FIFO: case NFS_SPECFILE_SOCK: + /* DataBuffer for fifos and sockets is empty */ + if (len != 0) { + cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type); + return -EIO; + } break; default: cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n", -- GitLab From d3a49f60917323228f8fdeee313260ef14f94df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> Date: Sat, 28 Sep 2024 23:59:46 +0200 Subject: [PATCH 688/970] cifs: Do not convert delimiter when parsing NFS-style symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NFS-style symlinks have target location always stored in NFS/UNIX form where backslash means the real UNIX backslash and not the SMB path separator. So do not mangle slash and backslash content of NFS-style symlink during readlink() syscall as it is already in the correct Linux form. This fixes interoperability of NFS-style symlinks with backslashes created by Linux NFS3 client throw Windows NFS server and retrieved by Linux SMB client throw Windows SMB server, where both Windows servers exports the same directory. Fixes: d5ecebc4900d ("smb3: Allow query of symlinks stored as reparse points") Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> --- fs/smb/client/reparse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index f0cfcf32de19..c848b5e88d32 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -347,7 +347,6 @@ static int parse_reparse_posix(struct reparse_posix_data *buf, cifs_sb->local_nls); if (!data->symlink_target) return -ENOMEM; - convert_delimiter(data->symlink_target, '/'); cifs_dbg(FYI, "%s: target path: %s\n", __func__, data->symlink_target); break; -- GitLab From 231bb9b4c42398db3114c087ba39ba00c4b7ac2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Sz=C5=91ke?= <egyszeregy@freemail.hu> Date: Mon, 3 Jun 2024 11:15:58 +0200 Subject: [PATCH 689/970] drm/nouveau/i2c: rename aux.c and aux.h to auxch.c and auxch.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The goal is to clean-up Linux repository from AUX file names, because the use of such file names is prohibited on other operating systems such as Windows, so the Linux repository cannot be cloned and edited on them. Signed-off-by: Benjamin SzÅ‘ke <egyszeregy@freemail.hu> Reviewed-by: Ben Skeggs <bskeggs@nvidia.com> Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240603091558.35672-1-egyszeregy@freemail.hu --- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => auxch.c} | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => auxch.h} | 0 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c | 2 +- 11 files changed, 10 insertions(+), 10 deletions(-) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.c => auxch.c} (99%) rename drivers/gpu/drm/nouveau/nvkm/subdev/i2c/{aux.h => auxch.h} (100%) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild index 819703913a00..2c551bdc9bc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild @@ -25,7 +25,7 @@ nvkm-y += nvkm/subdev/i2c/busnv50.o nvkm-y += nvkm/subdev/i2c/busgf119.o nvkm-y += nvkm/subdev/i2c/bit.o -nvkm-y += nvkm/subdev/i2c/aux.o +nvkm-y += nvkm/subdev/i2c/auxch.o nvkm-y += nvkm/subdev/i2c/auxg94.o nvkm-y += nvkm/subdev/i2c/auxgf119.o nvkm-y += nvkm/subdev/i2c/auxgm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c index dd391809fef7..6c76e5e14b75 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c @@ -24,7 +24,7 @@ #define anx9805_pad(p) container_of((p), struct anx9805_pad, base) #define anx9805_bus(p) container_of((p), struct anx9805_bus, base) #define anx9805_aux(p) container_of((p), struct anx9805_aux, base) -#include "aux.h" +#include "auxch.h" #include "bus.h" struct anx9805_pad { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c similarity index 99% rename from drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c rename to drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c index d063d0dc13c5..fafc634acbf6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c @@ -24,7 +24,7 @@ #include <linux/string_helpers.h> -#include "aux.h" +#include "auxch.h" #include "pad.h" static int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.h similarity index 100% rename from drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h rename to drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.h diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c index 47068f6f9c55..854bb4b5fdb4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ #define g94_i2c_aux(p) container_of((p), struct g94_i2c_aux, base) -#include "aux.h" +#include "auxch.h" struct g94_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c index dab40cd8fe3a..c17d5647cb99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "aux.h" +#include "auxch.h" static const struct nvkm_i2c_aux_func gf119_i2c_aux = { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c index 8bd1d442e465..3c5005e3b330 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ #define gm200_i2c_aux(p) container_of((p), struct gm200_i2c_aux, base) -#include "aux.h" +#include "auxch.h" struct gm200_i2c_aux { struct nvkm_i2c_aux base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 731b2f68d3db..7ec17e8435a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" -#include "aux.h" +#include "auxch.h" #include "bus.h" #include "pad.h" diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c index 5904bc5f2d2a..cc26cd677917 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "pad.h" -#include "aux.h" +#include "auxch.h" #include "bus.h" void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c index 3bc4d0310076..1797c6c65979 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "pad.h" -#include "aux.h" +#include "auxch.h" #include "bus.h" static const struct nvkm_i2c_pad_func diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c index 7d417f6a816e..5afc1bf8e798 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ #include "pad.h" -#include "aux.h" +#include "auxch.h" #include "bus.h" static void -- GitLab From 491418a258322bbd7f045e36884d2849b673f23d Mon Sep 17 00:00:00 2001 From: Vinay Belgaumkar <vinay.belgaumkar@intel.com> Date: Wed, 25 Sep 2024 13:49:18 -0700 Subject: [PATCH 690/970] drm/xe: Restore GT freq on GSC load error As part of a Wa_22019338487, ensure that GT freq is restored even when GSC reload is not successful. Fixes: 3b1592fb7835 ("drm/xe/lnl: Apply Wa_22019338487") Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925204918.1989574-1-vinay.belgaumkar@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> --- drivers/gpu/drm/xe/xe_gt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 274737417b0f..c6b6c585c57d 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -907,7 +907,9 @@ int xe_gt_sanitize_freq(struct xe_gt *gt) int ret = 0; if ((!xe_uc_fw_is_available(>->uc.gsc.fw) || - xe_uc_fw_is_loaded(>->uc.gsc.fw)) && XE_WA(gt, 22019338487)) + xe_uc_fw_is_loaded(>->uc.gsc.fw) || + xe_uc_fw_is_in_error_state(>->uc.gsc.fw)) && + XE_WA(gt, 22019338487)) ret = xe_guc_pc_restore_stashed_freq(>->uc.guc.pc); return ret; -- GitLab From a1d402abf8e3ff1d821e88993fc5331784fac0da Mon Sep 17 00:00:00 2001 From: Marc Zyngier <maz@kernel.org> Date: Wed, 2 Oct 2024 21:42:39 +0100 Subject: [PATCH 691/970] KVM: arm64: Fix kvm_has_feat*() handling of negative features Oliver reports that the kvm_has_feat() helper is not behaviing as expected for negative feature. On investigation, the main issue seems to be caused by the following construct: #define get_idreg_field(kvm, id, fld) \ (id##_##fld##_SIGNED ? \ get_idreg_field_signed(kvm, id, fld) : \ get_idreg_field_unsigned(kvm, id, fld)) where one side of the expression evaluates as something signed, and the other as something unsigned. In retrospect, this is totally braindead, as the compiler converts this into an unsigned expression. When compared to something that is 0, the test is simply elided. Epic fail. Similar issue exists in the expand_field_sign() macro. The correct way to handle this is to chose between signed and unsigned comparisons, so that both sides of the ternary expression are of the same type (bool). In order to keep the code readable (sort of), we introduce new comparison primitives taking an operator as a parameter, and rewrite the kvm_has_feat*() helpers in terms of these primitives. Fixes: c62d7a23b947 ("KVM: arm64: Add feature checking helpers") Reported-by: Oliver Upton <oliver.upton@linux.dev> Tested-by: Oliver Upton <oliver.upton@linux.dev> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20241002204239.2051637-1-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/include/asm/kvm_host.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 329619c6fa96..94cff508874b 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1441,11 +1441,6 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); sign_extend64(__val, id##_##fld##_WIDTH - 1); \ }) -#define expand_field_sign(id, fld, val) \ - (id##_##fld##_SIGNED ? \ - __expand_field_sign_signed(id, fld, val) : \ - __expand_field_sign_unsigned(id, fld, val)) - #define get_idreg_field_unsigned(kvm, id, fld) \ ({ \ u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id); \ @@ -1461,20 +1456,26 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); #define get_idreg_field_enum(kvm, id, fld) \ get_idreg_field_unsigned(kvm, id, fld) -#define get_idreg_field(kvm, id, fld) \ +#define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ + (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id, fld, limit)) + +#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ + (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned(id, fld, limit)) + +#define kvm_cmp_feat(kvm, id, fld, op, limit) \ (id##_##fld##_SIGNED ? \ - get_idreg_field_signed(kvm, id, fld) : \ - get_idreg_field_unsigned(kvm, id, fld)) + kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ + kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) #define kvm_has_feat(kvm, id, fld, limit) \ - (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit)) + kvm_cmp_feat(kvm, id, fld, >=, limit) #define kvm_has_feat_enum(kvm, id, fld, val) \ - (get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val)) + kvm_cmp_feat_unsigned(kvm, id, fld, ==, val) #define kvm_has_feat_range(kvm, id, fld, min, max) \ - (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \ - get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max)) + (kvm_cmp_feat(kvm, id, fld, >=, min) && \ + kvm_cmp_feat(kvm, id, fld, <=, max)) /* Check for a given level of PAuth support */ #define kvm_has_pauth(k, l) \ -- GitLab From 7b99b5ab885993bff010ebcd93be5e511c56e28a Mon Sep 17 00:00:00 2001 From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Date: Thu, 3 Oct 2024 14:13:51 +0100 Subject: [PATCH 692/970] gpiolib: Fix potential NULL pointer dereference in gpiod_get_label() In `gpiod_get_label()`, it is possible that `srcu_dereference_check()` may return a NULL pointer, leading to a scenario where `label->str` is accessed without verifying if `label` itself is NULL. This patch adds a proper NULL check for `label` before accessing `label->str`. The check for `label->str != NULL` is removed because `label->str` can never be NULL if `label` is not NULL. This fixes the issue where the label name was being printed as `(efault)` when dumping the sysfs GPIO file when `label == NULL`. Fixes: 5a646e03e956 ("gpiolib: Return label, if set, for IRQ only line") Fixes: a86d27693066 ("gpiolib: fix the speed of descriptor label setting with SRCU") Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Link: https://lore.kernel.org/r/20241003131351.472015-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> --- drivers/gpio/gpiolib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c6afbf434366..d5952ab7752c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -114,12 +114,12 @@ const char *gpiod_get_label(struct gpio_desc *desc) srcu_read_lock_held(&desc->gdev->desc_srcu)); if (test_bit(FLAG_USED_AS_IRQ, &flags)) - return label->str ?: "interrupt"; + return label ? label->str : "interrupt"; if (!test_bit(FLAG_REQUESTED, &flags)) return NULL; - return label->str; + return label ? label->str : NULL; } static void desc_free_label(struct rcu_head *rh) -- GitLab From 00ae002116a14c2e6a342c4c9ae080cdbb9b4b21 Mon Sep 17 00:00:00 2001 From: Pin-yen Lin <treapking@chromium.org> Date: Thu, 26 Sep 2024 17:29:08 +0800 Subject: [PATCH 693/970] drm/bridge: anx7625: Drop EDID cache on bridge power off The bridge might miss the display change events when it's powered off. This happens when a user changes the external monitor when the system is suspended and the embedded controller doesn't not wake AP up. It's also observed that one DP-to-HDMI bridge doesn't work correctly when there is no EDID read after it is powered on. Drop the cache to force an EDID read after system resume to fix this. Fixes: 8bdfc5dae4e3 ("drm/bridge: anx7625: Add anx7625 MIPI DSI/DPI to DP") Signed-off-by: Pin-yen Lin <treapking@chromium.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240926092931.3870342-2-treapking@chromium.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index a2e9bb485c36..a2675b121fe4 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2551,6 +2551,8 @@ static int __maybe_unused anx7625_runtime_pm_suspend(struct device *dev) mutex_lock(&ctx->lock); anx7625_stop_dp_work(ctx); + if (!ctx->pdata.panel_bridge) + anx7625_remove_edid(ctx); anx7625_power_standby(ctx); mutex_unlock(&ctx->lock); -- GitLab From 574c558ddb68591c9a4b7a95e45e935ab22c0fc6 Mon Sep 17 00:00:00 2001 From: Pin-yen Lin <treapking@chromium.org> Date: Thu, 26 Sep 2024 17:29:09 +0800 Subject: [PATCH 694/970] drm/bridge: it6505: Drop EDID cache on bridge power off The bridge might miss the display change events when it's powered off. This happens when a user changes the external monitor when the system is suspended and the embedded controller doesn't not wake AP up. It's also observed that one DP-to-HDMI bridge doesn't work correctly when there is no EDID read after it is powered on. Drop the cache to force an EDID read after system resume to fix this. Fixes: 11feaef69d0c ("drm/bridge: it6505: Add caching for EDID") Signed-off-by: Pin-yen Lin <treapking@chromium.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240926092931.3870342-3-treapking@chromium.org --- drivers/gpu/drm/bridge/ite-it6505.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index f372c05360f2..7ff17aa14b01 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -3107,6 +3107,8 @@ static __maybe_unused int it6505_bridge_suspend(struct device *dev) { struct it6505 *it6505 = dev_get_drvdata(dev); + it6505_remove_edid(it6505); + return it6505_poweroff(it6505); } -- GitLab From 50a3242d84ee1625b0bfef29b95f935958dccfbe Mon Sep 17 00:00:00 2001 From: Steven Rostedt <rostedt@goodmis.org> Date: Thu, 3 Oct 2024 10:49:25 -0400 Subject: [PATCH 695/970] tracing: Fix trace_check_vprintf() when tp_printk is used When the tp_printk kernel command line is used, the trace events go directly to printk(). It is still checked via the trace_check_vprintf() function to make sure the pointers of the trace event are legit. The addition of reading buffers from previous boots required adding a delta between the addresses of the previous boot and the current boot so that the pointers in the old buffer can still be used. But this required adding a trace_array pointer to acquire the delta offsets. The tp_printk code does not provide a trace_array (tr) pointer, so when the offsets were examined, a NULL pointer dereference happened and the kernel crashed. If the trace_array does not exist, just default the delta offsets to zero, as that also means the trace event is not being read from a previous boot. Link: https://lore.kernel.org/all/Zv3z5UsG_jsO9_Tb@aschofie-mobl2.lan/ Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/20241003104925.4e1b1fd9@gandalf.local.home Fixes: 07714b4bb3f98 ("tracing: Handle old buffer mappings for event strings and functions") Reported-by: Alison Schofield <alison.schofield@intel.com> Tested-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- kernel/trace/trace.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c01375adc471..1c69ca1f1088 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3697,8 +3697,8 @@ static void test_can_verify(void) void trace_check_vprintf(struct trace_iterator *iter, const char *fmt, va_list ap) { - long text_delta = iter->tr->text_delta; - long data_delta = iter->tr->data_delta; + long text_delta = 0; + long data_delta = 0; const char *p = fmt; const char *str; bool good; @@ -3710,6 +3710,17 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt, if (static_branch_unlikely(&trace_no_verify)) goto print; + /* + * When the kernel is booted with the tp_printk command line + * parameter, trace events go directly through to printk(). + * It also is checked by this function, but it does not + * have an associated trace_array (tr) for it. + */ + if (iter->tr) { + text_delta = iter->tr->text_delta; + data_delta = iter->tr->data_delta; + } + /* Don't bother checking when doing a ftrace_dump() */ if (iter->fmt == static_fmt_buf) goto print; -- GitLab From f771d5369f1dbfe32c93bcb4f5d7ca8322b15389 Mon Sep 17 00:00:00 2001 From: Ben Hutchings <benh@debian.org> Date: Mon, 16 Sep 2024 01:31:58 +0200 Subject: [PATCH 696/970] tools/rtla: Fix installation from out-of-tree build rtla now supports out-of-tree builds, but installation fails as it still tries to install the rtla binary from the source tree. Use the existing macro $(RTLA) to refer to the binary. Link: https://lore.kernel.org/ZudubuoU_JHjPZ7w@decadent.org.uk Fixes: 01474dc706ca ("tools/rtla: Use tools/build makefiles to build rtla") Reviewed-by: Tomas Glozar <tglozar@redhat.com> Tested-by: Tomas Glozar <tglozar@redhat.com> Signed-off-by: Ben Hutchings <benh@debian.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- tools/tracing/rtla/Makefile.rtla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tracing/rtla/Makefile.rtla b/tools/tracing/rtla/Makefile.rtla index 3ff0b8970896..cc1d6b615475 100644 --- a/tools/tracing/rtla/Makefile.rtla +++ b/tools/tracing/rtla/Makefile.rtla @@ -38,7 +38,7 @@ BINDIR := /usr/bin .PHONY: install install: doc_install @$(MKDIR) -p $(DESTDIR)$(BINDIR) - $(call QUIET_INSTALL,rtla)$(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR) + $(call QUIET_INSTALL,rtla)$(INSTALL) $(RTLA) -m 755 $(DESTDIR)$(BINDIR) @$(STRIP) $(DESTDIR)$(BINDIR)/rtla @test ! -f $(DESTDIR)$(BINDIR)/osnoise || $(RM) $(DESTDIR)$(BINDIR)/osnoise @$(LN) rtla $(DESTDIR)$(BINDIR)/osnoise -- GitLab From 3d7b8ea7a8a20a45d019382c4dc6ed79e8bb95cf Mon Sep 17 00:00:00 2001 From: Eder Zulian <ezulian@redhat.com> Date: Tue, 13 Aug 2024 17:58:31 +0200 Subject: [PATCH 697/970] rtla: Fix the help text in osnoise and timerlat top tools The help text in osnoise top and timerlat top had some minor errors and omissions. The -d option was missing the 's' (second) abbreviation and the error message for '-d' used '-D'. Cc: stable@vger.kernel.org Fixes: 1eceb2fc2ca54 ("rtla/osnoise: Add osnoise top mode") Fixes: a828cd18bc4ad ("rtla: Add timerlat tool and timelart top mode") Link: https://lore.kernel.org/20240813155831.384446-1-ezulian@redhat.com Suggested-by: Tomas Glozar <tglozar@redhat.com> Reviewed-by: Tomas Glozar <tglozar@redhat.com> Signed-off-by: Eder Zulian <ezulian@redhat.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- tools/tracing/rtla/src/osnoise_top.c | 2 +- tools/tracing/rtla/src/timerlat_top.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c index 2f756628613d..30e3853076a0 100644 --- a/tools/tracing/rtla/src/osnoise_top.c +++ b/tools/tracing/rtla/src/osnoise_top.c @@ -442,7 +442,7 @@ struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv) case 'd': params->duration = parse_seconds_duration(optarg); if (!params->duration) - osnoise_top_usage(params, "Invalid -D duration\n"); + osnoise_top_usage(params, "Invalid -d duration\n"); break; case 'e': tevent = trace_event_alloc(optarg); diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c index 8c16419fe22a..210b0f533534 100644 --- a/tools/tracing/rtla/src/timerlat_top.c +++ b/tools/tracing/rtla/src/timerlat_top.c @@ -459,7 +459,7 @@ static void timerlat_top_usage(char *usage) " -c/--cpus cpus: run the tracer only on the given cpus", " -H/--house-keeping cpus: run rtla control threads only on the given cpus", " -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited", - " -d/--duration time[m|h|d]: duration of the session in seconds", + " -d/--duration time[s|m|h|d]: duration of the session", " -D/--debug: print debug info", " --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !--no-aa)", " -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]", @@ -613,7 +613,7 @@ static struct timerlat_top_params case 'd': params->duration = parse_seconds_duration(optarg); if (!params->duration) - timerlat_top_usage("Invalid -D duration\n"); + timerlat_top_usage("Invalid -d duration\n"); break; case 'e': tevent = trace_event_alloc(optarg); -- GitLab From ad686707ea16099a791bcdcd5372764c5059aecc Mon Sep 17 00:00:00 2001 From: Sami Tolvanen <samitolvanen@google.com> Date: Mon, 16 Sep 2024 22:15:57 +0000 Subject: [PATCH 698/970] x86/ftrace: Include <asm/ptrace.h> <asm/ftrace.h> uses struct pt_regs in several places. Include <asm/ptrace.h> to ensure it's visible. This is needed to make sure object files that only include <asm/asm-prototypes.h> compile. Cc: Mark Rutland <mark.rutland@arm.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Link: https://lore.kernel.org/20240916221557.846853-2-samitolvanen@google.com Suggested-by: Masahiro Yamada <masahiroy@kernel.org> Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- arch/x86/include/asm/ftrace.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 0152a81d9b4a..b4d719de2c84 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -2,6 +2,8 @@ #ifndef _ASM_X86_FTRACE_H #define _ASM_X86_FTRACE_H +#include <asm/ptrace.h> + #ifdef CONFIG_FUNCTION_TRACER #ifndef CC_USING_FENTRY # error Compiler does not support fentry? -- GitLab From 0bb0a5c12ecf36ad561542bbb95f96355e036a02 Mon Sep 17 00:00:00 2001 From: Wei Li <liwei391@huawei.com> Date: Tue, 24 Sep 2024 17:45:11 +0800 Subject: [PATCH 699/970] tracing/timerlat: Fix duplicated kthread creation due to CPU online/offline osnoise_hotplug_workfn() is the asynchronous online callback for "trace/osnoise:online". It may be congested when a CPU goes online and offline repeatedly and is invoked for multiple times after a certain online. This will lead to kthread leak and timer corruption. Add a check in start_kthread() to prevent this situation. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/20240924094515.3561410-2-liwei391@huawei.com Fixes: c8895e271f79 ("trace/osnoise: Support hotplug operations") Signed-off-by: Wei Li <liwei391@huawei.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- kernel/trace/trace_osnoise.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 1439064f65d6..d1a539913a5f 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -2007,6 +2007,10 @@ static int start_kthread(unsigned int cpu) void *main = osnoise_main; char comm[24]; + /* Do not start a new thread if it is already running */ + if (per_cpu(per_cpu_osnoise_var, cpu).kthread) + return 0; + if (timerlat_enabled()) { snprintf(comm, 24, "timerlat/%d", cpu); main = timerlat_main; @@ -2061,11 +2065,10 @@ static int start_per_cpu_kthreads(void) if (cpumask_test_and_clear_cpu(cpu, &kthread_cpumask)) { struct task_struct *kthread; - kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; + kthread = xchg_relaxed(&(per_cpu(per_cpu_osnoise_var, cpu).kthread), NULL); if (!WARN_ON(!kthread)) kthread_stop(kthread); } - per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; } for_each_cpu(cpu, current_mask) { -- GitLab From b484a02c9cedf8703eff8f0756f94618004bd165 Mon Sep 17 00:00:00 2001 From: Wei Li <liwei391@huawei.com> Date: Tue, 24 Sep 2024 17:45:12 +0800 Subject: [PATCH 700/970] tracing/timerlat: Drop interface_lock in stop_kthread() stop_kthread() is the offline callback for "trace/osnoise:online", since commit 5bfbcd1ee57b ("tracing/timerlat: Add interface_lock around clearing of kthread in stop_kthread()"), the following ABBA deadlock scenario is introduced: T1 | T2 [BP] | T3 [AP] osnoise_hotplug_workfn() | work_for_cpu_fn() | cpuhp_thread_fun() | _cpu_down() | osnoise_cpu_die() mutex_lock(&interface_lock) | | stop_kthread() | cpus_write_lock() | mutex_lock(&interface_lock) cpus_read_lock() | cpuhp_kick_ap() | As the interface_lock here in just for protecting the "kthread" field of the osn_var, use xchg() instead to fix this issue. Also use for_each_online_cpu() back in stop_per_cpu_kthreads() as it can take cpu_read_lock() again. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/20240924094515.3561410-3-liwei391@huawei.com Fixes: 5bfbcd1ee57b ("tracing/timerlat: Add interface_lock around clearing of kthread in stop_kthread()") Signed-off-by: Wei Li <liwei391@huawei.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- kernel/trace/trace_osnoise.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index d1a539913a5f..e22567174dd3 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -1953,12 +1953,8 @@ static void stop_kthread(unsigned int cpu) { struct task_struct *kthread; - mutex_lock(&interface_lock); - kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread; + kthread = xchg_relaxed(&(per_cpu(per_cpu_osnoise_var, cpu).kthread), NULL); if (kthread) { - per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL; - mutex_unlock(&interface_lock); - if (cpumask_test_and_clear_cpu(cpu, &kthread_cpumask) && !WARN_ON(!test_bit(OSN_WORKLOAD, &osnoise_options))) { kthread_stop(kthread); @@ -1972,7 +1968,6 @@ static void stop_kthread(unsigned int cpu) put_task_struct(kthread); } } else { - mutex_unlock(&interface_lock); /* if no workload, just return */ if (!test_bit(OSN_WORKLOAD, &osnoise_options)) { /* @@ -1994,8 +1989,12 @@ static void stop_per_cpu_kthreads(void) { int cpu; - for_each_possible_cpu(cpu) + cpus_read_lock(); + + for_each_online_cpu(cpu) stop_kthread(cpu); + + cpus_read_unlock(); } /* -- GitLab From 829e0c9f0855f26b3ae830d17b24aec103f7e915 Mon Sep 17 00:00:00 2001 From: Wei Li <liwei391@huawei.com> Date: Tue, 24 Sep 2024 17:45:13 +0800 Subject: [PATCH 701/970] tracing/timerlat: Fix a race during cpuhp processing There is another found exception that the "timerlat/1" thread was scheduled on CPU0, and lead to timer corruption finally: ``` ODEBUG: init active (active state 0) object: ffff888237c2e108 object type: hrtimer hint: timerlat_irq+0x0/0x220 WARNING: CPU: 0 PID: 426 at lib/debugobjects.c:518 debug_print_object+0x7d/0xb0 Modules linked in: CPU: 0 UID: 0 PID: 426 Comm: timerlat/1 Not tainted 6.11.0-rc7+ #45 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:debug_print_object+0x7d/0xb0 ... Call Trace: <TASK> ? __warn+0x7c/0x110 ? debug_print_object+0x7d/0xb0 ? report_bug+0xf1/0x1d0 ? prb_read_valid+0x17/0x20 ? handle_bug+0x3f/0x70 ? exc_invalid_op+0x13/0x60 ? asm_exc_invalid_op+0x16/0x20 ? debug_print_object+0x7d/0xb0 ? debug_print_object+0x7d/0xb0 ? __pfx_timerlat_irq+0x10/0x10 __debug_object_init+0x110/0x150 hrtimer_init+0x1d/0x60 timerlat_main+0xab/0x2d0 ? __pfx_timerlat_main+0x10/0x10 kthread+0xb7/0xe0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2d/0x40 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> ``` After tracing the scheduling event, it was discovered that the migration of the "timerlat/1" thread was performed during thread creation. Further analysis confirmed that it is because the CPU online processing for osnoise is implemented through workers, which is asynchronous with the offline processing. When the worker was scheduled to create a thread, the CPU may has already been removed from the cpu_online_mask during the offline process, resulting in the inability to select the right CPU: T1 | T2 [CPUHP_ONLINE] | cpu_device_down() osnoise_hotplug_workfn() | | cpus_write_lock() | takedown_cpu(1) | cpus_write_unlock() [CPUHP_OFFLINE] | cpus_read_lock() | start_kthread(1) | cpus_read_unlock() | To fix this, skip online processing if the CPU is already offline. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/20240924094515.3561410-4-liwei391@huawei.com Fixes: c8895e271f79 ("trace/osnoise: Support hotplug operations") Signed-off-by: Wei Li <liwei391@huawei.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- kernel/trace/trace_osnoise.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index e22567174dd3..a50ed23bee77 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -2097,6 +2097,8 @@ static void osnoise_hotplug_workfn(struct work_struct *dummy) mutex_lock(&interface_lock); cpus_read_lock(); + if (!cpu_online(cpu)) + goto out_unlock; if (!cpumask_test_cpu(cpu, &osnoise_cpumask)) goto out_unlock; -- GitLab From 2a13ca2e8abb12ee43ada8a107dadca83f140937 Mon Sep 17 00:00:00 2001 From: Wei Li <liwei391@huawei.com> Date: Tue, 24 Sep 2024 17:45:14 +0800 Subject: [PATCH 702/970] tracing/hwlat: Fix a race during cpuhp processing The cpuhp online/offline processing race also exists in percpu-mode hwlat tracer in theory, apply the fix too. That is: T1 | T2 [CPUHP_ONLINE] | cpu_device_down() hwlat_hotplug_workfn() | | cpus_write_lock() | takedown_cpu(1) | cpus_write_unlock() [CPUHP_OFFLINE] | cpus_read_lock() | start_kthread(1) | cpus_read_unlock() | Cc: stable@vger.kernel.org Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/20240924094515.3561410-5-liwei391@huawei.com Fixes: ba998f7d9531 ("trace/hwlat: Support hotplug operations") Signed-off-by: Wei Li <liwei391@huawei.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> --- kernel/trace/trace_hwlat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c index b791524a6536..3bd6071441ad 100644 --- a/kernel/trace/trace_hwlat.c +++ b/kernel/trace/trace_hwlat.c @@ -520,6 +520,8 @@ static void hwlat_hotplug_workfn(struct work_struct *dummy) if (!hwlat_busy || hwlat_data.thread_mode != MODE_PER_CPU) goto out_unlock; + if (!cpu_online(cpu)) + goto out_unlock; if (!cpumask_test_cpu(cpu, tr->tracing_cpumask)) goto out_unlock; -- GitLab From fcd1ec9cb59c4375803c2c3c18ba7f473fe91cdc Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Fri, 27 Sep 2024 06:25:35 -0400 Subject: [PATCH 703/970] KVM: x86/mmu: fix KVM_X86_QUIRK_SLOT_ZAP_ALL for shadow MMU As was tried in commit 4e103134b862 ("KVM: x86/mmu: Zap only the relevant pages when removing a memslot"), all shadow pages, i.e. non-leaf SPTEs, need to be zapped. All of the accounting for a shadow page is tied to the memslot, i.e. the shadow page holds a reference to the memslot, for all intents and purposes. Deleting the memslot without removing all relevant shadow pages, as is done when KVM_X86_QUIRK_SLOT_ZAP_ALL is disabled, results in NULL pointer derefs when tearing down the VM. Reintroduce from that commit the code that walks the whole memslot when there are active shadow MMU pages. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- arch/x86/kvm/mmu/mmu.c | 60 ++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index e081f785fb23..912bad4fa88c 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -1884,10 +1884,14 @@ static bool sp_has_gptes(struct kvm_mmu_page *sp) if (is_obsolete_sp((_kvm), (_sp))) { \ } else -#define for_each_gfn_valid_sp_with_gptes(_kvm, _sp, _gfn) \ +#define for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ for_each_valid_sp(_kvm, _sp, \ &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)]) \ - if ((_sp)->gfn != (_gfn) || !sp_has_gptes(_sp)) {} else + if ((_sp)->gfn != (_gfn)) {} else + +#define for_each_gfn_valid_sp_with_gptes(_kvm, _sp, _gfn) \ + for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ + if (!sp_has_gptes(_sp)) {} else static bool kvm_sync_page_check(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) { @@ -7049,14 +7053,42 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) kvm_mmu_zap_all(kvm); } -/* - * Zapping leaf SPTEs with memslot range when a memslot is moved/deleted. - * - * Zapping non-leaf SPTEs, a.k.a. not-last SPTEs, isn't required, worst - * case scenario we'll have unused shadow pages lying around until they - * are recycled due to age or when the VM is destroyed. - */ -static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *slot) +static void kvm_mmu_zap_memslot_pages_and_flush(struct kvm *kvm, + struct kvm_memory_slot *slot, + bool flush) +{ + LIST_HEAD(invalid_list); + unsigned long i; + + if (list_empty(&kvm->arch.active_mmu_pages)) + goto out_flush; + + /* + * Since accounting information is stored in struct kvm_arch_memory_slot, + * shadow pages deletion (e.g. unaccount_shadowed()) requires that all + * gfns with a shadow page have a corresponding memslot. Do so before + * the memslot goes away. + */ + for (i = 0; i < slot->npages; i++) { + struct kvm_mmu_page *sp; + gfn_t gfn = slot->base_gfn + i; + + for_each_gfn_valid_sp(kvm, sp, gfn) + kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); + + if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { + kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); + flush = false; + cond_resched_rwlock_write(&kvm->mmu_lock); + } + } + +out_flush: + kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); +} + +static void kvm_mmu_zap_memslot(struct kvm *kvm, + struct kvm_memory_slot *slot) { struct kvm_gfn_range range = { .slot = slot, @@ -7064,11 +7096,11 @@ static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *s .end = slot->base_gfn + slot->npages, .may_block = true, }; + bool flush; write_lock(&kvm->mmu_lock); - if (kvm_unmap_gfn_range(kvm, &range)) - kvm_flush_remote_tlbs_memslot(kvm, slot); - + flush = kvm_unmap_gfn_range(kvm, &range); + kvm_mmu_zap_memslot_pages_and_flush(kvm, slot, flush); write_unlock(&kvm->mmu_lock); } @@ -7084,7 +7116,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, if (kvm_memslot_flush_zap_all(kvm)) kvm_mmu_zap_all_fast(kvm); else - kvm_mmu_zap_memslot_leafs(kvm, slot); + kvm_mmu_zap_memslot(kvm, slot); } void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) -- GitLab From 3840cbe24cf060ea05a585ca497814609f5d47d1 Mon Sep 17 00:00:00 2001 From: Johannes Weiner <hannes@cmpxchg.org> Date: Thu, 3 Oct 2024 07:29:05 -0400 Subject: [PATCH 704/970] sched: psi: fix bogus pressure spikes from aggregation race Brandon reports sporadic, non-sensical spikes in cumulative pressure time (total=) when reading cpu.pressure at a high rate. This is due to a race condition between reader aggregation and tasks changing states. While it affects all states and all resources captured by PSI, in practice it most likely triggers with CPU pressure, since scheduling events are so frequent compared to other resource events. The race context is the live snooping of ongoing stalls during a pressure read. The read aggregates per-cpu records for stalls that have concluded, but will also incorporate ad-hoc the duration of any active state that hasn't been recorded yet. This is important to get timely measurements of ongoing stalls. Those ad-hoc samples are calculated on-the-fly up to the current time on that CPU; since the stall hasn't concluded, it's expected that this is the minimum amount of stall time that will enter the per-cpu records once it does. The problem is that the path that concludes the state uses a CPU clock read that is not synchronized against aggregators; the clock is read outside of the seqlock protection. This allows aggregators to race and snoop a stall with a longer duration than will actually be recorded. With the recorded stall time being less than the last snapshot remembered by the aggregator, a subsequent sample will underflow and observe a bogus delta value, resulting in an erratic jump in pressure. Fix this by moving the clock read of the state change into the seqlock protection. This ensures no aggregation can snoop live stalls past the time that's recorded when the state concludes. Reported-by: Brandon Duffany <brandon@buildbuddy.io> Link: https://bugzilla.kernel.org/show_bug.cgi?id=219194 Link: https://lore.kernel.org/lkml/20240827121851.GB438928@cmpxchg.org/ Fixes: df77430639c9 ("psi: Reduce calls to sched_clock() in psi") Cc: stable@vger.kernel.org Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Chengming Zhou <chengming.zhou@linux.dev> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> --- kernel/sched/psi.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 020d58967d4e..84dad1511d1e 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -769,12 +769,13 @@ static void record_times(struct psi_group_cpu *groupc, u64 now) } static void psi_group_change(struct psi_group *group, int cpu, - unsigned int clear, unsigned int set, u64 now, + unsigned int clear, unsigned int set, bool wake_clock) { struct psi_group_cpu *groupc; unsigned int t, m; u32 state_mask; + u64 now; lockdep_assert_rq_held(cpu_rq(cpu)); groupc = per_cpu_ptr(group->pcpu, cpu); @@ -789,6 +790,7 @@ static void psi_group_change(struct psi_group *group, int cpu, * SOME and FULL time these may have resulted in. */ write_seqcount_begin(&groupc->seq); + now = cpu_clock(cpu); /* * Start with TSK_ONCPU, which doesn't have a corresponding @@ -899,18 +901,15 @@ void psi_task_change(struct task_struct *task, int clear, int set) { int cpu = task_cpu(task); struct psi_group *group; - u64 now; if (!task->pid) return; psi_flags_change(task, clear, set); - now = cpu_clock(cpu); - group = task_psi_group(task); do { - psi_group_change(group, cpu, clear, set, now, true); + psi_group_change(group, cpu, clear, set, true); } while ((group = group->parent)); } @@ -919,7 +918,6 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next, { struct psi_group *group, *common = NULL; int cpu = task_cpu(prev); - u64 now = cpu_clock(cpu); if (next->pid) { psi_flags_change(next, 0, TSK_ONCPU); @@ -936,7 +934,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next, break; } - psi_group_change(group, cpu, 0, TSK_ONCPU, now, true); + psi_group_change(group, cpu, 0, TSK_ONCPU, true); } while ((group = group->parent)); } @@ -974,7 +972,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next, do { if (group == common) break; - psi_group_change(group, cpu, clear, set, now, wake_clock); + psi_group_change(group, cpu, clear, set, wake_clock); } while ((group = group->parent)); /* @@ -986,7 +984,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next, if ((prev->psi_flags ^ next->psi_flags) & ~TSK_ONCPU) { clear &= ~TSK_ONCPU; for (; group; group = group->parent) - psi_group_change(group, cpu, clear, set, now, wake_clock); + psi_group_change(group, cpu, clear, set, wake_clock); } } } @@ -997,8 +995,8 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st int cpu = task_cpu(curr); struct psi_group *group; struct psi_group_cpu *groupc; - u64 now, irq; s64 delta; + u64 irq; if (static_branch_likely(&psi_disabled)) return; @@ -1011,7 +1009,6 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st if (prev && task_psi_group(prev) == group) return; - now = cpu_clock(cpu); irq = irq_time_read(cpu); delta = (s64)(irq - rq->psi_irq_time); if (delta < 0) @@ -1019,12 +1016,15 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st rq->psi_irq_time = irq; do { + u64 now; + if (!group->enabled) continue; groupc = per_cpu_ptr(group->pcpu, cpu); write_seqcount_begin(&groupc->seq); + now = cpu_clock(cpu); record_times(groupc, now); groupc->times[PSI_IRQ_FULL] += delta; @@ -1223,11 +1223,9 @@ void psi_cgroup_restart(struct psi_group *group) for_each_possible_cpu(cpu) { struct rq *rq = cpu_rq(cpu); struct rq_flags rf; - u64 now; rq_lock_irq(rq, &rf); - now = cpu_clock(cpu); - psi_group_change(group, cpu, 0, 0, now, true); + psi_group_change(group, cpu, 0, 0, true); rq_unlock_irq(rq, &rf); } } -- GitLab From 9df39a872c462ea07a3767ebd0093c42b2ff78a2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Date: Thu, 3 Oct 2024 21:34:01 +0200 Subject: [PATCH 705/970] ALSA: gus: Fix some error handling paths related to get_bpos() usage If get_bpos() fails, it is likely that the corresponding error code should be returned. Fixes: a6970bb1dd99 ("ALSA: gus: Convert to the new PCM ops") Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Link: https://patch.msgid.link/d9ca841edad697154afa97c73a5d7a14919330d9.1727984008.git.christophe.jaillet@wanadoo.fr Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/isa/gus/gus_pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index bcbcaa924c12..16f9bbb43a54 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -364,7 +364,7 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream, bpos = get_bpos(pcmp, voice, pos, len); if (bpos < 0) - return pos; + return bpos; if (copy_from_iter(runtime->dma_area + bpos, len, src) != len) return -EFAULT; return playback_copy_ack(substream, bpos, len); @@ -381,7 +381,7 @@ static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream, bpos = get_bpos(pcmp, voice, pos, len); if (bpos < 0) - return pos; + return bpos; snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, bytes_to_samples(runtime, count)); return playback_copy_ack(substream, bpos, len); -- GitLab From 703235a244e533652346844cfa42623afb36eed1 Mon Sep 17 00:00:00 2001 From: "Hans P. Moller" <hmoller@uc.cl> Date: Thu, 3 Oct 2024 20:28:28 -0300 Subject: [PATCH 706/970] ALSA: line6: add hw monitor volume control to POD HD500X Add hw monitor volume control for POD HD500X. This is done adding LINE6_CAP_HWMON_CTL to the capabilities Signed-off-by: Hans P. Moller <hmoller@uc.cl> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20241003232828.5819-1-hmoller@uc.cl --- sound/usb/line6/podhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index ffd8c157a281..70de08635f54 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -507,7 +507,7 @@ static const struct line6_properties podhd_properties_table[] = { [LINE6_PODHD500X] = { .id = "PODHD500X", .name = "POD HD500X", - .capabilities = LINE6_CAP_CONTROL + .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_HWMON_CTL | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 1, .ep_ctrl_r = 0x81, -- GitLab From b3ebb007060f89d5a45c9b99f06a55e36a1945b5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Fri, 4 Oct 2024 10:25:58 +0200 Subject: [PATCH 707/970] ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin We received a regression report for System76 Pangolin (pang14) due to the recent fix for Tuxedo Sirius devices to support the top speaker. The reason was the conflicting PCI SSID, as often seen. As a workaround, now the codec SSID is checked and the quirk is applied conditionally only to Sirius devices. Fixes: 4178d78cd7a8 ("ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius devices") Reported-by: Christian Heusel <christian@heusel.eu> Reported-by: Jerry <jerryluo225@gmail.com> Closes: https://lore.kernel.org/c930b6a6-64e5-498f-b65a-1cd5e0a1d733@heusel.eu Link: https://patch.msgid.link/20241004082602.29016-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> --- sound/pci/hda/patch_conexant.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ade42a8209c2..b61ce5e6f5ec 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -816,6 +816,23 @@ static const struct hda_pintbl cxt_pincfg_sws_js201d[] = { {} }; +/* pincfg quirk for Tuxedo Sirius; + * unfortunately the (PCI) SSID conflicts with System76 Pangolin pang14, + * which has incompatible pin setup, so we check the codec SSID (luckily + * different one!) and conditionally apply the quirk here + */ +static void cxt_fixup_sirius_top_speaker(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + /* ignore for incorrectly picked-up pang14 */ + if (codec->core.subsystem_id == 0x278212b3) + return; + /* set up the top speaker pin */ + if (action == HDA_FIXUP_ACT_PRE_PROBE) + snd_hda_codec_set_pincfg(codec, 0x1d, 0x82170111); +} + static const struct hda_fixup cxt_fixups[] = { [CXT_PINCFG_LENOVO_X200] = { .type = HDA_FIXUP_PINS, @@ -976,11 +993,8 @@ static const struct hda_fixup cxt_fixups[] = { .v.pins = cxt_pincfg_sws_js201d, }, [CXT_PINCFG_TOP_SPEAKER] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl[]) { - { 0x1d, 0x82170111 }, - { } - }, + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_sirius_top_speaker, }, }; -- GitLab From 3eddb108abe3de6723cc4b77e8558ce1b3047987 Mon Sep 17 00:00:00 2001 From: Easwar Hariharan <eahariha@linux.microsoft.com> Date: Thu, 3 Oct 2024 22:52:35 +0000 Subject: [PATCH 708/970] arm64: Subscribe Microsoft Azure Cobalt 100 to erratum 3194386 Add the Microsoft Azure Cobalt 100 CPU to the list of CPUs suffering from erratum 3194386 added in commit 75b3c43eab59 ("arm64: errata: Expand speculative SSBS workaround") CC: Mark Rutland <mark.rutland@arm.com> CC: James More <james.morse@arm.com> CC: Will Deacon <will@kernel.org> CC: stable@vger.kernel.org # 6.6+ Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com> Link: https://lore.kernel.org/r/20241003225239.321774-1-eahariha@linux.microsoft.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/kernel/cpu_errata.c | 1 + 2 files changed, 3 insertions(+) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index ae45a409f76f..65bfab1b1861 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -293,3 +293,5 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Microsoft | Azure Cobalt 100| #2253138 | ARM64_ERRATUM_2253138 | +----------------+-----------------+-----------------+-----------------------------+ +| Microsoft | Azure Cobalt 100| #3324339 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index d9b9ec2bd6ff..a78f247029ae 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -448,6 +448,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), + MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3), -- GitLab From 93d93813422758f6c99289de446b19184019ef5a Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Wed, 2 Oct 2024 16:06:21 -0700 Subject: [PATCH 709/970] drm/xe: Make wedged_mode debugfs writable The intent of this debugfs entry is to allow modification of wedging behavior, either from IGT tests or during manual debug; it should be marked as writable to properly reflect this. In practice this hasn't caused a problem because we always access wedged_mode as root, which ignores file permissions, but it's still misleading to have the entry incorrectly marked as RO. Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Fixes: 6b8ef44cc0a9 ("drm/xe: Introduce the wedged_mode debugfs") Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241002230620.1249258-2-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c index 668615c6b172..fe4319eb13fd 100644 --- a/drivers/gpu/drm/xe/xe_debugfs.c +++ b/drivers/gpu/drm/xe/xe_debugfs.c @@ -187,7 +187,7 @@ void xe_debugfs_register(struct xe_device *xe) debugfs_create_file("forcewake_all", 0400, root, xe, &forcewake_all_fops); - debugfs_create_file("wedged_mode", 0400, root, xe, + debugfs_create_file("wedged_mode", 0600, root, xe, &wedged_mode_fops); for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) { -- GitLab From c5e3cdbf2afedef77b64229fd0aed693abf0a0c4 Mon Sep 17 00:00:00 2001 From: Paul Moore <paul@paul-moore.com> Date: Thu, 3 Oct 2024 16:43:39 -0400 Subject: [PATCH 710/970] tomoyo: revert CONFIG_SECURITY_TOMOYO_LKM support This patch reverts two TOMOYO patches that were merged into Linus' tree during the v6.12 merge window: 8b985bbfabbe ("tomoyo: allow building as a loadable LSM module") 268225a1de1a ("tomoyo: preparation step for building as a loadable LSM module") Together these two patches introduced the CONFIG_SECURITY_TOMOYO_LKM Kconfig build option which enabled a TOMOYO specific dynamic LSM loading mechanism (see the original commits for more details). Unfortunately, this approach was widely rejected by the LSM community as well as some members of the general kernel community. Objections included concerns over setting a bad precedent regarding individual LSMs managing their LSM callback registrations as well as general kernel symbol exporting practices. With little to no support for the CONFIG_SECURITY_TOMOYO_LKM approach outside of Tetsuo, and multiple objections, we need to revert these changes. Link: https://lore.kernel.org/all/0c4b443a-9c72-4800-97e8-a3816b6a9ae2@I-love.SAKURA.ne.jp Link: https://lore.kernel.org/all/CAHC9VhR=QjdoHG3wJgHFJkKYBg7vkQH2MpffgVzQ0tAByo_wRg@mail.gmail.com Acked-by: John Johansen <john.johansen@canonical.com> Signed-off-by: Paul Moore <paul@paul-moore.com> --- security/tomoyo/Kconfig | 15 -- security/tomoyo/Makefile | 8 +- security/tomoyo/common.c | 14 +- security/tomoyo/common.h | 72 ----- security/tomoyo/gc.c | 3 - security/tomoyo/init.c | 366 -------------------------- security/tomoyo/load_policy.c | 12 - security/tomoyo/proxy.c | 82 ------ security/tomoyo/securityfs_if.c | 10 +- security/tomoyo/{hooks.h => tomoyo.c} | 110 +++++++- security/tomoyo/util.c | 3 + 11 files changed, 118 insertions(+), 577 deletions(-) delete mode 100644 security/tomoyo/init.c delete mode 100644 security/tomoyo/proxy.c rename security/tomoyo/{hooks.h => tomoyo.c} (79%) diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig index 90eccc6cd464..1e0dd1a6d0b0 100644 --- a/security/tomoyo/Kconfig +++ b/security/tomoyo/Kconfig @@ -13,21 +13,6 @@ config SECURITY_TOMOYO found at <https://tomoyo.sourceforge.net/>. If you are unsure how to answer this question, answer N. -config SECURITY_TOMOYO_LKM - bool "Cut out most of TOMOYO's code to a loadable kernel module" - default n - depends on SECURITY_TOMOYO - depends on MODULES - help - Say Y here if you want to include TOMOYO without bloating - vmlinux file. If you say Y, most of TOMOYO code is cut out to - a loadable kernel module named tomoyo.ko . This option will be - useful for kernels built by Linux distributors where TOMOYO is - included but TOMOYO is not enabled by default. Please be sure - to explicitly load tomoyo.ko if you want to activate TOMOYO - without calling userspace policy loader, for tomoyo.ko is - loaded immediately before calling userspace policy loader. - config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY int "Default maximal count for learning mode" default 2048 diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile index 287a7d16fa15..55c67b9846a9 100644 --- a/security/tomoyo/Makefile +++ b/security/tomoyo/Makefile @@ -1,11 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -tomoyo-objs := audit.o common.o condition.o domain.o environ.o file.o gc.o group.o memory.o mount.o network.o proxy.o realpath.o securityfs_if.o util.o -obj-y += init.o load_policy.o -ifdef CONFIG_SECURITY_TOMOYO_LKM -obj-m += tomoyo.o -else -obj-y += tomoyo.o -endif +obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o targets += builtin-policy.h diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index c0ef014f8009..5c7b059a332a 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -998,13 +998,8 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, p = find_task_by_pid_ns(pid, &init_pid_ns); else p = find_task_by_vpid(pid); - if (p) { + if (p) domain = tomoyo_task(p)->domain_info; -#ifdef CONFIG_SECURITY_TOMOYO_LKM - if (!domain) - domain = &tomoyo_kernel_domain; -#endif - } rcu_read_unlock(); } else if (!strncmp(data, "domain=", 7)) { if (tomoyo_domain_def(data + 7)) @@ -1715,13 +1710,8 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head) p = find_task_by_pid_ns(pid, &init_pid_ns); else p = find_task_by_vpid(pid); - if (p) { + if (p) domain = tomoyo_task(p)->domain_info; -#ifdef CONFIG_SECURITY_TOMOYO_LKM - if (!domain) - domain = &tomoyo_kernel_domain; -#endif - } rcu_read_unlock(); if (!domain) return; diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 4f6c52a9f478..0e8e2e959aef 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -978,7 +978,6 @@ int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile, int tomoyo_init_request_info(struct tomoyo_request_info *r, struct tomoyo_domain_info *domain, const u8 index); -int __init tomoyo_interface_init(void); int tomoyo_mkdev_perm(const u8 operation, const struct path *path, const unsigned int mode, unsigned int dev); int tomoyo_mount_permission(const char *dev_name, const struct path *path, @@ -1215,14 +1214,10 @@ static inline void tomoyo_put_group(struct tomoyo_group *group) * * Returns pointer to "struct tomoyo_task" for specified thread. */ -#ifdef CONFIG_SECURITY_TOMOYO_LKM -extern struct tomoyo_task *tomoyo_task(struct task_struct *task); -#else static inline struct tomoyo_task *tomoyo_task(struct task_struct *task) { return task->security + tomoyo_blob_sizes.lbs_task; } -#endif /** * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry. @@ -1289,71 +1284,4 @@ static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void) pos = srcu_dereference((head)->next, &tomoyo_ss); \ for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss)) -#ifdef CONFIG_SECURITY_TOMOYO_LKM - -#define LSM_HOOK(RET, DEFAULT, NAME, ...) typedef RET (NAME##_t)(__VA_ARGS__); -#include <linux/lsm_hook_defs.h> -#undef LSM_HOOK - -struct tomoyo_hooks { - cred_prepare_t *cred_prepare; - bprm_committed_creds_t *bprm_committed_creds; - task_alloc_t *task_alloc; - task_free_t *task_free; - bprm_check_security_t *bprm_check_security; - file_fcntl_t *file_fcntl; - file_open_t *file_open; - file_truncate_t *file_truncate; - path_truncate_t *path_truncate; - path_unlink_t *path_unlink; - path_mkdir_t *path_mkdir; - path_rmdir_t *path_rmdir; - path_symlink_t *path_symlink; - path_mknod_t *path_mknod; - path_link_t *path_link; - path_rename_t *path_rename; - inode_getattr_t *inode_getattr; - file_ioctl_t *file_ioctl; - file_ioctl_compat_t *file_ioctl_compat; - path_chmod_t *path_chmod; - path_chown_t *path_chown; - path_chroot_t *path_chroot; - sb_mount_t *sb_mount; - sb_umount_t *sb_umount; - sb_pivotroot_t *sb_pivotroot; - socket_bind_t *socket_bind; - socket_connect_t *socket_connect; - socket_listen_t *socket_listen; - socket_sendmsg_t *socket_sendmsg; -}; - -extern void tomoyo_register_hooks(const struct tomoyo_hooks *tomoyo_hooks); - -struct tomoyo_operations { - void (*check_profile)(void); - int enabled; -}; - -extern struct tomoyo_operations tomoyo_ops; - -/* - * Temporary hack: functions needed by tomoyo.ko . This will be removed - * after all functions are marked as EXPORT_STMBOL_GPL(). - */ -struct tomoyo_tmp_exports { - struct task_struct * (*find_task_by_vpid)(pid_t nr); - struct task_struct * (*find_task_by_pid_ns)(pid_t nr, struct pid_namespace *ns); - void (*put_filesystem)(struct file_system_type *fs); - struct file * (*get_mm_exe_file)(struct mm_struct *mm); - char * (*d_absolute_path)(const struct path *path, char *buf, int buflen); -}; -extern const struct tomoyo_tmp_exports tomoyo_tmp_exports; -#define find_task_by_vpid tomoyo_tmp_exports.find_task_by_vpid -#define find_task_by_pid_ns tomoyo_tmp_exports.find_task_by_pid_ns -#define put_filesystem tomoyo_tmp_exports.put_filesystem -#define get_mm_exe_file tomoyo_tmp_exports.get_mm_exe_file -#define d_absolute_path tomoyo_tmp_exports.d_absolute_path - -#endif /* defined(CONFIG_SECURITY_TOMOYO_LKM) */ - #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c index 6eccca150839..026e29ea3796 100644 --- a/security/tomoyo/gc.c +++ b/security/tomoyo/gc.c @@ -9,9 +9,6 @@ #include <linux/kthread.h> #include <linux/slab.h> -/* Lock for GC. */ -DEFINE_SRCU(tomoyo_ss); - /** * tomoyo_memory_free - Free memory for elements. * diff --git a/security/tomoyo/init.c b/security/tomoyo/init.c deleted file mode 100644 index 034e7db22d4e..000000000000 --- a/security/tomoyo/init.c +++ /dev/null @@ -1,366 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * security/tomoyo/init.c - * - * Copyright (C) 2005-2011 NTT DATA CORPORATION - */ - -#include <linux/lsm_hooks.h> -#include <uapi/linux/lsm.h> -#include "common.h" - -#ifndef CONFIG_SECURITY_TOMOYO_LKM - -#include "hooks.h" - -#else - -#define DEFINE_STATIC_CALL_PROXY(NAME) \ - static NAME##_t tomoyo_##NAME; \ - DEFINE_STATIC_CALL_RET0(tomoyo_##NAME, tomoyo_##NAME); -DEFINE_STATIC_CALL_PROXY(cred_prepare) -DEFINE_STATIC_CALL_PROXY(bprm_committed_creds) -DEFINE_STATIC_CALL_PROXY(bprm_check_security) -DEFINE_STATIC_CALL_PROXY(inode_getattr) -DEFINE_STATIC_CALL_PROXY(path_truncate) -DEFINE_STATIC_CALL_PROXY(file_truncate) -DEFINE_STATIC_CALL_PROXY(path_unlink) -DEFINE_STATIC_CALL_PROXY(path_mkdir) -DEFINE_STATIC_CALL_PROXY(path_rmdir) -DEFINE_STATIC_CALL_PROXY(path_symlink) -DEFINE_STATIC_CALL_PROXY(path_mknod) -DEFINE_STATIC_CALL_PROXY(path_link) -DEFINE_STATIC_CALL_PROXY(path_rename) -DEFINE_STATIC_CALL_PROXY(file_fcntl) -DEFINE_STATIC_CALL_PROXY(file_open) -DEFINE_STATIC_CALL_PROXY(file_ioctl) -DEFINE_STATIC_CALL_PROXY(path_chmod) -DEFINE_STATIC_CALL_PROXY(path_chown) -DEFINE_STATIC_CALL_PROXY(path_chroot) -DEFINE_STATIC_CALL_PROXY(sb_mount) -DEFINE_STATIC_CALL_PROXY(sb_umount) -DEFINE_STATIC_CALL_PROXY(sb_pivotroot) -DEFINE_STATIC_CALL_PROXY(socket_listen) -DEFINE_STATIC_CALL_PROXY(socket_connect) -DEFINE_STATIC_CALL_PROXY(socket_bind) -DEFINE_STATIC_CALL_PROXY(socket_sendmsg) -DEFINE_STATIC_CALL_PROXY(task_alloc) -DEFINE_STATIC_CALL_PROXY(task_free) -#undef DEFINE_STATIC_CALL_PROXY - -static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp) -{ - return static_call(tomoyo_cred_prepare)(new, old, gfp); -} - -static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm) -{ - static_call(tomoyo_bprm_committed_creds)(bprm); -} - -static int tomoyo_bprm_check_security(struct linux_binprm *bprm) -{ - return static_call(tomoyo_bprm_check_security)(bprm); -} - -static int tomoyo_inode_getattr(const struct path *path) -{ - return static_call(tomoyo_inode_getattr)(path); -} - -static int tomoyo_path_truncate(const struct path *path) -{ - return static_call(tomoyo_path_truncate)(path); -} - -static int tomoyo_file_truncate(struct file *file) -{ - return static_call(tomoyo_file_truncate)(file); -} - -static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry) -{ - return static_call(tomoyo_path_unlink)(parent, dentry); -} - -static int tomoyo_path_mkdir(const struct path *parent, struct dentry *dentry, umode_t mode) -{ - return static_call(tomoyo_path_mkdir)(parent, dentry, mode); -} - -static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry) -{ - return static_call(tomoyo_path_rmdir)(parent, dentry); -} - -static int tomoyo_path_symlink(const struct path *parent, struct dentry *dentry, - const char *old_name) -{ - return static_call(tomoyo_path_symlink)(parent, dentry, old_name); -} - -static int tomoyo_path_mknod(const struct path *parent, struct dentry *dentry, - umode_t mode, unsigned int dev) -{ - return static_call(tomoyo_path_mknod)(parent, dentry, mode, dev); -} - -static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry) -{ - return static_call(tomoyo_path_link)(old_dentry, new_dir, new_dentry); -} - -static int tomoyo_path_rename(const struct path *old_parent, struct dentry *old_dentry, - const struct path *new_parent, struct dentry *new_dentry, - const unsigned int flags) -{ - return static_call(tomoyo_path_rename)(old_parent, old_dentry, new_parent, new_dentry, flags); -} - -static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) -{ - return static_call(tomoyo_file_fcntl)(file, cmd, arg); -} - -static int tomoyo_file_open(struct file *f) -{ - return static_call(tomoyo_file_open)(f); -} - -static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - return static_call(tomoyo_file_ioctl)(file, cmd, arg); -} - -static int tomoyo_path_chmod(const struct path *path, umode_t mode) -{ - return static_call(tomoyo_path_chmod)(path, mode); -} - -static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid) -{ - return static_call(tomoyo_path_chown)(path, uid, gid); -} - -static int tomoyo_path_chroot(const struct path *path) -{ - return static_call(tomoyo_path_chroot)(path); -} - -static int tomoyo_sb_mount(const char *dev_name, const struct path *path, - const char *type, unsigned long flags, void *data) -{ - return static_call(tomoyo_sb_mount)(dev_name, path, type, flags, data); -} - -static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) -{ - return static_call(tomoyo_sb_umount)(mnt, flags); -} - -static int tomoyo_sb_pivotroot(const struct path *old_path, const struct path *new_path) -{ - return static_call(tomoyo_sb_pivotroot)(old_path, new_path); -} - -static int tomoyo_socket_listen(struct socket *sock, int backlog) -{ - return static_call(tomoyo_socket_listen)(sock, backlog); -} - -static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr, int addr_len) -{ - return static_call(tomoyo_socket_connect)(sock, addr, addr_len); -} - -static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr, int addr_len) -{ - return static_call(tomoyo_socket_bind)(sock, addr, addr_len); -} - -static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) -{ - return static_call(tomoyo_socket_sendmsg)(sock, msg, size); -} - -static int tomoyo_task_alloc(struct task_struct *task, unsigned long clone_flags) -{ - return static_call(tomoyo_task_alloc)(task, clone_flags); -} - -static void tomoyo_task_free(struct task_struct *task) -{ - static_call(tomoyo_task_free)(task); -} - -void tomoyo_register_hooks(const struct tomoyo_hooks *tomoyo_hooks) -{ - static void *registered; - - if (cmpxchg(®istered, NULL, ®istered)) - panic("%s was called twice!\n", __func__); - static_call_update(tomoyo_task_free, tomoyo_hooks->task_free); - static_call_update(tomoyo_task_alloc, tomoyo_hooks->task_alloc); - static_call_update(tomoyo_cred_prepare, tomoyo_hooks->cred_prepare); - static_call_update(tomoyo_bprm_committed_creds, tomoyo_hooks->bprm_committed_creds); - static_call_update(tomoyo_bprm_check_security, tomoyo_hooks->bprm_check_security); - static_call_update(tomoyo_inode_getattr, tomoyo_hooks->inode_getattr); - static_call_update(tomoyo_path_truncate, tomoyo_hooks->path_truncate); - static_call_update(tomoyo_file_truncate, tomoyo_hooks->file_truncate); - static_call_update(tomoyo_path_unlink, tomoyo_hooks->path_unlink); - static_call_update(tomoyo_path_mkdir, tomoyo_hooks->path_mkdir); - static_call_update(tomoyo_path_rmdir, tomoyo_hooks->path_rmdir); - static_call_update(tomoyo_path_symlink, tomoyo_hooks->path_symlink); - static_call_update(tomoyo_path_mknod, tomoyo_hooks->path_mknod); - static_call_update(tomoyo_path_link, tomoyo_hooks->path_link); - static_call_update(tomoyo_path_rename, tomoyo_hooks->path_rename); - static_call_update(tomoyo_file_fcntl, tomoyo_hooks->file_fcntl); - static_call_update(tomoyo_file_open, tomoyo_hooks->file_open); - static_call_update(tomoyo_file_ioctl, tomoyo_hooks->file_ioctl); - static_call_update(tomoyo_path_chmod, tomoyo_hooks->path_chmod); - static_call_update(tomoyo_path_chown, tomoyo_hooks->path_chown); - static_call_update(tomoyo_path_chroot, tomoyo_hooks->path_chroot); - static_call_update(tomoyo_sb_mount, tomoyo_hooks->sb_mount); - static_call_update(tomoyo_sb_umount, tomoyo_hooks->sb_umount); - static_call_update(tomoyo_sb_pivotroot, tomoyo_hooks->sb_pivotroot); - static_call_update(tomoyo_socket_listen, tomoyo_hooks->socket_listen); - static_call_update(tomoyo_socket_connect, tomoyo_hooks->socket_connect); - static_call_update(tomoyo_socket_bind, tomoyo_hooks->socket_bind); - static_call_update(tomoyo_socket_sendmsg, tomoyo_hooks->socket_sendmsg); -} -EXPORT_SYMBOL_GPL(tomoyo_register_hooks); - -/* - * Temporary hack: functions needed by tomoyo.ko . This hack will be removed - * after all functions are marked as EXPORT_STMBOL_GPL(). - */ -#undef find_task_by_vpid -#undef find_task_by_pid_ns -#undef put_filesystem -#undef get_mm_exe_file -#undef d_absolute_path -const struct tomoyo_tmp_exports tomoyo_tmp_exports = { - .find_task_by_vpid = find_task_by_vpid, - .find_task_by_pid_ns = find_task_by_pid_ns, - .put_filesystem = put_filesystem, - .get_mm_exe_file = get_mm_exe_file, - .d_absolute_path = d_absolute_path, -}; -EXPORT_SYMBOL_GPL(tomoyo_tmp_exports); - -#endif - -#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER -static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm) -{ - /* - * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested - * for the first time. - */ - if (!tomoyo_policy_loaded) - tomoyo_load_policy(bprm->filename); - return 0; -} -#endif - -struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = { - .lbs_task = sizeof(struct tomoyo_task), -}; - -static const struct lsm_id tomoyo_lsmid = { - .name = "tomoyo", - .id = LSM_ID_TOMOYO, -}; - -/* tomoyo_hooks is used for registering TOMOYO. */ -static struct security_hook_list tomoyo_hooks[] __ro_after_init = { - LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare), - LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds), - LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc), - LSM_HOOK_INIT(task_free, tomoyo_task_free), -#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER - LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec), -#endif - LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security), - LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl), - LSM_HOOK_INIT(file_open, tomoyo_file_open), - LSM_HOOK_INIT(file_truncate, tomoyo_file_truncate), - LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate), - LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink), - LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir), - LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir), - LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink), - LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod), - LSM_HOOK_INIT(path_link, tomoyo_path_link), - LSM_HOOK_INIT(path_rename, tomoyo_path_rename), - LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr), - LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl), - LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl), - LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod), - LSM_HOOK_INIT(path_chown, tomoyo_path_chown), - LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot), - LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount), - LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount), - LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot), - LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind), - LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect), - LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen), - LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg), -}; - -int tomoyo_enabled __ro_after_init = 1; - -/* Has /sbin/init started? */ -bool tomoyo_policy_loaded; - -#ifdef CONFIG_SECURITY_TOMOYO_LKM -EXPORT_SYMBOL_GPL(tomoyo_blob_sizes); -EXPORT_SYMBOL_GPL(tomoyo_policy_loaded); - -struct tomoyo_operations tomoyo_ops; -EXPORT_SYMBOL_GPL(tomoyo_ops); - -/** - * tomoyo_init - Reserve hooks for TOMOYO Linux. - * - * Returns 0. - */ -static int __init tomoyo_init(void) -{ - /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), &tomoyo_lsmid); - tomoyo_ops.enabled = tomoyo_enabled; - pr_info("Hooks for initializing TOMOYO Linux are ready\n"); - return 0; -} -#else -/** - * tomoyo_init - Register TOMOYO Linux as a LSM module. - * - * Returns 0. - */ -static int __init tomoyo_init(void) -{ - struct tomoyo_task *s = tomoyo_task(current); - - /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), - &tomoyo_lsmid); - pr_info("TOMOYO Linux initialized\n"); - s->domain_info = &tomoyo_kernel_domain; - atomic_inc(&tomoyo_kernel_domain.users); - s->old_domain_info = NULL; - tomoyo_mm_init(); - - return 0; -} -#endif - -DEFINE_LSM(tomoyo) = { - .name = "tomoyo", - .enabled = &tomoyo_enabled, - .flags = LSM_FLAG_LEGACY_MAJOR, - .blobs = &tomoyo_blob_sizes, - .init = tomoyo_init, -}; diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c index 6a2a72354a64..363b65be87ab 100644 --- a/security/tomoyo/load_policy.c +++ b/security/tomoyo/load_policy.c @@ -97,14 +97,6 @@ void tomoyo_load_policy(const char *filename) if (!tomoyo_policy_loader_exists()) return; done = true; -#ifdef CONFIG_SECURITY_TOMOYO_LKM - /* Load tomoyo.ko if not yet loaded. */ - if (!tomoyo_ops.check_profile) - request_module("tomoyo"); - /* Check if tomoyo.ko was successfully loaded. */ - if (!tomoyo_ops.check_profile) - panic("Failed to load tomoyo module."); -#endif pr_info("Calling %s to load policy. Please wait.\n", tomoyo_loader); argv[0] = (char *) tomoyo_loader; argv[1] = NULL; @@ -112,11 +104,7 @@ void tomoyo_load_policy(const char *filename) envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; envp[2] = NULL; call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); -#ifdef CONFIG_SECURITY_TOMOYO_LKM - tomoyo_ops.check_profile(); -#else tomoyo_check_profile(); -#endif } #endif diff --git a/security/tomoyo/proxy.c b/security/tomoyo/proxy.c deleted file mode 100644 index 1618cc0f2af8..000000000000 --- a/security/tomoyo/proxy.c +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * security/tomoyo/proxy.c - * - * Copyright (C) 2005-2011 NTT DATA CORPORATION - */ - -#include <linux/security.h> -#include "common.h" - -#ifdef CONFIG_SECURITY_TOMOYO_LKM - -struct tomoyo_task *tomoyo_task(struct task_struct *task) -{ - struct tomoyo_task *s = task->security + tomoyo_blob_sizes.lbs_task; - - if (unlikely(!s->domain_info)) { - if (likely(task == current)) { - s->domain_info = &tomoyo_kernel_domain; - atomic_inc(&tomoyo_kernel_domain.users); - } else { - /* Caller handles s->domain_info == NULL case. */ - } - } - return s; -} - -#include "hooks.h" - -/** - * tomoyo_runtime_init - Register TOMOYO Linux as a loadable LSM module. - * - * Returns 0 if TOMOYO is enabled, -EINVAL otherwise. - */ -static int __init tomoyo_runtime_init(void) -{ - const struct tomoyo_hooks tomoyo_hooks = { - .cred_prepare = tomoyo_cred_prepare, - .bprm_committed_creds = tomoyo_bprm_committed_creds, - .task_alloc = tomoyo_task_alloc, - .task_free = tomoyo_task_free, - .bprm_check_security = tomoyo_bprm_check_security, - .file_fcntl = tomoyo_file_fcntl, - .file_open = tomoyo_file_open, - .file_truncate = tomoyo_file_truncate, - .path_truncate = tomoyo_path_truncate, - .path_unlink = tomoyo_path_unlink, - .path_mkdir = tomoyo_path_mkdir, - .path_rmdir = tomoyo_path_rmdir, - .path_symlink = tomoyo_path_symlink, - .path_mknod = tomoyo_path_mknod, - .path_link = tomoyo_path_link, - .path_rename = tomoyo_path_rename, - .inode_getattr = tomoyo_inode_getattr, - .file_ioctl = tomoyo_file_ioctl, - .file_ioctl_compat = tomoyo_file_ioctl, - .path_chmod = tomoyo_path_chmod, - .path_chown = tomoyo_path_chown, - .path_chroot = tomoyo_path_chroot, - .sb_mount = tomoyo_sb_mount, - .sb_umount = tomoyo_sb_umount, - .sb_pivotroot = tomoyo_sb_pivotroot, - .socket_bind = tomoyo_socket_bind, - .socket_connect = tomoyo_socket_connect, - .socket_listen = tomoyo_socket_listen, - .socket_sendmsg = tomoyo_socket_sendmsg, - }; - - if (!tomoyo_ops.enabled) - return -EINVAL; - tomoyo_ops.check_profile = tomoyo_check_profile; - pr_info("TOMOYO Linux initialized\n"); - tomoyo_task(current); - tomoyo_mm_init(); - tomoyo_interface_init(); - tomoyo_register_hooks(&tomoyo_hooks); - return 0; -} -module_init(tomoyo_runtime_init); -MODULE_LICENSE("GPL"); - -#endif diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c index a3b821b7f477..a2705798476f 100644 --- a/security/tomoyo/securityfs_if.c +++ b/security/tomoyo/securityfs_if.c @@ -229,19 +229,17 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode, } /** - * tomoyo_interface_init - Initialize /sys/kernel/security/tomoyo/ interface. + * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface. * * Returns 0. */ -int __init tomoyo_interface_init(void) +static int __init tomoyo_initerface_init(void) { struct tomoyo_domain_info *domain; struct dentry *tomoyo_dir; -#ifndef CONFIG_SECURITY_TOMOYO_LKM if (!tomoyo_enabled) return 0; -#endif domain = tomoyo_domain(); /* Don't create securityfs entries unless registered. */ if (domain != &tomoyo_kernel_domain) @@ -272,6 +270,4 @@ int __init tomoyo_interface_init(void) return 0; } -#ifndef CONFIG_SECURITY_TOMOYO_LKM -fs_initcall(tomoyo_interface_init); -#endif +fs_initcall(tomoyo_initerface_init); diff --git a/security/tomoyo/hooks.h b/security/tomoyo/tomoyo.c similarity index 79% rename from security/tomoyo/hooks.h rename to security/tomoyo/tomoyo.c index 58929bb71477..04a92c3d65d4 100644 --- a/security/tomoyo/hooks.h +++ b/security/tomoyo/tomoyo.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 /* - * security/tomoyo/hooks.h + * security/tomoyo/tomoyo.c * * Copyright (C) 2005-2011 NTT DATA CORPORATION */ +#include <linux/lsm_hooks.h> +#include <uapi/linux/lsm.h> #include "common.h" /** @@ -16,6 +18,10 @@ struct tomoyo_domain_info *tomoyo_domain(void) { struct tomoyo_task *s = tomoyo_task(current); + if (s->old_domain_info && !current->in_execve) { + atomic_dec(&s->old_domain_info->users); + s->old_domain_info = NULL; + } return s->domain_info; } @@ -56,6 +62,26 @@ static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm) s->old_domain_info = NULL; } +#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER +/** + * tomoyo_bprm_creds_for_exec - Target for security_bprm_creds_for_exec(). + * + * @bprm: Pointer to "struct linux_binprm". + * + * Returns 0. + */ +static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm) +{ + /* + * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested + * for the first time. + */ + if (!tomoyo_policy_loaded) + tomoyo_load_policy(bprm->filename); + return 0; +} +#endif + /** * tomoyo_bprm_check_security - Target for security_bprm_check(). * @@ -475,6 +501,10 @@ static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg, return tomoyo_socket_sendmsg_permission(sock, msg, size); } +struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = { + .lbs_task = sizeof(struct tomoyo_task), +}; + /** * tomoyo_task_alloc - Target for security_task_alloc(). * @@ -513,3 +543,81 @@ static void tomoyo_task_free(struct task_struct *task) s->old_domain_info = NULL; } } + +static const struct lsm_id tomoyo_lsmid = { + .name = "tomoyo", + .id = LSM_ID_TOMOYO, +}; + +/* + * tomoyo_security_ops is a "struct security_operations" which is used for + * registering TOMOYO. + */ +static struct security_hook_list tomoyo_hooks[] __ro_after_init = { + LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare), + LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds), + LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc), + LSM_HOOK_INIT(task_free, tomoyo_task_free), +#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER + LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec), +#endif + LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security), + LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl), + LSM_HOOK_INIT(file_open, tomoyo_file_open), + LSM_HOOK_INIT(file_truncate, tomoyo_file_truncate), + LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate), + LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink), + LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir), + LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir), + LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink), + LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod), + LSM_HOOK_INIT(path_link, tomoyo_path_link), + LSM_HOOK_INIT(path_rename, tomoyo_path_rename), + LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr), + LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl), + LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl), + LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod), + LSM_HOOK_INIT(path_chown, tomoyo_path_chown), + LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot), + LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount), + LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount), + LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot), + LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind), + LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect), + LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen), + LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg), +}; + +/* Lock for GC. */ +DEFINE_SRCU(tomoyo_ss); + +int tomoyo_enabled __ro_after_init = 1; + +/** + * tomoyo_init - Register TOMOYO Linux as a LSM module. + * + * Returns 0. + */ +static int __init tomoyo_init(void) +{ + struct tomoyo_task *s = tomoyo_task(current); + + /* register ourselves with the security framework */ + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); + pr_info("TOMOYO Linux initialized\n"); + s->domain_info = &tomoyo_kernel_domain; + atomic_inc(&tomoyo_kernel_domain.users); + s->old_domain_info = NULL; + tomoyo_mm_init(); + + return 0; +} + +DEFINE_LSM(tomoyo) = { + .name = "tomoyo", + .enabled = &tomoyo_enabled, + .flags = LSM_FLAG_LEGACY_MAJOR, + .blobs = &tomoyo_blob_sizes, + .init = tomoyo_init, +}; diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index b851ff377382..6799b1122c9d 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c @@ -13,6 +13,9 @@ /* Lock for protecting policy. */ DEFINE_MUTEX(tomoyo_policy_lock); +/* Has /sbin/init started? */ +bool tomoyo_policy_loaded; + /* * Mapping table from "enum tomoyo_mac_index" to * "enum tomoyo_mac_category_index". -- GitLab From faab35a0370fd6e0821c7a8dd213492946fc776f Mon Sep 17 00:00:00 2001 From: "Luis Henriques (SUSE)" <luis.henriques@linux.dev> Date: Mon, 23 Sep 2024 11:49:08 +0100 Subject: [PATCH 711/970] ext4: use handle to mark fc as ineligible in __track_dentry_update() Calling ext4_fc_mark_ineligible() with a NULL handle is racy and may result in a fast-commit being done before the filesystem is effectively marked as ineligible. This patch fixes the calls to this function in __track_dentry_update() by adding an extra parameter to the callback used in ext4_fc_track_template(). Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Luis Henriques (SUSE) <luis.henriques@linux.dev> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240923104909.18342-2-luis.henriques@linux.dev Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@kernel.org --- fs/ext4/fast_commit.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c index eaa5f5b51f50..b33664f6ce2a 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -379,7 +379,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handl */ static int ext4_fc_track_template( handle_t *handle, struct inode *inode, - int (*__fc_track_fn)(struct inode *, void *, bool), + int (*__fc_track_fn)(handle_t *handle, struct inode *, void *, bool), void *args, int enqueue) { bool update = false; @@ -396,7 +396,7 @@ static int ext4_fc_track_template( ext4_fc_reset_inode(inode); ei->i_sync_tid = tid; } - ret = __fc_track_fn(inode, args, update); + ret = __fc_track_fn(handle, inode, args, update); mutex_unlock(&ei->i_fc_lock); if (!enqueue) @@ -420,7 +420,8 @@ struct __track_dentry_update_args { }; /* __track_fn for directory entry updates. Called with ei->i_fc_lock. */ -static int __track_dentry_update(struct inode *inode, void *arg, bool update) +static int __track_dentry_update(handle_t *handle, struct inode *inode, + void *arg, bool update) { struct ext4_fc_dentry_update *node; struct ext4_inode_info *ei = EXT4_I(inode); @@ -435,14 +436,14 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update) if (IS_ENCRYPTED(dir)) { ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME, - NULL); + handle); mutex_lock(&ei->i_fc_lock); return -EOPNOTSUPP; } node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS); if (!node) { - ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL); + ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, handle); mutex_lock(&ei->i_fc_lock); return -ENOMEM; } @@ -454,7 +455,7 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update) node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS); if (!node->fcd_name.name) { kmem_cache_free(ext4_fc_dentry_cachep, node); - ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL); + ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, handle); mutex_lock(&ei->i_fc_lock); return -ENOMEM; } @@ -576,7 +577,8 @@ void ext4_fc_track_create(handle_t *handle, struct dentry *dentry) } /* __track_fn for inode tracking */ -static int __track_inode(struct inode *inode, void *arg, bool update) +static int __track_inode(handle_t *handle, struct inode *inode, void *arg, + bool update) { if (update) return -EEXIST; @@ -614,7 +616,8 @@ struct __track_range_args { }; /* __track_fn for tracking data updates */ -static int __track_range(struct inode *inode, void *arg, bool update) +static int __track_range(handle_t *handle, struct inode *inode, void *arg, + bool update) { struct ext4_inode_info *ei = EXT4_I(inode); ext4_lblk_t oldstart; -- GitLab From 04e6ce8f06d161399e5afde3df5dcfa9455b4952 Mon Sep 17 00:00:00 2001 From: "Luis Henriques (SUSE)" <luis.henriques@linux.dev> Date: Mon, 23 Sep 2024 11:49:09 +0100 Subject: [PATCH 712/970] ext4: mark fc as ineligible using an handle in ext4_xattr_set() Calling ext4_fc_mark_ineligible() with a NULL handle is racy and may result in a fast-commit being done before the filesystem is effectively marked as ineligible. This patch moves the call to this function so that an handle can be used. If a transaction fails to start, then there's not point in trying to mark the filesystem as ineligible, and an error will eventually be returned to user-space. Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Luis Henriques (SUSE) <luis.henriques@linux.dev> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240923104909.18342-3-luis.henriques@linux.dev Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@kernel.org --- fs/ext4/xattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index e0e1956dcdd3..7647e9f6e190 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2559,6 +2559,8 @@ ext4_xattr_set(struct inode *inode, int name_index, const char *name, error = ext4_xattr_set_handle(handle, inode, name_index, name, value, value_len, flags); + ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR, + handle); error2 = ext4_journal_stop(handle); if (error == -ENOSPC && ext4_should_retry_alloc(sb, &retries)) @@ -2566,7 +2568,6 @@ ext4_xattr_set(struct inode *inode, int name_index, const char *name, if (error == 0) error = error2; } - ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR, NULL); return error; } -- GitLab From 6121258c2b33ceac3d21f6a221452692c465df88 Mon Sep 17 00:00:00 2001 From: Baokun Li <libaokun1@huawei.com> Date: Fri, 27 Sep 2024 21:33:29 +0800 Subject: [PATCH 713/970] ext4: fix off by one issue in alloc_flex_gd() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wesley reported an issue: ================================================================== EXT4-fs (dm-5): resizing filesystem from 7168 to 786432 blocks ------------[ cut here ]------------ kernel BUG at fs/ext4/resize.c:324! CPU: 9 UID: 0 PID: 3576 Comm: resize2fs Not tainted 6.11.0+ #27 RIP: 0010:ext4_resize_fs+0x1212/0x12d0 Call Trace: __ext4_ioctl+0x4e0/0x1800 ext4_ioctl+0x12/0x20 __x64_sys_ioctl+0x99/0xd0 x64_sys_call+0x1206/0x20d0 do_syscall_64+0x72/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e ================================================================== While reviewing the patch, Honza found that when adjusting resize_bg in alloc_flex_gd(), it was possible for flex_gd->resize_bg to be bigger than flexbg_size. The reproduction of the problem requires the following: o_group = flexbg_size * 2 * n; o_size = (o_group + 1) * group_size; n_group: [o_group + flexbg_size, o_group + flexbg_size * 2) o_size = (n_group + 1) * group_size; Take n=0,flexbg_size=16 as an example: last:15 |o---------------|--------------n-| o_group:0 resize to n_group:30 The corresponding reproducer is: img=test.img rm -f $img truncate -s 600M $img mkfs.ext4 -F $img -b 1024 -G 16 8M dev=`losetup -f --show $img` mkdir -p /tmp/test mount $dev /tmp/test resize2fs $dev 248M Delete the problematic plus 1 to fix the issue, and add a WARN_ON_ONCE() to prevent the issue from happening again. [ Note: another reproucer which this commit fixes is: img=test.img rm -f $img truncate -s 25MiB $img mkfs.ext4 -b 4096 -E nodiscard,lazy_itable_init=0,lazy_journal_init=0 $img truncate -s 3GiB $img dev=`losetup -f --show $img` mkdir -p /tmp/test mount $dev /tmp/test resize2fs $dev 3G umount $dev losetup -d $dev -- TYT ] Reported-by: Wesley Hershberger <wesley.hershberger@canonical.com> Closes: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2081231 Reported-by: Stéphane Graber <stgraber@stgraber.org> Closes: https://lore.kernel.org/all/20240925143325.518508-1-aleksandr.mikhalitsyn@canonical.com/ Tested-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Tested-by: Eric Sandeen <sandeen@redhat.com> Fixes: 665d3e0af4d3 ("ext4: reduce unnecessary memory allocation in alloc_flex_gd()") Cc: stable@vger.kernel.org Signed-off-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240927133329.1015041-1-libaokun@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu> --- fs/ext4/resize.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index e04eb08b9060..a2704f064361 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -230,8 +230,8 @@ struct ext4_new_flex_group_data { #define MAX_RESIZE_BG 16384 /* - * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of - * @flexbg_size. + * alloc_flex_gd() allocates an ext4_new_flex_group_data that satisfies the + * resizing from @o_group to @n_group, its size is typically @flexbg_size. * * Returns NULL on failure otherwise address of the allocated structure. */ @@ -239,25 +239,27 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size, ext4_group_t o_group, ext4_group_t n_group) { ext4_group_t last_group; + unsigned int max_resize_bg; struct ext4_new_flex_group_data *flex_gd; flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS); if (flex_gd == NULL) goto out3; - if (unlikely(flexbg_size > MAX_RESIZE_BG)) - flex_gd->resize_bg = MAX_RESIZE_BG; - else - flex_gd->resize_bg = flexbg_size; + max_resize_bg = umin(flexbg_size, MAX_RESIZE_BG); + flex_gd->resize_bg = max_resize_bg; /* Avoid allocating large 'groups' array if not needed */ last_group = o_group | (flex_gd->resize_bg - 1); if (n_group <= last_group) - flex_gd->resize_bg = 1 << fls(n_group - o_group + 1); + flex_gd->resize_bg = 1 << fls(n_group - o_group); else if (n_group - last_group < flex_gd->resize_bg) - flex_gd->resize_bg = 1 << max(fls(last_group - o_group + 1), + flex_gd->resize_bg = 1 << max(fls(last_group - o_group), fls(n_group - last_group)); + if (WARN_ON_ONCE(flex_gd->resize_bg > max_resize_bg)) + flex_gd->resize_bg = max_resize_bg; + flex_gd->groups = kmalloc_array(flex_gd->resize_bg, sizeof(struct ext4_new_group_data), GFP_NOFS); -- GitLab From 6b63a948a73ba3df0fb3ab0c44807df344bc5bbf Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Fri, 4 Oct 2024 19:44:32 -0400 Subject: [PATCH 714/970] bcachefs: Add missing wakeup to bch2_inode_hash_remove() This fixes two different bugs: - Looser locking with the rhashtable means we need to recheck if the inode is still hashed after prepare_to_wait(), and add a corresponding wakeup after removing from the hash table. - da18ecbf0fb6 ("fs: add i_state helpers") changed the bit waitqueues used for inodes, and bcachefs wasn't updated and thus broke; this updates bcachefs to the new helper. Fixes: 112d21fd1a12 ("bcachefs: switch to rhashtable for vfs inodes hash") Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fs.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index 4a1bb07a2574..5bfc26d58270 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -174,20 +174,24 @@ static const struct rhashtable_params bch2_vfs_inodes_params = { .automatic_shrinking = true, }; -static void __wait_on_freeing_inode(struct inode *inode) +struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum) { - wait_queue_head_t *wq; - DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW); - wq = bit_waitqueue(&inode->i_state, __I_NEW); - prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE); - spin_unlock(&inode->i_lock); - schedule(); - finish_wait(wq, &wait.wq_entry); + return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params); } -struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum) +static void __wait_on_freeing_inode(struct bch_fs *c, + struct bch_inode_info *inode, + subvol_inum inum) { - return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params); + wait_queue_head_t *wq; + DEFINE_WAIT_BIT(wait, &inode->v.i_state, __I_NEW); + wq = inode_bit_waitqueue(&wait, &inode->v, __I_NEW); + prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE); + spin_unlock(&inode->v.i_lock); + + if (__bch2_inode_hash_find(c, inum) == inode) + schedule_timeout(HZ * 10); + finish_wait(wq, &wait.wq_entry); } static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btree_trans *trans, @@ -204,10 +208,10 @@ static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btre } if ((inode->v.i_state & (I_FREEING|I_WILL_FREE))) { if (!trans) { - __wait_on_freeing_inode(&inode->v); + __wait_on_freeing_inode(c, inode, inum); } else { bch2_trans_unlock(trans); - __wait_on_freeing_inode(&inode->v); + __wait_on_freeing_inode(c, inode, inum); int ret = bch2_trans_relock(trans); if (ret) return ERR_PTR(ret); @@ -232,6 +236,11 @@ static void bch2_inode_hash_remove(struct bch_fs *c, struct bch_inode_info *inod &inode->hash, bch2_vfs_inodes_params); BUG_ON(ret); inode->v.i_hash.pprev = NULL; + /* + * This pairs with the bch2_inode_hash_find() -> + * __wait_on_freeing_inode() path + */ + inode_wake_up_bit(&inode->v, __I_NEW); } } -- GitLab From 20826fe6b810bce3efba9ef5d74cf13ebe5f23d9 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Sat, 28 Sep 2024 02:44:12 -0400 Subject: [PATCH 715/970] bcachefs: Fix reattach_inode() Ensure a copy of the lost+found inode exists in the snapshot that we're reattaching, so that we don't trigger warnings in lookup_inode_for_snapshot() later. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 351de61c7ed1..881ad5b9447f 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -354,13 +354,12 @@ static int reattach_inode(struct btree_trans *trans, if (ret) return ret; - if (S_ISDIR(inode->bi_mode)) { - lostfound.bi_nlink++; + lostfound.bi_nlink += S_ISDIR(inode->bi_mode); - ret = __bch2_fsck_write_inode(trans, &lostfound, U32_MAX); - if (ret) - return ret; - } + /* ensure lost+found inode is also present in inode snapshot */ + ret = __bch2_fsck_write_inode(trans, &lostfound, inode_snapshot); + if (ret) + return ret; dir_hash = bch2_hash_info_init(c, &lostfound); -- GitLab From fda7b1ffdef75cc0f4d34255e88b5894e2ce75b1 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Sat, 28 Sep 2024 15:33:08 -0400 Subject: [PATCH 716/970] bcachefs: Create lost+found in correct snapshot Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 881ad5b9447f..f0d6696c4df6 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -283,11 +283,17 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, return ret; create_lostfound: + /* + * we always create lost+found in the root snapshot; we don't want + * different branches of the snapshot tree to have different lost+found + */ + snapshot = le32_to_cpu(st.root_snapshot); /* * XXX: we could have a nicer log message here if we had a nice way to * walk backpointers to print a path */ - bch_notice(c, "creating lost+found in snapshot %u", le32_to_cpu(st.root_snapshot)); + bch_notice(c, "creating lost+found in subvol %llu snapshot %u", + root_inum.subvol, le32_to_cpu(st.root_snapshot)); u64 now = bch2_current_time(c); struct btree_iter lostfound_iter = { NULL }; -- GitLab From 658c82f41e8075e18b98b8705ed0cc34346f35c2 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Fri, 4 Oct 2024 15:05:40 -0400 Subject: [PATCH 717/970] bcachefs: bkey errors are only AUTOFIX during read Newly generated keys, in the transaction commit path or write path, should not be AUTOFIX; those indicate bugs that we need to fail fast for. Fixes: 5612daafb764 ("bcachefs: Fix fsck warnings from bkey validation") Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/error.c | 11 +++++++++-- fs/bcachefs/error.h | 9 +++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index 3a16b535b6c3..aac1960321b7 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -430,10 +430,17 @@ int __bch2_fsck_err(struct bch_fs *c, int __bch2_bkey_fsck_err(struct bch_fs *c, struct bkey_s_c k, - enum bch_fsck_flags flags, + enum bch_validate_flags validate_flags, enum bch_sb_error_id err, const char *fmt, ...) { + if (validate_flags & BCH_VALIDATE_silent) + return -BCH_ERR_fsck_delete_bkey; + + unsigned fsck_flags = 0; + if (!(validate_flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit))) + fsck_flags |= FSCK_AUTOFIX|FSCK_CAN_FIX; + struct printbuf buf = PRINTBUF; va_list args; @@ -445,7 +452,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c, va_end(args); prt_str(&buf, ": delete?"); - int ret = __bch2_fsck_err(c, NULL, flags, err, "%s", buf.buf); + int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf); printbuf_exit(&buf); return ret; } diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h index 21ee7211b03e..6551ada926b6 100644 --- a/fs/bcachefs/error.h +++ b/fs/bcachefs/error.h @@ -167,10 +167,11 @@ void bch2_flush_fsck_errs(struct bch_fs *); #define fsck_err_on(cond, c, _err_type, ...) \ __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__) +enum bch_validate_flags; __printf(5, 6) int __bch2_bkey_fsck_err(struct bch_fs *, struct bkey_s_c, - enum bch_fsck_flags, + enum bch_validate_flags, enum bch_sb_error_id, const char *, ...); @@ -180,11 +181,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *, */ #define bkey_fsck_err(c, _err_type, _err_msg, ...) \ do { \ - if ((flags & BCH_VALIDATE_silent)) { \ - ret = -BCH_ERR_fsck_delete_bkey; \ - goto fsck_err; \ - } \ - int _ret = __bch2_bkey_fsck_err(c, k, FSCK_CAN_FIX|FSCK_AUTOFIX,\ + int _ret = __bch2_bkey_fsck_err(c, k, flags, \ BCH_FSCK_ERR_##_err_type, \ _err_msg, ##__VA_ARGS__); \ if (_ret != -BCH_ERR_fsck_fix && \ -- GitLab From 492e24d7604a1b78c8af3c30984a0cffc17d6bdf Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Tue, 1 Oct 2024 16:26:02 -0400 Subject: [PATCH 718/970] bcachefs: Make sure we print error that causes fsck to bail out Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/error.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index aac1960321b7..7a79f695ba2e 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -393,6 +393,14 @@ int __bch2_fsck_err(struct bch_fs *c, !(flags & FSCK_CAN_IGNORE))) ret = -BCH_ERR_fsck_errors_not_fixed; + bool exiting = + test_bit(BCH_FS_fsck_running, &c->flags) && + (ret != -BCH_ERR_fsck_fix && + ret != -BCH_ERR_fsck_ignore); + + if (exiting) + print = true; + if (print) { if (bch2_fs_stdio_redirect(c)) bch2_print(c, "%s\n", out->buf); @@ -400,9 +408,7 @@ int __bch2_fsck_err(struct bch_fs *c, bch2_print_string_as_lines(KERN_ERR, out->buf); } - if (test_bit(BCH_FS_fsck_running, &c->flags) && - (ret != -BCH_ERR_fsck_fix && - ret != -BCH_ERR_fsck_ignore)) + if (exiting) bch_err(c, "Unable to continue, halting"); else if (suppressing) bch_err(c, "Ratelimiting new instances of previous error"); -- GitLab From 1bea714c532abf101e939a90b8c920ef9205cfa3 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Tue, 1 Oct 2024 16:26:21 -0400 Subject: [PATCH 719/970] bcachefs: Mark more errors AUTOFIX Errors are getting marked as AUTOFIX once they've been (re)-tested and audited. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/sb-errors_format.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h index ed5dca5e1161..6a63d24180ca 100644 --- a/fs/bcachefs/sb-errors_format.h +++ b/fs/bcachefs/sb-errors_format.h @@ -129,20 +129,20 @@ enum bch_fsck_flags { x(freespace_key_wrong, 115, 0) \ x(freespace_hole_missing, 116, 0) \ x(bucket_gens_val_size_bad, 117, 0) \ - x(bucket_gens_key_wrong, 118, 0) \ - x(bucket_gens_hole_wrong, 119, 0) \ - x(bucket_gens_to_invalid_dev, 120, 0) \ - x(bucket_gens_to_invalid_buckets, 121, 0) \ - x(bucket_gens_nonzero_for_invalid_buckets, 122, 0) \ + x(bucket_gens_key_wrong, 118, FSCK_AUTOFIX) \ + x(bucket_gens_hole_wrong, 119, FSCK_AUTOFIX) \ + x(bucket_gens_to_invalid_dev, 120, FSCK_AUTOFIX) \ + x(bucket_gens_to_invalid_buckets, 121, FSCK_AUTOFIX) \ + x(bucket_gens_nonzero_for_invalid_buckets, 122, FSCK_AUTOFIX) \ x(need_discard_freespace_key_to_invalid_dev_bucket, 123, 0) \ x(need_discard_freespace_key_bad, 124, 0) \ x(backpointer_bucket_offset_wrong, 125, 0) \ x(backpointer_to_missing_device, 126, 0) \ x(backpointer_to_missing_alloc, 127, 0) \ x(backpointer_to_missing_ptr, 128, 0) \ - x(lru_entry_at_time_0, 129, 0) \ - x(lru_entry_to_invalid_bucket, 130, 0) \ - x(lru_entry_bad, 131, 0) \ + x(lru_entry_at_time_0, 129, FSCK_AUTOFIX) \ + x(lru_entry_to_invalid_bucket, 130, FSCK_AUTOFIX) \ + x(lru_entry_bad, 131, FSCK_AUTOFIX) \ x(btree_ptr_val_too_big, 132, 0) \ x(btree_ptr_v2_val_too_big, 133, 0) \ x(btree_ptr_has_non_ptr, 134, 0) \ @@ -158,9 +158,9 @@ enum bch_fsck_flags { x(ptr_after_last_bucket, 144, 0) \ x(ptr_before_first_bucket, 145, 0) \ x(ptr_spans_multiple_buckets, 146, 0) \ - x(ptr_to_missing_backpointer, 147, 0) \ - x(ptr_to_missing_alloc_key, 148, 0) \ - x(ptr_to_missing_replicas_entry, 149, 0) \ + x(ptr_to_missing_backpointer, 147, FSCK_AUTOFIX) \ + x(ptr_to_missing_alloc_key, 148, FSCK_AUTOFIX) \ + x(ptr_to_missing_replicas_entry, 149, FSCK_AUTOFIX) \ x(ptr_to_missing_stripe, 150, 0) \ x(ptr_to_incorrect_stripe, 151, 0) \ x(ptr_gen_newer_than_bucket_gen, 152, 0) \ @@ -194,7 +194,7 @@ enum bch_fsck_flags { x(snapshot_skiplist_not_normalized, 180, 0) \ x(snapshot_skiplist_bad, 181, 0) \ x(snapshot_should_not_have_subvol, 182, 0) \ - x(snapshot_to_bad_snapshot_tree, 183, 0) \ + x(snapshot_to_bad_snapshot_tree, 183, FSCK_AUTOFIX) \ x(snapshot_bad_depth, 184, 0) \ x(snapshot_bad_skiplist, 185, 0) \ x(subvol_pos_bad, 186, 0) \ -- GitLab From 01bf5e3bd26ff8e49bf06fa4180f3eab51ab06df Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Tue, 1 Oct 2024 16:40:33 -0400 Subject: [PATCH 720/970] bcachefs: minor lru fsck fixes check_lru_key() wasn't using write buffer updates for deleting bad lru entries - dating from before the lru btree used the btree write buffer. And when possibly flushing the btree write buffer (to make sure we're seeing a real inconsistency), we need to be using the modern bch2_btree_write_buffer_maybe_flush(). Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/lru.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/fs/bcachefs/lru.c b/fs/bcachefs/lru.c index 96f2f4f8c397..dd5df668131a 100644 --- a/fs/bcachefs/lru.c +++ b/fs/bcachefs/lru.c @@ -2,6 +2,7 @@ #include "bcachefs.h" #include "alloc_background.h" +#include "bkey_buf.h" #include "btree_iter.h" #include "btree_update.h" #include "btree_write_buffer.h" @@ -118,7 +119,7 @@ int bch2_lru_check_set(struct btree_trans *trans, static int bch2_check_lru_key(struct btree_trans *trans, struct btree_iter *lru_iter, struct bkey_s_c lru_k, - struct bpos *last_flushed_pos) + struct bkey_buf *last_flushed) { struct bch_fs *c = trans->c; struct btree_iter iter; @@ -136,7 +137,7 @@ static int bch2_check_lru_key(struct btree_trans *trans, trans, lru_entry_to_invalid_bucket, "lru key points to nonexistent device:bucket %llu:%llu", alloc_pos.inode, alloc_pos.offset)) - return bch2_btree_delete_at(trans, lru_iter, 0); + return bch2_btree_bit_mod_buffered(trans, BTREE_ID_lru, lru_iter->pos, false); k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc, alloc_pos, 0); ret = bkey_err(k); @@ -156,12 +157,9 @@ static int bch2_check_lru_key(struct btree_trans *trans, if (lru_k.k->type != KEY_TYPE_set || lru_pos_time(lru_k.k->p) != idx) { - if (!bpos_eq(*last_flushed_pos, lru_k.k->p)) { - *last_flushed_pos = lru_k.k->p; - ret = bch2_btree_write_buffer_flush_sync(trans) ?: - -BCH_ERR_transaction_restart_write_buffer_flush; - goto out; - } + ret = bch2_btree_write_buffer_maybe_flush(trans, lru_k, last_flushed); + if (ret) + goto err; if (fsck_err(trans, lru_entry_bad, "incorrect lru entry: lru %s time %llu\n" @@ -171,9 +169,8 @@ static int bch2_check_lru_key(struct btree_trans *trans, lru_pos_time(lru_k.k->p), (bch2_bkey_val_to_text(&buf1, c, lru_k), buf1.buf), (bch2_bkey_val_to_text(&buf2, c, k), buf2.buf))) - ret = bch2_btree_delete_at(trans, lru_iter, 0); + ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_lru, lru_iter->pos, false); } -out: err: fsck_err: bch2_trans_iter_exit(trans, &iter); @@ -184,12 +181,18 @@ static int bch2_check_lru_key(struct btree_trans *trans, int bch2_check_lrus(struct bch_fs *c) { - struct bpos last_flushed_pos = POS_MIN; + struct bkey_buf last_flushed; + + bch2_bkey_buf_init(&last_flushed); + bkey_init(&last_flushed.k->k); + int ret = bch2_trans_run(c, for_each_btree_key_commit(trans, iter, BTREE_ID_lru, POS_MIN, BTREE_ITER_prefetch, k, NULL, NULL, BCH_TRANS_COMMIT_no_enospc|BCH_TRANS_COMMIT_lazy_rw, - bch2_check_lru_key(trans, &iter, k, &last_flushed_pos))); + bch2_check_lru_key(trans, &iter, k, &last_flushed))); + + bch2_bkey_buf_exit(&last_flushed, c); bch_err_fn(c, ret); return ret; -- GitLab From 260af1562ec14353824da24fe7acc179a902558e Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Tue, 1 Oct 2024 19:08:37 -0400 Subject: [PATCH 721/970] bcachefs: Kill alloc_v4.fragmentation_lru The fragmentation_lru field hasn't been needed since we reworked the LRU btrees to use the btree write buffer; previously it was used to resolve collisions, but the revised LRU btree uses the backpointer (the bucket) as part of the key. It should have been deleted at the time of the LRU rework; since it wasn't, that left places for bugs to hide, in check/repair. This fixes LRU fsck on a filesystem image helpfully provided by a user who disappeared before I could get his name for the reported-by. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/alloc_background.c | 30 ++++++++++++++++++--------- fs/bcachefs/alloc_background_format.h | 2 +- fs/bcachefs/btree_gc.c | 3 --- fs/bcachefs/lru.c | 7 +++++-- fs/bcachefs/move.c | 2 +- fs/bcachefs/movinggc.c | 12 ++++++++--- fs/bcachefs/sb-errors_format.h | 4 ++-- 7 files changed, 38 insertions(+), 22 deletions(-) diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 645b5ed4babb..4e4a448f6931 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -332,7 +332,6 @@ void bch2_alloc_v4_swab(struct bkey_s k) a->io_time[1] = swab64(a->io_time[1]); a->stripe = swab32(a->stripe); a->nr_external_backpointers = swab32(a->nr_external_backpointers); - a->fragmentation_lru = swab64(a->fragmentation_lru); a->stripe_sectors = swab32(a->stripe_sectors); bps = alloc_v4_backpointers(a); @@ -347,6 +346,7 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c { struct bch_alloc_v4 _a; const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a); + struct bch_dev *ca = c ? bch2_dev_bucket_tryget_noerror(c, k.k->p) : NULL; prt_newline(out); printbuf_indent_add(out, 2); @@ -364,9 +364,13 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c prt_printf(out, "stripe_redundancy %u\n", a->stripe_redundancy); prt_printf(out, "io_time[READ] %llu\n", a->io_time[READ]); prt_printf(out, "io_time[WRITE] %llu\n", a->io_time[WRITE]); - prt_printf(out, "fragmentation %llu\n", a->fragmentation_lru); + + if (ca) + prt_printf(out, "fragmentation %llu\n", alloc_lru_idx_fragmentation(*a, ca)); prt_printf(out, "bp_start %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a)); printbuf_indent_sub(out, 2); + + bch2_dev_put(ca); } void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out) @@ -882,12 +886,13 @@ int bch2_trigger_alloc(struct btree_trans *trans, goto err; } - new_a->fragmentation_lru = alloc_lru_idx_fragmentation(*new_a, ca); - if (old_a->fragmentation_lru != new_a->fragmentation_lru) { + old_lru = alloc_lru_idx_fragmentation(*old_a, ca); + new_lru = alloc_lru_idx_fragmentation(*new_a, ca); + if (old_lru != new_lru) { ret = bch2_lru_change(trans, BCH_LRU_FRAGMENTATION_START, bucket_to_u64(new.k->p), - old_a->fragmentation_lru, new_a->fragmentation_lru); + old_lru, new_lru); if (ret) goto err; } @@ -1629,18 +1634,22 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans, if (ret) return ret; + struct bch_dev *ca = bch2_dev_tryget_noerror(c, alloc_k.k->p.inode); + if (!ca) + return 0; + a = bch2_alloc_to_v4(alloc_k, &a_convert); - if (a->fragmentation_lru) { + u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca); + if (lru_idx) { ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START, - a->fragmentation_lru, - alloc_k, last_flushed); + lru_idx, alloc_k, last_flushed); if (ret) - return ret; + goto err; } if (a->data_type != BCH_DATA_cached) - return 0; + goto err; if (fsck_err_on(!a->io_time[READ], trans, alloc_key_cached_but_read_time_zero, @@ -1669,6 +1678,7 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans, goto err; err: fsck_err: + bch2_dev_put(ca); printbuf_exit(&buf); return ret; } diff --git a/fs/bcachefs/alloc_background_format.h b/fs/bcachefs/alloc_background_format.h index f754a2951d8a..befdaa95c515 100644 --- a/fs/bcachefs/alloc_background_format.h +++ b/fs/bcachefs/alloc_background_format.h @@ -70,7 +70,7 @@ struct bch_alloc_v4 { __u32 stripe; __u32 nr_external_backpointers; /* end of fields in original version of alloc_v4 */ - __u64 fragmentation_lru; + __u64 _fragmentation_lru; /* obsolete */ __u32 stripe_sectors; __u32 pad; } __packed __aligned(8); diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index 660d2fa02da2..771154e3a291 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -828,8 +828,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans, return ret; } - gc.fragmentation_lru = alloc_lru_idx_fragmentation(gc, ca); - if (fsck_err_on(new.data_type != gc.data_type, trans, alloc_key_data_type_wrong, "bucket %llu:%llu gen %u has wrong data_type" @@ -857,7 +855,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans, copy_bucket_field(alloc_key_cached_sectors_wrong, cached_sectors); copy_bucket_field(alloc_key_stripe_wrong, stripe); copy_bucket_field(alloc_key_stripe_redundancy_wrong, stripe_redundancy); - copy_bucket_field(alloc_key_fragmentation_lru_wrong, fragmentation_lru); #undef copy_bucket_field if (!bch2_alloc_v4_cmp(*old, new)) diff --git a/fs/bcachefs/lru.c b/fs/bcachefs/lru.c index dd5df668131a..10857eccdeaf 100644 --- a/fs/bcachefs/lru.c +++ b/fs/bcachefs/lru.c @@ -133,7 +133,9 @@ static int bch2_check_lru_key(struct btree_trans *trans, u64 idx; int ret; - if (fsck_err_on(!bch2_dev_bucket_exists(c, alloc_pos), + struct bch_dev *ca = bch2_dev_bucket_tryget_noerror(c, alloc_pos); + + if (fsck_err_on(!ca, trans, lru_entry_to_invalid_bucket, "lru key points to nonexistent device:bucket %llu:%llu", alloc_pos.inode, alloc_pos.offset)) @@ -151,7 +153,7 @@ static int bch2_check_lru_key(struct btree_trans *trans, idx = alloc_lru_idx_read(*a); break; case BCH_LRU_fragmentation: - idx = a->fragmentation_lru; + idx = alloc_lru_idx_fragmentation(*a, ca); break; } @@ -174,6 +176,7 @@ static int bch2_check_lru_key(struct btree_trans *trans, err: fsck_err: bch2_trans_iter_exit(trans, &iter); + bch2_dev_put(ca); printbuf_exit(&buf2); printbuf_exit(&buf1); return ret; diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index 7d3920e03742..8c456d8b8b99 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -692,7 +692,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt, a = bch2_alloc_to_v4(k, &a_convert); dirty_sectors = bch2_bucket_sectors_dirty(*a); bucket_size = ca->mi.bucket_size; - fragmentation = a->fragmentation_lru; + fragmentation = alloc_lru_idx_fragmentation(*a, ca); ret = bch2_btree_write_buffer_tryflush(trans); bch_err_msg(c, ret, "flushing btree write buffer"); diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c index d86565bf07c8..d658be90f737 100644 --- a/fs/bcachefs/movinggc.c +++ b/fs/bcachefs/movinggc.c @@ -73,6 +73,7 @@ move_bucket_in_flight_add(struct buckets_in_flight *list, struct move_bucket b) static int bch2_bucket_is_movable(struct btree_trans *trans, struct move_bucket *b, u64 time) { + struct bch_fs *c = trans->c; struct btree_iter iter; struct bkey_s_c k; struct bch_alloc_v4 _a; @@ -90,14 +91,19 @@ static int bch2_bucket_is_movable(struct btree_trans *trans, if (ret) return ret; + struct bch_dev *ca = bch2_dev_tryget(c, k.k->p.inode); + if (!ca) + goto out; + a = bch2_alloc_to_v4(k, &_a); b->k.gen = a->gen; b->sectors = bch2_bucket_sectors_dirty(*a); + u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca); - ret = data_type_movable(a->data_type) && - a->fragmentation_lru && - a->fragmentation_lru <= time; + ret = lru_idx && lru_idx <= time; + bch2_dev_put(ca); +out: bch2_trans_iter_exit(trans, &iter); return ret; } diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h index 6a63d24180ca..b4024870b65e 100644 --- a/fs/bcachefs/sb-errors_format.h +++ b/fs/bcachefs/sb-errors_format.h @@ -115,8 +115,8 @@ enum bch_fsck_flags { x(alloc_key_data_type_inconsistency, 101, 0) \ x(alloc_key_to_missing_dev_bucket, 102, 0) \ x(alloc_key_cached_inconsistency, 103, 0) \ - x(alloc_key_cached_but_read_time_zero, 104, 0) \ - x(alloc_key_to_missing_lru_entry, 105, 0) \ + x(alloc_key_cached_but_read_time_zero, 104, FSCK_AUTOFIX) \ + x(alloc_key_to_missing_lru_entry, 105, FSCK_AUTOFIX) \ x(alloc_key_data_type_wrong, 106, FSCK_AUTOFIX) \ x(alloc_key_gen_wrong, 107, FSCK_AUTOFIX) \ x(alloc_key_dirty_sectors_wrong, 108, FSCK_AUTOFIX) \ -- GitLab From 1c6051bbd76b2767d6acef6a1d0bdf99aa319273 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Sat, 28 Sep 2024 15:27:37 -0400 Subject: [PATCH 722/970] bcachefs: Check for directories with no backpointers It's legal for regular files to have missing backpointers (due to hardlinks), and fsck should automatically add them, but for directories this is an error that should be flagged. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 22 +++++++++++++++------- fs/bcachefs/sb-errors_format.h | 3 ++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index f0d6696c4df6..d2aa6a5bc973 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1826,6 +1826,21 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, if (inode_points_to_dirent(target, d)) return 0; + if (!target->bi_dir && + !target->bi_dir_offset) { + fsck_err_on(S_ISDIR(target->bi_mode), + trans, inode_dir_missing_backpointer, + "directory with missing backpointer\n%s", + (bch2_bkey_val_to_text(&buf, c, d.s_c), + prt_printf(&buf, "\n "), + bch2_inode_unpacked_to_text(&buf, target), + buf.buf)); + + target->bi_dir = d.k->p.inode; + target->bi_dir_offset = d.k->p.offset; + return __bch2_fsck_write_inode(trans, target, target_snapshot); + } + if (bch2_inode_should_have_bp(target) && !fsck_err(trans, inode_wrong_backpointer, "dirent points to inode that does not point back:\n %s", @@ -1835,13 +1850,6 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, buf.buf))) goto err; - if (!target->bi_dir && - !target->bi_dir_offset) { - target->bi_dir = d.k->p.inode; - target->bi_dir_offset = d.k->p.offset; - return __bch2_fsck_write_inode(trans, target, target_snapshot); - } - struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter, SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot)); ret = bkey_err(bp_dirent); diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h index b4024870b65e..fc3d31ed5975 100644 --- a/fs/bcachefs/sb-errors_format.h +++ b/fs/bcachefs/sb-errors_format.h @@ -219,6 +219,7 @@ enum bch_fsck_flags { x(inode_i_sectors_wrong, 204, FSCK_AUTOFIX) \ x(inode_dir_wrong_nlink, 205, FSCK_AUTOFIX) \ x(inode_dir_multiple_links, 206, FSCK_AUTOFIX) \ + x(inode_dir_missing_backpointer, 284, FSCK_AUTOFIX) \ x(inode_multiple_links_but_nlink_0, 207, FSCK_AUTOFIX) \ x(inode_wrong_backpointer, 208, FSCK_AUTOFIX) \ x(inode_wrong_nlink, 209, FSCK_AUTOFIX) \ @@ -295,7 +296,7 @@ enum bch_fsck_flags { x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \ x(accounting_key_version_0, 282, FSCK_AUTOFIX) \ x(logged_op_but_clean, 283, FSCK_AUTOFIX) \ - x(MAX, 284, 0) + x(MAX, 285, 0) enum bch_sb_error_id { #define x(t, n, ...) BCH_FSCK_ERR_##t = n, -- GitLab From c7da5ee2e5cc30faca49e3ea9dbecf8f6ee4f1ea Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Sun, 29 Sep 2024 22:38:04 -0400 Subject: [PATCH 723/970] bcachefs: Check for unlinked inodes with dirents link count works differently in bcachefs - it's only nonzero for files with multiple hardlinks, which means we can also avoid checking it except for files that are known to have hardlinks. That means we need a few different checks instead; in particular, we don't want fsck to delet a file that has a dirent pointing to it. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 53 +++++++++++++++++++++++++--------- fs/bcachefs/sb-errors_format.h | 3 +- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index d2aa6a5bc973..09f890539ded 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1029,6 +1029,7 @@ static int check_inode(struct btree_trans *trans, bool full) { struct bch_fs *c = trans->c; + struct printbuf buf = PRINTBUF; struct bch_inode_unpacked u; bool do_update = false; int ret; @@ -1062,7 +1063,24 @@ static int check_inode(struct btree_trans *trans, trans, inode_snapshot_mismatch, "inodes in different snapshots don't match")) { bch_err(c, "repair not implemented yet"); - return -BCH_ERR_fsck_repair_unimplemented; + ret = -BCH_ERR_fsck_repair_unimplemented; + goto err_noprint; + } + + if (u.bi_dir || u.bi_dir_offset) { + ret = check_inode_dirent_inode(trans, &u, &do_update); + if (ret) + goto err; + } + + if (fsck_err_on(u.bi_dir && (u.bi_flags & BCH_INODE_unlinked), + trans, inode_unlinked_but_has_dirent, + "inode unlinked but has dirent\n%s", + (printbuf_reset(&buf), + bch2_inode_unpacked_to_text(&buf, &u), + buf.buf))) { + u.bi_flags &= ~BCH_INODE_unlinked; + do_update = true; } if ((u.bi_flags & (BCH_INODE_i_size_dirty|BCH_INODE_unlinked)) && @@ -1079,11 +1097,11 @@ static int check_inode(struct btree_trans *trans, bch_err_msg(c, ret, "in fsck updating inode"); if (ret) - return ret; + goto err_noprint; if (!bpos_eq(new_min_pos, POS_MIN)) bch2_btree_iter_set_pos(iter, bpos_predecessor(new_min_pos)); - return 0; + goto err_noprint; } if (u.bi_flags & BCH_INODE_unlinked) { @@ -1100,7 +1118,7 @@ static int check_inode(struct btree_trans *trans, */ ret = check_inode_deleted_list(trans, k.k->p); if (ret < 0) - return ret; + goto err_noprint; fsck_err_on(!ret, trans, unlinked_inode_not_on_deleted_list, @@ -1117,7 +1135,7 @@ static int check_inode(struct btree_trans *trans, u.bi_inum, u.bi_snapshot)) { ret = bch2_inode_rm_snapshot(trans, u.bi_inum, iter->pos.snapshot); bch_err_msg(c, ret, "in fsck deleting inode"); - return ret; + goto err_noprint; } } } @@ -1182,12 +1200,6 @@ static int check_inode(struct btree_trans *trans, do_update = true; } - if (u.bi_dir || u.bi_dir_offset) { - ret = check_inode_dirent_inode(trans, &u, &do_update); - if (ret) - goto err; - } - if (fsck_err_on(u.bi_parent_subvol && (u.bi_subvol == 0 || u.bi_subvol == BCACHEFS_ROOT_SUBVOL), @@ -1232,11 +1244,13 @@ static int check_inode(struct btree_trans *trans, ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); bch_err_msg(c, ret, "in fsck updating inode"); if (ret) - return ret; + goto err_noprint; } err: fsck_err: bch_err_fn(c, ret); +err_noprint: + printbuf_exit(&buf); return ret; } @@ -1831,11 +1845,22 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, fsck_err_on(S_ISDIR(target->bi_mode), trans, inode_dir_missing_backpointer, "directory with missing backpointer\n%s", - (bch2_bkey_val_to_text(&buf, c, d.s_c), - prt_printf(&buf, "\n "), + (printbuf_reset(&buf), + bch2_bkey_val_to_text(&buf, c, d.s_c), + prt_printf(&buf, "\n"), bch2_inode_unpacked_to_text(&buf, target), buf.buf)); + fsck_err_on(target->bi_flags & BCH_INODE_unlinked, + trans, inode_unlinked_but_has_dirent, + "inode unlinked but has dirent\n%s", + (printbuf_reset(&buf), + bch2_bkey_val_to_text(&buf, c, d.s_c), + prt_printf(&buf, "\n"), + bch2_inode_unpacked_to_text(&buf, target), + buf.buf)); + + target->bi_flags &= ~BCH_INODE_unlinked; target->bi_dir = d.k->p.inode; target->bi_dir_offset = d.k->p.offset; return __bch2_fsck_write_inode(trans, target, target_snapshot); diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h index fc3d31ed5975..4c8ff4cc17c2 100644 --- a/fs/bcachefs/sb-errors_format.h +++ b/fs/bcachefs/sb-errors_format.h @@ -211,6 +211,7 @@ enum bch_fsck_flags { x(inode_unlinked_but_clean, 197, 0) \ x(inode_unlinked_but_nlink_nonzero, 198, 0) \ x(inode_unlinked_and_not_open, 281, 0) \ + x(inode_unlinked_but_has_dirent, 285, 0) \ x(inode_checksum_type_invalid, 199, 0) \ x(inode_compression_type_invalid, 200, 0) \ x(inode_subvol_root_but_not_dir, 201, 0) \ @@ -296,7 +297,7 @@ enum bch_fsck_flags { x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \ x(accounting_key_version_0, 282, FSCK_AUTOFIX) \ x(logged_op_but_clean, 283, FSCK_AUTOFIX) \ - x(MAX, 285, 0) + x(MAX, 286, 0) enum bch_sb_error_id { #define x(t, n, ...) BCH_FSCK_ERR_##t = n, -- GitLab From c9306a91c3fdc9915f5408561ea432c70b03383b Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Sun, 29 Sep 2024 23:38:37 -0400 Subject: [PATCH 724/970] bcachefs: Check for unlinked, non-empty dirs in check_inode() We want to check for this early so it can be reattached if necessary in check_unreachable_inodes(); better than letting it be deleted and having the children reattached, losing their filenames. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 17 +++++++++++++++++ fs/bcachefs/sb-errors_format.h | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 09f890539ded..30eca76554f6 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1083,6 +1083,23 @@ static int check_inode(struct btree_trans *trans, do_update = true; } + if (S_ISDIR(u.bi_mode) && (u.bi_flags & BCH_INODE_unlinked)) { + /* Check for this early so that check_unreachable_inode() will reattach it */ + + ret = bch2_empty_dir_snapshot(trans, k.k->p.offset, 0, k.k->p.snapshot); + if (ret && ret != -BCH_ERR_ENOTEMPTY_dir_not_empty) + goto err; + + fsck_err_on(ret, trans, inode_dir_unlinked_but_not_empty, + "dir unlinked but not empty\n%s", + (printbuf_reset(&buf), + bch2_inode_unpacked_to_text(&buf, &u), + buf.buf)); + u.bi_flags &= ~BCH_INODE_unlinked; + do_update = true; + ret = 0; + } + if ((u.bi_flags & (BCH_INODE_i_size_dirty|BCH_INODE_unlinked)) && bch2_key_has_snapshot_overwrites(trans, BTREE_ID_inodes, k.k->p)) { struct bpos new_min_pos; diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h index 4c8ff4cc17c2..4135b1ea2fec 100644 --- a/fs/bcachefs/sb-errors_format.h +++ b/fs/bcachefs/sb-errors_format.h @@ -221,6 +221,7 @@ enum bch_fsck_flags { x(inode_dir_wrong_nlink, 205, FSCK_AUTOFIX) \ x(inode_dir_multiple_links, 206, FSCK_AUTOFIX) \ x(inode_dir_missing_backpointer, 284, FSCK_AUTOFIX) \ + x(inode_dir_unlinked_but_not_empty, 286, FSCK_AUTOFIX) \ x(inode_multiple_links_but_nlink_0, 207, FSCK_AUTOFIX) \ x(inode_wrong_backpointer, 208, FSCK_AUTOFIX) \ x(inode_wrong_nlink, 209, FSCK_AUTOFIX) \ @@ -297,7 +298,7 @@ enum bch_fsck_flags { x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \ x(accounting_key_version_0, 282, FSCK_AUTOFIX) \ x(logged_op_but_clean, 283, FSCK_AUTOFIX) \ - x(MAX, 286, 0) + x(MAX, 287, 0) enum bch_sb_error_id { #define x(t, n, ...) BCH_FSCK_ERR_##t = n, -- GitLab From 72350ee0ea22c053f2683e50f1beba97df2ad053 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Mon, 30 Sep 2024 00:00:33 -0400 Subject: [PATCH 725/970] bcachefs: Kill snapshot arg to fsck_write_inode() It was initially believed that it would be better to be explicit about the snapshot we're updating when writing inodes in fsck; however, it turns out that passing around the snapshot separately is more error prone and we're usually updating the inode in the same snapshow we read it from. This is different from normal filesystem paths, where we do the update in the snapshot of the subvolume we're in. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/fsck.c | 87 ++++++++++++++++++++--------------------- fs/bcachefs/inode.c | 12 ++---- fs/bcachefs/inode.h | 4 +- fs/bcachefs/subvolume.c | 3 +- 4 files changed, 51 insertions(+), 55 deletions(-) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 30eca76554f6..b8a6ceb0cc7a 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -137,16 +137,15 @@ static int lookup_first_inode(struct btree_trans *trans, u64 inode_nr, return ret; } -static int lookup_inode(struct btree_trans *trans, u64 inode_nr, - struct bch_inode_unpacked *inode, - u32 *snapshot) +static int lookup_inode(struct btree_trans *trans, u64 inode_nr, u32 snapshot, + struct bch_inode_unpacked *inode) { struct btree_iter iter; struct bkey_s_c k; int ret; k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes, - SPOS(0, inode_nr, *snapshot), 0); + SPOS(0, inode_nr, snapshot), 0); ret = bkey_err(k); if (ret) goto err; @@ -154,8 +153,6 @@ static int lookup_inode(struct btree_trans *trans, u64 inode_nr, ret = bkey_is_inode(k.k) ? bch2_inode_unpack(k, inode) : -BCH_ERR_ENOENT_inode; - if (!ret) - *snapshot = iter.pos.snapshot; err: bch2_trans_iter_exit(trans, &iter); return ret; @@ -250,8 +247,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, struct bch_inode_unpacked root_inode; struct bch_hash_info root_hash_info; - u32 root_inode_snapshot = snapshot; - ret = lookup_inode(trans, root_inum.inum, &root_inode, &root_inode_snapshot); + ret = lookup_inode(trans, root_inum.inum, snapshot, &root_inode); bch_err_msg(c, ret, "looking up root inode %llu for subvol %u", root_inum.inum, le32_to_cpu(st.master_subvol)); if (ret) @@ -277,7 +273,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, * The bch2_check_dirents pass has already run, dangling dirents * shouldn't exist here: */ - ret = lookup_inode(trans, inum, lostfound, &snapshot); + ret = lookup_inode(trans, inum, snapshot, lostfound); bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)", inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot)); return ret; @@ -302,6 +298,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, bch2_inode_init_early(c, lostfound); bch2_inode_init_late(lostfound, now, 0, 0, S_IFDIR|0700, 0, &root_inode); lostfound->bi_dir = root_inode.bi_inum; + lostfound->bi_snapshot = le32_to_cpu(st.root_snapshot); root_inode.bi_nlink++; @@ -329,9 +326,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot, return ret; } -static int reattach_inode(struct btree_trans *trans, - struct bch_inode_unpacked *inode, - u32 inode_snapshot) +static int reattach_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode) { struct bch_fs *c = trans->c; struct bch_hash_info dir_hash; @@ -339,7 +334,7 @@ static int reattach_inode(struct btree_trans *trans, char name_buf[20]; struct qstr name; u64 dir_offset = 0; - u32 dirent_snapshot = inode_snapshot; + u32 dirent_snapshot = inode->bi_snapshot; int ret; if (inode->bi_subvol) { @@ -363,7 +358,12 @@ static int reattach_inode(struct btree_trans *trans, lostfound.bi_nlink += S_ISDIR(inode->bi_mode); /* ensure lost+found inode is also present in inode snapshot */ - ret = __bch2_fsck_write_inode(trans, &lostfound, inode_snapshot); + if (!inode->bi_subvol) { + BUG_ON(!bch2_snapshot_is_ancestor(c, inode->bi_snapshot, lostfound.bi_snapshot)); + lostfound.bi_snapshot = inode->bi_snapshot; + } + + ret = __bch2_fsck_write_inode(trans, &lostfound); if (ret) return ret; @@ -388,7 +388,7 @@ static int reattach_inode(struct btree_trans *trans, inode->bi_dir = lostfound.bi_inum; inode->bi_dir_offset = dir_offset; - return __bch2_fsck_write_inode(trans, inode, inode_snapshot); + return __bch2_fsck_write_inode(trans, inode); } static int remove_backpointer(struct btree_trans *trans, @@ -427,7 +427,7 @@ static int reattach_subvol(struct btree_trans *trans, struct bkey_s_c_subvolume if (ret) return ret; - ret = reattach_inode(trans, &inode, le32_to_cpu(s.v->snapshot)); + ret = reattach_inode(trans, &inode); bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum); return ret; } @@ -545,8 +545,9 @@ static int reconstruct_inode(struct btree_trans *trans, enum btree_id btree, u32 bch2_inode_init_late(&new_inode, bch2_current_time(c), 0, 0, i_mode|0600, 0, NULL); new_inode.bi_size = i_size; new_inode.bi_inum = inum; + new_inode.bi_snapshot = snapshot; - return __bch2_fsck_write_inode(trans, &new_inode, snapshot); + return __bch2_fsck_write_inode(trans, &new_inode); } struct snapshots_seen { @@ -1110,7 +1111,7 @@ static int check_inode(struct btree_trans *trans, u.bi_flags &= ~BCH_INODE_i_size_dirty|BCH_INODE_unlinked; - ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); + ret = __bch2_fsck_write_inode(trans, &u); bch_err_msg(c, ret, "in fsck updating inode"); if (ret) @@ -1258,7 +1259,7 @@ static int check_inode(struct btree_trans *trans, } do_update: if (do_update) { - ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot); + ret = __bch2_fsck_write_inode(trans, &u); bch_err_msg(c, ret, "in fsck updating inode"); if (ret) goto err_noprint; @@ -1383,7 +1384,7 @@ static int check_i_sectors_notnested(struct btree_trans *trans, struct inode_wal w->last_pos.inode, i->snapshot, i->inode.bi_sectors, i->count)) { i->inode.bi_sectors = i->count; - ret = bch2_fsck_write_inode(trans, &i->inode, i->snapshot); + ret = bch2_fsck_write_inode(trans, &i->inode); if (ret) break; } @@ -1825,7 +1826,7 @@ static int check_subdir_count_notnested(struct btree_trans *trans, struct inode_ "directory %llu:%u with wrong i_nlink: got %u, should be %llu", w->last_pos.inode, i->snapshot, i->inode.bi_nlink, i->count)) { i->inode.bi_nlink = i->count; - ret = bch2_fsck_write_inode(trans, &i->inode, i->snapshot); + ret = bch2_fsck_write_inode(trans, &i->inode); if (ret) break; } @@ -1846,8 +1847,7 @@ noinline_for_stack static int check_dirent_inode_dirent(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c_dirent d, - struct bch_inode_unpacked *target, - u32 target_snapshot) + struct bch_inode_unpacked *target) { struct bch_fs *c = trans->c; struct printbuf buf = PRINTBUF; @@ -1880,7 +1880,7 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, target->bi_flags &= ~BCH_INODE_unlinked; target->bi_dir = d.k->p.inode; target->bi_dir_offset = d.k->p.offset; - return __bch2_fsck_write_inode(trans, target, target_snapshot); + return __bch2_fsck_write_inode(trans, target); } if (bch2_inode_should_have_bp(target) && @@ -1893,7 +1893,7 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, goto err; struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter, - SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot)); + SPOS(target->bi_dir, target->bi_dir_offset, target->bi_snapshot)); ret = bkey_err(bp_dirent); if (ret && !bch2_err_matches(ret, ENOENT)) goto err; @@ -1906,14 +1906,14 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, "inode %llu:%u has wrong backpointer:\n" "got %llu:%llu\n" "should be %llu:%llu", - target->bi_inum, target_snapshot, + target->bi_inum, target->bi_snapshot, target->bi_dir, target->bi_dir_offset, d.k->p.inode, d.k->p.offset)) { target->bi_dir = d.k->p.inode; target->bi_dir_offset = d.k->p.offset; - ret = __bch2_fsck_write_inode(trans, target, target_snapshot); + ret = __bch2_fsck_write_inode(trans, target); goto out; } @@ -1928,7 +1928,7 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, trans, inode_dir_multiple_links, "%s %llu:%u with multiple links\n%s", S_ISDIR(target->bi_mode) ? "directory" : "subvolume", - target->bi_inum, target_snapshot, buf.buf)) { + target->bi_inum, target->bi_snapshot, buf.buf)) { ret = __remove_dirent(trans, d.k->p); goto out; } @@ -1941,10 +1941,10 @@ static int check_dirent_inode_dirent(struct btree_trans *trans, if (fsck_err_on(backpointer_exists && !target->bi_nlink, trans, inode_multiple_links_but_nlink_0, "inode %llu:%u type %s has multiple links but i_nlink 0\n%s", - target->bi_inum, target_snapshot, bch2_d_types[d.v->d_type], buf.buf)) { + target->bi_inum, target->bi_snapshot, bch2_d_types[d.v->d_type], buf.buf)) { target->bi_nlink++; target->bi_flags &= ~BCH_INODE_unlinked; - ret = __bch2_fsck_write_inode(trans, target, target_snapshot); + ret = __bch2_fsck_write_inode(trans, target); if (ret) goto err; } @@ -1961,15 +1961,14 @@ noinline_for_stack static int check_dirent_target(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c_dirent d, - struct bch_inode_unpacked *target, - u32 target_snapshot) + struct bch_inode_unpacked *target) { struct bch_fs *c = trans->c; struct bkey_i_dirent *n; struct printbuf buf = PRINTBUF; int ret = 0; - ret = check_dirent_inode_dirent(trans, iter, d, target, target_snapshot); + ret = check_dirent_inode_dirent(trans, iter, d, target); if (ret) goto err; @@ -2128,7 +2127,7 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * u64 target_inum = le64_to_cpu(s.v->inode); u32 target_snapshot = le32_to_cpu(s.v->snapshot); - ret = lookup_inode(trans, target_inum, &subvol_root, &target_snapshot); + ret = lookup_inode(trans, target_inum, target_snapshot, &subvol_root); if (ret && !bch2_err_matches(ret, ENOENT)) goto err; @@ -2144,13 +2143,13 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * target_inum, subvol_root.bi_parent_subvol, parent_subvol)) { subvol_root.bi_parent_subvol = parent_subvol; - ret = __bch2_fsck_write_inode(trans, &subvol_root, target_snapshot); + subvol_root.bi_snapshot = le32_to_cpu(s.v->snapshot); + ret = __bch2_fsck_write_inode(trans, &subvol_root); if (ret) goto err; } - ret = check_dirent_target(trans, iter, d, &subvol_root, - target_snapshot); + ret = check_dirent_target(trans, iter, d, &subvol_root); if (ret) goto err; out: @@ -2243,8 +2242,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter, } darray_for_each(target->inodes, i) { - ret = check_dirent_target(trans, iter, d, - &i->inode, i->snapshot); + ret = check_dirent_target(trans, iter, d, &i->inode); if (ret) goto err; } @@ -2385,7 +2383,7 @@ static int check_root_trans(struct btree_trans *trans) goto err; } - ret = lookup_inode(trans, BCACHEFS_ROOT_INO, &root_inode, &snapshot); + ret = lookup_inode(trans, BCACHEFS_ROOT_INO, snapshot, &root_inode); if (ret && !bch2_err_matches(ret, ENOENT)) return ret; @@ -2398,8 +2396,9 @@ static int check_root_trans(struct btree_trans *trans) bch2_inode_init(c, &root_inode, 0, 0, S_IFDIR|0755, 0, NULL); root_inode.bi_inum = inum; + root_inode.bi_snapshot = snapshot; - ret = __bch2_fsck_write_inode(trans, &root_inode, snapshot); + ret = __bch2_fsck_write_inode(trans, &root_inode); bch_err_msg(c, ret, "writing root inode"); } err: @@ -2566,7 +2565,7 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, inode_k), buf.buf))) - ret = reattach_inode(trans, &inode, snapshot); + ret = reattach_inode(trans, &inode); goto out; } @@ -2612,7 +2611,7 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino if (ret) break; - ret = reattach_inode(trans, &inode, snapshot); + ret = reattach_inode(trans, &inode); bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum); } break; @@ -2842,7 +2841,7 @@ static int check_nlinks_update_inode(struct btree_trans *trans, struct btree_ite u.bi_inum, bch2_d_types[mode_to_type(u.bi_mode)], bch2_inode_nlink_get(&u), link->count)) { bch2_inode_nlink_set(&u, link->count); - ret = __bch2_fsck_write_inode(trans, &u, k.k->p.snapshot); + ret = __bch2_fsck_write_inode(trans, &u); } fsck_err: return ret; diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c index 753c208896c3..19aa31c6812f 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -387,9 +387,7 @@ int bch2_inode_write_flags(struct btree_trans *trans, return bch2_trans_update(trans, iter, &inode_p->inode.k_i, flags); } -int __bch2_fsck_write_inode(struct btree_trans *trans, - struct bch_inode_unpacked *inode, - u32 snapshot) +int __bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode) { struct bkey_inode_buf *inode_p = bch2_trans_kmalloc(trans, sizeof(*inode_p)); @@ -398,19 +396,17 @@ int __bch2_fsck_write_inode(struct btree_trans *trans, return PTR_ERR(inode_p); bch2_inode_pack(inode_p, inode); - inode_p->inode.k.p.snapshot = snapshot; + inode_p->inode.k.p.snapshot = inode->bi_snapshot; return bch2_btree_insert_nonextent(trans, BTREE_ID_inodes, &inode_p->inode.k_i, BTREE_UPDATE_internal_snapshot_node); } -int bch2_fsck_write_inode(struct btree_trans *trans, - struct bch_inode_unpacked *inode, - u32 snapshot) +int bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode) { int ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, - __bch2_fsck_write_inode(trans, inode, snapshot)); + __bch2_fsck_write_inode(trans, inode)); bch_err_fn(trans->c, ret); return ret; } diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h index 695abd707cb6..f597d10a252d 100644 --- a/fs/bcachefs/inode.h +++ b/fs/bcachefs/inode.h @@ -112,8 +112,8 @@ static inline int bch2_inode_write(struct btree_trans *trans, return bch2_inode_write_flags(trans, iter, inode, 0); } -int __bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *, u32); -int bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *, u32); +int __bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *); +int bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *); void bch2_inode_init_early(struct bch_fs *, struct bch_inode_unpacked *); diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c index 6845dde1b339..44210a86c367 100644 --- a/fs/bcachefs/subvolume.c +++ b/fs/bcachefs/subvolume.c @@ -102,7 +102,8 @@ static int check_subvol(struct btree_trans *trans, inode.bi_inum, inode.bi_snapshot, inode.bi_subvol, subvol.k->p.offset)) { inode.bi_subvol = subvol.k->p.offset; - ret = __bch2_fsck_write_inode(trans, &inode, le32_to_cpu(subvol.v->snapshot)); + inode.bi_snapshot = le32_to_cpu(subvol.v->snapshot); + ret = __bch2_fsck_write_inode(trans, &inode); if (ret) goto err; } -- GitLab From 1f73cb4d34e787b3671f1e9d527eb8cf72c05283 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Tue, 24 Sep 2024 05:33:07 -0400 Subject: [PATCH 726/970] bcachefs: Add warn param to subvol_get_snapshot, peek_inode These shouldn't always be fatal errors - logged op resume, in particular, and we want it as a parameter there. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/inode.c | 32 +++++++++++--------------------- fs/bcachefs/inode.h | 24 ++++++++++++++++++++---- fs/bcachefs/subvolume.c | 13 ++++++++++--- fs/bcachefs/subvolume.h | 2 ++ 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c index 19aa31c6812f..74d7a42ba1a2 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -327,22 +327,20 @@ int bch2_inode_unpack(struct bkey_s_c k, : bch2_inode_unpack_slowpath(k, unpacked); } -int bch2_inode_peek_nowarn(struct btree_trans *trans, - struct btree_iter *iter, - struct bch_inode_unpacked *inode, - subvol_inum inum, unsigned flags) +int __bch2_inode_peek(struct btree_trans *trans, + struct btree_iter *iter, + struct bch_inode_unpacked *inode, + subvol_inum inum, unsigned flags, + bool warn) { - struct bkey_s_c k; u32 snapshot; - int ret; - - ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot); + int ret = __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot, warn); if (ret) return ret; - k = bch2_bkey_get_iter(trans, iter, BTREE_ID_inodes, - SPOS(0, inum.inum, snapshot), - flags|BTREE_ITER_cached); + struct bkey_s_c k = bch2_bkey_get_iter(trans, iter, BTREE_ID_inodes, + SPOS(0, inum.inum, snapshot), + flags|BTREE_ITER_cached); ret = bkey_err(k); if (ret) return ret; @@ -357,20 +355,12 @@ int bch2_inode_peek_nowarn(struct btree_trans *trans, return 0; err: + if (warn) + bch_err_msg(trans->c, ret, "looking up inum %llu:%llu:", inum.subvol, inum.inum); bch2_trans_iter_exit(trans, iter); return ret; } -int bch2_inode_peek(struct btree_trans *trans, - struct btree_iter *iter, - struct bch_inode_unpacked *inode, - subvol_inum inum, unsigned flags) -{ - int ret = bch2_inode_peek_nowarn(trans, iter, inode, inum, flags); - bch_err_msg(trans->c, ret, "looking up inum %llu:%llu:", inum.subvol, inum.inum); - return ret; -} - int bch2_inode_write_flags(struct btree_trans *trans, struct btree_iter *iter, struct bch_inode_unpacked *inode, diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h index f597d10a252d..9c1f67705684 100644 --- a/fs/bcachefs/inode.h +++ b/fs/bcachefs/inode.h @@ -97,10 +97,26 @@ struct bkey_i *bch2_inode_to_v3(struct btree_trans *, struct bkey_i *); void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *); -int bch2_inode_peek_nowarn(struct btree_trans *, struct btree_iter *, - struct bch_inode_unpacked *, subvol_inum, unsigned); -int bch2_inode_peek(struct btree_trans *, struct btree_iter *, - struct bch_inode_unpacked *, subvol_inum, unsigned); +int __bch2_inode_peek(struct btree_trans *, struct btree_iter *, + struct bch_inode_unpacked *, subvol_inum, unsigned, bool); + +static inline int bch2_inode_peek_nowarn(struct btree_trans *trans, + struct btree_iter *iter, + struct bch_inode_unpacked *inode, + subvol_inum inum, unsigned flags) +{ + return __bch2_inode_peek(trans, iter, inode, inum, flags, false); +} + +static inline int bch2_inode_peek(struct btree_trans *trans, + struct btree_iter *iter, + struct bch_inode_unpacked *inode, + subvol_inum inum, unsigned flags) +{ + return __bch2_inode_peek(trans, iter, inode, inum, flags, true); + int ret = bch2_inode_peek_nowarn(trans, iter, inode, inum, flags); + return ret; +} int bch2_inode_write_flags(struct btree_trans *, struct btree_iter *, struct bch_inode_unpacked *, enum btree_iter_update_trigger_flags); diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c index 44210a86c367..91d8187ee168 100644 --- a/fs/bcachefs/subvolume.c +++ b/fs/bcachefs/subvolume.c @@ -332,8 +332,8 @@ int bch2_snapshot_get_subvol(struct btree_trans *trans, u32 snapshot, bch2_subvolume_get(trans, le32_to_cpu(snap.subvol), true, 0, subvol); } -int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid, - u32 *snapid) +int __bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid, + u32 *snapid, bool warn) { struct btree_iter iter; struct bkey_s_c_subvolume subvol; @@ -344,7 +344,8 @@ int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid, BTREE_ITER_cached|BTREE_ITER_with_updates, subvolume); ret = bkey_err(subvol); - bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), trans->c, + + bch2_fs_inconsistent_on(warn && bch2_err_matches(ret, ENOENT), trans->c, "missing subvolume %u", subvolid); if (likely(!ret)) @@ -353,6 +354,12 @@ int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid, return ret; } +int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid, + u32 *snapid) +{ + return __bch2_subvolume_get_snapshot(trans, subvolid, snapid, true); +} + static int bch2_subvolume_reparent(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k, diff --git a/fs/bcachefs/subvolume.h b/fs/bcachefs/subvolume.h index e62f876541fe..f897d106e142 100644 --- a/fs/bcachefs/subvolume.h +++ b/fs/bcachefs/subvolume.h @@ -26,6 +26,8 @@ int bch2_subvolume_trigger(struct btree_trans *, enum btree_id, unsigned, int bch2_subvol_has_children(struct btree_trans *, u32); int bch2_subvolume_get(struct btree_trans *, unsigned, bool, int, struct bch_subvolume *); +int __bch2_subvolume_get_snapshot(struct btree_trans *, u32, + u32 *, bool); int bch2_subvolume_get_snapshot(struct btree_trans *, u32, u32 *); int bch2_subvol_is_ro_trans(struct btree_trans *, u32); -- GitLab From 0f25eb4b60771f08fbcca878a8f7f88086d0c885 Mon Sep 17 00:00:00 2001 From: Kent Overstreet <kent.overstreet@linux.dev> Date: Mon, 23 Sep 2024 22:06:58 -0400 Subject: [PATCH 727/970] bcachefs: Rework logged op error handling Initially it was thought that we just wanted to ignore errors from logged op replay, but it turns out we do need to catch -EROFS, or we'll go into an infinite loop. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev> --- fs/bcachefs/io_misc.c | 63 +++++++++++++++++++++++++++------------- fs/bcachefs/logged_ops.c | 16 +++++----- fs/bcachefs/logged_ops.h | 2 +- 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/fs/bcachefs/io_misc.c b/fs/bcachefs/io_misc.c index 177ed331c00b..307ed0a45184 100644 --- a/fs/bcachefs/io_misc.c +++ b/fs/bcachefs/io_misc.c @@ -224,13 +224,14 @@ void bch2_logged_op_truncate_to_text(struct printbuf *out, struct bch_fs *c, str static int truncate_set_isize(struct btree_trans *trans, subvol_inum inum, - u64 new_i_size) + u64 new_i_size, + bool warn) { struct btree_iter iter = { NULL }; struct bch_inode_unpacked inode_u; int ret; - ret = bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent) ?: + ret = __bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent, warn) ?: (inode_u.bi_size = new_i_size, 0) ?: bch2_inode_write(trans, &iter, &inode_u); @@ -247,10 +248,11 @@ static int __bch2_resume_logged_op_truncate(struct btree_trans *trans, struct bkey_i_logged_op_truncate *op = bkey_i_to_logged_op_truncate(op_k); subvol_inum inum = { le32_to_cpu(op->v.subvol), le64_to_cpu(op->v.inum) }; u64 new_i_size = le64_to_cpu(op->v.new_i_size); + bool warn_errors = i_sectors_delta != NULL; int ret; ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, - truncate_set_isize(trans, inum, new_i_size)); + truncate_set_isize(trans, inum, new_i_size, i_sectors_delta != NULL)); if (ret) goto err; @@ -263,8 +265,8 @@ static int __bch2_resume_logged_op_truncate(struct btree_trans *trans, if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) ret = 0; err: - bch2_logged_op_finish(trans, op_k); - bch_err_fn(c, ret); + if (warn_errors) + bch_err_fn(c, ret); return ret; } @@ -288,9 +290,14 @@ int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sec * resume only proceeding in one of the snapshots */ down_read(&c->snapshot_create_lock); - int ret = bch2_trans_run(c, - bch2_logged_op_start(trans, &op.k_i) ?: - __bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta)); + struct btree_trans *trans = bch2_trans_get(c); + int ret = bch2_logged_op_start(trans, &op.k_i); + if (ret) + goto out; + ret = __bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta); + ret = bch2_logged_op_finish(trans, &op.k_i) ?: ret; +out: + bch2_trans_put(trans); up_read(&c->snapshot_create_lock); return ret; @@ -308,7 +315,8 @@ void bch2_logged_op_finsert_to_text(struct printbuf *out, struct bch_fs *c, stru prt_printf(out, " src_offset=%llu", le64_to_cpu(op.v->src_offset)); } -static int adjust_i_size(struct btree_trans *trans, subvol_inum inum, u64 offset, s64 len) +static int adjust_i_size(struct btree_trans *trans, subvol_inum inum, + u64 offset, s64 len, bool warn) { struct btree_iter iter; struct bch_inode_unpacked inode_u; @@ -317,7 +325,7 @@ static int adjust_i_size(struct btree_trans *trans, subvol_inum inum, u64 offset offset <<= 9; len <<= 9; - ret = bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent); + ret = __bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent, warn); if (ret) return ret; @@ -357,12 +365,22 @@ static int __bch2_resume_logged_op_finsert(struct btree_trans *trans, u64 len = abs(shift); u64 pos = le64_to_cpu(op->v.pos); bool insert = shift > 0; + u32 snapshot; + bool warn_errors = i_sectors_delta != NULL; int ret = 0; ret = bch2_inum_opts_get(trans, inum, &opts); if (ret) return ret; + /* + * check for missing subvolume before fpunch, as in resume we don't want + * it to be a fatal error + */ + ret = __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot, warn_errors); + if (ret) + return ret; + bch2_trans_iter_init(trans, &iter, BTREE_ID_extents, POS(inum.inum, 0), BTREE_ITER_intent); @@ -373,7 +391,7 @@ case LOGGED_OP_FINSERT_start: if (insert) { ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, - adjust_i_size(trans, inum, src_offset, len) ?: + adjust_i_size(trans, inum, src_offset, len, warn_errors) ?: bch2_logged_op_update(trans, &op->k_i)); if (ret) goto err; @@ -396,11 +414,11 @@ case LOGGED_OP_FINSERT_shift_extents: struct bkey_i delete, *copy; struct bkey_s_c k; struct bpos src_pos = POS(inum.inum, src_offset); - u32 snapshot; bch2_trans_begin(trans); - ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot); + ret = __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot, + warn_errors); if (ret) goto btree_err; @@ -463,12 +481,12 @@ case LOGGED_OP_FINSERT_shift_extents: if (!insert) { ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, - adjust_i_size(trans, inum, src_offset, shift) ?: + adjust_i_size(trans, inum, src_offset, shift, warn_errors) ?: bch2_logged_op_update(trans, &op->k_i)); } else { /* We need an inode update to update bi_journal_seq for fsync: */ ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, - adjust_i_size(trans, inum, 0, 0) ?: + adjust_i_size(trans, inum, 0, 0, warn_errors) ?: bch2_logged_op_update(trans, &op->k_i)); } @@ -477,9 +495,9 @@ case LOGGED_OP_FINSERT_finish: break; } err: - bch_err_fn(c, ret); - bch2_logged_op_finish(trans, op_k); bch2_trans_iter_exit(trans, &iter); + if (warn_errors) + bch_err_fn(c, ret); return ret; } @@ -508,9 +526,14 @@ int bch2_fcollapse_finsert(struct bch_fs *c, subvol_inum inum, * resume only proceeding in one of the snapshots */ down_read(&c->snapshot_create_lock); - int ret = bch2_trans_run(c, - bch2_logged_op_start(trans, &op.k_i) ?: - __bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta)); + struct btree_trans *trans = bch2_trans_get(c); + int ret = bch2_logged_op_start(trans, &op.k_i); + if (ret) + goto out; + ret = __bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta); + ret = bch2_logged_op_finish(trans, &op.k_i) ?: ret; +out: + bch2_trans_put(trans); up_read(&c->snapshot_create_lock); return ret; diff --git a/fs/bcachefs/logged_ops.c b/fs/bcachefs/logged_ops.c index 6f4a4e1083c9..60e00702d1a4 100644 --- a/fs/bcachefs/logged_ops.c +++ b/fs/bcachefs/logged_ops.c @@ -34,8 +34,6 @@ static int resume_logged_op(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k) { struct bch_fs *c = trans->c; - const struct bch_logged_op_fn *fn = logged_op_fn(k.k->type); - struct bkey_buf sk; u32 restart_count = trans->restart_count; struct printbuf buf = PRINTBUF; int ret = 0; @@ -46,13 +44,15 @@ static int resume_logged_op(struct btree_trans *trans, struct btree_iter *iter, (bch2_bkey_val_to_text(&buf, c, k), buf.buf)); - if (!fn) - return 0; - + struct bkey_buf sk; bch2_bkey_buf_init(&sk); bch2_bkey_buf_reassemble(&sk, c, k); - fn->resume(trans, sk.k); + const struct bch_logged_op_fn *fn = logged_op_fn(sk.k->k.type); + if (fn) + fn->resume(trans, sk.k); + + ret = bch2_logged_op_finish(trans, sk.k); bch2_bkey_buf_exit(&sk, c); fsck_err: @@ -93,7 +93,7 @@ int bch2_logged_op_start(struct btree_trans *trans, struct bkey_i *k) __bch2_logged_op_start(trans, k)); } -void bch2_logged_op_finish(struct btree_trans *trans, struct bkey_i *k) +int bch2_logged_op_finish(struct btree_trans *trans, struct bkey_i *k) { int ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, bch2_btree_delete(trans, BTREE_ID_logged_ops, k->k.p, 0)); @@ -113,4 +113,6 @@ void bch2_logged_op_finish(struct btree_trans *trans, struct bkey_i *k) buf.buf, bch2_err_str(ret)); printbuf_exit(&buf); } + + return ret; } diff --git a/fs/bcachefs/logged_ops.h b/fs/bcachefs/logged_ops.h index 4d1e786a27a8..30ae9ef737dd 100644 --- a/fs/bcachefs/logged_ops.h +++ b/fs/bcachefs/logged_ops.h @@ -15,6 +15,6 @@ static inline int bch2_logged_op_update(struct btree_trans *trans, struct bkey_i int bch2_resume_logged_ops(struct bch_fs *); int bch2_logged_op_start(struct btree_trans *, struct bkey_i *); -void bch2_logged_op_finish(struct btree_trans *, struct bkey_i *); +int bch2_logged_op_finish(struct btree_trans *, struct bkey_i *); #endif /* _BCACHEFS_LOGGED_OPS_H */ -- GitLab From 7d59ac07ccb58f8f604f8057db63b8efcebeb3de Mon Sep 17 00:00:00 2001 From: Zach Wade <zachwade.k@gmail.com> Date: Mon, 23 Sep 2024 22:45:08 +0800 Subject: [PATCH 728/970] platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug Attaching SST PCI device to VM causes "BUG: KASAN: slab-out-of-bounds". kasan report: [ 19.411889] ================================================================== [ 19.413702] BUG: KASAN: slab-out-of-bounds in _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.415634] Read of size 8 at addr ffff888829e65200 by task cpuhp/16/113 [ 19.417368] [ 19.418627] CPU: 16 PID: 113 Comm: cpuhp/16 Tainted: G E 6.9.0 #10 [ 19.420435] Hardware name: VMware, Inc. VMware20,1/440BX Desktop Reference Platform, BIOS VMW201.00V.20192059.B64.2207280713 07/28/2022 [ 19.422687] Call Trace: [ 19.424091] <TASK> [ 19.425448] dump_stack_lvl+0x5d/0x80 [ 19.426963] ? _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.428694] print_report+0x19d/0x52e [ 19.430206] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 19.431837] ? _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.433539] kasan_report+0xf0/0x170 [ 19.435019] ? _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.436709] _isst_if_get_pci_dev+0x3d5/0x400 [isst_if_common] [ 19.438379] ? __pfx_sched_clock_cpu+0x10/0x10 [ 19.439910] isst_if_cpu_online+0x406/0x58f [isst_if_common] [ 19.441573] ? __pfx_isst_if_cpu_online+0x10/0x10 [isst_if_common] [ 19.443263] ? ttwu_queue_wakelist+0x2c1/0x360 [ 19.444797] cpuhp_invoke_callback+0x221/0xec0 [ 19.446337] cpuhp_thread_fun+0x21b/0x610 [ 19.447814] ? __pfx_cpuhp_thread_fun+0x10/0x10 [ 19.449354] smpboot_thread_fn+0x2e7/0x6e0 [ 19.450859] ? __pfx_smpboot_thread_fn+0x10/0x10 [ 19.452405] kthread+0x29c/0x350 [ 19.453817] ? __pfx_kthread+0x10/0x10 [ 19.455253] ret_from_fork+0x31/0x70 [ 19.456685] ? __pfx_kthread+0x10/0x10 [ 19.458114] ret_from_fork_asm+0x1a/0x30 [ 19.459573] </TASK> [ 19.460853] [ 19.462055] Allocated by task 1198: [ 19.463410] kasan_save_stack+0x30/0x50 [ 19.464788] kasan_save_track+0x14/0x30 [ 19.466139] __kasan_kmalloc+0xaa/0xb0 [ 19.467465] __kmalloc+0x1cd/0x470 [ 19.468748] isst_if_cdev_register+0x1da/0x350 [isst_if_common] [ 19.470233] isst_if_mbox_init+0x108/0xff0 [isst_if_mbox_msr] [ 19.471670] do_one_initcall+0xa4/0x380 [ 19.472903] do_init_module+0x238/0x760 [ 19.474105] load_module+0x5239/0x6f00 [ 19.475285] init_module_from_file+0xd1/0x130 [ 19.476506] idempotent_init_module+0x23b/0x650 [ 19.477725] __x64_sys_finit_module+0xbe/0x130 [ 19.476506] idempotent_init_module+0x23b/0x650 [ 19.477725] __x64_sys_finit_module+0xbe/0x130 [ 19.478920] do_syscall_64+0x82/0x160 [ 19.480036] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 19.481292] [ 19.482205] The buggy address belongs to the object at ffff888829e65000 which belongs to the cache kmalloc-512 of size 512 [ 19.484818] The buggy address is located 0 bytes to the right of allocated 512-byte region [ffff888829e65000, ffff888829e65200) [ 19.487447] [ 19.488328] The buggy address belongs to the physical page: [ 19.489569] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888829e60c00 pfn:0x829e60 [ 19.491140] head: order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 19.492466] anon flags: 0x57ffffc0000840(slab|head|node=1|zone=2|lastcpupid=0x1fffff) [ 19.493914] page_type: 0xffffffff() [ 19.494988] raw: 0057ffffc0000840 ffff88810004cc80 0000000000000000 0000000000000001 [ 19.496451] raw: ffff888829e60c00 0000000080200018 00000001ffffffff 0000000000000000 [ 19.497906] head: 0057ffffc0000840 ffff88810004cc80 0000000000000000 0000000000000001 [ 19.499379] head: ffff888829e60c00 0000000080200018 00000001ffffffff 0000000000000000 [ 19.500844] head: 0057ffffc0000003 ffffea0020a79801 ffffea0020a79848 00000000ffffffff [ 19.502316] head: 0000000800000000 0000000000000000 00000000ffffffff 0000000000000000 [ 19.503784] page dumped because: kasan: bad access detected [ 19.505058] [ 19.505970] Memory state around the buggy address: [ 19.507172] ffff888829e65100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 19.508599] ffff888829e65180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 19.510013] >ffff888829e65200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 19.510014] ^ [ 19.510016] ffff888829e65280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 19.510018] ffff888829e65300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 19.515367] ================================================================== The reason for this error is physical_package_ids assigned by VMware VMM are not continuous and have gaps. This will cause value returned by topology_physical_package_id() to be more than topology_max_packages(). Here the allocation uses topology_max_packages(). The call to topology_max_packages() returns maximum logical package ID not physical ID. Hence use topology_logical_package_id() instead of topology_physical_package_id(). Fixes: 9a1aac8a96dc ("platform/x86: ISST: PUNIT device mapping with Sub-NUMA clustering") Cc: stable@vger.kernel.org Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Zach Wade <zachwade.k@gmail.com> Link: https://lore.kernel.org/r/20240923144508.1764-1-zachwade.k@gmail.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/platform/x86/intel/speed_select_if/isst_if_common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c index 9ad35fefea47..49be22c0313a 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c @@ -316,7 +316,9 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn cpu >= nr_cpu_ids || cpu >= num_possible_cpus()) return NULL; - pkg_id = topology_physical_package_id(cpu); + pkg_id = topology_logical_package_id(cpu); + if (pkg_id >= topology_max_packages()) + return NULL; bus_number = isst_cpu_info[cpu].bus_info[bus_no]; if (bus_number < 0) -- GitLab From ea4290d77bda2bd1f173a86f07aa79b568e0a6f8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Tue, 1 Oct 2024 10:15:01 -0400 Subject: [PATCH 729/970] KVM: x86: leave kvm.ko out of the build if no vendor module is requested kvm.ko is nothing but library code shared by kvm-intel.ko and kvm-amd.ko. It provides no functionality on its own and it is unnecessary unless one of the vendor-specific module is compiled. In particular, /dev/kvm is not created until one of kvm-intel.ko or kvm-amd.ko is loaded. Use CONFIG_KVM to decide if it is built-in or a module, but use the vendor-specific modules for the actual decision on whether to build it. This also fixes a build failure when CONFIG_KVM_INTEL and CONFIG_KVM_AMD are both disabled. The cpu_emergency_register_virt_callback() function is called from kvm.ko, but it is only defined if at least one of CONFIG_KVM_INTEL and CONFIG_KVM_AMD is provided. Fixes: 590b09b1d88e ("KVM: x86: Register "emergency disable" callbacks when virt is enabled") Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- arch/x86/kvm/Kconfig | 9 ++++++--- arch/x86/kvm/Makefile | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 730c2f34d347..f09f13c01c6b 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -17,8 +17,8 @@ menuconfig VIRTUALIZATION if VIRTUALIZATION -config KVM - tristate "Kernel-based Virtual Machine (KVM) support" +config KVM_X86 + def_tristate KVM if KVM_INTEL || KVM_AMD depends on X86_LOCAL_APIC select KVM_COMMON select KVM_GENERIC_MMU_NOTIFIER @@ -44,7 +44,11 @@ config KVM select HAVE_KVM_PM_NOTIFIER if PM select KVM_GENERIC_HARDWARE_ENABLING select KVM_GENERIC_PRE_FAULT_MEMORY + select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM select KVM_WERROR if WERROR + +config KVM + tristate "Kernel-based Virtual Machine (KVM) support" help Support hosting fully virtualized guest machines using hardware virtualization extensions. You will need a fairly recent @@ -77,7 +81,6 @@ config KVM_SW_PROTECTED_VM bool "Enable support for KVM software-protected VMs" depends on EXPERT depends on KVM && X86_64 - select KVM_GENERIC_PRIVATE_MEM help Enable support for KVM software-protected VMs. Currently, software- protected VMs are purely a development and testing vehicle for diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 5494669a055a..f9dddb8cb466 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -32,7 +32,7 @@ kvm-intel-y += vmx/vmx_onhyperv.o vmx/hyperv_evmcs.o kvm-amd-y += svm/svm_onhyperv.o endif -obj-$(CONFIG_KVM) += kvm.o +obj-$(CONFIG_KVM_X86) += kvm.o obj-$(CONFIG_KVM_INTEL) += kvm-intel.o obj-$(CONFIG_KVM_AMD) += kvm-amd.o -- GitLab From 2a5fe5a01668e831af1de3951718fbf88b9a9b9c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonzini@redhat.com> Date: Tue, 1 Oct 2024 10:34:58 -0400 Subject: [PATCH 730/970] x86/reboot: emergency callbacks are now registered by common KVM code Guard them with CONFIG_KVM_X86_COMMON rather than the two vendor modules. In practice this has no functional change, because CONFIG_KVM_X86_COMMON is set if and only if at least one vendor-specific module is being built. However, it is cleaner to specify CONFIG_KVM_X86_COMMON for functions that are used in kvm.ko. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Fixes: 590b09b1d88e ("KVM: x86: Register "emergency disable" callbacks when virt is enabled") Fixes: 6d55a94222db ("x86/reboot: Unconditionally define cpu_emergency_virt_cb typedef") Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- arch/x86/include/asm/reboot.h | 4 ++-- arch/x86/kernel/reboot.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index d0ef2a678d66..2d8525a51478 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -26,13 +26,13 @@ void __noreturn machine_real_restart(unsigned int type); #define MRR_APM 1 typedef void (cpu_emergency_virt_cb)(void); -#if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) +#if IS_ENABLED(CONFIG_KVM_X86) void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); void cpu_emergency_disable_virtualization(void); #else static inline void cpu_emergency_disable_virtualization(void) {} -#endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ +#endif /* CONFIG_KVM_X86 */ typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); void nmi_shootdown_cpus(nmi_shootdown_cb callback); diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 0e0a4cf6b5eb..615922838c51 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -530,7 +530,7 @@ static inline void kb_wait(void) static inline void nmi_shootdown_cpus_on_restart(void); -#if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) +#if IS_ENABLED(CONFIG_KVM_X86) /* RCU-protected callback to disable virtualization prior to reboot. */ static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; @@ -600,7 +600,7 @@ static void emergency_reboot_disable_virtualization(void) } #else static void emergency_reboot_disable_virtualization(void) { } -#endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ +#endif /* CONFIG_KVM_X86 */ void __attribute__((weak)) mach_reboot_fixups(void) { -- GitLab From ed0e64d85fe79db0472531e6bf43d8fe2524c75c Mon Sep 17 00:00:00 2001 From: Jithu Joseph <jithu.joseph@intel.com> Date: Tue, 1 Oct 2024 10:08:08 -0700 Subject: [PATCH 731/970] MAINTAINERS: Update Intel In Field Scan(IFS) entry Ashok is no longer with Intel and his e-mail address will start bouncing soon. Update his email address to the new one he provided to ensure correct contact details in the MAINTAINERS file. Signed-off-by: Jithu Joseph <jithu.joseph@intel.com> Link: https://lore.kernel.org/r/20241001170808.203970-1-jithu.joseph@intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c27f3190737f..89fb731384ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11496,7 +11496,7 @@ F: include/uapi/linux/idxd.h INTEL IN FIELD SCAN (IFS) DEVICE M: Jithu Joseph <jithu.joseph@intel.com> -R: Ashok Raj <ashok.raj@intel.com> +R: Ashok Raj <ashok.raj.linux@gmail.com> R: Tony Luck <tony.luck@intel.com> S: Maintained F: drivers/platform/x86/intel/ifs -- GitLab From b6c57b70a343da512e0fdcae9a097b3aa506b9bb Mon Sep 17 00:00:00 2001 From: Armin Wolf <W_Armin@gmx.de> Date: Tue, 1 Oct 2024 23:28:35 +0200 Subject: [PATCH 732/970] platform/x86: dell-laptop: Do not fail when encountering unsupported batteries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the battery hook encounters a unsupported battery, it will return an error. This in turn will cause the battery driver to automatically unregister the battery hook. On machines with multiple batteries however, this will prevent the battery hook from handling the primary battery, since it will always get unregistered upon encountering one of the unsupported batteries. Fix this by simply ignoring unsupported batteries. Reviewed-by: Pali Rohár <pali@kernel.org> Fixes: ab58016c68cc ("platform/x86:dell-laptop: Add knobs to change battery charge settings") Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://lore.kernel.org/r/20241001212835.341788-4-W_Armin@gmx.de Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/platform/x86/dell/dell-laptop.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/dell/dell-laptop.c b/drivers/platform/x86/dell/dell-laptop.c index a3cd0505f282..5671bd0deee7 100644 --- a/drivers/platform/x86/dell/dell-laptop.c +++ b/drivers/platform/x86/dell/dell-laptop.c @@ -2391,12 +2391,18 @@ static struct attribute *dell_battery_attrs[] = { }; ATTRIBUTE_GROUPS(dell_battery); +static bool dell_battery_supported(struct power_supply *battery) +{ + /* We currently only support the primary battery */ + return strcmp(battery->desc->name, "BAT0") == 0; +} + static int dell_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) { - /* this currently only supports the primary battery */ - if (strcmp(battery->desc->name, "BAT0") != 0) - return -ENODEV; + /* Return 0 instead of an error to avoid being unloaded */ + if (!dell_battery_supported(battery)) + return 0; return device_add_groups(&battery->dev, dell_battery_groups); } @@ -2404,6 +2410,9 @@ static int dell_battery_add(struct power_supply *battery, static int dell_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) { + if (!dell_battery_supported(battery)) + return 0; + device_remove_groups(&battery->dev, dell_battery_groups); return 0; } -- GitLab From 0bdb4e57a1b0622685e6973321d7c417fb386b42 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Thu, 3 Oct 2024 22:26:13 +0200 Subject: [PATCH 733/970] platform/x86:intel/pmc: Disable ACPI PM Timer disabling on Sky and Kaby Lake There have been multiple reports that the ACPI PM Timer disabling is causing Sky and Kaby Lake systems to hang on all suspend (s2idle, s3, hibernate) methods. Remove the acpi_pm_tmr_ctl_offset and acpi_pm_tmr_disable_bit settings from spt_reg_map to disable the ACPI PM Timer disabling on Sky and Kaby Lake to fix the hang on suspend. Fixes: e86c8186d03a ("platform/x86:intel/pmc: Enable the ACPI PM Timer to be turned off when suspended") Reported-by: Paul Menzel <pmenzel@molgen.mpg.de> Closes: https://lore.kernel.org/linux-pm/18784f62-91ff-4d88-9621-6c88eb0af2b5@molgen.mpg.de/ Reported-by: Todd Brandt <todd.e.brandt@intel.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219346 Cc: Marek Maslanka <mmaslanka@google.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Tested-by: Todd Brandt <todd.e.brandt@intel.com> Tested-by: Paul Menzel <pmenzel@molgen.mpg.de> # Dell XPS 13 9360/0596KF Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20241003202614.17181-2-hdegoede@redhat.com --- drivers/platform/x86/intel/pmc/spt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/spt.c b/drivers/platform/x86/intel/pmc/spt.c index 2cd2b3c68e46..ab993a69e33e 100644 --- a/drivers/platform/x86/intel/pmc/spt.c +++ b/drivers/platform/x86/intel/pmc/spt.c @@ -130,8 +130,6 @@ const struct pmc_reg_map spt_reg_map = { .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, - .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, - .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, }; -- GitLab From 2f95a035b8fdd3bba58228212a01bb114f541b03 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Date: Thu, 3 Oct 2024 14:55:53 -0700 Subject: [PATCH 734/970] platform/x86: ISST: Add Diamond Rapids to support list Add Diamond Rapids (INTEL_PANTHERCOVE_X) to SST support list by adding to isst_cpu_ids. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Link: https://lore.kernel.org/r/20241003215554.3013807-2-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/platform/x86/intel/speed_select_if/isst_if_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c index 49be22c0313a..1e46e30dae96 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c @@ -809,6 +809,7 @@ static const struct x86_cpu_id isst_cpu_ids[] = { X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, SST_HPM_SUPPORTED), X86_MATCH_VFM(INTEL_ICELAKE_D, 0), X86_MATCH_VFM(INTEL_ICELAKE_X, 0), + X86_MATCH_VFM(INTEL_PANTHERCOVE_X, SST_HPM_SUPPORTED), X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0), X86_MATCH_VFM(INTEL_SKYLAKE_X, SST_MBOX_SUPPORTED), {} -- GitLab From e16f7eee7c80f9ec7084e06efbe2398586dbf38e Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Date: Thu, 3 Oct 2024 14:55:54 -0700 Subject: [PATCH 735/970] platform/x86/intel: power-domains: Add Diamond Rapids support Add Diamond Rapids (INTEL_PANTHERCOVE_X) to tpmi_cpu_ids to support domaid id mappings. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Link: https://lore.kernel.org/r/20241003215554.3013807-3-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/platform/x86/intel/tpmi_power_domains.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel/tpmi_power_domains.c b/drivers/platform/x86/intel/tpmi_power_domains.c index 4eb02553957c..0609a8320f7e 100644 --- a/drivers/platform/x86/intel/tpmi_power_domains.c +++ b/drivers/platform/x86/intel/tpmi_power_domains.c @@ -82,6 +82,7 @@ static const struct x86_cpu_id tpmi_cpu_ids[] = { X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, NULL), X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, NULL), X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, NULL), + X86_MATCH_VFM(INTEL_PANTHERCOVE_X, NULL), {} }; MODULE_DEVICE_TABLE(x86cpu, tpmi_cpu_ids); -- GitLab From a561509b4187a8908eb7fbb2d1bf35bbc20ec74b Mon Sep 17 00:00:00 2001 From: Crag Wang <crag_wang@dell.com> Date: Fri, 4 Oct 2024 23:27:58 +0800 Subject: [PATCH 736/970] platform/x86: dell-sysman: add support for alienware products Alienware supports firmware-attributes and has its own OEM string. Signed-off-by: Crag Wang <crag_wang@dell.com> Link: https://lore.kernel.org/r/20241004152826.93992-1-crag_wang@dell.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/platform/x86/dell/dell-wmi-sysman/sysman.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c index 9def7983d7d6..40ddc6eb7562 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -521,6 +521,7 @@ static int __init sysman_init(void) int ret = 0; if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) && + !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Alienware", NULL) && !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) { pr_err("Unable to run on non-Dell system\n"); return -ENODEV; -- GitLab From 7b954b9ba007d03ba26135ac49b2c93208cf090e Mon Sep 17 00:00:00 2001 From: Anaswara T Rajan <anaswaratrajan@gmail.com> Date: Sat, 5 Oct 2024 12:30:56 +0530 Subject: [PATCH 737/970] platform/x86: dell-ddv: Fix typo in documentation Fix typo in word 'diagnostics' in documentation. Signed-off-by: Anaswara T Rajan <anaswaratrajan@gmail.com> Reviewed-by: Armin Wolf <W_Armin@gmx.de> Link: https://lore.kernel.org/r/20241005070056.16326-1-anaswaratrajan@gmail.com Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- Documentation/wmi/devices/dell-wmi-ddv.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/wmi/devices/dell-wmi-ddv.rst b/Documentation/wmi/devices/dell-wmi-ddv.rst index 2fcdfcf03327..e0c20af30948 100644 --- a/Documentation/wmi/devices/dell-wmi-ddv.rst +++ b/Documentation/wmi/devices/dell-wmi-ddv.rst @@ -8,7 +8,7 @@ Introduction ============ Many Dell notebooks made after ~2020 support a WMI-based interface for -retrieving various system data like battery temperature, ePPID, diagostic data +retrieving various system data like battery temperature, ePPID, diagnostic data and fan/thermal sensor data. This interface is likely used by the `Dell Data Vault` software on Windows, @@ -277,7 +277,7 @@ Reverse-Engineering the DDV WMI interface 4. Try to deduce the meaning of a certain WMI method by comparing the control flow with other ACPI methods (_BIX or _BIF for battery related methods for example). -5. Use the built-in UEFI diagostics to view sensor types/values for fan/thermal +5. Use the built-in UEFI diagnostics to view sensor types/values for fan/thermal related methods (sometimes overwriting static ACPI data fields can be used to test different sensor type values, since on some machines this data is not reinitialized upon a warm reset). -- GitLab From 5984b40f5bcd41bfd08359cdb9c8cb7ca9d3cc60 Mon Sep 17 00:00:00 2001 From: Armin Wolf <W_Armin@gmx.de> Date: Sat, 5 Oct 2024 23:38:24 +0200 Subject: [PATCH 738/970] platform/x86: wmi: Update WMI driver API documentation The WMI driver core now passes the WMI event data to legacy notify handlers, so WMI devices sharing notification IDs are now being handled properly. Fixes: e04e2b760ddb ("platform/x86: wmi: Pass event data directly to legacy notify handlers") Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://lore.kernel.org/r/20241005213825.701887-1-W_Armin@gmx.de Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- Documentation/driver-api/wmi.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Documentation/driver-api/wmi.rst b/Documentation/driver-api/wmi.rst index 6ca58c8249e5..4e8dbdb1fc67 100644 --- a/Documentation/driver-api/wmi.rst +++ b/Documentation/driver-api/wmi.rst @@ -7,12 +7,11 @@ WMI Driver API The WMI driver core supports a more modern bus-based interface for interacting with WMI devices, and an older GUID-based interface. The latter interface is considered to be deprecated, so new WMI drivers should generally avoid it since -it has some issues with multiple WMI devices and events sharing the same GUIDs -and/or notification IDs. The modern bus-based interface instead maps each -WMI device to a :c:type:`struct wmi_device <wmi_device>`, so it supports -WMI devices sharing GUIDs and/or notification IDs. Drivers can then register -a :c:type:`struct wmi_driver <wmi_driver>`, which will be bound to compatible -WMI devices by the driver core. +it has some issues with multiple WMI devices sharing the same GUID. +The modern bus-based interface instead maps each WMI device to a +:c:type:`struct wmi_device <wmi_device>`, so it supports WMI devices sharing the +same GUID. Drivers can then register a :c:type:`struct wmi_driver <wmi_driver>` +which will be bound to compatible WMI devices by the driver core. .. kernel-doc:: include/linux/wmi.h :internal: -- GitLab From 2fae3129c0c08e72b1fe93e61fd8fd203252094a Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Sat, 5 Oct 2024 15:05:45 +0200 Subject: [PATCH 739/970] platform/x86: x86-android-tablets: Fix use after free on platform_device_register() errors x86_android_tablet_remove() frees the pdevs[] array, so it should not be used after calling x86_android_tablet_remove(). When platform_device_register() fails, store the pdevs[x] PTR_ERR() value into the local ret variable before calling x86_android_tablet_remove() to avoid using pdevs[] after it has been freed. Fixes: 5eba0141206e ("platform/x86: x86-android-tablets: Add support for instantiating platform-devs") Fixes: e2200d3f26da ("platform/x86: x86-android-tablets: Add gpio_keys support to x86_android_tablet_init()") Cc: stable@vger.kernel.org Reported-by: Aleksandr Burakov <a.burakov@rosalinux.ru> Closes: https://lore.kernel.org/platform-driver-x86/20240917120458.7300-1-a.burakov@rosalinux.ru/ Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20241005130545.64136-1-hdegoede@redhat.com --- drivers/platform/x86/x86-android-tablets/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 1427a9a39008..ef572b90e06b 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -390,8 +390,9 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) for (i = 0; i < pdev_count; i++) { pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); if (IS_ERR(pdevs[i])) { + ret = PTR_ERR(pdevs[i]); x86_android_tablet_remove(pdev); - return PTR_ERR(pdevs[i]); + return ret; } } @@ -443,8 +444,9 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) PLATFORM_DEVID_AUTO, &pdata, sizeof(pdata)); if (IS_ERR(pdevs[pdev_count])) { + ret = PTR_ERR(pdevs[pdev_count]); x86_android_tablet_remove(pdev); - return PTR_ERR(pdevs[pdev_count]); + return ret; } pdev_count++; } -- GitLab From 95336cfd5b2ce81f839614dd897e26cffd5204e0 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Wed, 25 Sep 2024 10:44:45 +0200 Subject: [PATCH 740/970] drm/xe: Add memirq report page address helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both xe_memirq_{source,status}_ptr functions are now strictly for obtaining an address of the memory based interrupt report pages used by the HW engines. When initializing the GuC that does not require special per instance page preparation, we don't need to abuse these public functions and pass a NULL instead of valid hwe pointer. Also, without further fixes, this actually may lead to NPD crash once the hw_reports_to_instance_zero() will be true. Add internal helpers that will provide report page addresses based solely on the instance number, which will be always 0 for both GuCs. Fixes: ef6103d20f97 ("drm/xe: memirq infra changes for MSI-X") Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Piotr Piórkowski <piotr.piorkowski@intel.com> Cc: Ilia Levi <ilia.levi@intel.com> Reviewed-by: Ilia Levi <ilia.levi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925084445.1495-1-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_memirq.c | 35 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c index e3610cb90bb9..f833da88150a 100644 --- a/drivers/gpu/drm/xe/xe_memirq.c +++ b/drivers/gpu/drm/xe/xe_memirq.c @@ -261,6 +261,15 @@ int xe_memirq_init(struct xe_memirq *memirq) return 0; } +static u32 __memirq_source_page(struct xe_memirq *memirq, u16 instance) +{ + memirq_assert(memirq, instance <= XE_HW_ENGINE_MAX_INSTANCE); + memirq_assert(memirq, memirq->bo); + + instance = hw_reports_to_instance_zero(memirq) ? instance : 0; + return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET(instance); +} + /** * xe_memirq_source_ptr - Get GGTT's offset of the `Interrupt Source Report Page`_. * @memirq: the &xe_memirq to query @@ -273,14 +282,18 @@ int xe_memirq_init(struct xe_memirq *memirq) */ u32 xe_memirq_source_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { - u16 instance; - memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); - memirq_assert(memirq, memirq->bo); - instance = hw_reports_to_instance_zero(memirq) ? hwe->instance : 0; + return __memirq_source_page(memirq, hwe->instance); +} - return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_SOURCE_OFFSET(instance); +static u32 __memirq_status_page(struct xe_memirq *memirq, u16 instance) +{ + memirq_assert(memirq, instance <= XE_HW_ENGINE_MAX_INSTANCE); + memirq_assert(memirq, memirq->bo); + + instance = hw_reports_to_instance_zero(memirq) ? instance : 0; + return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET(instance); } /** @@ -295,14 +308,9 @@ u32 xe_memirq_source_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) */ u32 xe_memirq_status_ptr(struct xe_memirq *memirq, struct xe_hw_engine *hwe) { - u16 instance; - memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); - memirq_assert(memirq, memirq->bo); - - instance = hw_reports_to_instance_zero(memirq) ? hwe->instance : 0; - return xe_bo_ggtt_addr(memirq->bo) + XE_MEMIRQ_STATUS_OFFSET(instance); + return __memirq_status_page(memirq, hwe->instance); } /** @@ -343,10 +351,9 @@ int xe_memirq_init_guc(struct xe_memirq *memirq, struct xe_guc *guc) int err; memirq_assert(memirq, xe_device_uses_memirq(memirq_to_xe(memirq))); - memirq_assert(memirq, memirq->bo); - source = xe_memirq_source_ptr(memirq, NULL) + offset; - status = xe_memirq_status_ptr(memirq, NULL) + offset * SZ_16; + source = __memirq_source_page(memirq, 0) + offset; + status = __memirq_status_page(memirq, 0) + offset * SZ_16; err = xe_guc_self_cfg64(guc, GUC_KLV_SELF_CFG_MEMIRQ_SOURCE_ADDR_KEY, source); -- GitLab From c14a30468230c608731f36569bfd9785bb486131 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen <samitolvanen@google.com> Date: Mon, 23 Sep 2024 18:18:47 +0000 Subject: [PATCH 741/970] scripts: import more list macros Import list_is_first, list_is_last, list_replace, and list_replace_init. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/include/list.h | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/scripts/include/list.h b/scripts/include/list.h index fea1e2b79063..8bdcaadca709 100644 --- a/scripts/include/list.h +++ b/scripts/include/list.h @@ -127,6 +127,36 @@ static inline void list_del(struct list_head *entry) entry->prev = LIST_POISON2; } +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +/** + * list_replace_init - replace old entry by new one and initialize the old one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void list_replace_init(struct list_head *old, + struct list_head *new) +{ + list_replace(old, new); + INIT_LIST_HEAD(old); +} + /** * list_move - delete from one list and add as another's head * @list: the entry to move @@ -150,6 +180,26 @@ static inline void list_move_tail(struct list_head *list, list_add_tail(list, head); } +/** + * list_is_first -- tests whether @list is the first entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_first(const struct list_head *list, const struct list_head *head) +{ + return list->prev == head; +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_last(const struct list_head *list, const struct list_head *head) +{ + return list->next == head; +} + /** * list_is_head - tests whether @list is the list @head * @list: the entry to test -- GitLab From d939881a15b13c028257471d8853d12d83686bcc Mon Sep 17 00:00:00 2001 From: Xu Yang <xu.yang_2@nxp.com> Date: Wed, 25 Sep 2024 13:32:30 +0800 Subject: [PATCH 742/970] kbuild: fix a typo dt_binding_schema -> dt_binding_schemas If we follow "make help" to "make dt_binding_schema", we will see below error: $ make dt_binding_schema make[1]: *** No rule to make target 'dt_binding_schema'. Stop. make: *** [Makefile:224: __sub-make] Error 2 It should be a typo. So this will fix it. Fixes: 604a57ba9781 ("dt-bindings: kbuild: Add separate target/dependency for processed-schema.json") Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Reviewed-by: Nicolas Schier <n.schier@avm.de> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 187a4ce2728e..7bb521fae64a 100644 --- a/Makefile +++ b/Makefile @@ -1645,7 +1645,7 @@ help: echo '* dtbs - Build device tree blobs for enabled boards'; \ echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'; \ echo ' dt_binding_check - Validate device tree binding documents and examples'; \ - echo ' dt_binding_schema - Build processed device tree binding schemas'; \ + echo ' dt_binding_schemas - Build processed device tree binding schemas'; \ echo ' dtbs_check - Validate device tree source files';\ echo '') -- GitLab From 82cb44308951ad4ce7a8500b9e025d27d7fb3526 Mon Sep 17 00:00:00 2001 From: Aaron Thompson <dev@aaront.org> Date: Fri, 4 Oct 2024 07:52:45 +0000 Subject: [PATCH 743/970] kbuild: deb-pkg: Remove blank first line from maint scripts The blank line causes execve() to fail: # strace ./postinst execve("./postinst", ...) = -1 ENOEXEC (Exec format error) strace: exec: Exec format error +++ exited with 1 +++ However running the scripts via shell does work (at least with bash) because the shell attempts to execute the file as a shell script when execve() fails. Fixes: b611daae5efc ("kbuild: deb-pkg: split image and debug objects staging out into functions") Signed-off-by: Aaron Thompson <dev@aaront.org> Reviewed-by: Nathan Chancellor <nathan@kernel.org> Reviewed-by: Nicolas Schier <nicolas@fjasle.eu> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- scripts/package/builddeb | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index c1757db6aa8a..404587fc71fe 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -74,7 +74,6 @@ install_linux_image () { mkdir -p "${pdir}/DEBIAN" cat <<-EOF > "${pdir}/DEBIAN/${script}" - #!/bin/sh set -e -- GitLab From 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b Mon Sep 17 00:00:00 2001 From: Linus Torvalds <torvalds@linux-foundation.org> Date: Sun, 6 Oct 2024 15:32:27 -0700 Subject: [PATCH 744/970] Linux 6.12-rc2 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7bb521fae64a..c5493c0c0ca1 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 6 PATCHLEVEL = 12 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Baby Opossum Posse # *DOCUMENTATION* -- GitLab From 43971e30fd8ae24d8c4b6ce1203c1773bde781a4 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 19 Sep 2024 19:15:24 +0200 Subject: [PATCH 745/970] drm/xe/guc: Add yet another helper macro for threshold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already have and use MAKE_GUC_KLV_VF_CFG_THRESHOLD_KEY, but in upcoming patch we want to generate the key for the length. Add MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN for this purpose. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240919171528.1451-2-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_guc_klv_thresholds_set.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_guc_klv_thresholds_set.h b/drivers/gpu/drm/xe/xe_guc_klv_thresholds_set.h index da0fedbbdbaf..da10cf0389cb 100644 --- a/drivers/gpu/drm/xe/xe_guc_klv_thresholds_set.h +++ b/drivers/gpu/drm/xe/xe_guc_klv_thresholds_set.h @@ -17,6 +17,13 @@ #define MAKE_GUC_KLV_VF_CFG_THRESHOLD_KEY(TAG) \ MAKE_GUC_KLV_KEY(CONCATENATE(VF_CFG_THRESHOLD_, TAG)) +/** + * MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN - Prepare the name of the KLV length constant. + * @TAG: unique tag of the GuC threshold KLV key. + */ +#define MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN(TAG) \ + MAKE_GUC_KLV_LEN(CONCATENATE(VF_CFG_THRESHOLD_, TAG)) + /** * xe_guc_klv_threshold_key_to_index - Find index of the tracked GuC threshold. * @key: GuC threshold KLV key. -- GitLab From 99ce45cc25ebfb81328fe520ed5773c2e4929a8d Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 19 Sep 2024 19:15:25 +0200 Subject: [PATCH 746/970] drm/xe/pf: Update success code of pf_validate_vf_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function may return negative error codes on invalid or incomplete VF configuration, but unlike other int functions, it was returning 1 instead of 0 on success, which might be little inconvinient if we would like to use it directly in other functions. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240919171528.1451-3-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c index 8250ef71e685..27a593b1d52a 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c @@ -2042,7 +2042,7 @@ static int pf_validate_vf_config(struct xe_gt *gt, unsigned int vfid) valid_all = valid_all && valid_lmem; } - return valid_all ? 1 : valid_any ? -ENOKEY : -ENODATA; + return valid_all ? 0 : valid_any ? -ENOKEY : -ENODATA; } /** -- GitLab From bdc2c4d5756c8baaca820fec24fcc6355946da61 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 19 Sep 2024 19:15:26 +0200 Subject: [PATCH 747/970] drm/xe/pf: Allow to encode subset of VF configuration KLVs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to reuse format of the GuC KLVs while saving and restoring VF configuration by the PF driver, but some of those KLVs (like doorbell begin index or GGTT starting offset) are not strictly needed to correctly restore VF configuration. Modify functions to omit encoding of some of the KLVs with GuC only details. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240919171528.1451-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 32 +++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c index 27a593b1d52a..28e2b26c2d88 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c @@ -229,14 +229,16 @@ static struct xe_gt_sriov_config *pf_pick_vf_config(struct xe_gt *gt, unsigned i } /* Return: number of configuration dwords written */ -static u32 encode_config_ggtt(u32 *cfg, const struct xe_gt_sriov_config *config) +static u32 encode_config_ggtt(u32 *cfg, const struct xe_gt_sriov_config *config, bool details) { u32 n = 0; if (xe_ggtt_node_allocated(config->ggtt_region)) { - cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_GGTT_START); - cfg[n++] = lower_32_bits(config->ggtt_region->base.start); - cfg[n++] = upper_32_bits(config->ggtt_region->base.start); + if (details) { + cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_GGTT_START); + cfg[n++] = lower_32_bits(config->ggtt_region->base.start); + cfg[n++] = upper_32_bits(config->ggtt_region->base.start); + } cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_GGTT_SIZE); cfg[n++] = lower_32_bits(config->ggtt_region->base.size); @@ -247,20 +249,24 @@ static u32 encode_config_ggtt(u32 *cfg, const struct xe_gt_sriov_config *config) } /* Return: number of configuration dwords written */ -static u32 encode_config(u32 *cfg, const struct xe_gt_sriov_config *config) +static u32 encode_config(u32 *cfg, const struct xe_gt_sriov_config *config, bool details) { u32 n = 0; - n += encode_config_ggtt(cfg, config); + n += encode_config_ggtt(cfg, config, details); - cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_BEGIN_CONTEXT_ID); - cfg[n++] = config->begin_ctx; + if (details) { + cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_BEGIN_CONTEXT_ID); + cfg[n++] = config->begin_ctx; + } cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_NUM_CONTEXTS); cfg[n++] = config->num_ctxs; - cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_BEGIN_DOORBELL_ID); - cfg[n++] = config->begin_db; + if (details) { + cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_BEGIN_DOORBELL_ID); + cfg[n++] = config->begin_db; + } cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_NUM_DOORBELLS); cfg[n++] = config->num_dbs; @@ -301,7 +307,7 @@ static int pf_push_full_vf_config(struct xe_gt *gt, unsigned int vfid) if (!cfg) return -ENOMEM; - num_dwords = encode_config(cfg, config); + num_dwords = encode_config(cfg, config, true); xe_gt_assert(gt, num_dwords <= max_cfg_dwords); if (xe_gt_is_media_type(gt)) { @@ -309,10 +315,10 @@ static int pf_push_full_vf_config(struct xe_gt *gt, unsigned int vfid) struct xe_gt_sriov_config *other = pf_pick_vf_config(primary, vfid); /* media-GT will never include a GGTT config */ - xe_gt_assert(gt, !encode_config_ggtt(cfg + num_dwords, config)); + xe_gt_assert(gt, !encode_config_ggtt(cfg + num_dwords, config, true)); /* the GGTT config must be taken from the primary-GT instead */ - num_dwords += encode_config_ggtt(cfg + num_dwords, other); + num_dwords += encode_config_ggtt(cfg + num_dwords, other, true); } xe_gt_assert(gt, num_dwords <= max_cfg_dwords); -- GitLab From e9a14537feb9f4223548b569748098c1ad7360d0 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 19 Sep 2024 19:15:27 +0200 Subject: [PATCH 748/970] drm/xe/pf: Add functions to save and restore VF configuration blob MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already have support to save and restore GuC VF state, but that will only work when the target VF configuration (provisioning) will be exactly the same as the source VF configuration. To help with assuring that both configurations match, allow to encode whole VF configuration that can be saved as blob and restored later. In the future we may want to use such captured configuration blobs as templates to make sure we provision VFs with exactly the same configuration that was previously tested or recommended, or when debugfs knobs are not be available. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240919171528.1451-5-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 170 +++++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h | 4 + 2 files changed, 174 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c index 28e2b26c2d88..a863e50b756e 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c @@ -34,6 +34,8 @@ #include "xe_ttm_vram_mgr.h" #include "xe_wopcm.h" +#define make_u64_from_u32(hi, lo) ((u64)((u64)(u32)(hi) << 32 | (u32)(lo))) + /* * Return: number of KLVs that were successfully parsed and saved, * negative error code on failure. @@ -2074,6 +2076,174 @@ bool xe_gt_sriov_pf_config_is_empty(struct xe_gt *gt, unsigned int vfid) return empty; } +/** + * xe_gt_sriov_pf_config_save - Save a VF provisioning config as binary blob. + * @gt: the &xe_gt + * @vfid: the VF identifier (can't be PF) + * @buf: the buffer to save a config to (or NULL if query the buf size) + * @size: the size of the buffer (or 0 if query the buf size) + * + * This function can only be called on PF. + * + * Return: mininum size of the buffer or the number of bytes saved, + * or a negative error code on failure. + */ +ssize_t xe_gt_sriov_pf_config_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size) +{ + struct xe_gt_sriov_config *config; + ssize_t ret; + + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid); + xe_gt_assert(gt, !(!buf ^ !size)); + + mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); + ret = pf_validate_vf_config(gt, vfid); + if (!size) { + ret = ret ? 0 : SZ_4K; + } else if (!ret) { + if (size < SZ_4K) { + ret = -ENOBUFS; + } else { + config = pf_pick_vf_config(gt, vfid); + ret = encode_config(buf, config, false) * sizeof(u32); + } + } + mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); + + return ret; +} + +static int pf_restore_vf_config_klv(struct xe_gt *gt, unsigned int vfid, + u32 key, u32 len, const u32 *value) +{ + switch (key) { + case GUC_KLV_VF_CFG_NUM_CONTEXTS_KEY: + if (len != GUC_KLV_VF_CFG_NUM_CONTEXTS_LEN) + return -EBADMSG; + return pf_provision_vf_ctxs(gt, vfid, value[0]); + + case GUC_KLV_VF_CFG_NUM_DOORBELLS_KEY: + if (len != GUC_KLV_VF_CFG_NUM_DOORBELLS_LEN) + return -EBADMSG; + return pf_provision_vf_dbs(gt, vfid, value[0]); + + case GUC_KLV_VF_CFG_EXEC_QUANTUM_KEY: + if (len != GUC_KLV_VF_CFG_EXEC_QUANTUM_LEN) + return -EBADMSG; + return pf_provision_exec_quantum(gt, vfid, value[0]); + + case GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_KEY: + if (len != GUC_KLV_VF_CFG_PREEMPT_TIMEOUT_LEN) + return -EBADMSG; + return pf_provision_preempt_timeout(gt, vfid, value[0]); + + /* auto-generate case statements */ +#define define_threshold_key_to_provision_case(TAG, ...) \ + case MAKE_GUC_KLV_VF_CFG_THRESHOLD_KEY(TAG): \ + BUILD_BUG_ON(MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN(TAG) != 1u); \ + if (len != MAKE_GUC_KLV_VF_CFG_THRESHOLD_LEN(TAG)) \ + return -EBADMSG; \ + return pf_provision_threshold(gt, vfid, \ + MAKE_XE_GUC_KLV_THRESHOLD_INDEX(TAG), \ + value[0]); + + MAKE_XE_GUC_KLV_THRESHOLDS_SET(define_threshold_key_to_provision_case) +#undef define_threshold_key_to_provision_case + } + + if (xe_gt_is_media_type(gt)) + return -EKEYREJECTED; + + switch (key) { + case GUC_KLV_VF_CFG_GGTT_SIZE_KEY: + if (len != GUC_KLV_VF_CFG_GGTT_SIZE_LEN) + return -EBADMSG; + return pf_provision_vf_ggtt(gt, vfid, make_u64_from_u32(value[1], value[0])); + + case GUC_KLV_VF_CFG_LMEM_SIZE_KEY: + if (!IS_DGFX(gt_to_xe(gt))) + return -EKEYREJECTED; + if (len != GUC_KLV_VF_CFG_LMEM_SIZE_LEN) + return -EBADMSG; + return pf_provision_vf_lmem(gt, vfid, make_u64_from_u32(value[1], value[0])); + } + + return -EKEYREJECTED; +} + +static int pf_restore_vf_config(struct xe_gt *gt, unsigned int vfid, + const u32 *klvs, size_t num_dwords) +{ + int err; + + while (num_dwords >= GUC_KLV_LEN_MIN) { + u32 key = FIELD_GET(GUC_KLV_0_KEY, klvs[0]); + u32 len = FIELD_GET(GUC_KLV_0_LEN, klvs[0]); + + klvs += GUC_KLV_LEN_MIN; + num_dwords -= GUC_KLV_LEN_MIN; + + if (num_dwords < len) + err = -EBADMSG; + else + err = pf_restore_vf_config_klv(gt, vfid, key, len, klvs); + + if (err) { + xe_gt_sriov_dbg(gt, "restore failed on key %#x (%pe)\n", key, ERR_PTR(err)); + return err; + } + + klvs += len; + num_dwords -= len; + } + + return pf_validate_vf_config(gt, vfid); +} + +/** + * xe_gt_sriov_pf_config_restore - Restore a VF provisioning config from binary blob. + * @gt: the &xe_gt + * @vfid: the VF identifier (can't be PF) + * @buf: the buffer with config data + * @size: the size of the config data + * + * This function can only be called on PF. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_config_restore(struct xe_gt *gt, unsigned int vfid, + const void *buf, size_t size) +{ + int err; + + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + xe_gt_assert(gt, vfid); + + if (!size) + return -ENODATA; + + if (size % sizeof(u32)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) { + struct drm_printer p = xe_gt_info_printer(gt); + + drm_printf(&p, "restoring VF%u config:\n", vfid); + xe_guc_klv_print(buf, size / sizeof(u32), &p); + } + + mutex_lock(xe_gt_sriov_pf_master_mutex(gt)); + err = pf_send_vf_cfg_reset(gt, vfid); + if (!err) { + pf_release_vf_config(gt, vfid); + err = pf_restore_vf_config(gt, vfid, buf, size / sizeof(u32)); + } + mutex_unlock(xe_gt_sriov_pf_master_mutex(gt)); + + return err; +} + /** * xe_gt_sriov_pf_config_restart - Restart SR-IOV configurations after a GT reset. * @gt: the &xe_gt diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h index 42e64769f666..b74ec38baa18 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h @@ -54,6 +54,10 @@ int xe_gt_sriov_pf_config_sanitize(struct xe_gt *gt, unsigned int vfid, long tim int xe_gt_sriov_pf_config_release(struct xe_gt *gt, unsigned int vfid, bool force); int xe_gt_sriov_pf_config_push(struct xe_gt *gt, unsigned int vfid, bool refresh); +ssize_t xe_gt_sriov_pf_config_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size); +int xe_gt_sriov_pf_config_restore(struct xe_gt *gt, unsigned int vfid, + const void *buf, size_t size); + bool xe_gt_sriov_pf_config_is_empty(struct xe_gt *gt, unsigned int vfid); void xe_gt_sriov_pf_config_restart(struct xe_gt *gt); -- GitLab From d42b0435254f0965ab5484c69cd45b4097f2f47d Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Thu, 19 Sep 2024 19:15:28 +0200 Subject: [PATCH 749/970] drm/xe/pf: Allow to save and restore VF config blob from debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For feature enabling and testing purposes, allow to capture and replace full VF configuration using debugfs blob file, but only under strict debug config. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: MichaÅ‚ Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240919171528.1451-6-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c | 78 +++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c index ccbcf6e572d0..91fc42e386d8 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c @@ -417,6 +417,81 @@ static const struct file_operations guc_state_ops = { .llseek = default_llseek, }; +/* + * /sys/kernel/debug/dri/0/ + * ├── gt0 + * │  ├── vf1 + * │  │  ├── config_blob + */ +static ssize_t config_blob_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + struct dentry *dent = file_dentry(file); + struct dentry *parent = dent->d_parent; + struct xe_gt *gt = extract_gt(parent); + unsigned int vfid = extract_vfid(parent); + ssize_t ret; + void *tmp; + + ret = xe_gt_sriov_pf_config_save(gt, vfid, NULL, 0); + if (!ret) + return -ENODATA; + if (ret < 0) + return ret; + + tmp = kzalloc(ret, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = xe_gt_sriov_pf_config_save(gt, vfid, tmp, ret); + if (ret > 0) + ret = simple_read_from_buffer(buf, count, pos, tmp, ret); + + kfree(tmp); + return ret; +} + +static ssize_t config_blob_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + struct dentry *dent = file_dentry(file); + struct dentry *parent = dent->d_parent; + struct xe_gt *gt = extract_gt(parent); + unsigned int vfid = extract_vfid(parent); + ssize_t ret; + void *tmp; + + if (*pos) + return -EINVAL; + + if (!count) + return -ENODATA; + + if (count > SZ_4K) + return -EINVAL; + + tmp = kzalloc(count, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + if (copy_from_user(tmp, buf, count)) { + ret = -EFAULT; + } else { + ret = xe_gt_sriov_pf_config_restore(gt, vfid, tmp, count); + if (!ret) + ret = count; + } + kfree(tmp); + return ret; +} + +static const struct file_operations config_blob_ops = { + .owner = THIS_MODULE, + .read = config_blob_read, + .write = config_blob_write, + .llseek = default_llseek, +}; + /** * xe_gt_sriov_pf_debugfs_register - Register SR-IOV PF specific entries in GT debugfs. * @gt: the &xe_gt to register @@ -471,6 +546,9 @@ void xe_gt_sriov_pf_debugfs_register(struct xe_gt *gt, struct dentry *root) debugfs_create_file("guc_state", IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 0600 : 0400, vfdentry, NULL, &guc_state_ops); + debugfs_create_file("config_blob", + IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 0600 : 0400, + vfdentry, NULL, &config_blob_ops); } } } -- GitLab From 82fe69e63d2b5a5e86ea94c7361c833d3848ab69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Fri, 4 Oct 2024 09:35:59 -0300 Subject: [PATCH 750/970] drm/vc4: Use `vc4_perfmon_find()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to commit f2a4bcb25328 ("drm/v3d: Use v3d_perfmon_find()"), replace the open-coded `vc4_perfmon_find()` with the real thing. Cc: Christian Gmeiner <cgmeiner@igalia.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Juan A. Suarez <jasuarez@igalia.com> Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004123817.890016-1-mcanal@igalia.com --- drivers/gpu/drm/vc4/vc4_perfmon.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c index 4cd3643c3ba7..f2e56d0f6298 100644 --- a/drivers/gpu/drm/vc4/vc4_perfmon.c +++ b/drivers/gpu/drm/vc4/vc4_perfmon.c @@ -236,11 +236,7 @@ int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, return -ENODEV; } - mutex_lock(&vc4file->perfmon.lock); - perfmon = idr_find(&vc4file->perfmon.idr, req->id); - vc4_perfmon_get(perfmon); - mutex_unlock(&vc4file->perfmon.lock); - + perfmon = vc4_perfmon_find(vc4file, req->id); if (!perfmon) return -EINVAL; -- GitLab From 0114f66370bfe139d6407a0b6b8f309af4c12148 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:01 -0700 Subject: [PATCH 751/970] drm/xe/guc: Remove spurious line feed in debug print Including line feeds at the start of a debug print messes up the output when sent to dmesg. The break appears between all the useful prefix information and the actual string being printed. In this case, each block of data has a very clear start line and an extra delimeter is really not necessary. So don't do it. v2: Fix typo in commit message (review feedback from Michal W.) Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-2-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_guc_ct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 5aef2be2d027..c0dded21621f 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -1533,7 +1533,7 @@ void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, drm_puts(p, "H2G CTB (all sizes in DW):\n"); guc_ctb_snapshot_print(&snapshot->h2g, p); - drm_puts(p, "\nG2H CTB (all sizes in DW):\n"); + drm_puts(p, "G2H CTB (all sizes in DW):\n"); guc_ctb_snapshot_print(&snapshot->g2h, p); drm_printf(p, "\tg2h outstanding: %d\n", -- GitLab From 9d86d080cfb3ab935c842ac5525a90430a14c998 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:02 -0700 Subject: [PATCH 752/970] drm/xe/devcoredump: Use drm_puts and already cached local variables There are a bunch of calls to drm_printf with static strings. Switch them to drm_puts instead. There are also a bunch of 'coredump->snapshot.XXX' references when 'coredump->snapshot' has alread been cached locally as 'ss'. So use 'ss->XXX' instead. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-3-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_devcoredump.c | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index bdb76e834e4c..d23719d5c2a3 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -85,9 +85,9 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, p = drm_coredump_printer(&iter); - drm_printf(&p, "**** Xe Device Coredump ****\n"); - drm_printf(&p, "kernel: " UTS_RELEASE "\n"); - drm_printf(&p, "module: " KBUILD_MODNAME "\n"); + drm_puts(&p, "**** Xe Device Coredump ****\n"); + drm_puts(&p, "kernel: " UTS_RELEASE "\n"); + drm_puts(&p, "module: " KBUILD_MODNAME "\n"); ts = ktime_to_timespec64(ss->snapshot_time); drm_printf(&p, "Snapshot time: %lld.%09ld\n", ts.tv_sec, ts.tv_nsec); @@ -96,20 +96,20 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, drm_printf(&p, "Process: %s\n", ss->process_name); xe_device_snapshot_print(xe, &p); - drm_printf(&p, "\n**** GuC CT ****\n"); - xe_guc_ct_snapshot_print(coredump->snapshot.ct, &p); - xe_guc_exec_queue_snapshot_print(coredump->snapshot.ge, &p); + drm_puts(&p, "\n**** GuC CT ****\n"); + xe_guc_ct_snapshot_print(ss->ct, &p); + xe_guc_exec_queue_snapshot_print(ss->ge, &p); - drm_printf(&p, "\n**** Job ****\n"); - xe_sched_job_snapshot_print(coredump->snapshot.job, &p); + drm_puts(&p, "\n**** Job ****\n"); + xe_sched_job_snapshot_print(ss->job, &p); - drm_printf(&p, "\n**** HW Engines ****\n"); + drm_puts(&p, "\n**** HW Engines ****\n"); for (i = 0; i < XE_NUM_HW_ENGINES; i++) - if (coredump->snapshot.hwe[i]) - xe_hw_engine_snapshot_print(coredump->snapshot.hwe[i], - &p); - drm_printf(&p, "\n**** VM state ****\n"); - xe_vm_snapshot_print(coredump->snapshot.vm, &p); + if (ss->hwe[i]) + xe_hw_engine_snapshot_print(ss->hwe[i], &p); + + drm_puts(&p, "\n**** VM state ****\n"); + xe_vm_snapshot_print(ss->vm, &p); return count - iter.remain; } @@ -247,18 +247,18 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump, if (xe_force_wake_get(gt_to_fw(q->gt), XE_FORCEWAKE_ALL)) xe_gt_info(ss->gt, "failed to get forcewake for coredump capture\n"); - coredump->snapshot.ct = xe_guc_ct_snapshot_capture(&guc->ct, true); - coredump->snapshot.ge = xe_guc_exec_queue_snapshot_capture(q); - coredump->snapshot.job = xe_sched_job_snapshot_capture(job); - coredump->snapshot.vm = xe_vm_snapshot_capture(q->vm); + ss->ct = xe_guc_ct_snapshot_capture(&guc->ct, true); + ss->ge = xe_guc_exec_queue_snapshot_capture(q); + ss->job = xe_sched_job_snapshot_capture(job); + ss->vm = xe_vm_snapshot_capture(q->vm); for_each_hw_engine(hwe, q->gt, id) { if (hwe->class != q->hwe->class || !(BIT(hwe->logical_instance) & adj_logical_mask)) { - coredump->snapshot.hwe[id] = NULL; + ss->hwe[id] = NULL; continue; } - coredump->snapshot.hwe[id] = xe_hw_engine_snapshot_capture(hwe); + ss->hwe[id] = xe_hw_engine_snapshot_capture(hwe); } queue_work(system_unbound_wq, &ss->work); -- GitLab From c28fd6c358db44c87a1408f27ba412c94e25e6c2 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:03 -0700 Subject: [PATCH 753/970] drm/xe/devcoredump: Improve section headings and add tile info The xe_guc_exec_queue_snapshot is not really a GuC internal thing and is definitely not a GuC CT thing. So give it its own section heading. The snapshot itself is really a capture of the submission backend's internal state. Although all it currently prints out is the submission contexts. So label it as 'Contexts'. If more general state is added later then it could be change to 'Submission backend' or some such. Further, everything from the GuC CT section onwards is GT specific but there was no indication of which GT it was related to (and that is impossible to work out from the other fields that are given). So add a GT section heading. Also include the tile id of the GT, because again significant information. Lastly, drop a couple of unnecessary line feeds within sections. v2: Add GT section heading, add tile id to device section. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-4-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_devcoredump.c | 5 +++++ drivers/gpu/drm/xe/xe_devcoredump_types.h | 3 ++- drivers/gpu/drm/xe/xe_device.c | 1 + drivers/gpu/drm/xe/xe_guc_submit.c | 2 +- drivers/gpu/drm/xe/xe_hw_engine.c | 1 - 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index d23719d5c2a3..2690f1d1cde4 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -96,8 +96,13 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, drm_printf(&p, "Process: %s\n", ss->process_name); xe_device_snapshot_print(xe, &p); + drm_printf(&p, "\n**** GT #%d ****\n", ss->gt->info.id); + drm_printf(&p, "\tTile: %d\n", ss->gt->tile->id); + drm_puts(&p, "\n**** GuC CT ****\n"); xe_guc_ct_snapshot_print(ss->ct, &p); + + drm_puts(&p, "\n**** Contexts ****\n"); xe_guc_exec_queue_snapshot_print(ss->ge, &p); drm_puts(&p, "\n**** Job ****\n"); diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h index 440d05d77a5a..3cc2f095fdfb 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump_types.h +++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h @@ -37,7 +37,8 @@ struct xe_devcoredump_snapshot { /* GuC snapshots */ /** @ct: GuC CT snapshot */ struct xe_guc_ct_snapshot *ct; - /** @ge: Guc Engine snapshot */ + + /** @ge: GuC Submission Engine snapshot */ struct xe_guc_submit_exec_queue_snapshot *ge; /** @hwe: HW Engine snapshot array */ diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 1940cd3229f4..cd241a8e1838 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -964,6 +964,7 @@ void xe_device_snapshot_print(struct xe_device *xe, struct drm_printer *p) for_each_gt(gt, xe, id) { drm_printf(p, "GT id: %u\n", id); + drm_printf(p, "\tTile: %u\n", gt->tile->id); drm_printf(p, "\tType: %s\n", gt->info.type == XE_GT_TYPE_MAIN ? "main" : "media"); drm_printf(p, "\tIP ver: %u.%u.%u\n", diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 8a5c21a87977..fc4008018d1f 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -2237,7 +2237,7 @@ xe_guc_exec_queue_snapshot_print(struct xe_guc_submit_exec_queue_snapshot *snaps if (!snapshot) return; - drm_printf(p, "\nGuC ID: %d\n", snapshot->guc.id); + drm_printf(p, "GuC ID: %d\n", snapshot->guc.id); drm_printf(p, "\tName: %s\n", snapshot->name); drm_printf(p, "\tClass: %d\n", snapshot->class); drm_printf(p, "\tLogical mask: 0x%x\n", snapshot->logical_mask); diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index ea6d9ef7fab6..6c9c27304cdc 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -1084,7 +1084,6 @@ void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, if (snapshot->hwe->class == XE_ENGINE_CLASS_COMPUTE) drm_printf(p, "\tRCU_MODE: 0x%08x\n", snapshot->reg.rcu_mode); - drm_puts(p, "\n"); } /** -- GitLab From ec1455ce7e35a31289d2dbc1070b980538698921 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:04 -0700 Subject: [PATCH 754/970] drm/xe/devcoredump: Add ASCII85 dump helper function There is a need to include the GuC log and other large binary objects in core dumps and via dmesg. So add a helper for dumping to a printer function via conversion to ASCII85 encoding. Another issue with dumping such a large buffer is that it can be slow, especially if dumping to dmesg over a serial port. So add a yield to prevent the 'task has been stuck for 120s' kernel hang check feature from firing. v2: Add a prefix to the output string. Fix memory allocation bug. v3: Correct a string size calculation and clean up a define (review feedback from Julia F). Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-5-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_devcoredump.c | 87 +++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_devcoredump.h | 6 ++ 2 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index 2690f1d1cde4..0884c49942fe 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -6,6 +6,7 @@ #include "xe_devcoredump.h" #include "xe_devcoredump_types.h" +#include <linux/ascii85.h> #include <linux/devcoredump.h> #include <generated/utsrelease.h> @@ -315,3 +316,89 @@ int xe_devcoredump_init(struct xe_device *xe) } #endif + +/** + * xe_print_blob_ascii85 - print a BLOB to some useful location in ASCII85 + * + * The output is split to multiple lines because some print targets, e.g. dmesg + * cannot handle arbitrarily long lines. Note also that printing to dmesg in + * piece-meal fashion is not possible, each separate call to drm_puts() has a + * line-feed automatically added! Therefore, the entire output line must be + * constructed in a local buffer first, then printed in one atomic output call. + * + * There is also a scheduler yield call to prevent the 'task has been stuck for + * 120s' kernel hang check feature from firing when printing to a slow target + * such as dmesg over a serial port. + * + * TODO: Add compression prior to the ASCII85 encoding to shrink huge buffers down. + * + * @p: the printer object to output to + * @prefix: optional prefix to add to output string + * @blob: the Binary Large OBject to dump out + * @offset: offset in bytes to skip from the front of the BLOB, must be a multiple of sizeof(u32) + * @size: the size in bytes of the BLOB, must be a multiple of sizeof(u32) + */ +void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, + const void *blob, size_t offset, size_t size) +{ + const u32 *blob32 = (const u32 *)blob; + char buff[ASCII85_BUFSZ], *line_buff; + size_t line_pos = 0; + +#define DMESG_MAX_LINE_LEN 800 +#define MIN_SPACE (ASCII85_BUFSZ + 2) /* 85 + "\n\0" */ + + if (size & 3) + drm_printf(p, "Size not word aligned: %zu", size); + if (offset & 3) + drm_printf(p, "Offset not word aligned: %zu", size); + + line_buff = kzalloc(DMESG_MAX_LINE_LEN, GFP_KERNEL); + if (IS_ERR_OR_NULL(line_buff)) { + drm_printf(p, "Failed to allocate line buffer: %pe", line_buff); + return; + } + + blob32 += offset / sizeof(*blob32); + size /= sizeof(*blob32); + + if (prefix) { + strscpy(line_buff, prefix, DMESG_MAX_LINE_LEN - MIN_SPACE - 2); + line_pos = strlen(line_buff); + + line_buff[line_pos++] = ':'; + line_buff[line_pos++] = ' '; + } + + while (size--) { + u32 val = *(blob32++); + + strscpy(line_buff + line_pos, ascii85_encode(val, buff), + DMESG_MAX_LINE_LEN - line_pos); + line_pos += strlen(line_buff + line_pos); + + if ((line_pos + MIN_SPACE) >= DMESG_MAX_LINE_LEN) { + line_buff[line_pos++] = '\n'; + line_buff[line_pos++] = 0; + + drm_puts(p, line_buff); + + line_pos = 0; + + /* Prevent 'stuck thread' time out errors */ + cond_resched(); + } + } + + if (line_pos) { + line_buff[line_pos++] = '\n'; + line_buff[line_pos++] = 0; + + drm_puts(p, line_buff); + } + + kfree(line_buff); + +#undef MIN_SPACE +#undef DMESG_MAX_LINE_LEN +} diff --git a/drivers/gpu/drm/xe/xe_devcoredump.h b/drivers/gpu/drm/xe/xe_devcoredump.h index e2fa65ce0932..a4eebc285fc8 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.h +++ b/drivers/gpu/drm/xe/xe_devcoredump.h @@ -6,6 +6,9 @@ #ifndef _XE_DEVCOREDUMP_H_ #define _XE_DEVCOREDUMP_H_ +#include <linux/types.h> + +struct drm_printer; struct xe_device; struct xe_sched_job; @@ -23,4 +26,7 @@ static inline int xe_devcoredump_init(struct xe_device *xe) } #endif +void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, + const void *blob, size_t offset, size_t size); + #endif -- GitLab From a59a403419aa03d5e44c8cf014e415490395b17f Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:05 -0700 Subject: [PATCH 755/970] drm/xe/guc: Copy GuC log prior to dumping Add an extra stage to the GuC log print to copy the log buffer into regular host memory first, rather than printing the live GPU buffer object directly. Doing so helps prevent inconsistencies due to the log being updated as it is being dumped. It also allows the use of the ASCII85 helper function for printing the log in a more compact form than a straight hex dump. v2: Use %zx instead of %lx for size_t prints. v3: Replace hexdump code with ascii85 call (review feedback from Matthew B). Move chunking code into next patch as that reduces the deltas of both. v4: Add a prefix to the ASCII85 output to aid tool parsing. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-6-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_guc_log.c | 40 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index 651543721ce5..bb9446b2d29d 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -8,9 +8,12 @@ #include <linux/fault-inject.h> #include <drm/drm_managed.h> +#include <linux/vmalloc.h> #include "xe_bo.h" +#include "xe_devcoredump.h" #include "xe_gt.h" +#include "xe_gt_printk.h" #include "xe_map.h" #include "xe_module.h" @@ -51,32 +54,35 @@ static size_t guc_log_size(void) CAPTURE_BUFFER_SIZE; } +/** + * xe_guc_log_print - dump a copy of the GuC log to some useful location + * @log: GuC log structure + * @p: the printer object to output to + */ void xe_guc_log_print(struct xe_guc_log *log, struct drm_printer *p) { struct xe_device *xe = log_to_xe(log); size_t size; - int i, j; + void *copy; - xe_assert(xe, log->bo); + if (!log->bo) { + drm_puts(p, "GuC log buffer not allocated"); + return; + } size = log->bo->size; -#define DW_PER_READ 128 - xe_assert(xe, !(size % (DW_PER_READ * sizeof(u32)))); - for (i = 0; i < size / sizeof(u32); i += DW_PER_READ) { - u32 read[DW_PER_READ]; - - xe_map_memcpy_from(xe, read, &log->bo->vmap, i * sizeof(u32), - DW_PER_READ * sizeof(u32)); -#define DW_PER_PRINT 4 - for (j = 0; j < DW_PER_READ / DW_PER_PRINT; ++j) { - u32 *print = read + j * DW_PER_PRINT; - - drm_printf(p, "0x%08x 0x%08x 0x%08x 0x%08x\n", - *(print + 0), *(print + 1), - *(print + 2), *(print + 3)); - } + copy = vmalloc(size); + if (!copy) { + drm_printf(p, "Failed to allocate %zu", size); + return; } + + xe_map_memcpy_from(xe, copy, &log->bo->vmap, 0, size); + + xe_print_blob_ascii85(p, "Log data", copy, 0, size); + + vfree(copy); } int xe_guc_log_init(struct xe_guc_log *log) -- GitLab From d8ce1a97722617317b04eb9f19ab8d6d95379f7a Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:06 -0700 Subject: [PATCH 756/970] drm/xe/guc: Use a two stage dump for GuC logs and add more info Split the GuC log dump into a two stage snapshot and print mechanism. This allows the log to be captured at the point of an error (which may be in a restricted context) and then dump it out later (from a regular context such as a worker function or a sysfs file handler). Also add a bunch of other useful pieces of information that can help (or are fundamentally required!) to decode and parse the log. v2: Add kerneldoc and fix a couple of comment typos - review feedback from Michal W. v3: Move chunking code to this patch as it makes the deltas simpler. Fix a bunch of kerneldoc issues. v4: Move the CS frequency out of the coredump snapshot function into the debugfs only code (as that info is already part of the main devcoredump). Add a header to the debugfs log to match the one in the devcoredump to aid processing by a unified tool. Add forcewake to the GuC timestamp read so it actually works. v6: Add colon to GuC version string (review feedback by Julia F). Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-7-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/regs/xe_guc_regs.h | 1 + drivers/gpu/drm/xe/xe_guc_log.c | 178 +++++++++++++++++++++++--- drivers/gpu/drm/xe/xe_guc_log.h | 4 + drivers/gpu/drm/xe/xe_guc_log_types.h | 27 ++++ 4 files changed, 195 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/xe/regs/xe_guc_regs.h b/drivers/gpu/drm/xe/regs/xe_guc_regs.h index a5fd14307f94..b27b73680c12 100644 --- a/drivers/gpu/drm/xe/regs/xe_guc_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_guc_regs.h @@ -84,6 +84,7 @@ #define HUC_LOADING_AGENT_GUC REG_BIT(1) #define GUC_WOPCM_OFFSET_VALID REG_BIT(0) #define GUC_MAX_IDLE_COUNT XE_REG(0xc3e4) +#define GUC_PMTIMESTAMP XE_REG(0xc3e8) #define GUC_SEND_INTERRUPT XE_REG(0xc4c8) #define GUC_SEND_TRIGGER REG_BIT(0) diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index bb9446b2d29d..79e01d724509 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -8,15 +8,23 @@ #include <linux/fault-inject.h> #include <drm/drm_managed.h> -#include <linux/vmalloc.h> +#include "regs/xe_guc_regs.h" #include "xe_bo.h" #include "xe_devcoredump.h" +#include "xe_force_wake.h" #include "xe_gt.h" #include "xe_gt_printk.h" #include "xe_map.h" +#include "xe_mmio.h" #include "xe_module.h" +static struct xe_guc * +log_to_guc(struct xe_guc_log *log) +{ + return container_of(log, struct xe_guc, log); +} + static struct xe_gt * log_to_gt(struct xe_guc_log *log) { @@ -54,35 +62,175 @@ static size_t guc_log_size(void) CAPTURE_BUFFER_SIZE; } +#define GUC_LOG_CHUNK_SIZE SZ_2M + +static struct xe_guc_log_snapshot *xe_guc_log_snapshot_alloc(struct xe_guc_log *log, bool atomic) +{ + struct xe_guc_log_snapshot *snapshot; + size_t remain; + int i; + + snapshot = kzalloc(sizeof(*snapshot), atomic ? GFP_ATOMIC : GFP_KERNEL); + if (!snapshot) + return NULL; + + /* + * NB: kmalloc has a hard limit well below the maximum GuC log buffer size. + * Also, can't use vmalloc as might be called from atomic context. So need + * to break the buffer up into smaller chunks that can be allocated. + */ + snapshot->size = log->bo->size; + snapshot->num_chunks = DIV_ROUND_UP(snapshot->size, GUC_LOG_CHUNK_SIZE); + + snapshot->copy = kcalloc(snapshot->num_chunks, sizeof(*snapshot->copy), + atomic ? GFP_ATOMIC : GFP_KERNEL); + if (!snapshot->copy) + goto fail_snap; + + remain = snapshot->size; + for (i = 0; i < snapshot->num_chunks; i++) { + size_t size = min(GUC_LOG_CHUNK_SIZE, remain); + + snapshot->copy[i] = kmalloc(size, atomic ? GFP_ATOMIC : GFP_KERNEL); + if (!snapshot->copy[i]) + goto fail_copy; + remain -= size; + } + + return snapshot; + +fail_copy: + for (i = 0; i < snapshot->num_chunks; i++) + kfree(snapshot->copy[i]); + kfree(snapshot->copy); +fail_snap: + kfree(snapshot); + return NULL; +} + /** - * xe_guc_log_print - dump a copy of the GuC log to some useful location + * xe_guc_log_snapshot_free - free a previously captured GuC log snapshot + * @snapshot: GuC log snapshot structure + * + * Return: pointer to a newly allocated snapshot object or null if out of memory. Caller is + * responsible for calling xe_guc_log_snapshot_free when done with the snapshot. + */ +void xe_guc_log_snapshot_free(struct xe_guc_log_snapshot *snapshot) +{ + int i; + + if (!snapshot) + return; + + if (!snapshot->copy) { + for (i = 0; i < snapshot->num_chunks; i++) + kfree(snapshot->copy[i]); + kfree(snapshot->copy); + } + + kfree(snapshot); +} + +/** + * xe_guc_log_snapshot_capture - create a new snapshot copy the GuC log for later dumping * @log: GuC log structure - * @p: the printer object to output to + * @atomic: is the call inside an atomic section of some kind? + * + * Return: pointer to a newly allocated snapshot object or null if out of memory. Caller is + * responsible for calling xe_guc_log_snapshot_free when done with the snapshot. */ -void xe_guc_log_print(struct xe_guc_log *log, struct drm_printer *p) +struct xe_guc_log_snapshot *xe_guc_log_snapshot_capture(struct xe_guc_log *log, bool atomic) { + struct xe_guc_log_snapshot *snapshot; struct xe_device *xe = log_to_xe(log); - size_t size; - void *copy; + struct xe_guc *guc = log_to_guc(log); + struct xe_gt *gt = log_to_gt(log); + size_t remain; + int i, err; if (!log->bo) { - drm_puts(p, "GuC log buffer not allocated"); - return; + xe_gt_err(gt, "GuC log buffer not allocated\n"); + return NULL; + } + + snapshot = xe_guc_log_snapshot_alloc(log, atomic); + if (!snapshot) { + xe_gt_err(gt, "GuC log snapshot not allocated\n"); + return NULL; } - size = log->bo->size; + remain = snapshot->size; + for (i = 0; i < snapshot->num_chunks; i++) { + size_t size = min(GUC_LOG_CHUNK_SIZE, remain); + + xe_map_memcpy_from(xe, snapshot->copy[i], &log->bo->vmap, + i * GUC_LOG_CHUNK_SIZE, size); + remain -= size; + } + + err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT); + if (err) { + snapshot->stamp = ~0; + } else { + snapshot->stamp = xe_mmio_read32(>->mmio, GUC_PMTIMESTAMP); + xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); + } + snapshot->ktime = ktime_get_boottime_ns(); + snapshot->level = log->level; + snapshot->ver_found = guc->fw.versions.found[XE_UC_FW_VER_RELEASE]; + snapshot->ver_want = guc->fw.versions.wanted; + snapshot->path = guc->fw.path; + + return snapshot; +} + +/** + * xe_guc_log_snapshot_print - dump a previously saved copy of the GuC log to some useful location + * @snapshot: a snapshot of the GuC log + * @p: the printer object to output to + */ +void xe_guc_log_snapshot_print(struct xe_guc_log_snapshot *snapshot, struct drm_printer *p) +{ + size_t remain; + int i; - copy = vmalloc(size); - if (!copy) { - drm_printf(p, "Failed to allocate %zu", size); + if (!snapshot) { + drm_printf(p, "GuC log snapshot not allocated!\n"); return; } - xe_map_memcpy_from(xe, copy, &log->bo->vmap, 0, size); + drm_printf(p, "GuC firmware: %s\n", snapshot->path); + drm_printf(p, "GuC version: %u.%u.%u (wanted %u.%u.%u)\n", + snapshot->ver_found.major, snapshot->ver_found.minor, snapshot->ver_found.patch, + snapshot->ver_want.major, snapshot->ver_want.minor, snapshot->ver_want.patch); + drm_printf(p, "Kernel timestamp: 0x%08llX [%llu]\n", snapshot->ktime, snapshot->ktime); + drm_printf(p, "GuC timestamp: 0x%08X [%u]\n", snapshot->stamp, snapshot->stamp); + drm_printf(p, "Log level: %u\n", snapshot->level); + + remain = snapshot->size; + for (i = 0; i < snapshot->num_chunks; i++) { + size_t size = min(GUC_LOG_CHUNK_SIZE, remain); + + xe_print_blob_ascii85(p, i ? NULL : "Log data", snapshot->copy[i], 0, size); + remain -= size; + } +} + +/** + * xe_guc_log_print - dump a copy of the GuC log to some useful location + * @log: GuC log structure + * @p: the printer object to output to + */ +void xe_guc_log_print(struct xe_guc_log *log, struct drm_printer *p) +{ + struct xe_guc_log_snapshot *snapshot; - xe_print_blob_ascii85(p, "Log data", copy, 0, size); + drm_printf(p, "**** GuC Log ****\n"); - vfree(copy); + snapshot = xe_guc_log_snapshot_capture(log, false); + drm_printf(p, "CS reference clock: %u\n", log_to_gt(log)->info.reference_clock); + xe_guc_log_snapshot_print(snapshot, p); + xe_guc_log_snapshot_free(snapshot); } int xe_guc_log_init(struct xe_guc_log *log) diff --git a/drivers/gpu/drm/xe/xe_guc_log.h b/drivers/gpu/drm/xe/xe_guc_log.h index 2d25ab28b4b3..949d2c98343d 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.h +++ b/drivers/gpu/drm/xe/xe_guc_log.h @@ -9,6 +9,7 @@ #include "xe_guc_log_types.h" struct drm_printer; +struct xe_device; #if IS_ENABLED(CONFIG_DRM_XE_LARGE_GUC_BUFFER) #define CRASH_BUFFER_SIZE SZ_1M @@ -38,6 +39,9 @@ struct drm_printer; int xe_guc_log_init(struct xe_guc_log *log); void xe_guc_log_print(struct xe_guc_log *log, struct drm_printer *p); +struct xe_guc_log_snapshot *xe_guc_log_snapshot_capture(struct xe_guc_log *log, bool atomic); +void xe_guc_log_snapshot_print(struct xe_guc_log_snapshot *snapshot, struct drm_printer *p); +void xe_guc_log_snapshot_free(struct xe_guc_log_snapshot *snapshot); static inline u32 xe_guc_log_get_level(struct xe_guc_log *log) diff --git a/drivers/gpu/drm/xe/xe_guc_log_types.h b/drivers/gpu/drm/xe/xe_guc_log_types.h index 125080d138a7..962b9edbd9eb 100644 --- a/drivers/gpu/drm/xe/xe_guc_log_types.h +++ b/drivers/gpu/drm/xe/xe_guc_log_types.h @@ -8,8 +8,35 @@ #include <linux/types.h> +#include "xe_uc_fw_types.h" + struct xe_bo; +/** + * struct xe_guc_log_snapshot: + * Capture of the GuC log plus various state useful for decoding the log + */ +struct xe_guc_log_snapshot { + /** @size: Size in bytes of the @copy allocation */ + size_t size; + /** @copy: Host memory copy of the log buffer for later dumping, split into chunks */ + void **copy; + /** @num_chunks: Number of chunks within @copy */ + int num_chunks; + /** @ktime: Kernel time the snapshot was taken */ + u64 ktime; + /** @stamp: GuC timestamp at which the snapshot was taken */ + u32 stamp; + /** @level: GuC log verbosity level */ + u32 level; + /** @ver_found: GuC firmware version */ + struct xe_uc_fw_version ver_found; + /** @ver_want: GuC firmware version that driver expected */ + struct xe_uc_fw_version ver_want; + /** @path: Path of GuC firmware blob */ + const char *path; +}; + /** * struct xe_guc_log - GuC log */ -- GitLab From 754e707e20e47482384f6e64eb3af08273292010 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko <michal.wajdeczko@intel.com> Date: Wed, 2 Oct 2024 17:46:07 -0700 Subject: [PATCH 757/970] drm/print: Introduce drm_line_printer This drm printer wrapper can be used to increase the robustness of the captured output generated by any other drm_printer to make sure we didn't lost any intermediate lines of the output by adding line numbers to each output line. Helpful for capturing some crash data. v2: Extended short int counters to full int (JohnH) Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Cc: Jani Nikula <jani.nikula@intel.com> Cc: dri-devel@lists.freedesktop.org Reviewed-by: Jani Nikula <jani.nikula@intel.com> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-8-John.C.Harrison@Intel.com --- drivers/gpu/drm/drm_print.c | 14 ++++++++ include/drm/drm_print.h | 64 +++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index 0081190201a7..08cfea04e22b 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -235,6 +235,20 @@ void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf) } EXPORT_SYMBOL(__drm_printfn_err); +void __drm_printfn_line(struct drm_printer *p, struct va_format *vaf) +{ + unsigned int counter = ++p->line.counter; + const char *prefix = p->prefix ?: ""; + const char *pad = p->prefix ? " " : ""; + + if (p->line.series) + drm_printf(p->arg, "%s%s%u.%u: %pV", + prefix, pad, p->line.series, counter, vaf); + else + drm_printf(p->arg, "%s%s%u: %pV", prefix, pad, counter, vaf); +} +EXPORT_SYMBOL(__drm_printfn_line); + /** * drm_puts - print a const string to a &drm_printer stream * @p: the &drm printer diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index d2676831d765..b3906dc04388 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -177,6 +177,10 @@ struct drm_printer { void *arg; const void *origin; const char *prefix; + struct { + unsigned int series; + unsigned int counter; + } line; enum drm_debug_category category; }; @@ -187,6 +191,7 @@ void __drm_puts_seq_file(struct drm_printer *p, const char *str); void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf); void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf); +void __drm_printfn_line(struct drm_printer *p, struct va_format *vaf); __printf(2, 3) void drm_printf(struct drm_printer *p, const char *f, ...); @@ -411,6 +416,65 @@ static inline struct drm_printer drm_err_printer(struct drm_device *drm, return p; } +/** + * drm_line_printer - construct a &drm_printer that prefixes outputs with line numbers + * @p: the &struct drm_printer which actually generates the output + * @prefix: optional output prefix, or NULL for no prefix + * @series: optional unique series identifier, or 0 to omit identifier in the output + * + * This printer can be used to increase the robustness of the captured output + * to make sure we didn't lost any intermediate lines of the output. Helpful + * while capturing some crash data. + * + * Example 1:: + * + * void crash_dump(struct drm_device *drm) + * { + * static unsigned int id; + * struct drm_printer p = drm_err_printer(drm, "crash"); + * struct drm_printer lp = drm_line_printer(&p, "dump", ++id); + * + * drm_printf(&lp, "foo"); + * drm_printf(&lp, "bar"); + * } + * + * Above code will print into the dmesg something like:: + * + * [ ] 0000:00:00.0: [drm] *ERROR* crash dump 1.1: foo + * [ ] 0000:00:00.0: [drm] *ERROR* crash dump 1.2: bar + * + * Example 2:: + * + * void line_dump(struct device *dev) + * { + * struct drm_printer p = drm_info_printer(dev); + * struct drm_printer lp = drm_line_printer(&p, NULL, 0); + * + * drm_printf(&lp, "foo"); + * drm_printf(&lp, "bar"); + * } + * + * Above code will print:: + * + * [ ] 0000:00:00.0: [drm] 1: foo + * [ ] 0000:00:00.0: [drm] 2: bar + * + * RETURNS: + * The &drm_printer object + */ +static inline struct drm_printer drm_line_printer(struct drm_printer *p, + const char *prefix, + unsigned int series) +{ + struct drm_printer lp = { + .printfn = __drm_printfn_line, + .arg = p, + .prefix = prefix, + .line = { .series = series, }, + }; + return lp; +} + /* * struct device based logging * -- GitLab From d2c5a5a926f43b2e42c5c955f917bad8ad6dd68c Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:08 -0700 Subject: [PATCH 758/970] drm/xe/guc: Dead CT helper Add a worker function helper for asynchronously dumping state when an internal/fatal error is detected in CT processing. Being asynchronous is required to avoid deadlocks and scheduling-while-atomic or process-stalled-for-too-long issues. Also check for a bunch more error conditions and improve the handling of some existing checks. v2: Use compile time CONFIG check for new (but not directly CT_DEAD related) checks and use unsigned int for a bitmask, rename CT_DEAD_RESET to CT_DEAD_REARM and add some explaining comments, rename 'hxg' macro parameter to 'ctb' - review feedback from Michal W. Drop CT_DEAD_ALIVE as no need for a bitfield define to just set the entire mask to zero. v3: Fix kerneldoc v4: Nullify some floating pointers after free. v5: Add section headings and device info to make the state dump look more like a devcoredump to allow parsing by the same tools (eventual aim is to just call the devcoredump code itself, but that currently requires an xe_sched_job, which is not available in the CT code). v6: Fix potential for leaking snapshots with concurrent error conditions (review feedback from Julia F). v7: Don't complain about unexpected G2H messages yet because there is a known issue causing them. Fix bit shift bug with v6 change. Add GT id to fake coredump headers and use puts instead of printf. v8: Disable the head mis-match check in g2h_read because it is failing on various discrete platforms due to unknown reasons. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-9-John.C.Harrison@Intel.com --- .../drm/xe/abi/guc_communication_ctb_abi.h | 1 + drivers/gpu/drm/xe/xe_guc.c | 2 +- drivers/gpu/drm/xe/xe_guc_ct.c | 336 ++++++++++++++++-- drivers/gpu/drm/xe/xe_guc_ct.h | 2 +- drivers/gpu/drm/xe/xe_guc_ct_types.h | 23 ++ 5 files changed, 335 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/xe/abi/guc_communication_ctb_abi.h b/drivers/gpu/drm/xe/abi/guc_communication_ctb_abi.h index 8f86a16dc577..f58198cf2cf6 100644 --- a/drivers/gpu/drm/xe/abi/guc_communication_ctb_abi.h +++ b/drivers/gpu/drm/xe/abi/guc_communication_ctb_abi.h @@ -52,6 +52,7 @@ struct guc_ct_buffer_desc { #define GUC_CTB_STATUS_OVERFLOW (1 << 0) #define GUC_CTB_STATUS_UNDERFLOW (1 << 1) #define GUC_CTB_STATUS_MISMATCH (1 << 2) +#define GUC_CTB_STATUS_DISABLED (1 << 3) u32 reserved[13]; } __packed; static_assert(sizeof(struct guc_ct_buffer_desc) == 64); diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index c2ddf883702b..4abc790ed1cd 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -1180,7 +1180,7 @@ void xe_guc_print_info(struct xe_guc *guc, struct drm_printer *p) xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); - xe_guc_ct_print(&guc->ct, p, false); + xe_guc_ct_print(&guc->ct, p); xe_guc_submit_print(guc, p); } diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index c0dded21621f..79571c9d180e 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -26,12 +26,48 @@ #include "xe_gt_sriov_pf_monitor.h" #include "xe_gt_tlb_invalidation.h" #include "xe_guc.h" +#include "xe_guc_log.h" #include "xe_guc_relay.h" #include "xe_guc_submit.h" #include "xe_map.h" #include "xe_pm.h" #include "xe_trace_guc.h" +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) +enum { + /* Internal states, not error conditions */ + CT_DEAD_STATE_REARM, /* 0x0001 */ + CT_DEAD_STATE_CAPTURE, /* 0x0002 */ + + /* Error conditions */ + CT_DEAD_SETUP, /* 0x0004 */ + CT_DEAD_H2G_WRITE, /* 0x0008 */ + CT_DEAD_H2G_HAS_ROOM, /* 0x0010 */ + CT_DEAD_G2H_READ, /* 0x0020 */ + CT_DEAD_G2H_RECV, /* 0x0040 */ + CT_DEAD_G2H_RELEASE, /* 0x0080 */ + CT_DEAD_DEADLOCK, /* 0x0100 */ + CT_DEAD_PROCESS_FAILED, /* 0x0200 */ + CT_DEAD_FAST_G2H, /* 0x0400 */ + CT_DEAD_PARSE_G2H_RESPONSE, /* 0x0800 */ + CT_DEAD_PARSE_G2H_UNKNOWN, /* 0x1000 */ + CT_DEAD_PARSE_G2H_ORIGIN, /* 0x2000 */ + CT_DEAD_PARSE_G2H_TYPE, /* 0x4000 */ +}; + +static void ct_dead_worker_func(struct work_struct *w); +static void ct_dead_capture(struct xe_guc_ct *ct, struct guc_ctb *ctb, u32 reason_code); + +#define CT_DEAD(ct, ctb, reason_code) ct_dead_capture((ct), (ctb), CT_DEAD_##reason_code) +#else +#define CT_DEAD(ct, ctb, reason) \ + do { \ + struct guc_ctb *_ctb = (ctb); \ + if (_ctb) \ + _ctb->info.broken = true; \ + } while (0) +#endif + /* Used when a CT send wants to block and / or receive data */ struct g2h_fence { u32 *response_buffer; @@ -184,6 +220,10 @@ int xe_guc_ct_init(struct xe_guc_ct *ct) xa_init(&ct->fence_lookup); INIT_WORK(&ct->g2h_worker, g2h_worker_func); INIT_DELAYED_WORK(&ct->safe_mode_worker, safe_mode_worker_func); +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) + spin_lock_init(&ct->dead.lock); + INIT_WORK(&ct->dead.worker, ct_dead_worker_func); +#endif init_waitqueue_head(&ct->wq); init_waitqueue_head(&ct->g2h_fence_wq); @@ -421,10 +461,22 @@ int xe_guc_ct_enable(struct xe_guc_ct *ct) if (ct_needs_safe_mode(ct)) ct_enter_safe_mode(ct); +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) + /* + * The CT has now been reset so the dumper can be re-armed + * after any existing dead state has been dumped. + */ + spin_lock_irq(&ct->dead.lock); + if (ct->dead.reason) + ct->dead.reason |= (1 << CT_DEAD_STATE_REARM); + spin_unlock_irq(&ct->dead.lock); +#endif + return 0; err_out: xe_gt_err(gt, "Failed to enable GuC CT (%pe)\n", ERR_PTR(err)); + CT_DEAD(ct, NULL, SETUP); return err; } @@ -468,6 +520,19 @@ static bool h2g_has_room(struct xe_guc_ct *ct, u32 cmd_len) if (cmd_len > h2g->info.space) { h2g->info.head = desc_read(ct_to_xe(ct), h2g, head); + + if (h2g->info.head > h2g->info.size) { + struct xe_device *xe = ct_to_xe(ct); + u32 desc_status = desc_read(xe, h2g, status); + + desc_write(xe, h2g, status, desc_status | GUC_CTB_STATUS_OVERFLOW); + + xe_gt_err(ct_to_gt(ct), "CT: invalid head offset %u >= %u)\n", + h2g->info.head, h2g->info.size); + CT_DEAD(ct, h2g, H2G_HAS_ROOM); + return false; + } + h2g->info.space = CIRC_SPACE(h2g->info.tail, h2g->info.head, h2g->info.size) - h2g->info.resv_space; @@ -523,10 +588,24 @@ static void __g2h_reserve_space(struct xe_guc_ct *ct, u32 g2h_len, u32 num_g2h) static void __g2h_release_space(struct xe_guc_ct *ct, u32 g2h_len) { + bool bad = false; + lockdep_assert_held(&ct->fast_lock); - xe_gt_assert(ct_to_gt(ct), ct->ctbs.g2h.info.space + g2h_len <= - ct->ctbs.g2h.info.size - ct->ctbs.g2h.info.resv_space); - xe_gt_assert(ct_to_gt(ct), ct->g2h_outstanding); + + bad = ct->ctbs.g2h.info.space + g2h_len > + ct->ctbs.g2h.info.size - ct->ctbs.g2h.info.resv_space; + bad |= !ct->g2h_outstanding; + + if (bad) { + xe_gt_err(ct_to_gt(ct), "Invalid G2H release: %d + %d vs %d - %d -> %d vs %d, outstanding = %d!\n", + ct->ctbs.g2h.info.space, g2h_len, + ct->ctbs.g2h.info.size, ct->ctbs.g2h.info.resv_space, + ct->ctbs.g2h.info.space + g2h_len, + ct->ctbs.g2h.info.size - ct->ctbs.g2h.info.resv_space, + ct->g2h_outstanding); + CT_DEAD(ct, &ct->ctbs.g2h, G2H_RELEASE); + return; + } ct->ctbs.g2h.info.space += g2h_len; if (!--ct->g2h_outstanding) @@ -553,12 +632,43 @@ static int h2g_write(struct xe_guc_ct *ct, const u32 *action, u32 len, u32 full_len; struct iosys_map map = IOSYS_MAP_INIT_OFFSET(&h2g->cmds, tail * sizeof(u32)); + u32 desc_status; full_len = len + GUC_CTB_HDR_LEN; lockdep_assert_held(&ct->lock); xe_gt_assert(gt, full_len <= GUC_CTB_MSG_MAX_LEN); - xe_gt_assert(gt, tail <= h2g->info.size); + + desc_status = desc_read(xe, h2g, status); + if (desc_status) { + xe_gt_err(gt, "CT write: non-zero status: %u\n", desc_status); + goto corrupted; + } + + if (IS_ENABLED(CONFIG_DRM_XE_DEBUG)) { + u32 desc_tail = desc_read(xe, h2g, tail); + u32 desc_head = desc_read(xe, h2g, head); + + if (tail != desc_tail) { + desc_write(xe, h2g, status, desc_status | GUC_CTB_STATUS_MISMATCH); + xe_gt_err(gt, "CT write: tail was modified %u != %u\n", desc_tail, tail); + goto corrupted; + } + + if (tail > h2g->info.size) { + desc_write(xe, h2g, status, desc_status | GUC_CTB_STATUS_OVERFLOW); + xe_gt_err(gt, "CT write: tail out of range: %u vs %u\n", + tail, h2g->info.size); + goto corrupted; + } + + if (desc_head >= h2g->info.size) { + desc_write(xe, h2g, status, desc_status | GUC_CTB_STATUS_OVERFLOW); + xe_gt_err(gt, "CT write: invalid head offset %u >= %u)\n", + desc_head, h2g->info.size); + goto corrupted; + } + } /* Command will wrap, zero fill (NOPs), return and check credits again */ if (tail + full_len > h2g->info.size) { @@ -611,6 +721,10 @@ static int h2g_write(struct xe_guc_ct *ct, const u32 *action, u32 len, desc_read(xe, h2g, head), h2g->info.tail); return 0; + +corrupted: + CT_DEAD(ct, &ct->ctbs.h2g, H2G_WRITE); + return -EPIPE; } /* @@ -718,7 +832,6 @@ static int guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, u32 len, { struct xe_device *xe = ct_to_xe(ct); struct xe_gt *gt = ct_to_gt(ct); - struct drm_printer p = xe_gt_info_printer(gt); unsigned int sleep_period_ms = 1; int ret; @@ -771,8 +884,13 @@ static int guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, u32 len, goto broken; #undef g2h_avail - if (dequeue_one_g2h(ct) < 0) + ret = dequeue_one_g2h(ct); + if (ret < 0) { + if (ret != -ECANCELED) + xe_gt_err(ct_to_gt(ct), "CTB receive failed (%pe)", + ERR_PTR(ret)); goto broken; + } goto try_again; } @@ -781,8 +899,7 @@ static int guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, u32 len, broken: xe_gt_err(gt, "No forward process on H2G, reset required\n"); - xe_guc_ct_print(ct, &p, true); - ct->ctbs.h2g.info.broken = true; + CT_DEAD(ct, &ct->ctbs.h2g, DEADLOCK); return -EDEADLK; } @@ -1021,6 +1138,7 @@ static int parse_g2h_response(struct xe_guc_ct *ct, u32 *msg, u32 len) else xe_gt_err(gt, "unexpected response %u for FAST_REQ H2G fence 0x%x!\n", type, fence); + CT_DEAD(ct, NULL, PARSE_G2H_RESPONSE); return -EPROTO; } @@ -1028,6 +1146,7 @@ static int parse_g2h_response(struct xe_guc_ct *ct, u32 *msg, u32 len) g2h_fence = xa_erase(&ct->fence_lookup, fence); if (unlikely(!g2h_fence)) { /* Don't tear down channel, as send could've timed out */ + /* CT_DEAD(ct, NULL, PARSE_G2H_UNKNOWN); */ xe_gt_warn(gt, "G2H fence (%u) not found!\n", fence); g2h_release_space(ct, GUC_CTB_HXG_MSG_MAX_LEN); return 0; @@ -1072,7 +1191,7 @@ static int parse_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len) if (unlikely(origin != GUC_HXG_ORIGIN_GUC)) { xe_gt_err(gt, "G2H channel broken on read, origin=%u, reset required\n", origin); - ct->ctbs.g2h.info.broken = true; + CT_DEAD(ct, &ct->ctbs.g2h, PARSE_G2H_ORIGIN); return -EPROTO; } @@ -1090,7 +1209,7 @@ static int parse_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len) default: xe_gt_err(gt, "G2H channel broken on read, type=%u, reset required\n", type); - ct->ctbs.g2h.info.broken = true; + CT_DEAD(ct, &ct->ctbs.g2h, PARSE_G2H_TYPE); ret = -EOPNOTSUPP; } @@ -1167,9 +1286,11 @@ static int process_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len) xe_gt_err(gt, "unexpected G2H action 0x%04x\n", action); } - if (ret) + if (ret) { xe_gt_err(gt, "G2H action 0x%04x failed (%pe)\n", action, ERR_PTR(ret)); + CT_DEAD(ct, NULL, PROCESS_FAILED); + } return 0; } @@ -1179,7 +1300,7 @@ static int g2h_read(struct xe_guc_ct *ct, u32 *msg, bool fast_path) struct xe_device *xe = ct_to_xe(ct); struct xe_gt *gt = ct_to_gt(ct); struct guc_ctb *g2h = &ct->ctbs.g2h; - u32 tail, head, len; + u32 tail, head, len, desc_status; s32 avail; u32 action; u32 *hxg; @@ -1198,6 +1319,63 @@ static int g2h_read(struct xe_guc_ct *ct, u32 *msg, bool fast_path) xe_gt_assert(gt, xe_guc_ct_enabled(ct)); + desc_status = desc_read(xe, g2h, status); + if (desc_status) { + if (desc_status & GUC_CTB_STATUS_DISABLED) { + /* + * Potentially valid if a CLIENT_RESET request resulted in + * contexts/engines being reset. But should never happen as + * no contexts should be active when CLIENT_RESET is sent. + */ + xe_gt_err(gt, "CT read: unexpected G2H after GuC has stopped!\n"); + desc_status &= ~GUC_CTB_STATUS_DISABLED; + } + + if (desc_status) { + xe_gt_err(gt, "CT read: non-zero status: %u\n", desc_status); + goto corrupted; + } + } + + if (IS_ENABLED(CONFIG_DRM_XE_DEBUG)) { + u32 desc_tail = desc_read(xe, g2h, tail); + /* + u32 desc_head = desc_read(xe, g2h, head); + + * info.head and desc_head are updated back-to-back at the end of + * this function and nowhere else. Hence, they cannot be different + * unless two g2h_read calls are running concurrently. Which is not + * possible because it is guarded by ct->fast_lock. And yet, some + * discrete platforms are reguarly hitting this error :(. + * + * desc_head rolling backwards shouldn't cause any noticeable + * problems - just a delay in GuC being allowed to proceed past that + * point in the queue. So for now, just disable the error until it + * can be root caused. + * + if (g2h->info.head != desc_head) { + desc_write(xe, g2h, status, desc_status | GUC_CTB_STATUS_MISMATCH); + xe_gt_err(gt, "CT read: head was modified %u != %u\n", + desc_head, g2h->info.head); + goto corrupted; + } + */ + + if (g2h->info.head > g2h->info.size) { + desc_write(xe, g2h, status, desc_status | GUC_CTB_STATUS_OVERFLOW); + xe_gt_err(gt, "CT read: head out of range: %u vs %u\n", + g2h->info.head, g2h->info.size); + goto corrupted; + } + + if (desc_tail >= g2h->info.size) { + desc_write(xe, g2h, status, desc_status | GUC_CTB_STATUS_OVERFLOW); + xe_gt_err(gt, "CT read: invalid tail offset %u >= %u)\n", + desc_tail, g2h->info.size); + goto corrupted; + } + } + /* Calculate DW available to read */ tail = desc_read(xe, g2h, tail); avail = tail - g2h->info.head; @@ -1214,9 +1392,7 @@ static int g2h_read(struct xe_guc_ct *ct, u32 *msg, bool fast_path) if (len > avail) { xe_gt_err(gt, "G2H channel broken on read, avail=%d, len=%d, reset required\n", avail, len); - g2h->info.broken = true; - - return -EPROTO; + goto corrupted; } head = (g2h->info.head + 1) % g2h->info.size; @@ -1262,6 +1438,10 @@ static int g2h_read(struct xe_guc_ct *ct, u32 *msg, bool fast_path) action, len, g2h->info.head, tail); return len; + +corrupted: + CT_DEAD(ct, &ct->ctbs.g2h, G2H_READ); + return -EPROTO; } static void g2h_fast_path(struct xe_guc_ct *ct, u32 *msg, u32 len) @@ -1288,9 +1468,11 @@ static void g2h_fast_path(struct xe_guc_ct *ct, u32 *msg, u32 len) xe_gt_warn(gt, "NOT_POSSIBLE"); } - if (ret) + if (ret) { xe_gt_err(gt, "G2H action 0x%04x failed (%pe)\n", action, ERR_PTR(ret)); + CT_DEAD(ct, NULL, FAST_G2H); + } } /** @@ -1350,7 +1532,6 @@ static int dequeue_one_g2h(struct xe_guc_ct *ct) static void receive_g2h(struct xe_guc_ct *ct) { - struct xe_gt *gt = ct_to_gt(ct); bool ongoing; int ret; @@ -1387,9 +1568,8 @@ static void receive_g2h(struct xe_guc_ct *ct) mutex_unlock(&ct->lock); if (unlikely(ret == -EPROTO || ret == -EOPNOTSUPP)) { - struct drm_printer p = xe_gt_info_printer(gt); - - xe_guc_ct_print(ct, &p, false); + xe_gt_err(ct_to_gt(ct), "CT dequeue failed: %d", ret); + CT_DEAD(ct, NULL, G2H_RECV); kick_reset(ct); } } while (ret == 1); @@ -1417,9 +1597,8 @@ static void guc_ctb_snapshot_capture(struct xe_device *xe, struct guc_ctb *ctb, snapshot->cmds = kmalloc_array(ctb->info.size, sizeof(u32), atomic ? GFP_ATOMIC : GFP_KERNEL); - if (!snapshot->cmds) { - drm_err(&xe->drm, "Skipping CTB commands snapshot. Only CTB info will be available.\n"); + drm_err(&xe->drm, "Skipping CTB commands snapshot. Only CT info will be available.\n"); return; } @@ -1500,7 +1679,7 @@ struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, atomic ? GFP_ATOMIC : GFP_KERNEL); if (!snapshot) { - drm_err(&xe->drm, "Skipping CTB snapshot entirely.\n"); + xe_gt_err(ct_to_gt(ct), "Skipping CTB snapshot entirely.\n"); return NULL; } @@ -1564,16 +1743,119 @@ void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot) * xe_guc_ct_print - GuC CT Print. * @ct: GuC CT. * @p: drm_printer where it will be printed out. - * @atomic: Boolean to indicate if this is called from atomic context like - * reset or CTB handler or from some regular path like debugfs. * * This function quickly capture a snapshot and immediately print it out. */ -void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p, bool atomic) +void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p) { struct xe_guc_ct_snapshot *snapshot; - snapshot = xe_guc_ct_snapshot_capture(ct, atomic); + snapshot = xe_guc_ct_snapshot_capture(ct, false); xe_guc_ct_snapshot_print(snapshot, p); xe_guc_ct_snapshot_free(snapshot); } + +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) +static void ct_dead_capture(struct xe_guc_ct *ct, struct guc_ctb *ctb, u32 reason_code) +{ + struct xe_guc_log_snapshot *snapshot_log; + struct xe_guc_ct_snapshot *snapshot_ct; + struct xe_guc *guc = ct_to_guc(ct); + unsigned long flags; + bool have_capture; + + if (ctb) + ctb->info.broken = true; + + /* Ignore further errors after the first dump until a reset */ + if (ct->dead.reported) + return; + + spin_lock_irqsave(&ct->dead.lock, flags); + + /* And only capture one dump at a time */ + have_capture = ct->dead.reason & (1 << CT_DEAD_STATE_CAPTURE); + ct->dead.reason |= (1 << reason_code) | + (1 << CT_DEAD_STATE_CAPTURE); + + spin_unlock_irqrestore(&ct->dead.lock, flags); + + if (have_capture) + return; + + snapshot_log = xe_guc_log_snapshot_capture(&guc->log, true); + snapshot_ct = xe_guc_ct_snapshot_capture((ct), true); + + spin_lock_irqsave(&ct->dead.lock, flags); + + if (ct->dead.snapshot_log || ct->dead.snapshot_ct) { + xe_gt_err(ct_to_gt(ct), "Got unexpected dead CT capture!\n"); + xe_guc_log_snapshot_free(snapshot_log); + xe_guc_ct_snapshot_free(snapshot_ct); + } else { + ct->dead.snapshot_log = snapshot_log; + ct->dead.snapshot_ct = snapshot_ct; + } + + spin_unlock_irqrestore(&ct->dead.lock, flags); + + queue_work(system_unbound_wq, &(ct)->dead.worker); +} + +static void ct_dead_print(struct xe_dead_ct *dead) +{ + struct xe_guc_ct *ct = container_of(dead, struct xe_guc_ct, dead); + struct xe_device *xe = ct_to_xe(ct); + struct xe_gt *gt = ct_to_gt(ct); + static int g_count; + struct drm_printer ip = xe_gt_info_printer(gt); + struct drm_printer lp = drm_line_printer(&ip, "Capture", ++g_count); + + if (!dead->reason) { + xe_gt_err(gt, "CTB is dead for no reason!?\n"); + return; + } + + drm_printf(&lp, "CTB is dead - reason=0x%X\n", dead->reason); + + /* Can't generate a genuine core dump at this point, so just do the good bits */ + drm_puts(&lp, "**** Xe Device Coredump ****\n"); + xe_device_snapshot_print(xe, &lp); + + drm_printf(&lp, "**** GT #%d ****\n", gt->info.id); + drm_printf(&lp, "\tTile: %d\n", gt->tile->id); + + drm_puts(&lp, "**** GuC Log ****\n"); + xe_guc_log_snapshot_print(dead->snapshot_log, &lp); + + drm_puts(&lp, "**** GuC CT ****\n"); + xe_guc_ct_snapshot_print(dead->snapshot_ct, &lp); + + drm_puts(&lp, "Done.\n"); +} + +static void ct_dead_worker_func(struct work_struct *w) +{ + struct xe_guc_ct *ct = container_of(w, struct xe_guc_ct, dead.worker); + + if (!ct->dead.reported) { + ct->dead.reported = true; + ct_dead_print(&ct->dead); + } + + spin_lock_irq(&ct->dead.lock); + + xe_guc_log_snapshot_free(ct->dead.snapshot_log); + ct->dead.snapshot_log = NULL; + xe_guc_ct_snapshot_free(ct->dead.snapshot_ct); + ct->dead.snapshot_ct = NULL; + + if (ct->dead.reason & (1 << CT_DEAD_STATE_REARM)) { + /* A reset has occurred so re-arm the error reporting */ + ct->dead.reason = 0; + ct->dead.reported = false; + } + + spin_unlock_irq(&ct->dead.lock); +} +#endif diff --git a/drivers/gpu/drm/xe/xe_guc_ct.h b/drivers/gpu/drm/xe/xe_guc_ct.h index 190202fce2d0..293041bed7ed 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.h +++ b/drivers/gpu/drm/xe/xe_guc_ct.h @@ -21,7 +21,7 @@ xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic); void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, struct drm_printer *p); void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot); -void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p, bool atomic); +void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p); static inline bool xe_guc_ct_enabled(struct xe_guc_ct *ct) { diff --git a/drivers/gpu/drm/xe/xe_guc_ct_types.h b/drivers/gpu/drm/xe/xe_guc_ct_types.h index 761cb9031298..85e127ec91d7 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct_types.h +++ b/drivers/gpu/drm/xe/xe_guc_ct_types.h @@ -86,6 +86,24 @@ enum xe_guc_ct_state { XE_GUC_CT_STATE_ENABLED, }; +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) +/** struct xe_dead_ct - Information for debugging a dead CT */ +struct xe_dead_ct { + /** @lock: protects memory allocation/free operations, and @reason updates */ + spinlock_t lock; + /** @reason: bit mask of CT_DEAD_* reason codes */ + unsigned int reason; + /** @reported: for preventing multiple dumps per error sequence */ + bool reported; + /** @worker: worker thread to get out of interrupt context before dumping */ + struct work_struct worker; + /** snapshot_ct: copy of CT state and CTB content at point of error */ + struct xe_guc_ct_snapshot *snapshot_ct; + /** snapshot_log: copy of GuC log at point of error */ + struct xe_guc_log_snapshot *snapshot_log; +}; +#endif + /** * struct xe_guc_ct - GuC command transport (CT) layer * @@ -128,6 +146,11 @@ struct xe_guc_ct { u32 msg[GUC_CTB_MSG_MAX_LEN]; /** @fast_msg: Message buffer */ u32 fast_msg[GUC_CTB_MSG_MAX_LEN]; + +#if IS_ENABLED(CONFIG_DRM_XE_DEBUG) + /** @dead: information for debugging dead CTs */ + struct xe_dead_ct dead; +#endif }; #endif -- GitLab From d7c925b2995f5cae3ad405f8988ad821d0dd0287 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:09 -0700 Subject: [PATCH 759/970] drm/xe/guc: Dump entire CTB on errors The dump of the CT buffers was only showing the unprocessed data which is not generally useful for saying why a hang occurred - because it was probably caused by the commands that were just processed. So save and dump the entire buffer but in a more compact dump format. Also zero fill it on allocation to avoid confusion over uninitialised data in the dump. v2: Add kerneldoc - review feedback from Michal W. v3: Fix kerneldoc. v4: Use ascii85 instead of hexdump (review feedback from Matthew B). v5: Dump the entire CTB object rather than separately dumping just the H2G and G2H sections. That way it includes the full header info. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-10-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_guc_ct.c | 94 ++++++++++------------------ drivers/gpu/drm/xe/xe_guc_ct.h | 8 +-- drivers/gpu/drm/xe/xe_guc_ct_types.h | 6 +- 3 files changed, 41 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 79571c9d180e..b7f80449bd83 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -18,6 +18,7 @@ #include "abi/guc_actions_sriov_abi.h" #include "abi/guc_klvs_abi.h" #include "xe_bo.h" +#include "xe_devcoredump.h" #include "xe_device.h" #include "xe_gt.h" #include "xe_gt_pagefault.h" @@ -437,6 +438,7 @@ int xe_guc_ct_enable(struct xe_guc_ct *ct) xe_gt_assert(gt, !xe_guc_ct_enabled(ct)); + xe_map_memset(xe, &ct->bo->vmap, 0, 0, ct->bo->size); guc_ct_ctb_h2g_init(xe, &ct->ctbs.h2g, &ct->bo->vmap); guc_ct_ctb_g2h_init(xe, &ct->ctbs.g2h, &ct->bo->vmap); @@ -1585,48 +1587,33 @@ static void g2h_worker_func(struct work_struct *w) receive_g2h(ct); } -static void guc_ctb_snapshot_capture(struct xe_device *xe, struct guc_ctb *ctb, - struct guc_ctb_snapshot *snapshot, - bool atomic) +struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic) { - u32 head, tail; + struct xe_guc_ct_snapshot *snapshot; - xe_map_memcpy_from(xe, &snapshot->desc, &ctb->desc, 0, - sizeof(struct guc_ct_buffer_desc)); - memcpy(&snapshot->info, &ctb->info, sizeof(struct guc_ctb_info)); + snapshot = kzalloc(sizeof(*snapshot), atomic ? GFP_ATOMIC : GFP_KERNEL); + if (!snapshot) + return NULL; - snapshot->cmds = kmalloc_array(ctb->info.size, sizeof(u32), - atomic ? GFP_ATOMIC : GFP_KERNEL); - if (!snapshot->cmds) { - drm_err(&xe->drm, "Skipping CTB commands snapshot. Only CT info will be available.\n"); - return; + if (ct->bo) { + snapshot->ctb_size = ct->bo->size; + snapshot->ctb = kmalloc(snapshot->ctb_size, atomic ? GFP_ATOMIC : GFP_KERNEL); } - head = snapshot->desc.head; - tail = snapshot->desc.tail; - - if (head != tail) { - struct iosys_map map = - IOSYS_MAP_INIT_OFFSET(&ctb->cmds, head * sizeof(u32)); - - while (head != tail) { - snapshot->cmds[head] = xe_map_rd(xe, &map, 0, u32); - ++head; - if (head == ctb->info.size) { - head = 0; - map = ctb->cmds; - } else { - iosys_map_incr(&map, sizeof(u32)); - } - } - } + return snapshot; +} + +static void guc_ctb_snapshot_capture(struct xe_device *xe, struct guc_ctb *ctb, + struct guc_ctb_snapshot *snapshot) +{ + xe_map_memcpy_from(xe, &snapshot->desc, &ctb->desc, 0, + sizeof(struct guc_ct_buffer_desc)); + memcpy(&snapshot->info, &ctb->info, sizeof(struct guc_ctb_info)); } static void guc_ctb_snapshot_print(struct guc_ctb_snapshot *snapshot, struct drm_printer *p) { - u32 head, tail; - drm_printf(p, "\tsize: %d\n", snapshot->info.size); drm_printf(p, "\tresv_space: %d\n", snapshot->info.resv_space); drm_printf(p, "\thead: %d\n", snapshot->info.head); @@ -1636,25 +1623,6 @@ static void guc_ctb_snapshot_print(struct guc_ctb_snapshot *snapshot, drm_printf(p, "\thead (memory): %d\n", snapshot->desc.head); drm_printf(p, "\ttail (memory): %d\n", snapshot->desc.tail); drm_printf(p, "\tstatus (memory): 0x%x\n", snapshot->desc.status); - - if (!snapshot->cmds) - return; - - head = snapshot->desc.head; - tail = snapshot->desc.tail; - - while (head != tail) { - drm_printf(p, "\tcmd[%d]: 0x%08x\n", head, - snapshot->cmds[head]); - ++head; - if (head == snapshot->info.size) - head = 0; - } -} - -static void guc_ctb_snapshot_free(struct guc_ctb_snapshot *snapshot) -{ - kfree(snapshot->cmds); } /** @@ -1675,9 +1643,7 @@ struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, struct xe_device *xe = ct_to_xe(ct); struct xe_guc_ct_snapshot *snapshot; - snapshot = kzalloc(sizeof(*snapshot), - atomic ? GFP_ATOMIC : GFP_KERNEL); - + snapshot = xe_guc_ct_snapshot_alloc(ct, atomic); if (!snapshot) { xe_gt_err(ct_to_gt(ct), "Skipping CTB snapshot entirely.\n"); return NULL; @@ -1686,12 +1652,13 @@ struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, if (xe_guc_ct_enabled(ct) || ct->state == XE_GUC_CT_STATE_STOPPED) { snapshot->ct_enabled = true; snapshot->g2h_outstanding = READ_ONCE(ct->g2h_outstanding); - guc_ctb_snapshot_capture(xe, &ct->ctbs.h2g, - &snapshot->h2g, atomic); - guc_ctb_snapshot_capture(xe, &ct->ctbs.g2h, - &snapshot->g2h, atomic); + guc_ctb_snapshot_capture(xe, &ct->ctbs.h2g, &snapshot->h2g); + guc_ctb_snapshot_capture(xe, &ct->ctbs.g2h, &snapshot->g2h); } + if (ct->bo && snapshot->ctb) + xe_map_memcpy_from(xe, snapshot->ctb, &ct->bo->vmap, 0, snapshot->ctb_size); + return snapshot; } @@ -1714,9 +1681,15 @@ void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, drm_puts(p, "G2H CTB (all sizes in DW):\n"); guc_ctb_snapshot_print(&snapshot->g2h, p); - drm_printf(p, "\tg2h outstanding: %d\n", snapshot->g2h_outstanding); + + if (snapshot->ctb) { + xe_print_blob_ascii85(p, "CTB data", snapshot->ctb, 0, snapshot->ctb_size); + } else { + drm_printf(p, "CTB snapshot missing!\n"); + return; + } } else { drm_puts(p, "CT disabled\n"); } @@ -1734,8 +1707,7 @@ void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot) if (!snapshot) return; - guc_ctb_snapshot_free(&snapshot->h2g); - guc_ctb_snapshot_free(&snapshot->g2h); + kfree(snapshot->ctb); kfree(snapshot); } diff --git a/drivers/gpu/drm/xe/xe_guc_ct.h b/drivers/gpu/drm/xe/xe_guc_ct.h index 293041bed7ed..338f0b75d29f 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.h +++ b/drivers/gpu/drm/xe/xe_guc_ct.h @@ -9,6 +9,7 @@ #include "xe_guc_ct_types.h" struct drm_printer; +struct xe_device; int xe_guc_ct_init(struct xe_guc_ct *ct); int xe_guc_ct_enable(struct xe_guc_ct *ct); @@ -16,10 +17,9 @@ void xe_guc_ct_disable(struct xe_guc_ct *ct); void xe_guc_ct_stop(struct xe_guc_ct *ct); void xe_guc_ct_fast_path(struct xe_guc_ct *ct); -struct xe_guc_ct_snapshot * -xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic); -void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, - struct drm_printer *p); +struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bool atomic); +struct xe_guc_ct_snapshot *xe_guc_ct_snapshot_capture(struct xe_guc_ct *ct, bool atomic); +void xe_guc_ct_snapshot_print(struct xe_guc_ct_snapshot *snapshot, struct drm_printer *p); void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot); void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p); diff --git a/drivers/gpu/drm/xe/xe_guc_ct_types.h b/drivers/gpu/drm/xe/xe_guc_ct_types.h index 85e127ec91d7..8e1b9d981d61 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct_types.h +++ b/drivers/gpu/drm/xe/xe_guc_ct_types.h @@ -52,8 +52,6 @@ struct guc_ctb { struct guc_ctb_snapshot { /** @desc: snapshot of the CTB descriptor */ struct guc_ct_buffer_desc desc; - /** @cmds: snapshot of the CTB commands */ - u32 *cmds; /** @info: snapshot of the CTB info */ struct guc_ctb_info info; }; @@ -70,6 +68,10 @@ struct xe_guc_ct_snapshot { struct guc_ctb_snapshot g2h; /** @h2g: H2G CTB snapshot */ struct guc_ctb_snapshot h2g; + /** @ctb_size: size of the snapshot of the CTB */ + size_t ctb_size; + /** @ctb: snapshot of the entire CTB */ + u32 *ctb; }; /** -- GitLab From 8b7dfb985532c69729d3b266a68fa379cd359f55 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:10 -0700 Subject: [PATCH 760/970] drm/xe/guc: Add GuC log to devcoredump captures Include the GuC log in devcoredump captures because they can be useful with debugging certain types of bug. v2: Fix kerneldoc v3: Drop module parameter as now using more compact ascii85 encoding rather than hexdump (although still not compressed) (review feedback from Matthew B). Rebase onto recent refactoring of devcoredump code. v4: Don't move the submission snapshot inside the GuC internals structure 'cos it really doesn't belong there. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-11-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_devcoredump.c | 16 ++++++++++++---- drivers/gpu/drm/xe/xe_devcoredump_types.h | 10 +++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index 0884c49942fe..a2d816713489 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -18,8 +18,10 @@ #include "xe_gt.h" #include "xe_gt_printk.h" #include "xe_guc_ct.h" +#include "xe_guc_log.h" #include "xe_guc_submit.h" #include "xe_hw_engine.h" +#include "xe_module.h" #include "xe_sched_job.h" #include "xe_vm.h" @@ -100,8 +102,10 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, drm_printf(&p, "\n**** GT #%d ****\n", ss->gt->info.id); drm_printf(&p, "\tTile: %d\n", ss->gt->tile->id); + drm_puts(&p, "\n**** GuC Log ****\n"); + xe_guc_log_snapshot_print(ss->guc.log, &p); drm_puts(&p, "\n**** GuC CT ****\n"); - xe_guc_ct_snapshot_print(ss->ct, &p); + xe_guc_ct_snapshot_print(ss->guc.ct, &p); drm_puts(&p, "\n**** Contexts ****\n"); xe_guc_exec_queue_snapshot_print(ss->ge, &p); @@ -124,8 +128,11 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss) { int i; - xe_guc_ct_snapshot_free(ss->ct); - ss->ct = NULL; + xe_guc_log_snapshot_free(ss->guc.log); + ss->guc.log = NULL; + + xe_guc_ct_snapshot_free(ss->guc.ct); + ss->guc.ct = NULL; xe_guc_exec_queue_snapshot_free(ss->ge); ss->ge = NULL; @@ -253,7 +260,8 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump, if (xe_force_wake_get(gt_to_fw(q->gt), XE_FORCEWAKE_ALL)) xe_gt_info(ss->gt, "failed to get forcewake for coredump capture\n"); - ss->ct = xe_guc_ct_snapshot_capture(&guc->ct, true); + ss->guc.log = xe_guc_log_snapshot_capture(&guc->log, true); + ss->guc.ct = xe_guc_ct_snapshot_capture(&guc->ct, true); ss->ge = xe_guc_exec_queue_snapshot_capture(q); ss->job = xe_sched_job_snapshot_capture(job); ss->vm = xe_vm_snapshot_capture(q->vm); diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h index 3cc2f095fdfb..06ac75ce63dd 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump_types.h +++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h @@ -34,9 +34,13 @@ struct xe_devcoredump_snapshot { /** @work: Workqueue for deferred capture outside of signaling context */ struct work_struct work; - /* GuC snapshots */ - /** @ct: GuC CT snapshot */ - struct xe_guc_ct_snapshot *ct; + /** @guc: GuC snapshots */ + struct { + /** @guc.ct: GuC CT snapshot */ + struct xe_guc_ct_snapshot *ct; + /** @guc.log: GuC log snapshot */ + struct xe_guc_log_snapshot *log; + } guc; /** @ge: GuC Submission Engine snapshot */ struct xe_guc_submit_exec_queue_snapshot *ge; -- GitLab From 691b5a6af36022648a0aa23899515a466eccbb61 Mon Sep 17 00:00:00 2001 From: John Harrison <John.C.Harrison@Intel.com> Date: Wed, 2 Oct 2024 17:46:11 -0700 Subject: [PATCH 761/970] drm/xe/guc: Add a helper function for dumping GuC log to dmesg Create a helper function that can be used to dump the GuC log to dmesg in a manner that is reliable for extraction and decode. The intention is that calls to this can be added by developers when debugging specific issues that require a GuC log but do not allow easy capture of the log - e.g. failures in selftests and failues that lead to kernel hangs. Also note that this is really a temporary stop-gap. The aim is to allow on demand creation and dumping of devcoredump captures (which includes the GuC log and much more). Currently this is not possible as much of the devcoredump code requires a 'struct xe_sched_job' and those are not available at many places that might want to do the dump. v2: Add kerneldoc - review feedback from Michal W. Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Julia Filipchuk <julia.filipchuk@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003004611.2323493-12-John.C.Harrison@Intel.com --- drivers/gpu/drm/xe/xe_guc_log.c | 18 ++++++++++++++++++ drivers/gpu/drm/xe/xe_guc_log.h | 1 + 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index 79e01d724509..7fbc56cceaba 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -216,6 +216,24 @@ void xe_guc_log_snapshot_print(struct xe_guc_log_snapshot *snapshot, struct drm_ } } +/** + * xe_guc_log_print_dmesg - dump a copy of the GuC log to dmesg + * @log: GuC log structure + */ +void xe_guc_log_print_dmesg(struct xe_guc_log *log) +{ + struct xe_gt *gt = log_to_gt(log); + static int g_count; + struct drm_printer ip = xe_gt_info_printer(gt); + struct drm_printer lp = drm_line_printer(&ip, "Capture", ++g_count); + + drm_printf(&lp, "Dumping GuC log for %ps...\n", __builtin_return_address(0)); + + xe_guc_log_print(log, &lp); + + drm_printf(&lp, "Done.\n"); +} + /** * xe_guc_log_print - dump a copy of the GuC log to some useful location * @log: GuC log structure diff --git a/drivers/gpu/drm/xe/xe_guc_log.h b/drivers/gpu/drm/xe/xe_guc_log.h index 949d2c98343d..1fb2fae1f4e1 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.h +++ b/drivers/gpu/drm/xe/xe_guc_log.h @@ -39,6 +39,7 @@ struct xe_device; int xe_guc_log_init(struct xe_guc_log *log); void xe_guc_log_print(struct xe_guc_log *log, struct drm_printer *p); +void xe_guc_log_print_dmesg(struct xe_guc_log *log); struct xe_guc_log_snapshot *xe_guc_log_snapshot_capture(struct xe_guc_log *log, bool atomic); void xe_guc_log_snapshot_print(struct xe_guc_log_snapshot *snapshot, struct drm_printer *p); void xe_guc_log_snapshot_free(struct xe_guc_log_snapshot *snapshot); -- GitLab From 56c594d8df64e726e803652ee9f4ab08659d4574 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Date: Thu, 3 Oct 2024 14:43:09 +0200 Subject: [PATCH 762/970] drm: add DRM_SET_CLIENT_NAME ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Giving the opportunity to userspace to associate a free-form name with a drm_file struct is helpful for tracking and debugging. This is similar to the existing DMA_BUF_SET_NAME ioctl. Access to client_name is protected by a mutex, and the 'clients' debugfs file has been updated to print it. Userspace MR to use this ioctl: https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1428 If the string passed by userspace contains chars that would mess up output when it's going to be printed (in dmesg, fdinfo, etc), -EINVAL is returned. A 0-length string is a valid use, and clears the existing name. Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003124506.470931-2-pierre-eric.pelloux-prayer@amd.com Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/drm_debugfs.c | 14 +++++++--- drivers/gpu/drm/drm_file.c | 5 ++++ drivers/gpu/drm/drm_ioctl.c | 51 +++++++++++++++++++++++++++++++++++ include/drm/drm_file.h | 9 +++++++ include/uapi/drm/drm.h | 17 ++++++++++++ 5 files changed, 92 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 6b239a24f1df..5c99322a4c6f 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -78,12 +78,14 @@ static int drm_clients_info(struct seq_file *m, void *data) kuid_t uid; seq_printf(m, - "%20s %5s %3s master a %5s %10s\n", + "%20s %5s %3s master a %5s %10s %*s\n", "command", "tgid", "dev", "uid", - "magic"); + "magic", + DRM_CLIENT_NAME_MAX_LEN, + "name"); /* dev->filelist is sorted youngest first, but we want to present * oldest first (i.e. kernel, servers, clients), so walk backwardss. @@ -94,19 +96,23 @@ static int drm_clients_info(struct seq_file *m, void *data) struct task_struct *task; struct pid *pid; + mutex_lock(&priv->client_name_lock); rcu_read_lock(); /* Locks priv->pid and pid_task()->comm! */ pid = rcu_dereference(priv->pid); task = pid_task(pid, PIDTYPE_TGID); uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID; - seq_printf(m, "%20s %5d %3d %c %c %5d %10u\n", + seq_printf(m, "%20s %5d %3d %c %c %5d %10u %*s\n", task ? task->comm : "<unknown>", pid_vnr(pid), priv->minor->index, is_current_master ? 'y' : 'n', priv->authenticated ? 'y' : 'n', from_kuid_munged(seq_user_ns(m), uid), - priv->magic); + priv->magic, + DRM_CLIENT_NAME_MAX_LEN, + priv->client_name ? priv->client_name : "<unset>"); rcu_read_unlock(); + mutex_unlock(&priv->client_name_lock); } mutex_unlock(&dev->filelist_mutex); return 0; diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index ad1dc638c83b..65c40ce3d61c 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -157,6 +157,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) spin_lock_init(&file->master_lookup_lock); mutex_init(&file->event_read_lock); + mutex_init(&file->client_name_lock); if (drm_core_check_feature(dev, DRIVER_GEM)) drm_gem_open(dev, file); @@ -258,6 +259,10 @@ void drm_file_free(struct drm_file *file) WARN_ON(!list_empty(&file->event_list)); put_pid(rcu_access_pointer(file->pid)); + + mutex_destroy(&file->client_name_lock); + kfree(file->client_name); + kfree(file); } diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 51f39912866f..f593dc569d31 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -540,6 +540,55 @@ int drm_version(struct drm_device *dev, void *data, return err; } +/* + * Check if the passed string contains control char or spaces or + * anything that would mess up a formatted output. + */ +static int drm_validate_value_string(const char *value, size_t len) +{ + int i; + + for (i = 0; i < len; i++) { + if (!isascii(value[i]) || !isgraph(value[i])) + return -EINVAL; + } + return 0; +} + +static int drm_set_client_name(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_set_client_name *name = data; + size_t len = name->name_len; + void __user *user_ptr; + char *new_name; + + if (len > DRM_CLIENT_NAME_MAX_LEN) { + return -EINVAL; + } else if (len) { + user_ptr = u64_to_user_ptr(name->name); + + new_name = memdup_user_nul(user_ptr, len); + if (IS_ERR(new_name)) + return PTR_ERR(new_name); + + if (strlen(new_name) != len || + drm_validate_value_string(new_name, len) < 0) { + kfree(new_name); + return -EINVAL; + } + } else { + new_name = NULL; + } + + mutex_lock(&file_priv->client_name_lock); + kfree(file_priv->client_name); + file_priv->client_name = new_name; + mutex_unlock(&file_priv->client_name_lock); + + return 0; +} + static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) { /* ROOT_ONLY is only for CAP_SYS_ADMIN */ @@ -610,6 +659,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_NAME, drm_set_client_name, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER), diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 8c0030c77308..d4f1c115ea0f 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -388,6 +388,15 @@ struct drm_file { * Per-file buffer caches used by the PRIME buffer sharing code. */ struct drm_prime_file_private prime; + + /** + * @client_name: + * + * Userspace-provided name; useful for accounting and debugging. + */ + const char *client_name; + /** @name_lock: Protects @client_name. */ + struct mutex client_name_lock; }; /** diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 16122819edfe..7fba37b94401 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -1024,6 +1024,13 @@ struct drm_crtc_queue_sequence { __u64 user_data; /* user data passed to event */ }; +#define DRM_CLIENT_NAME_MAX_LEN 64 +struct drm_set_client_name { + __u64 name_len; + __u64 name; +}; + + #if defined(__cplusplus) } #endif @@ -1288,6 +1295,16 @@ extern "C" { */ #define DRM_IOCTL_MODE_CLOSEFB DRM_IOWR(0xD0, struct drm_mode_closefb) +/** + * DRM_IOCTL_SET_CLIENT_NAME - Attach a name to a drm_file + * + * Having a name allows for easier tracking and debugging. + * The length of the name (without null ending char) must be + * <= DRM_CLIENT_NAME_MAX_LEN. + * The call will fail if the name contains whitespaces or non-printable chars. + */ +#define DRM_IOCTL_SET_CLIENT_NAME DRM_IOWR(0xD1, struct drm_set_client_name) + /* * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. -- GitLab From 2c34a5464007c45142af009d13c668b0630ef9c0 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Date: Thu, 3 Oct 2024 14:43:10 +0200 Subject: [PATCH 763/970] drm: use drm_file client_name in fdinfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional drm-client-name field to drm fdinfo's output. Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003124506.470931-3-pierre-eric.pelloux-prayer@amd.com Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> --- Documentation/gpu/drm-usage-stats.rst | 5 +++++ drivers/gpu/drm/drm_file.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst index a80f95ca1b2f..566e122e6e60 100644 --- a/Documentation/gpu/drm-usage-stats.rst +++ b/Documentation/gpu/drm-usage-stats.rst @@ -73,6 +73,11 @@ scope of each device, in which case `drm-pdev` shall be present as well. Userspace should make sure to not double account any usage statistics by using the above described criteria in order to associate data to individual clients. +- drm-client-name: <valstr> + +String optionally set by userspace using DRM_IOCTL_SET_CLIENT_NAME. + + Utilization ^^^^^^^^^^^ diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 65c40ce3d61c..2ee1c3233b0c 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -955,6 +955,11 @@ void drm_show_fdinfo(struct seq_file *m, struct file *f) PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); } + mutex_lock(&file->client_name_lock); + if (file->client_name) + drm_printf(&p, "drm-client-name:\t%s\n", file->client_name); + mutex_unlock(&file->client_name_lock); + if (dev->driver->show_fdinfo) dev->driver->show_fdinfo(&p, file); } -- GitLab From 9ab440a9d0426cf7842240891cc457155db1a97e Mon Sep 17 00:00:00 2001 From: Shekhar Chauhan <shekhar.chauhan@intel.com> Date: Mon, 7 Oct 2024 08:41:44 -0700 Subject: [PATCH 764/970] drm/xe/ptl: L3bank mask is not available on the media GT On PTL platforms with media version 30.00, the fuse registers for reporting L3 bank availability to the GT just read out as ~0 and do not provide proper values. Xe does not use the L3 bank mask for anything internally; it only passes the mask through to userspace via the GT topology query. Since we don't have any way to get the real L3 bank mask, we don't want to pass garbage to userspace. Passing a zeroed mask or a copy of the primary GT's L3 bank mask would also be inaccurate and likely to cause confusion for userspace. The best approach is to simply not include L3 in the list of masks returned by the topology query in cases where we aren't able to provide a meaningful value. This won't change the behavior for any existing platforms (where we can always obtain L3 masks successfully for all GTs), it will only prevent us from mis-reporting bad information on upcoming platform(s). There's a good chance this will become a formal workaround in the future, but for now we don't have a lineage number so "no_media_l3" is used in place of a lineage as the OOB workaround descriptor. v2: - Re-calculate query size to properly match data returned. (Gustavo) - Update kerneldoc to clarify that the L3bank mask may not be included in the query results if the hardware doesn't make it available. (Gustavo) Cc: Matt Atwood <matthew.s.atwood@intel.com> Cc: Gustavo Sousa <gustavo.sousa@intel.com> Signed-off-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Co-developed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com> Acked-by: Francois Dugast <francois.dugast@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241007154143.2021124-2-matthew.d.roper@intel.com --- drivers/gpu/drm/xe/xe_gt_topology.c | 14 ++++++++++ drivers/gpu/drm/xe/xe_query.c | 42 +++++++++++++++++++++-------- drivers/gpu/drm/xe/xe_wa_oob.rules | 1 + include/uapi/drm/xe_drm.h | 4 ++- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_topology.c b/drivers/gpu/drm/xe/xe_gt_topology.c index 651ba53623e5..df2042db7ee6 100644 --- a/drivers/gpu/drm/xe/xe_gt_topology.c +++ b/drivers/gpu/drm/xe/xe_gt_topology.c @@ -5,6 +5,7 @@ #include "xe_gt_topology.h" +#include <generated/xe_wa_oob.h> #include <linux/bitmap.h> #include <linux/compiler.h> @@ -12,6 +13,7 @@ #include "xe_assert.h" #include "xe_gt.h" #include "xe_mmio.h" +#include "xe_wa.h" static void load_dss_mask(struct xe_gt *gt, xe_dss_mask_t mask, int numregs, ...) @@ -129,6 +131,18 @@ load_l3_bank_mask(struct xe_gt *gt, xe_l3_bank_mask_t l3_bank_mask) struct xe_device *xe = gt_to_xe(gt); u32 fuse3 = xe_mmio_read32(>->mmio, MIRROR_FUSE3); + /* + * PTL platforms with media version 30.00 do not provide proper values + * for the media GT's L3 bank registers. Skip the readout since we + * don't have any way to obtain real values. + * + * This may get re-described as an official workaround in the future, + * but there's no tracking number assigned yet so we use a custom + * OOB workaround descriptor. + */ + if (XE_WA(gt, no_media_l3)) + return; + if (GRAPHICS_VER(xe) >= 20) { xe_l3_bank_mask_t per_node = {}; u32 meml3_en = REG_FIELD_GET(XE2_NODE_ENABLE_MASK, fuse3); diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c index 5246a4a2740e..158629971eab 100644 --- a/drivers/gpu/drm/xe/xe_query.c +++ b/drivers/gpu/drm/xe/xe_query.c @@ -9,6 +9,7 @@ #include <linux/sched/clock.h> #include <drm/ttm/ttm_placement.h> +#include <generated/xe_wa_oob.h> #include <uapi/drm/xe_drm.h> #include "regs/xe_engine_regs.h" @@ -23,6 +24,7 @@ #include "xe_macros.h" #include "xe_mmio.h" #include "xe_ttm_vram_mgr.h" +#include "xe_wa.h" static const u16 xe_to_user_engine_class[] = { [XE_ENGINE_CLASS_RENDER] = DRM_XE_ENGINE_CLASS_RENDER, @@ -455,12 +457,23 @@ static int query_hwconfig(struct xe_device *xe, static size_t calc_topo_query_size(struct xe_device *xe) { - return xe->info.gt_count * - (4 * sizeof(struct drm_xe_query_topology_mask) + - sizeof_field(struct xe_gt, fuse_topo.g_dss_mask) + - sizeof_field(struct xe_gt, fuse_topo.c_dss_mask) + - sizeof_field(struct xe_gt, fuse_topo.l3_bank_mask) + - sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss)); + struct xe_gt *gt; + size_t query_size = 0; + int id; + + for_each_gt(gt, xe, id) { + query_size += 3 * sizeof(struct drm_xe_query_topology_mask) + + sizeof_field(struct xe_gt, fuse_topo.g_dss_mask) + + sizeof_field(struct xe_gt, fuse_topo.c_dss_mask) + + sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss); + + /* L3bank mask may not be available for some GTs */ + if (!XE_WA(gt, no_media_l3)) + query_size += sizeof(struct drm_xe_query_topology_mask) + + sizeof_field(struct xe_gt, fuse_topo.l3_bank_mask); + } + + return query_size; } static int copy_mask(void __user **ptr, @@ -513,11 +526,18 @@ static int query_gt_topology(struct xe_device *xe, if (err) return err; - topo.type = DRM_XE_TOPO_L3_BANK; - err = copy_mask(&query_ptr, &topo, gt->fuse_topo.l3_bank_mask, - sizeof(gt->fuse_topo.l3_bank_mask)); - if (err) - return err; + /* + * If the kernel doesn't have a way to obtain a correct L3bank + * mask, then it's better to omit L3 from the query rather than + * reporting bogus or zeroed information to userspace. + */ + if (!XE_WA(gt, no_media_l3)) { + topo.type = DRM_XE_TOPO_L3_BANK; + err = copy_mask(&query_ptr, &topo, gt->fuse_topo.l3_bank_mask, + sizeof(gt->fuse_topo.l3_bank_mask)); + if (err) + return err; + } topo.type = gt->fuse_topo.eu_type == XE_GT_EU_TYPE_SIMD16 ? DRM_XE_TOPO_SIMD16_EU_PER_DSS : diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules index 920ca5060146..0154fbe154e9 100644 --- a/drivers/gpu/drm/xe/xe_wa_oob.rules +++ b/drivers/gpu/drm/xe/xe_wa_oob.rules @@ -37,3 +37,4 @@ 16023588340 GRAPHICS_VERSION(2001) 14019789679 GRAPHICS_VERSION(1255) GRAPHICS_VERSION_RANGE(1270, 2004) +no_media_l3 MEDIA_VERSION(3000) diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index b6fbe4988f2e..c4182e95a619 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -512,7 +512,9 @@ struct drm_xe_query_gt_list { * containing the following in mask: * ``DSS_COMPUTE ff ff ff ff 00 00 00 00`` * means 32 DSS are available for compute. - * - %DRM_XE_TOPO_L3_BANK - To query the mask of enabled L3 banks + * - %DRM_XE_TOPO_L3_BANK - To query the mask of enabled L3 banks. This type + * may be omitted if the driver is unable to query the mask from the + * hardware. * - %DRM_XE_TOPO_EU_PER_DSS - To query the mask of Execution Units (EU) * available per Dual Sub Slices (DSS). For example a query response * containing the following in mask: -- GitLab From 317d81085c87f12118754df0986b66b3f8581f2d Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Mon, 7 Oct 2024 18:35:04 -0700 Subject: [PATCH 765/970] drm/xe/xe3: Xe3 uses the same PAT settings as Xe2 Xe3 platforms use the same PAT tables as Xe2. Bspec: 71582 Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008013509.61233-2-matthew.s.atwood@intel.com --- drivers/gpu/drm/xe/xe_pat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c index 6bd6adfdfc74..b16473818173 100644 --- a/drivers/gpu/drm/xe/xe_pat.c +++ b/drivers/gpu/drm/xe/xe_pat.c @@ -387,7 +387,7 @@ static const struct xe_pat_ops xe2_pat_ops = { void xe_pat_init_early(struct xe_device *xe) { - if (GRAPHICS_VER(xe) == 20) { + if (GRAPHICS_VER(xe) == 30 || GRAPHICS_VER(xe) == 20) { xe->pat.ops = &xe2_pat_ops; xe->pat.table = xe2_pat_table; -- GitLab From 800d75bf20ae429698ecf7a8a392b638f86f9642 Mon Sep 17 00:00:00 2001 From: Haridhar Kalvala <haridhar.kalvala@intel.com> Date: Mon, 7 Oct 2024 18:35:05 -0700 Subject: [PATCH 766/970] drm/xe/xe3: Define Xe3 feature flags Define a common set of Xe3 feature flags and definitions that will be used for all platforms in this family. The feature flags are inherited unchanged from the Xe2 (XE2_FEATURES) platform. Following B-spec details inherited from Xe2 feature flag definition commit. v2: reuse graphics_xe2 definition Bspec: 58695 - dma_mask_size remains 46 (not documented in bspec) - supports_usm=1 (Bspec 59651) - has_flatccs=1 (Bspec 58797) - has_4tile=1 (Bspec 58788) - has_asid=1 (Bspec 59654, 59265, 60288) - has_range_tlb_invalidate=1 (Bspec 71126) - five-level page table (Bspec 59505) - 1 VD + 1 VE + 1 SFC (Bspec 67103, 70819) - platform engine mask (Bspec 60149) Cc: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Haridhar Kalvala <haridhar.kalvala@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008013509.61233-3-matthew.s.atwood@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index af7b2f2ff13a..d99f5ddbc70d 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -208,7 +208,7 @@ static const struct xe_media_desc media_xelpmp = { }; static const struct xe_media_desc media_xe2 = { - .name = "Xe2_LPM / Xe2_HPM", + .name = "Xe2_LPM / Xe2_HPM / Xe3_LPM", .hw_engine_mask = GENMASK(XE_HW_ENGINE_VCS7, XE_HW_ENGINE_VCS0) | GENMASK(XE_HW_ENGINE_VECS3, XE_HW_ENGINE_VECS0) | @@ -356,6 +356,8 @@ static const struct gmdid_map graphics_ip_map[] = { { 1274, &graphics_xelpg }, /* Xe_LPG+ */ { 2001, &graphics_xe2 }, { 2004, &graphics_xe2 }, + { 3000, &graphics_xe2 }, + { 3001, &graphics_xe2 }, }; /* Map of GMD_ID values to media IP */ @@ -363,6 +365,7 @@ static const struct gmdid_map media_ip_map[] = { { 1300, &media_xelpmp }, { 1301, &media_xe2 }, { 2000, &media_xe2 }, + { 3000, &media_xe2 }, }; #define INTEL_VGA_DEVICE(id, info) { \ -- GitLab From 37466119ff12c40ecf42b916f755ba4b0a5f8b1a Mon Sep 17 00:00:00 2001 From: Haridhar Kalvala <haridhar.kalvala@intel.com> Date: Mon, 7 Oct 2024 18:35:07 -0700 Subject: [PATCH 767/970] drm/xe/ptl: PTL re-uses Xe2 MOCS table PTL is Xe3 architecture but there is no difference between LNL and PTL in MOCS table. So, PTL uses the same MOCS table as LNL. Bspec: 71582 Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Shekhar Chauhan <shekhar.chauhan@intel.com> Signed-off-by: Haridhar Kalvala <haridhar.kalvala@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008013509.61233-5-matthew.s.atwood@intel.com --- drivers/gpu/drm/xe/xe_mocs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/xe/xe_mocs.c b/drivers/gpu/drm/xe/xe_mocs.c index 8df41cd12d51..231d0e86ed83 100644 --- a/drivers/gpu/drm/xe/xe_mocs.c +++ b/drivers/gpu/drm/xe/xe_mocs.c @@ -576,6 +576,7 @@ static unsigned int get_mocs_settings(struct xe_device *xe, memset(info, 0, sizeof(struct xe_mocs_info)); switch (xe->info.platform) { + case XE_PANTHERLAKE: case XE_LUNARLAKE: case XE_BATTLEMAGE: info->ops = &xe2_mocs_ops; -- GitLab From 2298d8a81f2dc6987448e5ddd823f4892194f5b6 Mon Sep 17 00:00:00 2001 From: Haridhar Kalvala <haridhar.kalvala@intel.com> Date: Mon, 7 Oct 2024 18:35:08 -0700 Subject: [PATCH 768/970] drm/xe/ptl: Add PTL platform definition PTL is an integrated GPU based on the Xe3 architecture. v2: explicitly turn off display until display patches land. Bspec: 72574 Cc: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Haridhar Kalvala <haridhar.kalvala@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008013509.61233-6-matthew.s.atwood@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 7 +++++++ drivers/gpu/drm/xe/xe_platform_types.h | 1 + include/drm/intel/xe_pciids.h | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index d99f5ddbc70d..64a8336ca437 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -346,6 +346,12 @@ static const struct xe_device_desc bmg_desc = { .has_heci_cscfi = 1, }; +static const struct xe_device_desc ptl_desc = { + PLATFORM(PANTHERLAKE), + .has_display = false, + .require_force_probe = true, +}; + #undef PLATFORM __diag_pop(); @@ -395,6 +401,7 @@ static const struct pci_device_id pciidlist[] = { XE_MTL_IDS(INTEL_VGA_DEVICE, &mtl_desc), XE_LNL_IDS(INTEL_VGA_DEVICE, &lnl_desc), XE_BMG_IDS(INTEL_VGA_DEVICE, &bmg_desc), + XE_PTL_IDS(INTEL_VGA_DEVICE, &ptl_desc), { } }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/gpu/drm/xe/xe_platform_types.h b/drivers/gpu/drm/xe/xe_platform_types.h index 79b7042c4534..d08574c4cdb8 100644 --- a/drivers/gpu/drm/xe/xe_platform_types.h +++ b/drivers/gpu/drm/xe/xe_platform_types.h @@ -23,6 +23,7 @@ enum xe_platform { XE_METEORLAKE, XE_LUNARLAKE, XE_BATTLEMAGE, + XE_PANTHERLAKE, }; enum xe_subplatform { diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h index 65520a90c17c..6d8d013f74e0 100644 --- a/include/drm/intel/xe_pciids.h +++ b/include/drm/intel/xe_pciids.h @@ -220,4 +220,15 @@ MACRO__(0xE20D, ## __VA_ARGS__), \ MACRO__(0xE212, ## __VA_ARGS__) +#define XE_PTL_IDS(MACRO__, ...) \ + MACRO__(0xB080, ## __VA_ARGS__), \ + MACRO__(0xB081, ## __VA_ARGS__), \ + MACRO__(0xB082, ## __VA_ARGS__), \ + MACRO__(0xB090, ## __VA_ARGS__), \ + MACRO__(0xB091, ## __VA_ARGS__), \ + MACRO__(0xB092, ## __VA_ARGS__), \ + MACRO__(0xB0A0, ## __VA_ARGS__), \ + MACRO__(0xB0A1, ## __VA_ARGS__), \ + MACRO__(0xB0A2, ## __VA_ARGS__) + #endif -- GitLab From d6d87a10d9e45f7b5ae142dedb7ff76d1cf9e475 Mon Sep 17 00:00:00 2001 From: Matt Roper <matthew.d.roper@intel.com> Date: Mon, 7 Oct 2024 18:35:09 -0700 Subject: [PATCH 769/970] drm/xe/xe3lpm: Add new "instance0" steering table MCR steering on Xe3 media IP is almost the same as it was on Xe2, except for one new range (0x38D0D0 - 0x38D0FF) which has changed to an MCR "MEDIAINF" range on Xe3. Since we can always steer to grpid / instanceid 0 for MEDIAINF ranges, define a new "INSTANCE0" steering table for Xe3 media. Xe3 can continue to use the same OADDRM/GPMXMT table as Xe2. v2: Merge continuous entries 38D0D0 - 38F0FF Bspec: 74298 Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008013509.61233-7-matthew.s.atwood@intel.com --- drivers/gpu/drm/xe/xe_gt_mcr.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index 4c0767403881..e21eb6c0fc20 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -237,6 +237,17 @@ static const struct xe_mmio_range xe2lpm_instance0_steering_table[] = { {}, }; +static const struct xe_mmio_range xe3lpm_instance0_steering_table[] = { + { 0x384000, 0x3847DF }, /* GAM, rsvd, GAM */ + { 0x384900, 0x384AFF }, /* GAM */ + { 0x389560, 0x3895FF }, /* MEDIAINF */ + { 0x38B600, 0x38B8FF }, /* L3BANK */ + { 0x38C800, 0x38D07F }, /* GAM, MEDIAINF */ + { 0x38D0D0, 0x38F0FF }, /* MEDIAINF, GAM */ + { 0x393C00, 0x393C7F }, /* MEDIAINF */ + {}, +}; + static void init_steering_l3bank(struct xe_gt *gt) { struct xe_mmio *mmio = >->mmio; @@ -441,7 +452,10 @@ void xe_gt_mcr_init(struct xe_gt *gt) if (gt->info.type == XE_GT_TYPE_MEDIA) { drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13); - if (MEDIA_VERx100(xe) >= 1301) { + if (MEDIA_VER(xe) >= 30) { + gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; + gt->steering[INSTANCE0].ranges = xe3lpm_instance0_steering_table; + } else if (MEDIA_VERx100(xe) >= 1301) { gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table; gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table; } else { -- GitLab From 9c8c7a7e6f1f55ec28cf0dbfe39a7a797f67be78 Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 4 Oct 2024 12:34:23 -0700 Subject: [PATCH 770/970] drm/xe/guc: Prepare GuC register list and update ADS size for error capture Add referenced registers defines and list of registers. Update GuC ADS size allocation to include space for the lists of error state capture register descriptors. Then, populate GuC ADS with the lists of registers we want GuC to report back to host on engine reset events. This list should include global, engine-class and engine-instance registers for every engine-class type on the current hardware. Ensure we allocate a persistent storage for the register lists that are populated into ADS so that we don't need to allocate memory during GT resets when GuC is reloaded and ADS population happens again. Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004193428.3311145-2-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/abi/guc_capture_abi.h | 186 ++++++++ drivers/gpu/drm/xe/regs/xe_gt_regs.h | 2 + drivers/gpu/drm/xe/xe_guc.c | 5 + drivers/gpu/drm/xe/xe_guc.h | 5 + drivers/gpu/drm/xe/xe_guc_ads.c | 151 ++++++- drivers/gpu/drm/xe/xe_guc_ads_types.h | 2 + drivers/gpu/drm/xe/xe_guc_capture.c | 520 ++++++++++++++++++++++ drivers/gpu/drm/xe/xe_guc_capture.h | 48 ++ drivers/gpu/drm/xe/xe_guc_capture_types.h | 68 +++ drivers/gpu/drm/xe/xe_guc_fwif.h | 26 +- drivers/gpu/drm/xe/xe_guc_types.h | 2 + 12 files changed, 979 insertions(+), 37 deletions(-) create mode 100644 drivers/gpu/drm/xe/abi/guc_capture_abi.h create mode 100644 drivers/gpu/drm/xe/xe_guc_capture.c create mode 100644 drivers/gpu/drm/xe/xe_guc_capture.h create mode 100644 drivers/gpu/drm/xe/xe_guc_capture_types.h diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index 8f1c5c329f79..cb6c625bdef0 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -56,6 +56,7 @@ xe-y += xe_bb.o \ xe_gt_topology.o \ xe_guc.o \ xe_guc_ads.o \ + xe_guc_capture.o \ xe_guc_ct.o \ xe_guc_db_mgr.o \ xe_guc_hwconfig.o \ diff --git a/drivers/gpu/drm/xe/abi/guc_capture_abi.h b/drivers/gpu/drm/xe/abi/guc_capture_abi.h new file mode 100644 index 000000000000..e7898edc6236 --- /dev/null +++ b/drivers/gpu/drm/xe/abi/guc_capture_abi.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef _ABI_GUC_CAPTURE_ABI_H +#define _ABI_GUC_CAPTURE_ABI_H + +#include <linux/types.h> + +/* Capture List Index */ +enum guc_capture_list_index_type { + GUC_CAPTURE_LIST_INDEX_PF = 0, + GUC_CAPTURE_LIST_INDEX_VF = 1, +}; + +#define GUC_CAPTURE_LIST_INDEX_MAX (GUC_CAPTURE_LIST_INDEX_VF + 1) + +/* Register-types of GuC capture register lists */ +enum guc_state_capture_type { + GUC_STATE_CAPTURE_TYPE_GLOBAL = 0, + GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE +}; + +#define GUC_STATE_CAPTURE_TYPE_MAX (GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE + 1) + +/* Class indecies for capture_class and capture_instance arrays */ +enum guc_capture_list_class_type { + GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE = 0, + GUC_CAPTURE_LIST_CLASS_VIDEO = 1, + GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE = 2, + GUC_CAPTURE_LIST_CLASS_BLITTER = 3, + GUC_CAPTURE_LIST_CLASS_GSC_OTHER = 4, +}; + +#define GUC_CAPTURE_LIST_CLASS_MAX (GUC_CAPTURE_LIST_CLASS_GSC_OTHER + 1) + +/** + * struct guc_mmio_reg - GuC MMIO reg state struct + * + * GuC MMIO reg state struct + */ +struct guc_mmio_reg { + /** @offset: MMIO Offset - filled in by Host */ + u32 offset; + /** @value: MMIO Value - Used by Firmware to store value */ + u32 value; + /** @flags: Flags for accessing the MMIO */ + u32 flags; + /** @mask: Value of a mask to apply if mask with value is set */ + u32 mask; +#define GUC_REGSET_MASKED BIT(0) +#define GUC_REGSET_STEERING_NEEDED BIT(1) +#define GUC_REGSET_MASKED_WITH_VALUE BIT(2) +#define GUC_REGSET_RESTORE_ONLY BIT(3) +#define GUC_REGSET_STEERING_GROUP GENMASK(16, 12) +#define GUC_REGSET_STEERING_INSTANCE GENMASK(23, 20) +} __packed; + +/** + * struct guc_mmio_reg_set - GuC register sets + * + * GuC register sets + */ +struct guc_mmio_reg_set { + /** @address: register address */ + u32 address; + /** @count: register count */ + u16 count; + /** @reserved: reserved */ + u16 reserved; +} __packed; + +/** + * struct guc_debug_capture_list_header - Debug capture list header. + * + * Debug capture list header. + */ +struct guc_debug_capture_list_header { + /** @info: contains number of MMIO descriptors in the capture list. */ + u32 info; +#define GUC_CAPTURELISTHDR_NUMDESCR GENMASK(15, 0) +} __packed; + +/** + * struct guc_debug_capture_list - Debug capture list + * + * As part of ADS registration, these header structures (followed by + * an array of 'struct guc_mmio_reg' entries) are used to register with + * GuC microkernel the list of registers we want it to dump out prior + * to a engine reset. + */ +struct guc_debug_capture_list { + /** @header: Debug capture list header. */ + struct guc_debug_capture_list_header header; + /** @regs: MMIO descriptors in the capture list. */ + struct guc_mmio_reg regs[]; +} __packed; + +/** + * struct guc_state_capture_header_t - State capture header. + * + * Prior to resetting engines that have hung or faulted, GuC microkernel + * reports the engine error-state (register values that was read) by + * logging them into the shared GuC log buffer using these hierarchy + * of structures. + */ +struct guc_state_capture_header_t { + /** + * @owner: VFID + * BR[ 7: 0] MBZ when SRIOV is disabled. When SRIOV is enabled + * VFID is an integer in range [0, 63] where 0 means the state capture + * is corresponding to the PF and an integer N in range [1, 63] means + * the state capture is for VF N. + */ + u32 owner; +#define GUC_STATE_CAPTURE_HEADER_VFID GENMASK(7, 0) + /** @info: Engine class/instance and capture type info */ + u32 info; +#define GUC_STATE_CAPTURE_HEADER_CAPTURE_TYPE GENMASK(3, 0) /* see guc_state_capture_type */ +#define GUC_STATE_CAPTURE_HEADER_ENGINE_CLASS GENMASK(7, 4) /* see guc_capture_list_class_type */ +#define GUC_STATE_CAPTURE_HEADER_ENGINE_INSTANCE GENMASK(11, 8) + /** + * @lrca: logical ring context address. + * if type-instance, LRCA (address) that hung, else set to ~0 + */ + u32 lrca; + /** + * @guc_id: context_index. + * if type-instance, context index of hung context, else set to ~0 + */ + u32 guc_id; + /** @num_mmio_entries: Number of captured MMIO entries. */ + u32 num_mmio_entries; +#define GUC_STATE_CAPTURE_HEADER_NUM_MMIO_ENTRIES GENMASK(9, 0) +} __packed; + +/** + * struct guc_state_capture_t - State capture. + * + * State capture + */ +struct guc_state_capture_t { + /** @header: State capture header. */ + struct guc_state_capture_header_t header; + /** @mmio_entries: Array of captured guc_mmio_reg entries. */ + struct guc_mmio_reg mmio_entries[]; +} __packed; + +/* State Capture Group Type */ +enum guc_state_capture_group_type { + GUC_STATE_CAPTURE_GROUP_TYPE_FULL = 0, + GUC_STATE_CAPTURE_GROUP_TYPE_PARTIAL +}; + +#define GUC_STATE_CAPTURE_GROUP_TYPE_MAX (GUC_STATE_CAPTURE_GROUP_TYPE_PARTIAL + 1) + +/** + * struct guc_state_capture_group_header_t - State capture group header + * + * State capture group header. + */ +struct guc_state_capture_group_header_t { + /** @owner: VFID */ + u32 owner; +#define GUC_STATE_CAPTURE_GROUP_HEADER_VFID GENMASK(7, 0) + /** @info: Engine class/instance and capture type info */ + u32 info; +#define GUC_STATE_CAPTURE_GROUP_HEADER_NUM_CAPTURES GENMASK(7, 0) +#define GUC_STATE_CAPTURE_GROUP_HEADER_CAPTURE_GROUP_TYPE GENMASK(15, 8) +} __packed; + +/** + * struct guc_state_capture_group_t - State capture group. + * + * this is the top level structure where an error-capture dump starts + */ +struct guc_state_capture_group_t { + /** @grp_header: State capture group header. */ + struct guc_state_capture_group_header_t grp_header; + /** @capture_entries: Array of state captures */ + struct guc_state_capture_t capture_entries[]; +} __packed; + +#endif diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index fb80042cbe0d..55092089bff6 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -567,4 +567,6 @@ #define GT_PERF_STATUS XE_REG(0x1381b4) #define VOLTAGE_MASK REG_GENMASK(10, 0) +#define SFC_DONE(n) XE_REG(0x1cc000 + (n) * 0x1000) + #endif diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c index 4abc790ed1cd..8570b1218287 100644 --- a/drivers/gpu/drm/xe/xe_guc.c +++ b/drivers/gpu/drm/xe/xe_guc.c @@ -23,6 +23,7 @@ #include "xe_gt_sriov_vf.h" #include "xe_gt_throttle.h" #include "xe_guc_ads.h" +#include "xe_guc_capture.h" #include "xe_guc_ct.h" #include "xe_guc_db_mgr.h" #include "xe_guc_hwconfig.h" @@ -339,6 +340,10 @@ int xe_guc_init(struct xe_guc *guc) if (ret) goto out; + ret = xe_guc_capture_init(guc); + if (ret) + goto out; + ret = xe_guc_ads_init(&guc->ads); if (ret) goto out; diff --git a/drivers/gpu/drm/xe/xe_guc.h b/drivers/gpu/drm/xe/xe_guc.h index 42116b167c98..58338be44558 100644 --- a/drivers/gpu/drm/xe/xe_guc.h +++ b/drivers/gpu/drm/xe/xe_guc.h @@ -82,4 +82,9 @@ static inline struct xe_device *guc_to_xe(struct xe_guc *guc) return gt_to_xe(guc_to_gt(guc)); } +static inline struct drm_device *guc_to_drm(struct xe_guc *guc) +{ + return &guc_to_xe(guc)->drm; +} + #endif diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c index 04485461aa20..b6820a18c2c8 100644 --- a/drivers/gpu/drm/xe/xe_guc_ads.c +++ b/drivers/gpu/drm/xe/xe_guc_ads.c @@ -20,6 +20,7 @@ #include "xe_gt_ccs_mode.h" #include "xe_gt_printk.h" #include "xe_guc.h" +#include "xe_guc_capture.h" #include "xe_guc_ct.h" #include "xe_hw_engine.h" #include "xe_lrc.h" @@ -151,8 +152,7 @@ static u32 guc_ads_waklv_size(struct xe_guc_ads *ads) static size_t guc_ads_capture_size(struct xe_guc_ads *ads) { - /* FIXME: Allocate a proper capture list */ - return PAGE_ALIGN(PAGE_SIZE); + return PAGE_ALIGN(ads->capture_size); } static size_t guc_ads_um_queues_size(struct xe_guc_ads *ads) @@ -406,6 +406,7 @@ int xe_guc_ads_init(struct xe_guc_ads *ads) struct xe_bo *bo; ads->golden_lrc_size = calculate_golden_lrc_size(ads); + ads->capture_size = xe_guc_capture_ads_input_worst_size(ads_to_guc(ads)); ads->regset_size = calculate_regset_size(gt); ads->ads_waklv_size = calculate_waklv_size(ads); @@ -426,9 +427,9 @@ ALLOW_ERROR_INJECTION(xe_guc_ads_init, ERRNO); /* See xe_pci_probe() */ * xe_guc_ads_init_post_hwconfig - initialize ADS post hwconfig load * @ads: Additional data structures object * - * Recalcuate golden_lrc_size & regset_size as the number hardware engines may - * have changed after the hwconfig was loaded. Also verify the new sizes fit in - * the already allocated ADS buffer object. + * Recalculate golden_lrc_size, capture_size and regset_size as the number + * hardware engines may have changed after the hwconfig was loaded. Also verify + * the new sizes fit in the already allocated ADS buffer object. * * Return: 0 on success, negative error code on error. */ @@ -440,6 +441,8 @@ int xe_guc_ads_init_post_hwconfig(struct xe_guc_ads *ads) xe_gt_assert(gt, ads->bo); ads->golden_lrc_size = calculate_golden_lrc_size(ads); + /* Calculate Capture size with worst size */ + ads->capture_size = xe_guc_capture_ads_input_worst_size(ads_to_guc(ads)); ads->regset_size = calculate_regset_size(gt); xe_gt_assert(gt, ads->golden_lrc_size + @@ -539,20 +542,142 @@ static void guc_mapping_table_init(struct xe_gt *gt, } } -static void guc_capture_list_init(struct xe_guc_ads *ads) +static u32 guc_get_capture_engine_mask(struct xe_gt *gt, struct iosys_map *info_map, + enum guc_capture_list_class_type capture_class) { + struct xe_device *xe = gt_to_xe(gt); + u32 mask; + + switch (capture_class) { + case GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE: + mask = info_map_read(xe, info_map, engine_enabled_masks[GUC_RENDER_CLASS]); + mask |= info_map_read(xe, info_map, engine_enabled_masks[GUC_COMPUTE_CLASS]); + break; + case GUC_CAPTURE_LIST_CLASS_VIDEO: + mask = info_map_read(xe, info_map, engine_enabled_masks[GUC_VIDEO_CLASS]); + break; + case GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE: + mask = info_map_read(xe, info_map, engine_enabled_masks[GUC_VIDEOENHANCE_CLASS]); + break; + case GUC_CAPTURE_LIST_CLASS_BLITTER: + mask = info_map_read(xe, info_map, engine_enabled_masks[GUC_BLITTER_CLASS]); + break; + case GUC_CAPTURE_LIST_CLASS_GSC_OTHER: + mask = info_map_read(xe, info_map, engine_enabled_masks[GUC_GSC_OTHER_CLASS]); + break; + default: + mask = 0; + } + + return mask; +} + +static inline bool get_capture_list(struct xe_guc_ads *ads, struct xe_guc *guc, struct xe_gt *gt, + int owner, int type, int class, u32 *total_size, size_t *size, + void **pptr) +{ + *size = 0; + + if (!xe_guc_capture_getlistsize(guc, owner, type, class, size)) { + if (*total_size + *size > ads->capture_size) + xe_gt_dbg(gt, "Capture size overflow :%zu vs %d\n", + *total_size + *size, ads->capture_size); + else if (!xe_guc_capture_getlist(guc, owner, type, class, pptr)) + return false; + } + + return true; +} + +static int guc_capture_prep_lists(struct xe_guc_ads *ads) +{ + struct xe_guc *guc = ads_to_guc(ads); + struct xe_gt *gt = ads_to_gt(ads); + u32 ads_ggtt, capture_offset, null_ggtt, total_size = 0; + struct iosys_map info_map; + size_t size = 0; + void *ptr; int i, j; - u32 addr = xe_bo_ggtt_addr(ads->bo) + guc_ads_capture_offset(ads); - /* FIXME: Populate a proper capture list */ + capture_offset = guc_ads_capture_offset(ads); + ads_ggtt = xe_bo_ggtt_addr(ads->bo); + info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads), + offsetof(struct __guc_ads_blob, system_info)); + + /* first, set aside the first page for a capture_list with zero descriptors */ + total_size = PAGE_SIZE; + if (!xe_guc_capture_getnullheader(guc, &ptr, &size)) + xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), capture_offset, ptr, size); + + null_ggtt = ads_ggtt + capture_offset; + capture_offset += PAGE_SIZE; + + /* + * Populate capture list : at this point adps is already allocated and + * mapped to worst case size + */ for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) { - for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) { - ads_blob_write(ads, ads.capture_instance[i][j], addr); - ads_blob_write(ads, ads.capture_class[i][j], addr); + bool write_empty_list; + + for (j = 0; j < GUC_CAPTURE_LIST_CLASS_MAX; j++) { + u32 engine_mask = guc_get_capture_engine_mask(gt, &info_map, j); + /* null list if we dont have said engine or list */ + if (!engine_mask) { + ads_blob_write(ads, ads.capture_class[i][j], null_ggtt); + ads_blob_write(ads, ads.capture_instance[i][j], null_ggtt); + continue; + } + + /* engine exists: start with engine-class registers */ + write_empty_list = get_capture_list(ads, guc, gt, i, + GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + j, &total_size, &size, &ptr); + if (!write_empty_list) { + ads_blob_write(ads, ads.capture_class[i][j], + ads_ggtt + capture_offset); + xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), capture_offset, + ptr, size); + total_size += size; + capture_offset += size; + } else { + ads_blob_write(ads, ads.capture_class[i][j], null_ggtt); + } + + /* engine exists: next, engine-instance registers */ + write_empty_list = get_capture_list(ads, guc, gt, i, + GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE, + j, &total_size, &size, &ptr); + if (!write_empty_list) { + ads_blob_write(ads, ads.capture_instance[i][j], + ads_ggtt + capture_offset); + xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), capture_offset, + ptr, size); + total_size += size; + capture_offset += size; + } else { + ads_blob_write(ads, ads.capture_instance[i][j], null_ggtt); + } } - ads_blob_write(ads, ads.capture_global[i], addr); + /* global registers is last in our PF/VF loops */ + write_empty_list = get_capture_list(ads, guc, gt, i, + GUC_STATE_CAPTURE_TYPE_GLOBAL, + 0, &total_size, &size, &ptr); + if (!write_empty_list) { + ads_blob_write(ads, ads.capture_global[i], ads_ggtt + capture_offset); + xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), capture_offset, ptr, + size); + total_size += size; + capture_offset += size; + } else { + ads_blob_write(ads, ads.capture_global[i], null_ggtt); + } } + + if (ads->capture_size != PAGE_ALIGN(total_size)) + xe_gt_dbg(gt, "ADS capture alloc size changed from %d to %d\n", + ads->capture_size, PAGE_ALIGN(total_size)); + return PAGE_ALIGN(total_size); } static void guc_mmio_regset_write_one(struct xe_guc_ads *ads, @@ -741,7 +866,7 @@ void xe_guc_ads_populate(struct xe_guc_ads *ads) guc_mmio_reg_state_init(ads); guc_prep_golden_lrc_null(ads); guc_mapping_table_init(gt, &info_map); - guc_capture_list_init(ads); + guc_capture_prep_lists(ads); guc_doorbell_init(ads); guc_waklv_init(ads); diff --git a/drivers/gpu/drm/xe/xe_guc_ads_types.h b/drivers/gpu/drm/xe/xe_guc_ads_types.h index 2de5decfe0fd..70c132458ac3 100644 --- a/drivers/gpu/drm/xe/xe_guc_ads_types.h +++ b/drivers/gpu/drm/xe/xe_guc_ads_types.h @@ -22,6 +22,8 @@ struct xe_guc_ads { u32 regset_size; /** @ads_waklv_size: total waklv size supported by platform */ u32 ads_waklv_size; + /** @capture_size: size of register set passed to GuC for capture */ + u32 capture_size; }; #endif diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c new file mode 100644 index 000000000000..279db5cb1cce --- /dev/null +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -0,0 +1,520 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2021-2024 Intel Corporation + */ + +#include <linux/types.h> + +#include <drm/drm_managed.h> +#include <drm/drm_print.h> + +#include "abi/guc_actions_abi.h" +#include "abi/guc_capture_abi.h" +#include "regs/xe_engine_regs.h" +#include "regs/xe_gt_regs.h" +#include "regs/xe_guc_regs.h" +#include "regs/xe_regs.h" + +#include "xe_bo.h" +#include "xe_device.h" +#include "xe_exec_queue_types.h" +#include "xe_gt.h" +#include "xe_gt_mcr.h" +#include "xe_gt_printk.h" +#include "xe_guc.h" +#include "xe_guc_capture.h" +#include "xe_guc_capture_types.h" +#include "xe_guc_ct.h" +#include "xe_guc_log.h" +#include "xe_guc_submit.h" +#include "xe_hw_engine_types.h" +#include "xe_macros.h" +#include "xe_map.h" + +/* + * Define all device tables of GuC error capture register lists + * NOTE: + * For engine-registers, GuC only needs the register offsets + * from the engine-mmio-base + * + * 64 bit registers need 2 entries for low 32 bit register and high 32 bit + * register, for example: + * Register data_type flags mask Register name + * { XXX_REG_LO(0), REG_64BIT_LOW_DW, 0, 0, NULL}, + * { XXX_REG_HI(0), REG_64BIT_HI_DW,, 0, 0, "XXX_REG"}, + * 1. data_type: Indicate is hi/low 32 bit for a 64 bit register + * A 64 bit register define requires 2 consecutive entries, + * with low dword first and hi dword the second. + * 2. Register name: null for incompleted define + */ +#define COMMON_XELP_BASE_GLOBAL \ + { FORCEWAKE_GT, REG_32BIT, 0, 0, "FORCEWAKE_GT"} + +#define COMMON_BASE_ENGINE_INSTANCE \ + { RING_HWSTAM(0), REG_32BIT, 0, 0, "HWSTAM"}, \ + { RING_HWS_PGA(0), REG_32BIT, 0, 0, "RING_HWS_PGA"}, \ + { RING_HEAD(0), REG_32BIT, 0, 0, "RING_HEAD"}, \ + { RING_TAIL(0), REG_32BIT, 0, 0, "RING_TAIL"}, \ + { RING_CTL(0), REG_32BIT, 0, 0, "RING_CTL"}, \ + { RING_MI_MODE(0), REG_32BIT, 0, 0, "RING_MI_MODE"}, \ + { RING_MODE(0), REG_32BIT, 0, 0, "RING_MODE"}, \ + { RING_ESR(0), REG_32BIT, 0, 0, "RING_ESR"}, \ + { RING_EMR(0), REG_32BIT, 0, 0, "RING_EMR"}, \ + { RING_EIR(0), REG_32BIT, 0, 0, "RING_EIR"}, \ + { RING_IMR(0), REG_32BIT, 0, 0, "RING_IMR"}, \ + { RING_IPEHR(0), REG_32BIT, 0, 0, "IPEHR"}, \ + { RING_INSTDONE(0), REG_32BIT, 0, 0, "RING_INSTDONE"}, \ + { INDIRECT_RING_STATE(0), REG_32BIT, 0, 0, "INDIRECT_RING_STATE"}, \ + { RING_ACTHD(0), REG_64BIT_LOW_DW, 0, 0, NULL}, \ + { RING_ACTHD_UDW(0), REG_64BIT_HI_DW, 0, 0, "ACTHD"}, \ + { RING_BBADDR(0), REG_64BIT_LOW_DW, 0, 0, NULL}, \ + { RING_BBADDR_UDW(0), REG_64BIT_HI_DW, 0, 0, "RING_BBADDR"}, \ + { RING_START(0), REG_64BIT_LOW_DW, 0, 0, NULL}, \ + { RING_START_UDW(0), REG_64BIT_HI_DW, 0, 0, "RING_START"}, \ + { RING_DMA_FADD(0), REG_64BIT_LOW_DW, 0, 0, NULL}, \ + { RING_DMA_FADD_UDW(0), REG_64BIT_HI_DW, 0, 0, "RING_DMA_FADD"}, \ + { RING_EXECLIST_STATUS_LO(0), REG_64BIT_LOW_DW, 0, 0, NULL}, \ + { RING_EXECLIST_STATUS_HI(0), REG_64BIT_HI_DW, 0, 0, "RING_EXECLIST_STATUS"}, \ + { RING_EXECLIST_SQ_CONTENTS_LO(0), REG_64BIT_LOW_DW, 0, 0, NULL}, \ + { RING_EXECLIST_SQ_CONTENTS_HI(0), REG_64BIT_HI_DW, 0, 0, "RING_EXECLIST_SQ_CONTENTS"} + +#define COMMON_XELP_RC_CLASS \ + { RCU_MODE, REG_32BIT, 0, 0, "RCU_MODE"} + +#define COMMON_XELP_RC_CLASS_INSTDONE \ + { SC_INSTDONE, REG_32BIT, 0, 0, "SC_INSTDONE"}, \ + { SC_INSTDONE_EXTRA, REG_32BIT, 0, 0, "SC_INSTDONE_EXTRA"}, \ + { SC_INSTDONE_EXTRA2, REG_32BIT, 0, 0, "SC_INSTDONE_EXTRA2"} + +#define XELP_VEC_CLASS_REGS \ + { SFC_DONE(0), 0, 0, 0, "SFC_DONE[0]"}, \ + { SFC_DONE(1), 0, 0, 0, "SFC_DONE[1]"}, \ + { SFC_DONE(2), 0, 0, 0, "SFC_DONE[2]"}, \ + { SFC_DONE(3), 0, 0, 0, "SFC_DONE[3]"} + +/* XE_LP Global */ +static const struct __guc_mmio_reg_descr xe_lp_global_regs[] = { + COMMON_XELP_BASE_GLOBAL, +}; + +/* Render / Compute Per-Engine-Instance */ +static const struct __guc_mmio_reg_descr xe_rc_inst_regs[] = { + COMMON_BASE_ENGINE_INSTANCE, +}; + +/* Render / Compute Engine-Class */ +static const struct __guc_mmio_reg_descr xe_rc_class_regs[] = { + COMMON_XELP_RC_CLASS, + COMMON_XELP_RC_CLASS_INSTDONE, +}; + +/* Render / Compute Engine-Class for xehpg */ +static const struct __guc_mmio_reg_descr xe_hpg_rc_class_regs[] = { + COMMON_XELP_RC_CLASS, +}; + +/* Media Decode/Encode Per-Engine-Instance */ +static const struct __guc_mmio_reg_descr xe_vd_inst_regs[] = { + COMMON_BASE_ENGINE_INSTANCE, +}; + +/* Video Enhancement Engine-Class */ +static const struct __guc_mmio_reg_descr xe_vec_class_regs[] = { + XELP_VEC_CLASS_REGS, +}; + +/* Video Enhancement Per-Engine-Instance */ +static const struct __guc_mmio_reg_descr xe_vec_inst_regs[] = { + COMMON_BASE_ENGINE_INSTANCE, +}; + +/* Blitter Per-Engine-Instance */ +static const struct __guc_mmio_reg_descr xe_blt_inst_regs[] = { + COMMON_BASE_ENGINE_INSTANCE, +}; + +/* XE_LP - GSC Per-Engine-Instance */ +static const struct __guc_mmio_reg_descr xe_lp_gsc_inst_regs[] = { + COMMON_BASE_ENGINE_INSTANCE, +}; + +/* + * Empty list to prevent warnings about unknown class/instance types + * as not all class/instance types have entries on all platforms. + */ +static const struct __guc_mmio_reg_descr empty_regs_list[] = { +}; + +#define TO_GCAP_DEF_OWNER(x) (GUC_CAPTURE_LIST_INDEX_##x) +#define TO_GCAP_DEF_TYPE(x) (GUC_STATE_CAPTURE_TYPE_##x) +#define MAKE_REGLIST(regslist, regsowner, regstype, class) \ + { \ + regslist, \ + ARRAY_SIZE(regslist), \ + TO_GCAP_DEF_OWNER(regsowner), \ + TO_GCAP_DEF_TYPE(regstype), \ + class \ + } + +/* List of lists for legacy graphic product version < 1255 */ +static const struct __guc_mmio_reg_descr_group xe_lp_lists[] = { + MAKE_REGLIST(xe_lp_global_regs, PF, GLOBAL, 0), + MAKE_REGLIST(xe_rc_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE), + MAKE_REGLIST(xe_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE), + MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEO), + MAKE_REGLIST(xe_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEO), + MAKE_REGLIST(xe_vec_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE), + MAKE_REGLIST(xe_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE), + MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER), + MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER), + MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER), + MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER), + {} +}; + + /* List of lists for graphic product version >= 1255 */ +static const struct __guc_mmio_reg_descr_group xe_hpg_lists[] = { + MAKE_REGLIST(xe_lp_global_regs, PF, GLOBAL, 0), + MAKE_REGLIST(xe_hpg_rc_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE), + MAKE_REGLIST(xe_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE), + MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEO), + MAKE_REGLIST(xe_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEO), + MAKE_REGLIST(xe_vec_class_regs, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE), + MAKE_REGLIST(xe_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE), + MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_BLITTER), + MAKE_REGLIST(xe_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_BLITTER), + MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_CAPTURE_LIST_CLASS_GSC_OTHER), + MAKE_REGLIST(xe_lp_gsc_inst_regs, PF, ENGINE_INSTANCE, GUC_CAPTURE_LIST_CLASS_GSC_OTHER), + {} +}; + +static const char * const capture_list_type_names[] = { + "Global", + "Class", + "Instance", +}; + +static const char * const capture_engine_class_names[] = { + "Render/Compute", + "Video", + "VideoEnhance", + "Blitter", + "GSC-Other", +}; + +struct __guc_capture_ads_cache { + bool is_valid; + void *ptr; + size_t size; + int status; +}; + +struct xe_guc_state_capture { + const struct __guc_mmio_reg_descr_group *reglists; + struct __guc_capture_ads_cache ads_cache[GUC_CAPTURE_LIST_INDEX_MAX] + [GUC_STATE_CAPTURE_TYPE_MAX] + [GUC_CAPTURE_LIST_CLASS_MAX]; + void *ads_null_cache; +}; + +static const struct __guc_mmio_reg_descr_group * +guc_capture_get_device_reglist(struct xe_device *xe) +{ + if (GRAPHICS_VERx100(xe) >= 1255) + return xe_hpg_lists; + else + return xe_lp_lists; +} + +static const struct __guc_mmio_reg_descr_group * +guc_capture_get_one_list(const struct __guc_mmio_reg_descr_group *reglists, + u32 owner, u32 type, enum guc_capture_list_class_type capture_class) +{ + int i; + + if (!reglists) + return NULL; + + for (i = 0; reglists[i].list; ++i) { + if (reglists[i].owner == owner && reglists[i].type == type && + (reglists[i].engine == capture_class || + reglists[i].type == GUC_STATE_CAPTURE_TYPE_GLOBAL)) + return ®lists[i]; + } + + return NULL; +} + +static int +guc_capture_list_init(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, struct guc_mmio_reg *ptr, + u16 num_entries) +{ + u32 i = 0; + const struct __guc_mmio_reg_descr_group *reglists = guc->capture->reglists; + const struct __guc_mmio_reg_descr_group *match; + + if (!reglists) + return -ENODEV; + + match = guc_capture_get_one_list(reglists, owner, type, capture_class); + if (!match) + return -ENODATA; + + for (i = 0; i < num_entries && i < match->num_regs; ++i) { + ptr[i].offset = match->list[i].reg.addr; + ptr[i].value = 0xDEADF00D; + ptr[i].flags = match->list[i].flags; + ptr[i].mask = match->list[i].mask; + } + + if (i < num_entries) + xe_gt_dbg(guc_to_gt(guc), "Got short capture reglist init: %d out %d.\n", i, + num_entries); + + return 0; +} + +static int +guc_cap_list_num_regs(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class) +{ + const struct __guc_mmio_reg_descr_group *match; + + match = guc_capture_get_one_list(guc->capture->reglists, owner, type, capture_class); + if (!match) + return 0; + + return match->num_regs; +} + +static int +guc_capture_getlistsize(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, + size_t *size, bool is_purpose_est) +{ + struct xe_guc_state_capture *gc = guc->capture; + struct xe_gt *gt = guc_to_gt(guc); + struct __guc_capture_ads_cache *cache; + int num_regs; + + xe_gt_assert(gt, type < GUC_STATE_CAPTURE_TYPE_MAX); + xe_gt_assert(gt, capture_class < GUC_CAPTURE_LIST_CLASS_MAX); + + cache = &gc->ads_cache[owner][type][capture_class]; + if (!gc->reglists) { + xe_gt_warn(gt, "No capture reglist for this device\n"); + return -ENODEV; + } + + if (cache->is_valid) { + *size = cache->size; + return cache->status; + } + + if (!is_purpose_est && owner == GUC_CAPTURE_LIST_INDEX_PF && + !guc_capture_get_one_list(gc->reglists, owner, type, capture_class)) { + if (type == GUC_STATE_CAPTURE_TYPE_GLOBAL) + xe_gt_warn(gt, "Missing capture reglist: global!\n"); + else + xe_gt_warn(gt, "Missing capture reglist: %s(%u):%s(%u)!\n", + capture_list_type_names[type], type, + capture_engine_class_names[capture_class], capture_class); + return -ENODEV; + } + + num_regs = guc_cap_list_num_regs(guc, owner, type, capture_class); + /* intentional empty lists can exist depending on hw config */ + if (!num_regs) + return -ENODATA; + + if (size) + *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) + + (num_regs * sizeof(struct guc_mmio_reg))); + + return 0; +} + +/** + * xe_guc_capture_getlistsize - Get list size for owner/type/class combination + * @guc: The GuC object + * @owner: PF/VF owner + * @type: GuC capture register type + * @capture_class: GuC capture engine class id + * @size: Point to the size + * + * This function will get the list for the owner/type/class combination, and + * return the page aligned list size. + * + * Returns: 0 on success or a negative error code on failure. + */ +int +xe_guc_capture_getlistsize(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, size_t *size) +{ + return guc_capture_getlistsize(guc, owner, type, capture_class, size, false); +} + +/** + * xe_guc_capture_getlist - Get register capture list for owner/type/class + * combination + * @guc: The GuC object + * @owner: PF/VF owner + * @type: GuC capture register type + * @capture_class: GuC capture engine class id + * @outptr: Point to cached register capture list + * + * This function will get the register capture list for the owner/type/class + * combination. + * + * Returns: 0 on success or a negative error code on failure. + */ +int +xe_guc_capture_getlist(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, void **outptr) +{ + struct xe_guc_state_capture *gc = guc->capture; + struct __guc_capture_ads_cache *cache = &gc->ads_cache[owner][type][capture_class]; + struct guc_debug_capture_list *listnode; + int ret, num_regs; + u8 *caplist, *tmp; + size_t size = 0; + + if (!gc->reglists) + return -ENODEV; + + if (cache->is_valid) { + *outptr = cache->ptr; + return cache->status; + } + + ret = xe_guc_capture_getlistsize(guc, owner, type, capture_class, &size); + if (ret) { + cache->is_valid = true; + cache->ptr = NULL; + cache->size = 0; + cache->status = ret; + return ret; + } + + caplist = drmm_kzalloc(guc_to_drm(guc), size, GFP_KERNEL); + if (!caplist) + return -ENOMEM; + + /* populate capture list header */ + tmp = caplist; + num_regs = guc_cap_list_num_regs(guc, owner, type, capture_class); + listnode = (struct guc_debug_capture_list *)tmp; + listnode->header.info = FIELD_PREP(GUC_CAPTURELISTHDR_NUMDESCR, (u32)num_regs); + + /* populate list of register descriptor */ + tmp += sizeof(struct guc_debug_capture_list); + guc_capture_list_init(guc, owner, type, capture_class, + (struct guc_mmio_reg *)tmp, num_regs); + + /* cache this list */ + cache->is_valid = true; + cache->ptr = caplist; + cache->size = size; + cache->status = 0; + + *outptr = caplist; + + return 0; +} + +/** + * xe_guc_capture_getnullheader - Get a null list for register capture + * @guc: The GuC object + * @outptr: Point to cached register capture list + * @size: Point to the size + * + * This function will alloc for a null list for register capture. + * + * Returns: 0 on success or a negative error code on failure. + */ +int +xe_guc_capture_getnullheader(struct xe_guc *guc, void **outptr, size_t *size) +{ + struct xe_guc_state_capture *gc = guc->capture; + int tmp = sizeof(u32) * 4; + void *null_header; + + if (gc->ads_null_cache) { + *outptr = gc->ads_null_cache; + *size = tmp; + return 0; + } + + null_header = drmm_kzalloc(guc_to_drm(guc), tmp, GFP_KERNEL); + if (!null_header) + return -ENOMEM; + + gc->ads_null_cache = null_header; + *outptr = null_header; + *size = tmp; + + return 0; +} + +/** + * xe_guc_capture_ads_input_worst_size - Calculate the worst size for GuC register capture + * @guc: point to xe_guc structure + * + * Calculate the worst size for GuC register capture by including all possible engines classes. + * + * Returns: Calculated size + */ +size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc) +{ + size_t total_size, class_size, instance_size, global_size; + int i, j; + + /* + * This function calculates the worst case register lists size by + * including all possible engines classes. It is called during the + * first of a two-phase GuC (and ADS-population) initialization + * sequence, that is, during the pre-hwconfig phase before we have + * the exact engine fusing info. + */ + total_size = PAGE_SIZE; /* Pad a page in front for empty lists */ + for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) { + for (j = 0; j < GUC_CAPTURE_LIST_CLASS_MAX; j++) { + if (xe_guc_capture_getlistsize(guc, i, + GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + j, &class_size) < 0) + class_size = 0; + if (xe_guc_capture_getlistsize(guc, i, + GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE, + j, &instance_size) < 0) + instance_size = 0; + total_size += class_size + instance_size; + } + if (xe_guc_capture_getlistsize(guc, i, + GUC_STATE_CAPTURE_TYPE_GLOBAL, + 0, &global_size) < 0) + global_size = 0; + total_size += global_size; + } + + return PAGE_ALIGN(total_size); +} + +/** + * xe_guc_capture_init - Init for GuC register capture + * @guc: The GuC object + * + * Init for GuC register capture, alloc memory for capture data structure. + * + * Returns: 0 if success. + -ENOMEM if out of memory + */ +int xe_guc_capture_init(struct xe_guc *guc) +{ + guc->capture = drmm_kzalloc(guc_to_drm(guc), sizeof(*guc->capture), GFP_KERNEL); + if (!guc->capture) + return -ENOMEM; + + guc->capture->reglists = guc_capture_get_device_reglist(guc_to_xe(guc)); + return 0; +} diff --git a/drivers/gpu/drm/xe/xe_guc_capture.h b/drivers/gpu/drm/xe/xe_guc_capture.h new file mode 100644 index 000000000000..55c1cedcb923 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_guc_capture.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021-2024 Intel Corporation + */ + +#ifndef _XE_GUC_CAPTURE_H +#define _XE_GUC_CAPTURE_H + +#include <linux/types.h> +#include "abi/guc_capture_abi.h" +#include "xe_guc.h" +#include "xe_guc_fwif.h" + +struct xe_guc; + +static inline enum guc_capture_list_class_type xe_guc_class_to_capture_class(u16 class) +{ + switch (class) { + case GUC_RENDER_CLASS: + case GUC_COMPUTE_CLASS: + return GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE; + case GUC_GSC_OTHER_CLASS: + return GUC_CAPTURE_LIST_CLASS_GSC_OTHER; + case GUC_VIDEO_CLASS: + case GUC_VIDEOENHANCE_CLASS: + case GUC_BLITTER_CLASS: + return class; + default: + XE_WARN_ON(class); + return GUC_CAPTURE_LIST_CLASS_MAX; + } +} + +static inline enum guc_capture_list_class_type +xe_engine_class_to_guc_capture_class(enum xe_engine_class class) +{ + return xe_guc_class_to_capture_class(xe_engine_class_to_guc_class(class)); +} + +int xe_guc_capture_getlist(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, void **outptr); +int xe_guc_capture_getlistsize(struct xe_guc *guc, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, size_t *size); +int xe_guc_capture_getnullheader(struct xe_guc *guc, void **outptr, size_t *size); +size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc); +int xe_guc_capture_init(struct xe_guc *guc); + +#endif diff --git a/drivers/gpu/drm/xe/xe_guc_capture_types.h b/drivers/gpu/drm/xe/xe_guc_capture_types.h new file mode 100644 index 000000000000..2057125b1bfa --- /dev/null +++ b/drivers/gpu/drm/xe/xe_guc_capture_types.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021-2024 Intel Corporation + */ + +#ifndef _XE_GUC_CAPTURE_TYPES_H +#define _XE_GUC_CAPTURE_TYPES_H + +#include <linux/types.h> +#include "regs/xe_reg_defs.h" + +struct xe_guc; + +/* data type of the register in register list */ +enum capture_register_data_type { + REG_32BIT = 0, + REG_64BIT_LOW_DW, + REG_64BIT_HI_DW, +}; + +/** + * struct __guc_mmio_reg_descr - GuC mmio register descriptor + * + * xe_guc_capture module uses these structures to define a register + * (offsets, names, flags,...) that are used at the ADS regisration + * time as well as during runtime processing and reporting of error- + * capture states generated by GuC just prior to engine reset events. + */ +struct __guc_mmio_reg_descr { + /** @reg: the register */ + struct xe_reg reg; + /** + * @data_type: data type of the register + * Could be 32 bit, low or hi dword of a 64 bit, see enum + * register_data_type + */ + enum capture_register_data_type data_type; + /** @flags: Flags for the register */ + u32 flags; + /** @mask: The mask to apply */ + u32 mask; + /** @regname: Name of the register */ + const char *regname; +}; + +/** + * struct __guc_mmio_reg_descr_group - The group of register descriptor + * + * xe_guc_capture module uses these structures to maintain static + * tables (per unique platform) that consists of lists of registers + * (offsets, names, flags,...) that are used at the ADS regisration + * time as well as during runtime processing and reporting of error- + * capture states generated by GuC just prior to engine reset events. + */ +struct __guc_mmio_reg_descr_group { + /** @list: The register list */ + const struct __guc_mmio_reg_descr *list; + /** @num_regs: Count of registers in the list */ + u32 num_regs; + /** @owner: PF/VF owner, see enum guc_capture_list_index_type */ + u32 owner; + /** @type: Capture register type, see enum guc_state_capture_type */ + u32 type; + /** @engine: The engine class, see enum guc_capture_list_class_type */ + u32 engine; +}; + +#endif diff --git a/drivers/gpu/drm/xe/xe_guc_fwif.h b/drivers/gpu/drm/xe/xe_guc_fwif.h index 19ee71aeaf17..01e3ab590c3a 100644 --- a/drivers/gpu/drm/xe/xe_guc_fwif.h +++ b/drivers/gpu/drm/xe/xe_guc_fwif.h @@ -8,7 +8,9 @@ #include <linux/bits.h> +#include "abi/guc_capture_abi.h" #include "abi/guc_klvs_abi.h" +#include "xe_hw_engine_types.h" #define G2H_LEN_DW_SCHED_CONTEXT_MODE_SET 4 #define G2H_LEN_DW_DEREGISTER_CONTEXT 3 @@ -157,24 +159,6 @@ struct guc_policies { u32 reserved[4]; } __packed; -/* GuC MMIO reg state struct */ -struct guc_mmio_reg { - u32 offset; - u32 value; - u32 flags; - u32 mask; -#define GUC_REGSET_MASKED BIT(0) -#define GUC_REGSET_MASKED_WITH_VALUE BIT(2) -#define GUC_REGSET_RESTORE_ONLY BIT(3) -} __packed; - -/* GuC register sets */ -struct guc_mmio_reg_set { - u32 address; - u16 count; - u16 reserved; -} __packed; - /* Generic GT SysInfo data types */ #define GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED 0 #define GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK 1 @@ -188,12 +172,6 @@ struct guc_gt_system_info { u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX]; } __packed; -enum { - GUC_CAPTURE_LIST_INDEX_PF = 0, - GUC_CAPTURE_LIST_INDEX_VF = 1, - GUC_CAPTURE_LIST_INDEX_MAX = 2, -}; - /* GuC Additional Data Struct */ struct guc_ads { struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS]; diff --git a/drivers/gpu/drm/xe/xe_guc_types.h b/drivers/gpu/drm/xe/xe_guc_types.h index 69046f698271..ebc5a2237648 100644 --- a/drivers/gpu/drm/xe/xe_guc_types.h +++ b/drivers/gpu/drm/xe/xe_guc_types.h @@ -58,6 +58,8 @@ struct xe_guc { struct xe_guc_ads ads; /** @ct: GuC ct */ struct xe_guc_ct ct; + /** @capture: the error-state-capture module's data and objects */ + struct xe_guc_state_capture *capture; /** @pc: GuC Power Conservation */ struct xe_guc_pc pc; /** @dbm: GuC Doorbell Manager */ -- GitLab From b170d696c1e2226713471d810c63b1162335079f Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 4 Oct 2024 12:34:24 -0700 Subject: [PATCH 771/970] drm/xe/guc: Add XE_LP steered register lists Add the ability for runtime allocation and freeing of steered register list extentions that depend on the detected HW config fuses. Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004193428.3311145-3-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/xe_guc_ads.c | 6 + drivers/gpu/drm/xe/xe_guc_capture.c | 212 ++++++++++++++++++++++++++-- drivers/gpu/drm/xe/xe_guc_capture.h | 1 + 3 files changed, 206 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c index b6820a18c2c8..25292997c7f3 100644 --- a/drivers/gpu/drm/xe/xe_guc_ads.c +++ b/drivers/gpu/drm/xe/xe_guc_ads.c @@ -599,6 +599,12 @@ static int guc_capture_prep_lists(struct xe_guc_ads *ads) void *ptr; int i, j; + /* + * GuC Capture's steered reg-list needs to be allocated and initialized + * after the GuC-hwconfig is available which guaranteed from here. + */ + xe_guc_capture_steered_list_init(ads_to_guc(ads)); + capture_offset = guc_ads_capture_offset(ads); ads_ggtt = xe_bo_ggtt_addr(ads->bo); info_map = IOSYS_MAP_INIT_OFFSET(ads_to_map(ads), diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c index 279db5cb1cce..4256051a04b6 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.c +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -211,6 +211,11 @@ struct __guc_capture_ads_cache { struct xe_guc_state_capture { const struct __guc_mmio_reg_descr_group *reglists; + /** + * NOTE: steered registers have multiple instances depending on the HW configuration + * (slices or dual-sub-slices) and thus depends on HW fuses discovered + */ + struct __guc_mmio_reg_descr_group *extlists; struct __guc_capture_ads_cache ads_cache[GUC_CAPTURE_LIST_INDEX_MAX] [GUC_STATE_CAPTURE_TYPE_MAX] [GUC_CAPTURE_LIST_CLASS_MAX]; @@ -245,14 +250,156 @@ guc_capture_get_one_list(const struct __guc_mmio_reg_descr_group *reglists, return NULL; } +struct __ext_steer_reg { + const char *name; + struct xe_reg_mcr reg; +}; + +static const struct __ext_steer_reg xe_extregs[] = { + {"SAMPLER_INSTDONE", SAMPLER_INSTDONE}, + {"ROW_INSTDONE", ROW_INSTDONE} +}; + +static const struct __ext_steer_reg xehpg_extregs[] = { + {"SC_INSTDONE", XEHPG_SC_INSTDONE}, + {"SC_INSTDONE_EXTRA", XEHPG_SC_INSTDONE_EXTRA}, + {"SC_INSTDONE_EXTRA2", XEHPG_SC_INSTDONE_EXTRA2}, + {"INSTDONE_GEOM_SVGUNIT", XEHPG_INSTDONE_GEOM_SVGUNIT} +}; + +static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext, + const struct __ext_steer_reg *extlist, + int slice_id, int subslice_id) +{ + if (!ext || !extlist) + return; + + ext->reg = XE_REG(extlist->reg.__reg.addr); + ext->flags = FIELD_PREP(GUC_REGSET_STEERING_NEEDED, 1); + ext->flags = FIELD_PREP(GUC_REGSET_STEERING_GROUP, slice_id); + ext->flags |= FIELD_PREP(GUC_REGSET_STEERING_INSTANCE, subslice_id); + ext->regname = extlist->name; +} + +static int +__alloc_ext_regs(struct drm_device *drm, struct __guc_mmio_reg_descr_group *newlist, + const struct __guc_mmio_reg_descr_group *rootlist, int num_regs) +{ + struct __guc_mmio_reg_descr *list; + + list = drmm_kzalloc(drm, num_regs * sizeof(struct __guc_mmio_reg_descr), GFP_KERNEL); + if (!list) + return -ENOMEM; + + newlist->list = list; + newlist->num_regs = num_regs; + newlist->owner = rootlist->owner; + newlist->engine = rootlist->engine; + newlist->type = rootlist->type; + + return 0; +} + +static int guc_capture_get_steer_reg_num(struct xe_device *xe) +{ + int num = ARRAY_SIZE(xe_extregs); + + if (GRAPHICS_VERx100(xe) >= 1255) + num += ARRAY_SIZE(xehpg_extregs); + + return num; +} + +static void guc_capture_alloc_steered_lists(struct xe_guc *guc) +{ + struct xe_gt *gt = guc_to_gt(guc); + u16 slice, subslice; + int iter, i, total = 0; + const struct __guc_mmio_reg_descr_group *lists = guc->capture->reglists; + const struct __guc_mmio_reg_descr_group *list; + struct __guc_mmio_reg_descr_group *extlists; + struct __guc_mmio_reg_descr *extarray; + bool has_xehpg_extregs = GRAPHICS_VERx100(gt_to_xe(gt)) >= 1255; + struct drm_device *drm = >_to_xe(gt)->drm; + bool has_rcs_ccs = false; + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + + /* + * If GT has no rcs/ccs, no need to alloc steered list. + * Currently, only rcs/ccs has steering register, if in the future, + * other engine types has steering register, this condition check need + * to be extended + */ + for_each_hw_engine(hwe, gt, id) { + if (xe_engine_class_to_guc_capture_class(hwe->class) == + GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE) { + has_rcs_ccs = true; + break; + } + } + + if (!has_rcs_ccs) + return; + + /* steered registers currently only exist for the render-class */ + list = guc_capture_get_one_list(lists, GUC_CAPTURE_LIST_INDEX_PF, + GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE); + /* + * Skip if this platform has no engine class registers or if extlists + * was previously allocated + */ + if (!list || guc->capture->extlists) + return; + + total = bitmap_weight(gt->fuse_topo.g_dss_mask, sizeof(gt->fuse_topo.g_dss_mask) * 8) * + guc_capture_get_steer_reg_num(guc_to_xe(guc)); + + if (!total) + return; + + /* allocate an extra for an end marker */ + extlists = drmm_kzalloc(drm, 2 * sizeof(struct __guc_mmio_reg_descr_group), GFP_KERNEL); + if (!extlists) + return; + + if (__alloc_ext_regs(drm, &extlists[0], list, total)) { + drmm_kfree(drm, extlists); + return; + } + + /* For steering registers, the list is generated at run-time */ + extarray = (struct __guc_mmio_reg_descr *)extlists[0].list; + for_each_dss_steering(iter, gt, slice, subslice) { + for (i = 0; i < ARRAY_SIZE(xe_extregs); ++i) { + __fill_ext_reg(extarray, &xe_extregs[i], slice, subslice); + ++extarray; + } + + if (has_xehpg_extregs) + for (i = 0; i < ARRAY_SIZE(xehpg_extregs); ++i) { + __fill_ext_reg(extarray, &xehpg_extregs[i], slice, subslice); + ++extarray; + } + } + + extlists[0].num_regs = total; + + xe_gt_dbg(guc_to_gt(guc), "capture found %d ext-regs.\n", total); + guc->capture->extlists = extlists; +} + static int guc_capture_list_init(struct xe_guc *guc, u32 owner, u32 type, enum guc_capture_list_class_type capture_class, struct guc_mmio_reg *ptr, u16 num_entries) { - u32 i = 0; + u32 ptr_idx = 0, list_idx = 0; const struct __guc_mmio_reg_descr_group *reglists = guc->capture->reglists; + struct __guc_mmio_reg_descr_group *extlists = guc->capture->extlists; const struct __guc_mmio_reg_descr_group *match; + u32 list_num; if (!reglists) return -ENODEV; @@ -261,16 +408,28 @@ guc_capture_list_init(struct xe_guc *guc, u32 owner, u32 type, if (!match) return -ENODATA; - for (i = 0; i < num_entries && i < match->num_regs; ++i) { - ptr[i].offset = match->list[i].reg.addr; - ptr[i].value = 0xDEADF00D; - ptr[i].flags = match->list[i].flags; - ptr[i].mask = match->list[i].mask; + list_num = match->num_regs; + for (list_idx = 0; ptr_idx < num_entries && list_idx < list_num; ++list_idx, ++ptr_idx) { + ptr[ptr_idx].offset = match->list[list_idx].reg.addr; + ptr[ptr_idx].value = 0xDEADF00D; + ptr[ptr_idx].flags = match->list[list_idx].flags; + ptr[ptr_idx].mask = match->list[list_idx].mask; } - if (i < num_entries) - xe_gt_dbg(guc_to_gt(guc), "Got short capture reglist init: %d out %d.\n", i, - num_entries); + match = guc_capture_get_one_list(extlists, owner, type, capture_class); + if (match) + for (ptr_idx = list_num, list_idx = 0; + ptr_idx < num_entries && list_idx < match->num_regs; + ++ptr_idx, ++list_idx) { + ptr[ptr_idx].offset = match->list[list_idx].reg.addr; + ptr[ptr_idx].value = 0xDEADF00D; + ptr[ptr_idx].flags = match->list[list_idx].flags; + ptr[ptr_idx].mask = match->list[list_idx].mask; + } + + if (ptr_idx < num_entries) + xe_gt_dbg(guc_to_gt(guc), "Got short capture reglist init: %d out-of %d.\n", + ptr_idx, num_entries); return 0; } @@ -280,12 +439,22 @@ guc_cap_list_num_regs(struct xe_guc *guc, u32 owner, u32 type, enum guc_capture_list_class_type capture_class) { const struct __guc_mmio_reg_descr_group *match; + int num_regs = 0; match = guc_capture_get_one_list(guc->capture->reglists, owner, type, capture_class); - if (!match) - return 0; + if (match) + num_regs = match->num_regs; + + match = guc_capture_get_one_list(guc->capture->extlists, owner, type, capture_class); + if (match) + num_regs += match->num_regs; + else + /* Estimate steering register size for rcs/ccs */ + if (capture_class == GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE) + num_regs += guc_capture_get_steer_reg_num(guc_to_xe(guc)) * + XE_MAX_DSS_FUSE_BITS; - return match->num_regs; + return num_regs; } static int @@ -500,6 +669,23 @@ size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc) return PAGE_ALIGN(total_size); } +/* + * xe_guc_capture_steered_list_init - Init steering register list + * @guc: The GuC object + * + * Init steering register list for GuC register capture + */ +void xe_guc_capture_steered_list_init(struct xe_guc *guc) +{ + /* + * For certain engine classes, there are slice and subslice + * level registers requiring steering. We allocate and populate + * these based on hw config and add it as an extension list at + * the end of the pre-populated render list. + */ + guc_capture_alloc_steered_lists(guc); +} + /** * xe_guc_capture_init - Init for GuC register capture * @guc: The GuC object @@ -507,7 +693,7 @@ size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc) * Init for GuC register capture, alloc memory for capture data structure. * * Returns: 0 if success. - -ENOMEM if out of memory + * -ENOMEM if out of memory */ int xe_guc_capture_init(struct xe_guc *guc) { diff --git a/drivers/gpu/drm/xe/xe_guc_capture.h b/drivers/gpu/drm/xe/xe_guc_capture.h index 55c1cedcb923..25d263e2ab1d 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.h +++ b/drivers/gpu/drm/xe/xe_guc_capture.h @@ -43,6 +43,7 @@ int xe_guc_capture_getlistsize(struct xe_guc *guc, u32 owner, u32 type, enum guc_capture_list_class_type capture_class, size_t *size); int xe_guc_capture_getnullheader(struct xe_guc *guc, void **outptr, size_t *size); size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc); +void xe_guc_capture_steered_list_init(struct xe_guc *guc); int xe_guc_capture_init(struct xe_guc *guc); #endif -- GitLab From 84d15f426110c9f39cedf499b04d7b3642dca428 Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 4 Oct 2024 12:34:25 -0700 Subject: [PATCH 772/970] drm/xe/guc: Add capture size check in GuC log buffer Capture-nodes generated by GuC are placed in the GuC capture ring buffer which is a sub-region of the larger Guc-Log-buffer. Add capture output size check before allocating the shared buffer. Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004193428.3311145-4-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/abi/guc_log_abi.h | 20 +++++++ drivers/gpu/drm/xe/xe_guc_capture.c | 83 +++++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_guc_log.c | 66 ++++++++++++++++++++++ drivers/gpu/drm/xe/xe_guc_log.h | 7 ++- 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/xe/abi/guc_log_abi.h diff --git a/drivers/gpu/drm/xe/abi/guc_log_abi.h b/drivers/gpu/drm/xe/abi/guc_log_abi.h new file mode 100644 index 000000000000..10db4ffaa17f --- /dev/null +++ b/drivers/gpu/drm/xe/abi/guc_log_abi.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef _ABI_GUC_LOG_ABI_H +#define _ABI_GUC_LOG_ABI_H + +#include <linux/types.h> + +/* GuC logging buffer types */ +enum guc_log_buffer_type { + GUC_LOG_BUFFER_CRASH_DUMP, + GUC_LOG_BUFFER_DEBUG, + GUC_LOG_BUFFER_CAPTURE, +}; + +#define GUC_LOG_BUFFER_TYPE_MAX 3 + +#endif diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c index 4256051a04b6..f1b9ddcb2d89 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.c +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -22,6 +22,7 @@ #include "xe_gt_mcr.h" #include "xe_gt_printk.h" #include "xe_guc.h" +#include "xe_guc_ads.h" #include "xe_guc_capture.h" #include "xe_guc_capture_types.h" #include "xe_guc_ct.h" @@ -669,6 +670,85 @@ size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc) return PAGE_ALIGN(total_size); } +static int guc_capture_output_size_est(struct xe_guc *guc) +{ + struct xe_gt *gt = guc_to_gt(guc); + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + + int capture_size = 0; + size_t tmp = 0; + + if (!guc->capture) + return -ENODEV; + + /* + * If every single engine-instance suffered a failure in quick succession but + * were all unrelated, then a burst of multiple error-capture events would dump + * registers for every one engine instance, one at a time. In this case, GuC + * would even dump the global-registers repeatedly. + * + * For each engine instance, there would be 1 x guc_state_capture_group_t output + * followed by 3 x guc_state_capture_t lists. The latter is how the register + * dumps are split across different register types (where the '3' are global vs class + * vs instance). + */ + for_each_hw_engine(hwe, gt, id) { + enum guc_capture_list_class_type capture_class; + + capture_class = xe_engine_class_to_guc_capture_class(hwe->class); + capture_size += sizeof(struct guc_state_capture_group_header_t) + + (3 * sizeof(struct guc_state_capture_header_t)); + + if (!guc_capture_getlistsize(guc, 0, GUC_STATE_CAPTURE_TYPE_GLOBAL, + 0, &tmp, true)) + capture_size += tmp; + if (!guc_capture_getlistsize(guc, 0, GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + capture_class, &tmp, true)) + capture_size += tmp; + if (!guc_capture_getlistsize(guc, 0, GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE, + capture_class, &tmp, true)) + capture_size += tmp; + } + + return capture_size; +} + +/* + * Add on a 3x multiplier to allow for multiple back-to-back captures occurring + * before the Xe can read the data out and process it + */ +#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3 + +static void check_guc_capture_size(struct xe_guc *guc) +{ + int capture_size = guc_capture_output_size_est(guc); + int spare_size = capture_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER; + u32 buffer_size = xe_guc_log_section_size_capture(&guc->log); + + /* + * NOTE: capture_size is much smaller than the capture region + * allocation (DG2: <80K vs 1MB). + * Additionally, its based on space needed to fit all engines getting + * reset at once within the same G2H handler task slot. This is very + * unlikely. However, if GuC really does run out of space for whatever + * reason, we will see an separate warning message when processing the + * G2H event capture-notification, search for: + * xe_guc_STATE_CAPTURE_EVENT_STATUS_NOSPACE. + */ + if (capture_size < 0) + xe_gt_dbg(guc_to_gt(guc), + "Failed to calculate error state capture buffer minimum size: %d!\n", + capture_size); + if (capture_size > buffer_size) + xe_gt_dbg(guc_to_gt(guc), "Error state capture buffer maybe small: %d < %d\n", + buffer_size, capture_size); + else if (spare_size > buffer_size) + xe_gt_dbg(guc_to_gt(guc), + "Error state capture buffer lacks spare size: %d < %d (min = %d)\n", + buffer_size, spare_size, capture_size); +} + /* * xe_guc_capture_steered_list_init - Init steering register list * @guc: The GuC object @@ -684,9 +764,10 @@ void xe_guc_capture_steered_list_init(struct xe_guc *guc) * the end of the pre-populated render list. */ guc_capture_alloc_steered_lists(guc); + check_guc_capture_size(guc); } -/** +/* * xe_guc_capture_init - Init for GuC register capture * @guc: The GuC object * diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index 7fbc56cceaba..5bab5a3948cc 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -270,4 +270,70 @@ int xe_guc_log_init(struct xe_guc_log *log) return 0; } + ALLOW_ERROR_INJECTION(xe_guc_log_init, ERRNO); /* See xe_pci_probe() */ + +static u32 xe_guc_log_section_size_crash(struct xe_guc_log *log) +{ + return CRASH_BUFFER_SIZE; +} + +static u32 xe_guc_log_section_size_debug(struct xe_guc_log *log) +{ + return DEBUG_BUFFER_SIZE; +} + +/** + * xe_guc_log_section_size_capture - Get capture buffer size within log sections. + * @log: The log object. + * + * This function will return the capture buffer size within log sections. + * + * Return: capture buffer size. + */ +u32 xe_guc_log_section_size_capture(struct xe_guc_log *log) +{ + return CAPTURE_BUFFER_SIZE; +} + +/** + * xe_guc_get_log_buffer_size - Get log buffer size for a type. + * @log: The log object. + * @type: The log buffer type + * + * Return: buffer size. + */ +u32 xe_guc_get_log_buffer_size(struct xe_guc_log *log, enum guc_log_buffer_type type) +{ + switch (type) { + case GUC_LOG_BUFFER_CRASH_DUMP: + return xe_guc_log_section_size_crash(log); + case GUC_LOG_BUFFER_DEBUG: + return xe_guc_log_section_size_debug(log); + case GUC_LOG_BUFFER_CAPTURE: + return xe_guc_log_section_size_capture(log); + } + return 0; +} + +/** + * xe_guc_get_log_buffer_offset - Get offset in log buffer for a type. + * @log: The log object. + * @type: The log buffer type + * + * This function will return the offset in the log buffer for a type. + * Return: buffer offset. + */ +u32 xe_guc_get_log_buffer_offset(struct xe_guc_log *log, enum guc_log_buffer_type type) +{ + enum guc_log_buffer_type i; + u32 offset = PAGE_SIZE;/* for the log_buffer_states */ + + for (i = GUC_LOG_BUFFER_CRASH_DUMP; i < GUC_LOG_BUFFER_TYPE_MAX; ++i) { + if (i == type) + break; + offset += xe_guc_get_log_buffer_size(log, i); + } + + return offset; +} diff --git a/drivers/gpu/drm/xe/xe_guc_log.h b/drivers/gpu/drm/xe/xe_guc_log.h index 1fb2fae1f4e1..86501643431b 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.h +++ b/drivers/gpu/drm/xe/xe_guc_log.h @@ -7,6 +7,7 @@ #define _XE_GUC_LOG_H_ #include "xe_guc_log_types.h" +#include "abi/guc_log_abi.h" struct drm_printer; struct xe_device; @@ -18,7 +19,7 @@ struct xe_device; #else #define CRASH_BUFFER_SIZE SZ_8K #define DEBUG_BUFFER_SIZE SZ_64K -#define CAPTURE_BUFFER_SIZE SZ_16K +#define CAPTURE_BUFFER_SIZE SZ_1M #endif /* * While we're using plain log level in i915, GuC controls are much more... @@ -50,4 +51,8 @@ xe_guc_log_get_level(struct xe_guc_log *log) return log->level; } +u32 xe_guc_log_section_size_capture(struct xe_guc_log *log); +u32 xe_guc_get_log_buffer_size(struct xe_guc_log *log, enum guc_log_buffer_type type); +u32 xe_guc_get_log_buffer_offset(struct xe_guc_log *log, enum guc_log_buffer_type type); + #endif -- GitLab From 8bfc496327ce0f3bd02445048e3a70cc97accc6d Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 4 Oct 2024 12:34:26 -0700 Subject: [PATCH 773/970] drm/xe/guc: Extract GuC error capture lists Upon the G2H Notify-Err-Capture event, parse through the GuC Log Buffer (error-capture-subregion) and generate one or more capture-nodes. A single node represents a single "engine- instance-capture-dump" and contains at least 3 register lists: global, engine-class and engine-instance. An internal link list is maintained to store one or more nodes. Because the link-list node generation happen before the call to devcoredump, duplicate global and engine-class register lists for each engine-instance register dump if we find dependent-engine resets in a engine-capture-group. To avoid dynamically allocate the output nodes during gt reset, pre-allocate a fixed number of empty nodes up front (at the time of ADS registration) that we can consume from or return to an internal cached list of nodes. Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004193428.3311145-5-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/abi/guc_actions_abi.h | 8 + drivers/gpu/drm/xe/abi/guc_log_abi.h | 55 ++ drivers/gpu/drm/xe/xe_guc_capture.c | 725 ++++++++++++++++++++++- drivers/gpu/drm/xe/xe_guc_capture.h | 1 + drivers/gpu/drm/xe/xe_guc_ct.c | 2 + drivers/gpu/drm/xe/xe_guc_log.c | 35 ++ drivers/gpu/drm/xe/xe_guc_log.h | 3 + drivers/gpu/drm/xe/xe_guc_log_types.h | 7 + drivers/gpu/drm/xe/xe_guc_submit.c | 65 +- drivers/gpu/drm/xe/xe_guc_submit.h | 2 + 10 files changed, 883 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/xe/abi/guc_actions_abi.h b/drivers/gpu/drm/xe/abi/guc_actions_abi.h index 43ad4652c2b2..b54fe40fc5a9 100644 --- a/drivers/gpu/drm/xe/abi/guc_actions_abi.h +++ b/drivers/gpu/drm/xe/abi/guc_actions_abi.h @@ -176,6 +176,14 @@ enum xe_guc_sleep_state_status { #define GUC_LOG_CONTROL_VERBOSITY_MASK (0xF << GUC_LOG_CONTROL_VERBOSITY_SHIFT) #define GUC_LOG_CONTROL_DEFAULT_LOGGING (1 << 8) +enum xe_guc_state_capture_event_status { + XE_GUC_STATE_CAPTURE_EVENT_STATUS_SUCCESS = 0x0, + XE_GUC_STATE_CAPTURE_EVENT_STATUS_NOSPACE = 0x1, +}; + +#define XE_GUC_STATE_CAPTURE_EVENT_STATUS_MASK 0x000000FF +#define XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION_DATA_LEN 1 + #define XE_GUC_TLB_INVAL_TYPE_SHIFT 0 #define XE_GUC_TLB_INVAL_MODE_SHIFT 8 /* Flush PPC or SMRO caches along with TLB invalidation request */ diff --git a/drivers/gpu/drm/xe/abi/guc_log_abi.h b/drivers/gpu/drm/xe/abi/guc_log_abi.h index 10db4ffaa17f..554630b7ccd9 100644 --- a/drivers/gpu/drm/xe/abi/guc_log_abi.h +++ b/drivers/gpu/drm/xe/abi/guc_log_abi.h @@ -17,4 +17,59 @@ enum guc_log_buffer_type { #define GUC_LOG_BUFFER_TYPE_MAX 3 +/** + * struct guc_log_buffer_state - GuC log buffer state + * + * Below state structure is used for coordination of retrieval of GuC firmware + * logs. Separate state is maintained for each log buffer type. + * read_ptr points to the location where Xe read last in log buffer and + * is read only for GuC firmware. write_ptr is incremented by GuC with number + * of bytes written for each log entry and is read only for Xe. + * When any type of log buffer becomes half full, GuC sends a flush interrupt. + * GuC firmware expects that while it is writing to 2nd half of the buffer, + * first half would get consumed by Host and then get a flush completed + * acknowledgment from Host, so that it does not end up doing any overwrite + * causing loss of logs. So when buffer gets half filled & Xe has requested + * for interrupt, GuC will set flush_to_file field, set the sampled_write_ptr + * to the value of write_ptr and raise the interrupt. + * On receiving the interrupt Xe should read the buffer, clear flush_to_file + * field and also update read_ptr with the value of sample_write_ptr, before + * sending an acknowledgment to GuC. marker & version fields are for internal + * usage of GuC and opaque to Xe. buffer_full_cnt field is incremented every + * time GuC detects the log buffer overflow. + */ +struct guc_log_buffer_state { + /** @marker: buffer state start marker */ + u32 marker[2]; + /** @read_ptr: the last byte offset that was read by KMD previously */ + u32 read_ptr; + /** + * @write_ptr: the next byte offset location that will be written by + * GuC + */ + u32 write_ptr; + /** @size: Log buffer size */ + u32 size; + /** + * @sampled_write_ptr: Log buffer write pointer + * This is written by GuC to the byte offset of the next free entry in + * the buffer on log buffer half full or state capture notification + */ + u32 sampled_write_ptr; + /** + * @wrap_offset: wraparound offset + * This is the byte offset of location 1 byte after last valid guc log + * event entry written by Guc firmware before there was a wraparound. + * This field is updated by guc firmware and should be used by Host + * when copying buffer contents to file. + */ + u32 wrap_offset; + /** @flags: Flush to file flag and buffer full count */ + u32 flags; +#define GUC_LOG_BUFFER_STATE_FLUSH_TO_FILE GENMASK(0, 0) +#define GUC_LOG_BUFFER_STATE_BUFFER_FULL_CNT GENMASK(4, 1) + /** @version: The Guc-Log-Entry format version */ + u32 version; +} __packed; + #endif diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c index f1b9ddcb2d89..d5cea907d2e6 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.c +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -10,6 +10,7 @@ #include "abi/guc_actions_abi.h" #include "abi/guc_capture_abi.h" +#include "abi/guc_log_abi.h" #include "regs/xe_engine_regs.h" #include "regs/xe_gt_regs.h" #include "regs/xe_guc_regs.h" @@ -32,6 +33,51 @@ #include "xe_macros.h" #include "xe_map.h" +/* + * struct __guc_capture_bufstate + * + * Book-keeping structure used to track read and write pointers + * as we extract error capture data from the GuC-log-buffer's + * error-capture region as a stream of dwords. + */ +struct __guc_capture_bufstate { + u32 size; + u32 data_offset; + u32 rd; + u32 wr; +}; + +/* + * struct __guc_capture_parsed_output - extracted error capture node + * + * A single unit of extracted error-capture output data grouped together + * at an engine-instance level. We keep these nodes in a linked list. + * See cachelist and outlist below. + */ +struct __guc_capture_parsed_output { + /* + * A single set of 3 capture lists: a global-list + * an engine-class-list and an engine-instance list. + * outlist in __guc_capture_parsed_output will keep + * a linked list of these nodes that will eventually + * be detached from outlist and attached into to + * xe_codedump in response to a context reset + */ + struct list_head link; + bool is_partial; + u32 eng_class; + u32 eng_inst; + u32 guc_id; + u32 lrca; + struct gcap_reg_list_info { + u32 vfid; + u32 num_regs; + struct guc_mmio_reg *regs; + } reginfo[GUC_STATE_CAPTURE_TYPE_MAX]; +#define GCAP_PARSED_REGLIST_INDEX_GLOBAL BIT(GUC_STATE_CAPTURE_TYPE_GLOBAL) +#define GCAP_PARSED_REGLIST_INDEX_ENGCLASS BIT(GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS) +}; + /* * Define all device tables of GuC error capture register lists * NOTE: @@ -221,6 +267,12 @@ struct xe_guc_state_capture { [GUC_STATE_CAPTURE_TYPE_MAX] [GUC_CAPTURE_LIST_CLASS_MAX]; void *ads_null_cache; + struct list_head cachelist; +#define PREALLOC_NODES_MAX_COUNT (3 * GUC_MAX_ENGINE_CLASSES * GUC_MAX_INSTANCES_PER_CLASS) +#define PREALLOC_NODES_DEFAULT_NUMREGS 64 + + int max_mmio_per_node; + struct list_head outlist; }; static const struct __guc_mmio_reg_descr_group * @@ -450,8 +502,17 @@ guc_cap_list_num_regs(struct xe_guc *guc, u32 owner, u32 type, if (match) num_regs += match->num_regs; else - /* Estimate steering register size for rcs/ccs */ - if (capture_class == GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE) + /* + * If a caller wants the full register dump size but we have + * not yet got the hw-config, which is before max_mmio_per_node + * is initialized, then provide a worst-case number for + * extlists based on max dss fuse bits, but only ever for + * render/compute + */ + if (owner == GUC_CAPTURE_LIST_INDEX_PF && + type == GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS && + capture_class == GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE && + !guc->capture->max_mmio_per_node) num_regs += guc_capture_get_steer_reg_num(guc_to_xe(guc)) * XE_MAX_DSS_FUSE_BITS; @@ -749,11 +810,664 @@ static void check_guc_capture_size(struct xe_guc *guc) buffer_size, spare_size, capture_size); } +static void +guc_capture_add_node_to_list(struct __guc_capture_parsed_output *node, + struct list_head *list) +{ + list_add_tail(&node->link, list); +} + +static void +guc_capture_add_node_to_outlist(struct xe_guc_state_capture *gc, + struct __guc_capture_parsed_output *node) +{ + guc_capture_add_node_to_list(node, &gc->outlist); +} + +static void +guc_capture_add_node_to_cachelist(struct xe_guc_state_capture *gc, + struct __guc_capture_parsed_output *node) +{ + guc_capture_add_node_to_list(node, &gc->cachelist); +} + +static void +guc_capture_init_node(struct xe_guc *guc, struct __guc_capture_parsed_output *node) +{ + struct guc_mmio_reg *tmp[GUC_STATE_CAPTURE_TYPE_MAX]; + int i; + + for (i = 0; i < GUC_STATE_CAPTURE_TYPE_MAX; ++i) { + tmp[i] = node->reginfo[i].regs; + memset(tmp[i], 0, sizeof(struct guc_mmio_reg) * + guc->capture->max_mmio_per_node); + } + memset(node, 0, sizeof(*node)); + for (i = 0; i < GUC_STATE_CAPTURE_TYPE_MAX; ++i) + node->reginfo[i].regs = tmp[i]; + + INIT_LIST_HEAD(&node->link); +} + +/** + * DOC: Init, G2H-event and reporting flows for GuC-error-capture + * + * KMD Init time flows: + * -------------------- + * --> alloc A: GuC input capture regs lists (registered to GuC via ADS). + * xe_guc_ads acquires the register lists by calling + * xe_guc_capture_getlistsize and xe_guc_capture_getlist 'n' times, + * where n = 1 for global-reg-list + + * num_engine_classes for class-reg-list + + * num_engine_classes for instance-reg-list + * (since all instances of the same engine-class type + * have an identical engine-instance register-list). + * ADS module also calls separately for PF vs VF. + * + * --> alloc B: GuC output capture buf (registered via guc_init_params(log_param)) + * Size = #define CAPTURE_BUFFER_SIZE (warns if on too-small) + * Note2: 'x 3' to hold multiple capture groups + * + * GUC Runtime notify capture: + * -------------------------- + * --> G2H STATE_CAPTURE_NOTIFICATION + * L--> xe_guc_capture_process + * L--> Loop through B (head..tail) and for each engine instance's + * err-state-captured register-list we find, we alloc 'C': + * --> alloc C: A capture-output-node structure that includes misc capture info along + * with 3 register list dumps (global, engine-class and engine-instance) + * This node is created from a pre-allocated list of blank nodes in + * guc->capture->cachelist and populated with the error-capture + * data from GuC and then it's added into guc->capture->outlist linked + * list. This list is used for matchup and printout by xe_devcoredump_read + * and xe_hw_engine_snapshot_print, (when user invokes the devcoredump sysfs). + * + * GUC --> notify context reset: + * ----------------------------- + * --> guc_exec_queue_timedout_job + * L--> xe_devcoredump + * L--> devcoredump_snapshot + * --> xe_hw_engine_snapshot_capture + * + * User Sysfs / Debugfs + * -------------------- + * --> xe_devcoredump_read-> + * L--> xxx_snapshot_print + * L--> xe_hw_engine_snapshot_print + * Print register lists values saved at + * guc->capture->outlist + * + */ + +static int guc_capture_buf_cnt(struct __guc_capture_bufstate *buf) +{ + if (buf->wr >= buf->rd) + return (buf->wr - buf->rd); + return (buf->size - buf->rd) + buf->wr; +} + +static int guc_capture_buf_cnt_to_end(struct __guc_capture_bufstate *buf) +{ + if (buf->rd > buf->wr) + return (buf->size - buf->rd); + return (buf->wr - buf->rd); +} + +/* + * GuC's error-capture output is a ring buffer populated in a byte-stream fashion: + * + * The GuC Log buffer region for error-capture is managed like a ring buffer. + * The GuC firmware dumps error capture logs into this ring in a byte-stream flow. + * Additionally, as per the current and foreseeable future, all packed error- + * capture output structures are dword aligned. + * + * That said, if the GuC firmware is in the midst of writing a structure that is larger + * than one dword but the tail end of the err-capture buffer-region has lesser space left, + * we would need to extract that structure one dword at a time straddled across the end, + * onto the start of the ring. + * + * Below function, guc_capture_log_remove_bytes is a helper for that. All callers of this + * function would typically do a straight-up memcpy from the ring contents and will only + * call this helper if their structure-extraction is straddling across the end of the + * ring. GuC firmware does not add any padding. The reason for the no-padding is to ease + * scalability for future expansion of output data types without requiring a redesign + * of the flow controls. + */ +static int +guc_capture_log_remove_bytes(struct xe_guc *guc, struct __guc_capture_bufstate *buf, + void *out, int bytes_needed) +{ +#define GUC_CAPTURE_LOG_BUF_COPY_RETRY_MAX 3 + + int fill_size = 0, tries = GUC_CAPTURE_LOG_BUF_COPY_RETRY_MAX; + int copy_size, avail; + + xe_assert(guc_to_xe(guc), bytes_needed % sizeof(u32) == 0); + + if (bytes_needed > guc_capture_buf_cnt(buf)) + return -1; + + while (bytes_needed > 0 && tries--) { + int misaligned; + + avail = guc_capture_buf_cnt_to_end(buf); + misaligned = avail % sizeof(u32); + /* wrap if at end */ + if (!avail) { + /* output stream clipped */ + if (!buf->rd) + return fill_size; + buf->rd = 0; + continue; + } + + /* Only copy to u32 aligned data */ + copy_size = avail < bytes_needed ? avail - misaligned : bytes_needed; + xe_map_memcpy_from(guc_to_xe(guc), out + fill_size, &guc->log.bo->vmap, + buf->data_offset + buf->rd, copy_size); + buf->rd += copy_size; + fill_size += copy_size; + bytes_needed -= copy_size; + + if (misaligned) + xe_gt_warn(guc_to_gt(guc), + "Bytes extraction not dword aligned, clipping.\n"); + } + + return fill_size; +} + +static int +guc_capture_log_get_group_hdr(struct xe_guc *guc, struct __guc_capture_bufstate *buf, + struct guc_state_capture_group_header_t *ghdr) +{ + int fullsize = sizeof(struct guc_state_capture_group_header_t); + + if (guc_capture_log_remove_bytes(guc, buf, ghdr, fullsize) != fullsize) + return -1; + return 0; +} + +static int +guc_capture_log_get_data_hdr(struct xe_guc *guc, struct __guc_capture_bufstate *buf, + struct guc_state_capture_header_t *hdr) +{ + int fullsize = sizeof(struct guc_state_capture_header_t); + + if (guc_capture_log_remove_bytes(guc, buf, hdr, fullsize) != fullsize) + return -1; + return 0; +} + +static int +guc_capture_log_get_register(struct xe_guc *guc, struct __guc_capture_bufstate *buf, + struct guc_mmio_reg *reg) +{ + int fullsize = sizeof(struct guc_mmio_reg); + + if (guc_capture_log_remove_bytes(guc, buf, reg, fullsize) != fullsize) + return -1; + return 0; +} + +static struct __guc_capture_parsed_output * +guc_capture_get_prealloc_node(struct xe_guc *guc) +{ + struct __guc_capture_parsed_output *found = NULL; + + if (!list_empty(&guc->capture->cachelist)) { + struct __guc_capture_parsed_output *n, *ntmp; + + /* get first avail node from the cache list */ + list_for_each_entry_safe(n, ntmp, &guc->capture->cachelist, link) { + found = n; + break; + } + } else { + struct __guc_capture_parsed_output *n, *ntmp; + + /* traverse down and steal back the oldest node already allocated */ + list_for_each_entry_safe(n, ntmp, &guc->capture->outlist, link) { + found = n; + } + } + if (found) { + list_del(&found->link); + guc_capture_init_node(guc, found); + } + + return found; +} + +static struct __guc_capture_parsed_output * +guc_capture_clone_node(struct xe_guc *guc, struct __guc_capture_parsed_output *original, + u32 keep_reglist_mask) +{ + struct __guc_capture_parsed_output *new; + int i; + + new = guc_capture_get_prealloc_node(guc); + if (!new) + return NULL; + if (!original) + return new; + + new->is_partial = original->is_partial; + + /* copy reg-lists that we want to clone */ + for (i = 0; i < GUC_STATE_CAPTURE_TYPE_MAX; ++i) { + if (keep_reglist_mask & BIT(i)) { + XE_WARN_ON(original->reginfo[i].num_regs > + guc->capture->max_mmio_per_node); + + memcpy(new->reginfo[i].regs, original->reginfo[i].regs, + original->reginfo[i].num_regs * sizeof(struct guc_mmio_reg)); + + new->reginfo[i].num_regs = original->reginfo[i].num_regs; + new->reginfo[i].vfid = original->reginfo[i].vfid; + + if (i == GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS) { + new->eng_class = original->eng_class; + } else if (i == GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE) { + new->eng_inst = original->eng_inst; + new->guc_id = original->guc_id; + new->lrca = original->lrca; + } + } + } + + return new; +} + +static int +guc_capture_extract_reglists(struct xe_guc *guc, struct __guc_capture_bufstate *buf) +{ + struct xe_gt *gt = guc_to_gt(guc); + struct guc_state_capture_group_header_t ghdr = {0}; + struct guc_state_capture_header_t hdr = {0}; + struct __guc_capture_parsed_output *node = NULL; + struct guc_mmio_reg *regs = NULL; + int i, numlists, numregs, ret = 0; + enum guc_state_capture_type datatype; + struct guc_mmio_reg tmp; + bool is_partial = false; + + i = guc_capture_buf_cnt(buf); + if (!i) + return -ENODATA; + + if (i % sizeof(u32)) { + xe_gt_warn(gt, "Got mis-aligned register capture entries\n"); + ret = -EIO; + goto bailout; + } + + /* first get the capture group header */ + if (guc_capture_log_get_group_hdr(guc, buf, &ghdr)) { + ret = -EIO; + goto bailout; + } + /* + * we would typically expect a layout as below where n would be expected to be + * anywhere between 3 to n where n > 3 if we are seeing multiple dependent engine + * instances being reset together. + * ____________________________________________ + * | Capture Group | + * | ________________________________________ | + * | | Capture Group Header: | | + * | | - num_captures = 5 | | + * | |______________________________________| | + * | ________________________________________ | + * | | Capture1: | | + * | | Hdr: GLOBAL, numregs=a | | + * | | ____________________________________ | | + * | | | Reglist | | | + * | | | - reg1, reg2, ... rega | | | + * | | |__________________________________| | | + * | |______________________________________| | + * | ________________________________________ | + * | | Capture2: | | + * | | Hdr: CLASS=RENDER/COMPUTE, numregs=b| | + * | | ____________________________________ | | + * | | | Reglist | | | + * | | | - reg1, reg2, ... regb | | | + * | | |__________________________________| | | + * | |______________________________________| | + * | ________________________________________ | + * | | Capture3: | | + * | | Hdr: INSTANCE=RCS, numregs=c | | + * | | ____________________________________ | | + * | | | Reglist | | | + * | | | - reg1, reg2, ... regc | | | + * | | |__________________________________| | | + * | |______________________________________| | + * | ________________________________________ | + * | | Capture4: | | + * | | Hdr: CLASS=RENDER/COMPUTE, numregs=d| | + * | | ____________________________________ | | + * | | | Reglist | | | + * | | | - reg1, reg2, ... regd | | | + * | | |__________________________________| | | + * | |______________________________________| | + * | ________________________________________ | + * | | Capture5: | | + * | | Hdr: INSTANCE=CCS0, numregs=e | | + * | | ____________________________________ | | + * | | | Reglist | | | + * | | | - reg1, reg2, ... rege | | | + * | | |__________________________________| | | + * | |______________________________________| | + * |__________________________________________| + */ + is_partial = FIELD_GET(GUC_STATE_CAPTURE_GROUP_HEADER_CAPTURE_GROUP_TYPE, ghdr.info); + numlists = FIELD_GET(GUC_STATE_CAPTURE_GROUP_HEADER_NUM_CAPTURES, ghdr.info); + + while (numlists--) { + if (guc_capture_log_get_data_hdr(guc, buf, &hdr)) { + ret = -EIO; + break; + } + + datatype = FIELD_GET(GUC_STATE_CAPTURE_HEADER_CAPTURE_TYPE, hdr.info); + if (datatype > GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE) { + /* unknown capture type - skip over to next capture set */ + numregs = FIELD_GET(GUC_STATE_CAPTURE_HEADER_NUM_MMIO_ENTRIES, + hdr.num_mmio_entries); + while (numregs--) { + if (guc_capture_log_get_register(guc, buf, &tmp)) { + ret = -EIO; + break; + } + } + continue; + } else if (node) { + /* + * Based on the current capture type and what we have so far, + * decide if we should add the current node into the internal + * linked list for match-up when xe_devcoredump calls later + * (and alloc a blank node for the next set of reglists) + * or continue with the same node or clone the current node + * but only retain the global or class registers (such as the + * case of dependent engine resets). + */ + if (datatype == GUC_STATE_CAPTURE_TYPE_GLOBAL) { + guc_capture_add_node_to_outlist(guc->capture, node); + node = NULL; + } else if (datatype == GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS && + node->reginfo[GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS].num_regs) { + /* Add to list, clone node and duplicate global list */ + guc_capture_add_node_to_outlist(guc->capture, node); + node = guc_capture_clone_node(guc, node, + GCAP_PARSED_REGLIST_INDEX_GLOBAL); + } else if (datatype == GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE && + node->reginfo[GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE].num_regs) { + /* Add to list, clone node and duplicate global + class lists */ + guc_capture_add_node_to_outlist(guc->capture, node); + node = guc_capture_clone_node(guc, node, + (GCAP_PARSED_REGLIST_INDEX_GLOBAL | + GCAP_PARSED_REGLIST_INDEX_ENGCLASS)); + } + } + + if (!node) { + node = guc_capture_get_prealloc_node(guc); + if (!node) { + ret = -ENOMEM; + break; + } + if (datatype != GUC_STATE_CAPTURE_TYPE_GLOBAL) + xe_gt_dbg(gt, "Register capture missing global dump: %08x!\n", + datatype); + } + node->is_partial = is_partial; + node->reginfo[datatype].vfid = FIELD_GET(GUC_STATE_CAPTURE_HEADER_VFID, hdr.owner); + + switch (datatype) { + case GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE: + node->eng_class = FIELD_GET(GUC_STATE_CAPTURE_HEADER_ENGINE_CLASS, + hdr.info); + node->eng_inst = FIELD_GET(GUC_STATE_CAPTURE_HEADER_ENGINE_INSTANCE, + hdr.info); + node->lrca = hdr.lrca; + node->guc_id = hdr.guc_id; + break; + case GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS: + node->eng_class = FIELD_GET(GUC_STATE_CAPTURE_HEADER_ENGINE_CLASS, + hdr.info); + break; + default: + break; + } + + numregs = FIELD_GET(GUC_STATE_CAPTURE_HEADER_NUM_MMIO_ENTRIES, + hdr.num_mmio_entries); + if (numregs > guc->capture->max_mmio_per_node) { + xe_gt_dbg(gt, "Register capture list extraction clipped by prealloc!\n"); + numregs = guc->capture->max_mmio_per_node; + } + node->reginfo[datatype].num_regs = numregs; + regs = node->reginfo[datatype].regs; + i = 0; + while (numregs--) { + if (guc_capture_log_get_register(guc, buf, ®s[i++])) { + ret = -EIO; + break; + } + } + } + +bailout: + if (node) { + /* If we have data, add to linked list for match-up when xe_devcoredump calls */ + for (i = GUC_STATE_CAPTURE_TYPE_GLOBAL; i < GUC_STATE_CAPTURE_TYPE_MAX; ++i) { + if (node->reginfo[i].regs) { + guc_capture_add_node_to_outlist(guc->capture, node); + node = NULL; + break; + } + } + if (node) /* else return it back to cache list */ + guc_capture_add_node_to_cachelist(guc->capture, node); + } + return ret; +} + +static int __guc_capture_flushlog_complete(struct xe_guc *guc) +{ + u32 action[] = { + XE_GUC_ACTION_LOG_BUFFER_FILE_FLUSH_COMPLETE, + GUC_LOG_BUFFER_CAPTURE + }; + + return xe_guc_ct_send_g2h_handler(&guc->ct, action, ARRAY_SIZE(action)); +} + +static void __guc_capture_process_output(struct xe_guc *guc) +{ + unsigned int buffer_size, read_offset, write_offset, full_count; + struct xe_uc *uc = container_of(guc, typeof(*uc), guc); + struct guc_log_buffer_state log_buf_state_local; + struct __guc_capture_bufstate buf; + bool new_overflow; + int ret, tmp; + u32 log_buf_state_offset; + u32 src_data_offset; + + log_buf_state_offset = sizeof(struct guc_log_buffer_state) * GUC_LOG_BUFFER_CAPTURE; + src_data_offset = xe_guc_get_log_buffer_offset(&guc->log, GUC_LOG_BUFFER_CAPTURE); + + /* + * Make a copy of the state structure, inside GuC log buffer + * (which is uncached mapped), on the stack to avoid reading + * from it multiple times. + */ + xe_map_memcpy_from(guc_to_xe(guc), &log_buf_state_local, &guc->log.bo->vmap, + log_buf_state_offset, sizeof(struct guc_log_buffer_state)); + + buffer_size = xe_guc_get_log_buffer_size(&guc->log, GUC_LOG_BUFFER_CAPTURE); + read_offset = log_buf_state_local.read_ptr; + write_offset = log_buf_state_local.sampled_write_ptr; + full_count = FIELD_GET(GUC_LOG_BUFFER_STATE_BUFFER_FULL_CNT, log_buf_state_local.flags); + + /* Bookkeeping stuff */ + tmp = FIELD_GET(GUC_LOG_BUFFER_STATE_FLUSH_TO_FILE, log_buf_state_local.flags); + guc->log.stats[GUC_LOG_BUFFER_CAPTURE].flush += tmp; + new_overflow = xe_guc_check_log_buf_overflow(&guc->log, GUC_LOG_BUFFER_CAPTURE, + full_count); + + /* Now copy the actual logs. */ + if (unlikely(new_overflow)) { + /* copy the whole buffer in case of overflow */ + read_offset = 0; + write_offset = buffer_size; + } else if (unlikely((read_offset > buffer_size) || + (write_offset > buffer_size))) { + xe_gt_err(guc_to_gt(guc), + "Register capture buffer in invalid state: read = 0x%X, size = 0x%X!\n", + read_offset, buffer_size); + /* copy whole buffer as offsets are unreliable */ + read_offset = 0; + write_offset = buffer_size; + } + + buf.size = buffer_size; + buf.rd = read_offset; + buf.wr = write_offset; + buf.data_offset = src_data_offset; + + if (!xe_guc_read_stopped(guc)) { + do { + ret = guc_capture_extract_reglists(guc, &buf); + if (ret && ret != -ENODATA) + xe_gt_dbg(guc_to_gt(guc), "Capture extraction failed:%d\n", ret); + } while (ret >= 0); + } + + /* Update the state of log buffer err-cap state */ + xe_map_wr(guc_to_xe(guc), &guc->log.bo->vmap, + log_buf_state_offset + offsetof(struct guc_log_buffer_state, read_ptr), u32, + write_offset); + + /* + * Clear the flush_to_file from local first, the local was loaded by above + * xe_map_memcpy_from, then write out the "updated local" through + * xe_map_wr() + */ + log_buf_state_local.flags &= ~GUC_LOG_BUFFER_STATE_FLUSH_TO_FILE; + xe_map_wr(guc_to_xe(guc), &guc->log.bo->vmap, + log_buf_state_offset + offsetof(struct guc_log_buffer_state, flags), u32, + log_buf_state_local.flags); + __guc_capture_flushlog_complete(guc); +} + +/* + * xe_guc_capture_process - Process GuC register captured data + * @guc: The GuC object + * + * When GuC captured data is ready, GuC will send message + * XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION to host, this function will be + * called to process the data comes with the message. + * + * Returns: None + */ +void xe_guc_capture_process(struct xe_guc *guc) +{ + if (guc->capture) + __guc_capture_process_output(guc); +} + +static struct __guc_capture_parsed_output * +guc_capture_alloc_one_node(struct xe_guc *guc) +{ + struct drm_device *drm = guc_to_drm(guc); + struct __guc_capture_parsed_output *new; + int i; + + new = drmm_kzalloc(drm, sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + + for (i = 0; i < GUC_STATE_CAPTURE_TYPE_MAX; ++i) { + new->reginfo[i].regs = drmm_kzalloc(drm, guc->capture->max_mmio_per_node * + sizeof(struct guc_mmio_reg), GFP_KERNEL); + if (!new->reginfo[i].regs) { + while (i) + drmm_kfree(drm, new->reginfo[--i].regs); + drmm_kfree(drm, new); + return NULL; + } + } + guc_capture_init_node(guc, new); + + return new; +} + +static void +__guc_capture_create_prealloc_nodes(struct xe_guc *guc) +{ + struct __guc_capture_parsed_output *node = NULL; + int i; + + for (i = 0; i < PREALLOC_NODES_MAX_COUNT; ++i) { + node = guc_capture_alloc_one_node(guc); + if (!node) { + xe_gt_warn(guc_to_gt(guc), "Register capture pre-alloc-cache failure\n"); + /* dont free the priors, use what we got and cleanup at shutdown */ + return; + } + guc_capture_add_node_to_cachelist(guc->capture, node); + } +} + +static int +guc_get_max_reglist_count(struct xe_guc *guc) +{ + int i, j, k, tmp, maxregcount = 0; + + for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; ++i) { + for (j = 0; j < GUC_STATE_CAPTURE_TYPE_MAX; ++j) { + for (k = 0; k < GUC_CAPTURE_LIST_CLASS_MAX; ++k) { + const struct __guc_mmio_reg_descr_group *match; + + if (j == GUC_STATE_CAPTURE_TYPE_GLOBAL && k > 0) + continue; + + tmp = 0; + match = guc_capture_get_one_list(guc->capture->reglists, i, j, k); + if (match) + tmp = match->num_regs; + + match = guc_capture_get_one_list(guc->capture->extlists, i, j, k); + if (match) + tmp += match->num_regs; + + if (tmp > maxregcount) + maxregcount = tmp; + } + } + } + if (!maxregcount) + maxregcount = PREALLOC_NODES_DEFAULT_NUMREGS; + + return maxregcount; +} + +static void +guc_capture_create_prealloc_nodes(struct xe_guc *guc) +{ + /* skip if we've already done the pre-alloc */ + if (guc->capture->max_mmio_per_node) + return; + + guc->capture->max_mmio_per_node = guc_get_max_reglist_count(guc); + __guc_capture_create_prealloc_nodes(guc); +} + /* * xe_guc_capture_steered_list_init - Init steering register list * @guc: The GuC object * - * Init steering register list for GuC register capture + * Init steering register list for GuC register capture, create pre-alloc node */ void xe_guc_capture_steered_list_init(struct xe_guc *guc) { @@ -765,6 +1479,7 @@ void xe_guc_capture_steered_list_init(struct xe_guc *guc) */ guc_capture_alloc_steered_lists(guc); check_guc_capture_size(guc); + guc_capture_create_prealloc_nodes(guc); } /* @@ -783,5 +1498,9 @@ int xe_guc_capture_init(struct xe_guc *guc) return -ENOMEM; guc->capture->reglists = guc_capture_get_device_reglist(guc_to_xe(guc)); + + INIT_LIST_HEAD(&guc->capture->outlist); + INIT_LIST_HEAD(&guc->capture->cachelist); + return 0; } diff --git a/drivers/gpu/drm/xe/xe_guc_capture.h b/drivers/gpu/drm/xe/xe_guc_capture.h index 25d263e2ab1d..4acf44472a63 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.h +++ b/drivers/gpu/drm/xe/xe_guc_capture.h @@ -37,6 +37,7 @@ xe_engine_class_to_guc_capture_class(enum xe_engine_class class) return xe_guc_class_to_capture_class(xe_engine_class_to_guc_class(class)); } +void xe_guc_capture_process(struct xe_guc *guc); int xe_guc_capture_getlist(struct xe_guc *guc, u32 owner, u32 type, enum guc_capture_list_class_type capture_class, void **outptr); int xe_guc_capture_getlistsize(struct xe_guc *guc, u32 owner, u32 type, diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index b7f80449bd83..c7673f56d413 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -1254,6 +1254,8 @@ static int process_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len) /* Selftest only at the moment */ break; case XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION: + ret = xe_guc_error_capture_handler(guc, payload, adj_len); + break; case XE_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE: /* FIXME: Handle this */ break; diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index 5bab5a3948cc..93921f04153f 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -337,3 +337,38 @@ u32 xe_guc_get_log_buffer_offset(struct xe_guc_log *log, enum guc_log_buffer_typ return offset; } + +/** + * xe_guc_check_log_buf_overflow - Check if log buffer overflowed + * @log: The log object. + * @type: The log buffer type + * @full_cnt: The count of buffer full + * + * This function will check count of buffer full against previous, mismatch + * indicate overflowed. + * Update the sampled_overflow counter, if the 4 bit counter overflowed, add + * up 16 to correct the value. + * + * Return: True if overflowed. + */ +bool xe_guc_check_log_buf_overflow(struct xe_guc_log *log, enum guc_log_buffer_type type, + unsigned int full_cnt) +{ + unsigned int prev_full_cnt = log->stats[type].sampled_overflow; + bool overflow = false; + + if (full_cnt != prev_full_cnt) { + overflow = true; + + log->stats[type].overflow = full_cnt; + log->stats[type].sampled_overflow += full_cnt - prev_full_cnt; + + if (full_cnt < prev_full_cnt) { + /* buffer_full_cnt is a 4 bit counter */ + log->stats[type].sampled_overflow += 16; + } + xe_gt_notice(log_to_gt(log), "log buffer overflow\n"); + } + + return overflow; +} diff --git a/drivers/gpu/drm/xe/xe_guc_log.h b/drivers/gpu/drm/xe/xe_guc_log.h index 86501643431b..5b896f5fafaf 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.h +++ b/drivers/gpu/drm/xe/xe_guc_log.h @@ -54,5 +54,8 @@ xe_guc_log_get_level(struct xe_guc_log *log) u32 xe_guc_log_section_size_capture(struct xe_guc_log *log); u32 xe_guc_get_log_buffer_size(struct xe_guc_log *log, enum guc_log_buffer_type type); u32 xe_guc_get_log_buffer_offset(struct xe_guc_log *log, enum guc_log_buffer_type type); +bool xe_guc_check_log_buf_overflow(struct xe_guc_log *log, + enum guc_log_buffer_type type, + unsigned int full_cnt); #endif diff --git a/drivers/gpu/drm/xe/xe_guc_log_types.h b/drivers/gpu/drm/xe/xe_guc_log_types.h index 962b9edbd9eb..4d57f8322efc 100644 --- a/drivers/gpu/drm/xe/xe_guc_log_types.h +++ b/drivers/gpu/drm/xe/xe_guc_log_types.h @@ -7,6 +7,7 @@ #define _XE_GUC_LOG_TYPES_H_ #include <linux/types.h> +#include "abi/guc_log_abi.h" #include "xe_uc_fw_types.h" @@ -45,6 +46,12 @@ struct xe_guc_log { u32 level; /** @bo: XE BO for GuC log */ struct xe_bo *bo; + /** @stats: logging related stats */ + struct { + u32 sampled_overflow; + u32 overflow; + u32 flush; + } stats[GUC_LOG_BUFFER_TYPE_MAX]; }; #endif diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index fc4008018d1f..4b6e953fb210 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -27,6 +27,7 @@ #include "xe_gt_clock.h" #include "xe_gt_printk.h" #include "xe_guc.h" +#include "xe_guc_capture.h" #include "xe_guc_ct.h" #include "xe_guc_exec_queue_types.h" #include "xe_guc_id_mgr.h" @@ -824,7 +825,7 @@ static void guc_exec_queue_free_job(struct drm_sched_job *drm_job) xe_sched_job_put(job); } -static int guc_read_stopped(struct xe_guc *guc) +int xe_guc_read_stopped(struct xe_guc *guc) { return atomic_read(&guc->submission_state.stopped); } @@ -846,7 +847,7 @@ static void disable_scheduling_deregister(struct xe_guc *guc, set_min_preemption_timeout(guc, q); smp_rmb(); ret = wait_event_timeout(guc->ct.wq, !exec_queue_pending_enable(q) || - guc_read_stopped(guc), HZ * 5); + xe_guc_read_stopped(guc), HZ * 5); if (!ret) { struct xe_gpu_scheduler *sched = &q->guc->sched; @@ -972,7 +973,7 @@ static void xe_guc_exec_queue_lr_cleanup(struct work_struct *w) */ ret = wait_event_timeout(guc->ct.wq, !exec_queue_pending_disable(q) || - guc_read_stopped(guc), HZ * 5); + xe_guc_read_stopped(guc), HZ * 5); if (!ret) { drm_warn(&xe->drm, "Schedule disable failed to respond"); xe_sched_submission_start(sched); @@ -1040,8 +1041,8 @@ static void enable_scheduling(struct xe_exec_queue *q) ret = wait_event_timeout(guc->ct.wq, !exec_queue_pending_enable(q) || - guc_read_stopped(guc), HZ * 5); - if (!ret || guc_read_stopped(guc)) { + xe_guc_read_stopped(guc), HZ * 5); + if (!ret || xe_guc_read_stopped(guc)) { xe_gt_warn(guc_to_gt(guc), "Schedule enable failed to respond"); set_exec_queue_banned(q); xe_gt_reset_async(q->gt); @@ -1146,8 +1147,8 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) */ ret = wait_event_timeout(guc->ct.wq, !exec_queue_pending_enable(q) || - guc_read_stopped(guc), HZ * 5); - if (!ret || guc_read_stopped(guc)) + xe_guc_read_stopped(guc), HZ * 5); + if (!ret || xe_guc_read_stopped(guc)) goto trigger_reset; /* @@ -1171,8 +1172,8 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) smp_rmb(); ret = wait_event_timeout(guc->ct.wq, !exec_queue_pending_disable(q) || - guc_read_stopped(guc), HZ * 5); - if (!ret || guc_read_stopped(guc)) { + xe_guc_read_stopped(guc), HZ * 5); + if (!ret || xe_guc_read_stopped(guc)) { trigger_reset: if (!ret) xe_gt_warn(guc_to_gt(guc), "Schedule disable failed to respond"); @@ -1361,7 +1362,7 @@ static void suspend_fence_signal(struct xe_exec_queue *q) struct xe_device *xe = guc_to_xe(guc); xe_assert(xe, exec_queue_suspended(q) || exec_queue_killed(q) || - guc_read_stopped(guc)); + xe_guc_read_stopped(guc)); xe_assert(xe, q->guc->suspend_pending); __suspend_fence_signal(q); @@ -1375,9 +1376,9 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg) if (guc_exec_queue_allowed_to_change_state(q) && !exec_queue_suspended(q) && exec_queue_enabled(q)) { wait_event(guc->ct.wq, q->guc->resume_time != RESUME_PENDING || - guc_read_stopped(guc)); + xe_guc_read_stopped(guc)); - if (!guc_read_stopped(guc)) { + if (!xe_guc_read_stopped(guc)) { s64 since_resume_ms = ktime_ms_delta(ktime_get(), q->guc->resume_time); @@ -1502,7 +1503,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q) q->entity = &ge->entity; - if (guc_read_stopped(guc)) + if (xe_guc_read_stopped(guc)) xe_sched_stop(sched); mutex_unlock(&guc->submission_state.lock); @@ -1658,7 +1659,7 @@ static int guc_exec_queue_suspend_wait(struct xe_exec_queue *q) ret = wait_event_interruptible_timeout(q->guc->suspend_wait, !READ_ONCE(q->guc->suspend_pending) || exec_queue_killed(q) || - guc_read_stopped(guc), + xe_guc_read_stopped(guc), HZ * 5); if (!ret) { @@ -1784,7 +1785,7 @@ int xe_guc_submit_reset_prepare(struct xe_guc *guc) void xe_guc_submit_reset_wait(struct xe_guc *guc) { wait_event(guc->ct.wq, xe_device_wedged(guc_to_xe(guc)) || - !guc_read_stopped(guc)); + !xe_guc_read_stopped(guc)); } void xe_guc_submit_stop(struct xe_guc *guc) @@ -1793,7 +1794,7 @@ void xe_guc_submit_stop(struct xe_guc *guc) unsigned long index; struct xe_device *xe = guc_to_xe(guc); - xe_assert(xe, guc_read_stopped(guc) == 1); + xe_assert(xe, xe_guc_read_stopped(guc) == 1); mutex_lock(&guc->submission_state.lock); @@ -1832,7 +1833,7 @@ int xe_guc_submit_start(struct xe_guc *guc) unsigned long index; struct xe_device *xe = guc_to_xe(guc); - xe_assert(xe, guc_read_stopped(guc) == 1); + xe_assert(xe, xe_guc_read_stopped(guc) == 1); mutex_lock(&guc->submission_state.lock); atomic_dec(&guc->submission_state.stopped); @@ -2023,6 +2024,36 @@ int xe_guc_exec_queue_reset_handler(struct xe_guc *guc, u32 *msg, u32 len) return 0; } +/* + * xe_guc_error_capture_handler - Handler of GuC captured message + * @guc: The GuC object + * @msg: Point to the message + * @len: The message length + * + * When GuC captured data is ready, GuC will send message + * XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION to host, this function will be + * called 1st to check status before process the data comes with the message. + * + * Returns: None + */ +int xe_guc_error_capture_handler(struct xe_guc *guc, u32 *msg, u32 len) +{ + u32 status; + + if (unlikely(len != XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION_DATA_LEN)) { + xe_gt_dbg(guc_to_gt(guc), "Invalid length %u", len); + return -EPROTO; + } + + status = msg[0] & XE_GUC_STATE_CAPTURE_EVENT_STATUS_MASK; + if (status == XE_GUC_STATE_CAPTURE_EVENT_STATUS_NOSPACE) + xe_gt_warn(guc_to_gt(guc), "G2H-Error capture no space"); + + xe_guc_capture_process(guc); + + return 0; +} + int xe_guc_exec_queue_memory_cat_error_handler(struct xe_guc *guc, u32 *msg, u32 len) { diff --git a/drivers/gpu/drm/xe/xe_guc_submit.h b/drivers/gpu/drm/xe/xe_guc_submit.h index bdf8c9f3d24a..9b71a986c6ca 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.h +++ b/drivers/gpu/drm/xe/xe_guc_submit.h @@ -20,12 +20,14 @@ void xe_guc_submit_stop(struct xe_guc *guc); int xe_guc_submit_start(struct xe_guc *guc); void xe_guc_submit_wedge(struct xe_guc *guc); +int xe_guc_read_stopped(struct xe_guc *guc); int xe_guc_sched_done_handler(struct xe_guc *guc, u32 *msg, u32 len); int xe_guc_deregister_done_handler(struct xe_guc *guc, u32 *msg, u32 len); int xe_guc_exec_queue_reset_handler(struct xe_guc *guc, u32 *msg, u32 len); int xe_guc_exec_queue_memory_cat_error_handler(struct xe_guc *guc, u32 *msg, u32 len); int xe_guc_exec_queue_reset_failure_handler(struct xe_guc *guc, u32 *msg, u32 len); +int xe_guc_error_capture_handler(struct xe_guc *guc, u32 *msg, u32 len); struct xe_guc_submit_exec_queue_snapshot * xe_guc_exec_queue_snapshot_capture(struct xe_exec_queue *q); -- GitLab From ecb6336463911d6eb684998754f8701d0f437f18 Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 4 Oct 2024 12:34:27 -0700 Subject: [PATCH 774/970] drm/xe/guc: Plumb GuC-capture into dev coredump When we decide to kill a job, (from guc_exec_queue_timedout_job), we could end up with 4 possible scenarios at this starting point of this decision: 1. the guc-captured register-dump is already there. 2. the driver is wedged.mode > 1, so GuC-engine-reset / GuC-err-capture will not happen. 3. the user has started the driver in execlist-submission mode. 4. the guc-captured register-dump is not ready yet so we force GuC to kill that context now, but: A. we don't know yet if GuC will be successful on the engine-reset and get the guc-err-capture, else kmd will do a manual reset later OR B. guc will be successful and we will get a guc-err-capture shortly. So to accomdate the scenarios of 2 and 4A, we will need to do a manual KMD capture first(which is not be reliable in guc-submission mode) and decide later if we need to use that for the cases of 2 or 4A. So this flow is part of the implementation for this patch. Provide xe_guc_capture_get_reg_desc_list to get the register dscriptor list. Add manual capture by read from hw engine if GuC capture is not ready. If it becomes ready at later time, GuC sourced data will be used. Although there may only be a small delay between (1) the check for whether guc-err-capture is available at the start of guc_exec_queue_timedout_job and (2) the decision on using a valid guc-err-capture or manual-capture, lets not take any chances and lock the matching node down so it doesn't get re-claimed if GuC-Err-Capture subsystem is running out of pre-cached nodes. Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004193428.3311145-6-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/xe_devcoredump.c | 17 +- drivers/gpu/drm/xe/xe_devcoredump_types.h | 8 + drivers/gpu/drm/xe/xe_gt_mcr.c | 13 + drivers/gpu/drm/xe/xe_gt_mcr.h | 1 + drivers/gpu/drm/xe/xe_guc_capture.c | 329 +++++++++++++++++++++- drivers/gpu/drm/xe/xe_guc_capture.h | 10 + drivers/gpu/drm/xe/xe_guc_submit.c | 20 +- drivers/gpu/drm/xe/xe_hw_engine.c | 165 ++++++----- drivers/gpu/drm/xe/xe_hw_engine.h | 4 +- drivers/gpu/drm/xe/xe_hw_engine_types.h | 7 + drivers/gpu/drm/xe/xe_lrc.c | 18 -- drivers/gpu/drm/xe/xe_lrc.h | 19 +- 12 files changed, 508 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index a2d816713489..30f9e8cb328c 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -17,6 +17,7 @@ #include "xe_force_wake.h" #include "xe_gt.h" #include "xe_gt_printk.h" +#include "xe_guc_capture.h" #include "xe_guc_ct.h" #include "xe_guc_log.h" #include "xe_guc_submit.h" @@ -134,6 +135,9 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss) xe_guc_ct_snapshot_free(ss->guc.ct); ss->guc.ct = NULL; + xe_guc_capture_put_matched_nodes(&ss->gt->uc.guc); + ss->matched_node = NULL; + xe_guc_exec_queue_snapshot_free(ss->ge); ss->ge = NULL; @@ -217,6 +221,7 @@ static void xe_devcoredump_free(void *data) /* To prevent stale data on next snapshot, clear everything */ memset(&coredump->snapshot, 0, sizeof(coredump->snapshot)); coredump->captured = false; + coredump->job = NULL; drm_info(&coredump_to_xe(coredump)->drm, "Xe device coredump has been deleted.\n"); } @@ -227,8 +232,6 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump, struct xe_devcoredump_snapshot *ss = &coredump->snapshot; struct xe_exec_queue *q = job->q; struct xe_guc *guc = exec_queue_to_guc(q); - struct xe_hw_engine *hwe; - enum xe_hw_engine_id id; u32 adj_logical_mask = q->logical_mask; u32 width_mask = (0x1 << q->width) - 1; const char *process_name = "no process"; @@ -244,6 +247,7 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump, strscpy(ss->process_name, process_name); ss->gt = q->gt; + coredump->job = job; INIT_WORK(&ss->work, xe_devcoredump_deferred_snap_work); cookie = dma_fence_begin_signalling(); @@ -266,14 +270,7 @@ static void devcoredump_snapshot(struct xe_devcoredump *coredump, ss->job = xe_sched_job_snapshot_capture(job); ss->vm = xe_vm_snapshot_capture(q->vm); - for_each_hw_engine(hwe, q->gt, id) { - if (hwe->class != q->hwe->class || - !(BIT(hwe->logical_instance) & adj_logical_mask)) { - ss->hwe[id] = NULL; - continue; - } - ss->hwe[id] = xe_hw_engine_snapshot_capture(hwe); - } + xe_engine_snapshot_capture_for_job(job); queue_work(system_unbound_wq, &ss->work); diff --git a/drivers/gpu/drm/xe/xe_devcoredump_types.h b/drivers/gpu/drm/xe/xe_devcoredump_types.h index 06ac75ce63dd..3703ddea1252 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump_types.h +++ b/drivers/gpu/drm/xe/xe_devcoredump_types.h @@ -49,6 +49,12 @@ struct xe_devcoredump_snapshot { struct xe_hw_engine_snapshot *hwe[XE_NUM_HW_ENGINES]; /** @job: Snapshot of job state */ struct xe_sched_job_snapshot *job; + /** + * @matched_node: The matched capture node for timedout job + * this single-node tracker works because devcoredump will always only + * produce one hw-engine capture per devcoredump event + */ + struct __guc_capture_parsed_output *matched_node; /** @vm: Snapshot of VM state */ struct xe_vm_snapshot *vm; @@ -74,6 +80,8 @@ struct xe_devcoredump { bool captured; /** @snapshot: Snapshot is captured at time of the first crash */ struct xe_devcoredump_snapshot snapshot; + /** @job: Point to the faulting job */ + struct xe_sched_job *job; }; #endif diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index e21eb6c0fc20..5013d674e17d 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -365,6 +365,19 @@ void xe_gt_mcr_get_dss_steering(struct xe_gt *gt, unsigned int dss, u16 *group, *instance = dss % gt->steering_dss_per_grp; } +/** + * xe_gt_mcr_steering_info_to_dss_id - Get DSS ID from group/instance steering + * @gt: GT structure + * @group: steering group ID + * @instance: steering instance ID + * + * Return: the coverted DSS id. + */ +u32 xe_gt_mcr_steering_info_to_dss_id(struct xe_gt *gt, u16 group, u16 instance) +{ + return group * dss_per_group(gt) + instance; +} + static void init_steering_dss(struct xe_gt *gt) { gt->steering_dss_per_grp = dss_per_group(gt); diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.h b/drivers/gpu/drm/xe/xe_gt_mcr.h index 8d119a0d5493..c0cd36021c24 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.h +++ b/drivers/gpu/drm/xe/xe_gt_mcr.h @@ -28,6 +28,7 @@ void xe_gt_mcr_multicast_write(struct xe_gt *gt, struct xe_reg_mcr mcr_reg, void xe_gt_mcr_steering_dump(struct xe_gt *gt, struct drm_printer *p); void xe_gt_mcr_get_dss_steering(struct xe_gt *gt, unsigned int dss, u16 *group, u16 *instance); +u32 xe_gt_mcr_steering_info_to_dss_id(struct xe_gt *gt, u16 group, u16 instance); /* * Loop over each DSS and determine the group and instance IDs that diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c index d5cea907d2e6..3853b778c4f0 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.c +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -27,11 +27,17 @@ #include "xe_guc_capture.h" #include "xe_guc_capture_types.h" #include "xe_guc_ct.h" +#include "xe_guc_exec_queue_types.h" #include "xe_guc_log.h" +#include "xe_guc_submit_types.h" #include "xe_guc_submit.h" #include "xe_hw_engine_types.h" +#include "xe_hw_engine.h" +#include "xe_lrc.h" #include "xe_macros.h" #include "xe_map.h" +#include "xe_mmio.h" +#include "xe_sched_job.h" /* * struct __guc_capture_bufstate @@ -69,6 +75,9 @@ struct __guc_capture_parsed_output { u32 eng_inst; u32 guc_id; u32 lrca; + u32 type; + bool locked; + enum xe_hw_engine_snapshot_source_id source; struct gcap_reg_list_info { u32 vfid; u32 num_regs; @@ -275,6 +284,10 @@ struct xe_guc_state_capture { struct list_head outlist; }; +static void +guc_capture_remove_stale_matches_from_list(struct xe_guc_state_capture *gc, + struct __guc_capture_parsed_output *node); + static const struct __guc_mmio_reg_descr_group * guc_capture_get_device_reglist(struct xe_device *xe) { @@ -303,6 +316,22 @@ guc_capture_get_one_list(const struct __guc_mmio_reg_descr_group *reglists, return NULL; } +const struct __guc_mmio_reg_descr_group * +xe_guc_capture_get_reg_desc_list(struct xe_gt *gt, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, bool is_ext) +{ + const struct __guc_mmio_reg_descr_group *reglists; + + if (is_ext) { + struct xe_guc *guc = >->uc.guc; + + reglists = guc->capture->extlists; + } else { + reglists = guc_capture_get_device_reglist(gt_to_xe(gt)); + } + return guc_capture_get_one_list(reglists, owner, type, capture_class); +} + struct __ext_steer_reg { const char *name; struct xe_reg_mcr reg; @@ -814,13 +843,14 @@ static void guc_capture_add_node_to_list(struct __guc_capture_parsed_output *node, struct list_head *list) { - list_add_tail(&node->link, list); + list_add(&node->link, list); } static void guc_capture_add_node_to_outlist(struct xe_guc_state_capture *gc, struct __guc_capture_parsed_output *node) { + guc_capture_remove_stale_matches_from_list(gc, node); guc_capture_add_node_to_list(node, &gc->outlist); } @@ -831,6 +861,31 @@ guc_capture_add_node_to_cachelist(struct xe_guc_state_capture *gc, guc_capture_add_node_to_list(node, &gc->cachelist); } +static void +guc_capture_free_outlist_node(struct xe_guc_state_capture *gc, + struct __guc_capture_parsed_output *n) +{ + if (n) { + n->locked = 0; + list_del(&n->link); + /* put node back to cache list */ + guc_capture_add_node_to_cachelist(gc, n); + } +} + +static void +guc_capture_remove_stale_matches_from_list(struct xe_guc_state_capture *gc, + struct __guc_capture_parsed_output *node) +{ + struct __guc_capture_parsed_output *n, *ntmp; + int guc_id = node->guc_id; + + list_for_each_entry_safe(n, ntmp, &gc->outlist, link) { + if (n != node && !n->locked && n->guc_id == guc_id) + guc_capture_free_outlist_node(gc, n); + } +} + static void guc_capture_init_node(struct xe_guc *guc, struct __guc_capture_parsed_output *node) { @@ -1026,9 +1081,13 @@ guc_capture_get_prealloc_node(struct xe_guc *guc) } else { struct __guc_capture_parsed_output *n, *ntmp; - /* traverse down and steal back the oldest node already allocated */ - list_for_each_entry_safe(n, ntmp, &guc->capture->outlist, link) { - found = n; + /* + * traverse reversed and steal back the oldest node already + * allocated + */ + list_for_each_entry_safe_reverse(n, ntmp, &guc->capture->outlist, link) { + if (!n->locked) + found = n; } } if (found) { @@ -1221,6 +1280,8 @@ guc_capture_extract_reglists(struct xe_guc *guc, struct __guc_capture_bufstate * } node->is_partial = is_partial; node->reginfo[datatype].vfid = FIELD_GET(GUC_STATE_CAPTURE_HEADER_VFID, hdr.owner); + node->source = XE_ENGINE_CAPTURE_SOURCE_GUC; + node->type = datatype; switch (datatype) { case GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE: @@ -1463,6 +1524,266 @@ guc_capture_create_prealloc_nodes(struct xe_guc *guc) __guc_capture_create_prealloc_nodes(guc); } +static struct guc_mmio_reg * +guc_capture_find_reg(struct gcap_reg_list_info *reginfo, u32 addr, u32 flags) +{ + int i; + + if (reginfo && reginfo->num_regs > 0) { + struct guc_mmio_reg *regs = reginfo->regs; + + if (regs) + for (i = 0; i < reginfo->num_regs; i++) + if (regs[i].offset == addr && regs[i].flags == flags) + return ®s[i]; + } + + return NULL; +} + +static void +snapshot_print_by_list_order(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p, + u32 type, const struct __guc_mmio_reg_descr_group *list) +{ + struct xe_gt *gt = snapshot->hwe->gt; + struct xe_device *xe = gt_to_xe(gt); + struct xe_guc *guc = >->uc.guc; + struct xe_devcoredump *devcoredump = &xe->devcoredump; + struct xe_devcoredump_snapshot *devcore_snapshot = &devcoredump->snapshot; + struct gcap_reg_list_info *reginfo = NULL; + u32 last_value, i; + bool is_ext; + + if (!list || list->num_regs == 0) + return; + XE_WARN_ON(!devcore_snapshot->matched_node); + + is_ext = list == guc->capture->extlists; + reginfo = &devcore_snapshot->matched_node->reginfo[type]; + + /* + * loop through descriptor first and find the register in the node + * this is more scalable for developer maintenance as it will ensure + * the printout matched the ordering of the static descriptor + * table-of-lists + */ + for (i = 0; i < list->num_regs; i++) { + const struct __guc_mmio_reg_descr *reg_desc = &list->list[i]; + struct guc_mmio_reg *reg; + u32 value; + + reg = guc_capture_find_reg(reginfo, reg_desc->reg.addr, reg_desc->flags); + if (!reg) + continue; + + value = reg->value; + if (reg_desc->data_type == REG_64BIT_LOW_DW) { + last_value = value; + /* Low 32 bit dword saved, continue for high 32 bit */ + continue; + } else if (reg_desc->data_type == REG_64BIT_HI_DW) { + u64 value_qw = ((u64)value << 32) | last_value; + + drm_printf(p, "\t%s: 0x%016llx\n", reg_desc->regname, value_qw); + continue; + } + + if (is_ext) { + int dss, group, instance; + + group = FIELD_GET(GUC_REGSET_STEERING_GROUP, reg_desc->flags); + instance = FIELD_GET(GUC_REGSET_STEERING_INSTANCE, reg_desc->flags); + dss = xe_gt_mcr_steering_info_to_dss_id(gt, group, instance); + + drm_printf(p, "\t%s[%u]: 0x%08x\n", reg_desc->regname, dss, value); + } else { + drm_printf(p, "\t%s: 0x%08x\n", reg_desc->regname, value); + } + } +} + +/** + * xe_engine_snapshot_print - Print out a given Xe HW Engine snapshot. + * @snapshot: Xe HW Engine snapshot object. + * @p: drm_printer where it will be printed out. + * + * This function prints out a given Xe HW Engine snapshot object. + */ +void xe_engine_guc_capture_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p) +{ + const char *grptype[GUC_STATE_CAPTURE_GROUP_TYPE_MAX] = { + "full-capture", + "partial-capture" + }; + int type; + const struct __guc_mmio_reg_descr_group *list; + enum guc_capture_list_class_type capture_class; + + struct xe_gt *gt; + struct xe_device *xe; + struct xe_devcoredump *devcoredump; + struct xe_devcoredump_snapshot *devcore_snapshot; + + if (!snapshot) + return; + + gt = snapshot->hwe->gt; + xe = gt_to_xe(gt); + devcoredump = &xe->devcoredump; + devcore_snapshot = &devcoredump->snapshot; + + if (!devcore_snapshot->matched_node) + return; + + xe_gt_assert(gt, snapshot->source <= XE_ENGINE_CAPTURE_SOURCE_GUC); + xe_gt_assert(gt, snapshot->hwe); + + capture_class = xe_engine_class_to_guc_capture_class(snapshot->hwe->class); + + drm_printf(p, "%s (physical), logical instance=%d\n", + snapshot->name ? snapshot->name : "", + snapshot->logical_instance); + drm_printf(p, "\tCapture_source: %s\n", + snapshot->source == XE_ENGINE_CAPTURE_SOURCE_GUC ? "GuC" : "Manual"); + drm_printf(p, "\tCoverage: %s\n", grptype[devcore_snapshot->matched_node->is_partial]); + drm_printf(p, "\tForcewake: domain 0x%x, ref %d\n", + snapshot->forcewake.domain, snapshot->forcewake.ref); + + for (type = GUC_STATE_CAPTURE_TYPE_GLOBAL; type < GUC_STATE_CAPTURE_TYPE_MAX; type++) { + list = xe_guc_capture_get_reg_desc_list(gt, GUC_CAPTURE_LIST_INDEX_PF, type, + capture_class, false); + snapshot_print_by_list_order(snapshot, p, type, list); + } + + if (capture_class == GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE) { + list = xe_guc_capture_get_reg_desc_list(gt, GUC_CAPTURE_LIST_INDEX_PF, + GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + capture_class, true); + snapshot_print_by_list_order(snapshot, p, GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS, + list); + } + + drm_puts(p, "\n"); +} + +/** + * xe_guc_capture_get_matching_and_lock - Matching GuC capture for the job. + * @job: The job object. + * + * Search within the capture outlist for the job, could be used for check if + * GuC capture is ready for the job. + * If found, the locked boolean of the node will be flagged. + * + * Returns: found guc-capture node ptr else NULL + */ +struct __guc_capture_parsed_output * +xe_guc_capture_get_matching_and_lock(struct xe_sched_job *job) +{ + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + struct xe_exec_queue *q; + struct xe_device *xe; + u16 guc_class = GUC_LAST_ENGINE_CLASS + 1; + struct xe_devcoredump_snapshot *ss; + + if (!job) + return NULL; + + q = job->q; + if (!q || !q->gt) + return NULL; + + xe = gt_to_xe(q->gt); + if (xe->wedged.mode >= 2 || !xe_device_uc_enabled(xe)) + return NULL; + + ss = &xe->devcoredump.snapshot; + if (ss->matched_node && ss->matched_node->source == XE_ENGINE_CAPTURE_SOURCE_GUC) + return ss->matched_node; + + /* Find hwe for the job */ + for_each_hw_engine(hwe, q->gt, id) { + if (hwe != q->hwe) + continue; + guc_class = xe_engine_class_to_guc_class(hwe->class); + break; + } + + if (guc_class <= GUC_LAST_ENGINE_CLASS) { + struct __guc_capture_parsed_output *n, *ntmp; + struct xe_guc *guc = &q->gt->uc.guc; + u16 guc_id = q->guc->id; + u32 lrca = xe_lrc_ggtt_addr(q->lrc[0]); + + /* + * Look for a matching GuC reported error capture node from + * the internal output link-list based on engine, guc id and + * lrca info. + */ + list_for_each_entry_safe(n, ntmp, &guc->capture->outlist, link) { + if (n->eng_class == guc_class && n->eng_inst == hwe->instance && + n->guc_id == guc_id && n->lrca == lrca && + n->source == XE_ENGINE_CAPTURE_SOURCE_GUC) { + n->locked = 1; + return n; + } + } + } + return NULL; +} + +/** + * xe_engine_snapshot_capture_for_job - Take snapshot of associated engine + * @job: The job object + * + * Take snapshot of associated HW Engine + * + * Returns: None. + */ +void +xe_engine_snapshot_capture_for_job(struct xe_sched_job *job) +{ + struct xe_exec_queue *q = job->q; + struct xe_device *xe = gt_to_xe(q->gt); + struct xe_devcoredump *coredump = &xe->devcoredump; + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + u32 adj_logical_mask = q->logical_mask; + + for_each_hw_engine(hwe, q->gt, id) { + if (hwe->class != q->hwe->class || + !(BIT(hwe->logical_instance) & adj_logical_mask)) { + coredump->snapshot.hwe[id] = NULL; + continue; + } + + if (!coredump->snapshot.hwe[id]) + coredump->snapshot.hwe[id] = xe_hw_engine_snapshot_capture(hwe, job); + + break; + } +} + +/* + * xe_guc_capture_put_matched_nodes - Cleanup macthed nodes + * @guc: The GuC object + * + * Free matched node and all nodes with the equal guc_id from + * GuC captured outlist + */ +void xe_guc_capture_put_matched_nodes(struct xe_guc *guc) +{ + struct xe_device *xe = guc_to_xe(guc); + struct xe_devcoredump *devcoredump = &xe->devcoredump; + struct __guc_capture_parsed_output *n = devcoredump->snapshot.matched_node; + + if (n) { + guc_capture_remove_stale_matches_from_list(guc->capture, n); + guc_capture_free_outlist_node(guc->capture, n); + devcoredump->snapshot.matched_node = NULL; + } +} + /* * xe_guc_capture_steered_list_init - Init steering register list * @guc: The GuC object diff --git a/drivers/gpu/drm/xe/xe_guc_capture.h b/drivers/gpu/drm/xe/xe_guc_capture.h index 4acf44472a63..fe695ab08a74 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.h +++ b/drivers/gpu/drm/xe/xe_guc_capture.h @@ -12,6 +12,9 @@ #include "xe_guc_fwif.h" struct xe_guc; +struct xe_hw_engine; +struct xe_hw_engine_snapshot; +struct xe_sched_job; static inline enum guc_capture_list_class_type xe_guc_class_to_capture_class(u16 class) { @@ -44,7 +47,14 @@ int xe_guc_capture_getlistsize(struct xe_guc *guc, u32 owner, u32 type, enum guc_capture_list_class_type capture_class, size_t *size); int xe_guc_capture_getnullheader(struct xe_guc *guc, void **outptr, size_t *size); size_t xe_guc_capture_ads_input_worst_size(struct xe_guc *guc); +const struct __guc_mmio_reg_descr_group * +xe_guc_capture_get_reg_desc_list(struct xe_gt *gt, u32 owner, u32 type, + enum guc_capture_list_class_type capture_class, bool is_ext); +struct __guc_capture_parsed_output *xe_guc_capture_get_matching_and_lock(struct xe_sched_job *job); +void xe_engine_snapshot_capture_for_job(struct xe_sched_job *job); +void xe_engine_guc_capture_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p); void xe_guc_capture_steered_list_init(struct xe_guc *guc); +void xe_guc_capture_put_matched_nodes(struct xe_guc *guc); int xe_guc_capture_init(struct xe_guc *guc); #endif diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 4b6e953fb210..c1ebc693a617 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1097,6 +1097,7 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) struct xe_gpu_scheduler *sched = &q->guc->sched; struct xe_guc *guc = exec_queue_to_guc(q); const char *process_name = "no process"; + struct xe_device *xe = guc_to_xe(guc); int err = -ETIME; pid_t pid = -1; int i = 0; @@ -1124,6 +1125,21 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) if (!skip_timeout_check && !xe_sched_job_started(job)) goto rearm; + /* + * If devcoredump not captured and GuC capture for the job is not ready + * do manual capture first and decide later if we need to use it + */ + if (!exec_queue_killed(q) && !xe->devcoredump.captured && + !xe_guc_capture_get_matching_and_lock(job)) { + /* take force wake before engine register manual capture */ + if (xe_force_wake_get(gt_to_fw(q->gt), XE_FORCEWAKE_ALL)) + xe_gt_info(q->gt, "failed to get forcewake for coredump capture\n"); + + xe_engine_snapshot_capture_for_job(job); + + xe_force_wake_put(gt_to_fw(q->gt), XE_FORCEWAKE_ALL); + } + /* * XXX: Sampling timeout doesn't work in wedged mode as we have to * modify scheduling state to read timestamp. We could read the @@ -2007,8 +2023,6 @@ int xe_guc_exec_queue_reset_handler(struct xe_guc *guc, u32 *msg, u32 len) xe_gt_info(gt, "Engine reset: engine_class=%s, logical_mask: 0x%x, guc_id=%d", xe_hw_engine_class_to_str(q->class), q->logical_mask, guc_id); - /* FIXME: Do error capture, most likely async */ - trace_xe_exec_queue_reset(q); /* @@ -2034,7 +2048,7 @@ int xe_guc_exec_queue_reset_handler(struct xe_guc *guc, u32 *msg, u32 len) * XE_GUC_ACTION_STATE_CAPTURE_NOTIFICATION to host, this function will be * called 1st to check status before process the data comes with the message. * - * Returns: None + * Returns: error code. 0 if success */ int xe_guc_error_capture_handler(struct xe_guc *guc, u32 *msg, u32 len) { diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index 6c9c27304cdc..18a06c2f78d1 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -24,6 +24,7 @@ #include "xe_gt_printk.h" #include "xe_gt_mcr.h" #include "xe_gt_topology.h" +#include "xe_guc_capture.h" #include "xe_hw_engine_group.h" #include "xe_hw_fence.h" #include "xe_irq.h" @@ -877,9 +878,69 @@ xe_hw_engine_snapshot_instdone_capture(struct xe_hw_engine *hwe, } } +static void +xe_hw_engine_manual_capture(struct xe_hw_engine *hwe, struct xe_hw_engine_snapshot *snapshot) +{ + u64 val; + + snapshot->reg.ring_execlist_status = + xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_STATUS_LO(0)); + val = xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_STATUS_HI(0)); + snapshot->reg.ring_execlist_status |= val << 32; + + snapshot->reg.ring_execlist_sq_contents = + xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_SQ_CONTENTS_LO(0)); + val = xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_SQ_CONTENTS_HI(0)); + snapshot->reg.ring_execlist_sq_contents |= val << 32; + + snapshot->reg.ring_acthd = xe_hw_engine_mmio_read32(hwe, RING_ACTHD(0)); + val = xe_hw_engine_mmio_read32(hwe, RING_ACTHD_UDW(0)); + snapshot->reg.ring_acthd |= val << 32; + + snapshot->reg.ring_bbaddr = xe_hw_engine_mmio_read32(hwe, RING_BBADDR(0)); + val = xe_hw_engine_mmio_read32(hwe, RING_BBADDR_UDW(0)); + snapshot->reg.ring_bbaddr |= val << 32; + + snapshot->reg.ring_dma_fadd = + xe_hw_engine_mmio_read32(hwe, RING_DMA_FADD(0)); + val = xe_hw_engine_mmio_read32(hwe, RING_DMA_FADD_UDW(0)); + snapshot->reg.ring_dma_fadd |= val << 32; + + snapshot->reg.ring_hwstam = xe_hw_engine_mmio_read32(hwe, RING_HWSTAM(0)); + snapshot->reg.ring_hws_pga = xe_hw_engine_mmio_read32(hwe, RING_HWS_PGA(0)); + snapshot->reg.ring_start = xe_hw_engine_mmio_read32(hwe, RING_START(0)); + if (GRAPHICS_VERx100(hwe->gt->tile->xe) >= 2000) { + val = xe_hw_engine_mmio_read32(hwe, RING_START_UDW(0)); + snapshot->reg.ring_start |= val << 32; + } + if (xe_gt_has_indirect_ring_state(hwe->gt)) { + snapshot->reg.indirect_ring_state = + xe_hw_engine_mmio_read32(hwe, INDIRECT_RING_STATE(0)); + } + + snapshot->reg.ring_head = + xe_hw_engine_mmio_read32(hwe, RING_HEAD(0)) & HEAD_ADDR; + snapshot->reg.ring_tail = + xe_hw_engine_mmio_read32(hwe, RING_TAIL(0)) & TAIL_ADDR; + snapshot->reg.ring_ctl = xe_hw_engine_mmio_read32(hwe, RING_CTL(0)); + snapshot->reg.ring_mi_mode = + xe_hw_engine_mmio_read32(hwe, RING_MI_MODE(0)); + snapshot->reg.ring_mode = xe_hw_engine_mmio_read32(hwe, RING_MODE(0)); + snapshot->reg.ring_imr = xe_hw_engine_mmio_read32(hwe, RING_IMR(0)); + snapshot->reg.ring_esr = xe_hw_engine_mmio_read32(hwe, RING_ESR(0)); + snapshot->reg.ring_emr = xe_hw_engine_mmio_read32(hwe, RING_EMR(0)); + snapshot->reg.ring_eir = xe_hw_engine_mmio_read32(hwe, RING_EIR(0)); + snapshot->reg.ipehr = xe_hw_engine_mmio_read32(hwe, RING_IPEHR(0)); + xe_hw_engine_snapshot_instdone_capture(hwe, snapshot); + + if (snapshot->hwe->class == XE_ENGINE_CLASS_COMPUTE) + snapshot->reg.rcu_mode = xe_mmio_read32(&hwe->gt->mmio, RCU_MODE); +} + /** * xe_hw_engine_snapshot_capture - Take a quick snapshot of the HW Engine. * @hwe: Xe HW Engine. + * @job: The job object. * * This can be printed out in a later stage like during dev_coredump * analysis. @@ -888,11 +949,11 @@ xe_hw_engine_snapshot_instdone_capture(struct xe_hw_engine *hwe, * caller, using `xe_hw_engine_snapshot_free`. */ struct xe_hw_engine_snapshot * -xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe) +xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_sched_job *job) { struct xe_hw_engine_snapshot *snapshot; size_t len; - u64 val; + struct __guc_capture_parsed_output *node; if (!xe_hw_engine_is_valid(hwe)) return NULL; @@ -937,58 +998,24 @@ xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe) if (IS_SRIOV_VF(gt_to_xe(hwe->gt))) return snapshot; - snapshot->reg.ring_execlist_status = - xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_STATUS_LO(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_STATUS_HI(0)); - snapshot->reg.ring_execlist_status |= val << 32; - - snapshot->reg.ring_execlist_sq_contents = - xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_SQ_CONTENTS_LO(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_SQ_CONTENTS_HI(0)); - snapshot->reg.ring_execlist_sq_contents |= val << 32; - - snapshot->reg.ring_acthd = xe_hw_engine_mmio_read32(hwe, RING_ACTHD(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_ACTHD_UDW(0)); - snapshot->reg.ring_acthd |= val << 32; - - snapshot->reg.ring_bbaddr = xe_hw_engine_mmio_read32(hwe, RING_BBADDR(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_BBADDR_UDW(0)); - snapshot->reg.ring_bbaddr |= val << 32; - - snapshot->reg.ring_dma_fadd = - xe_hw_engine_mmio_read32(hwe, RING_DMA_FADD(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_DMA_FADD_UDW(0)); - snapshot->reg.ring_dma_fadd |= val << 32; - - snapshot->reg.ring_hwstam = xe_hw_engine_mmio_read32(hwe, RING_HWSTAM(0)); - snapshot->reg.ring_hws_pga = xe_hw_engine_mmio_read32(hwe, RING_HWS_PGA(0)); - snapshot->reg.ring_start = xe_hw_engine_mmio_read32(hwe, RING_START(0)); - if (GRAPHICS_VERx100(hwe->gt->tile->xe) >= 2000) { - val = xe_hw_engine_mmio_read32(hwe, RING_START_UDW(0)); - snapshot->reg.ring_start |= val << 32; - } - if (xe_gt_has_indirect_ring_state(hwe->gt)) { - snapshot->reg.indirect_ring_state = - xe_hw_engine_mmio_read32(hwe, INDIRECT_RING_STATE(0)); + if (job) { + /* If got guc capture, set source to GuC */ + node = xe_guc_capture_get_matching_and_lock(job); + if (node) { + struct xe_device *xe = gt_to_xe(hwe->gt); + struct xe_devcoredump *coredump = &xe->devcoredump; + + coredump->snapshot.matched_node = node; + snapshot->source = XE_ENGINE_CAPTURE_SOURCE_GUC; + xe_gt_dbg(hwe->gt, "Found and locked GuC-err-capture node"); + return snapshot; + } } - snapshot->reg.ring_head = - xe_hw_engine_mmio_read32(hwe, RING_HEAD(0)) & HEAD_ADDR; - snapshot->reg.ring_tail = - xe_hw_engine_mmio_read32(hwe, RING_TAIL(0)) & TAIL_ADDR; - snapshot->reg.ring_ctl = xe_hw_engine_mmio_read32(hwe, RING_CTL(0)); - snapshot->reg.ring_mi_mode = - xe_hw_engine_mmio_read32(hwe, RING_MI_MODE(0)); - snapshot->reg.ring_mode = xe_hw_engine_mmio_read32(hwe, RING_MODE(0)); - snapshot->reg.ring_imr = xe_hw_engine_mmio_read32(hwe, RING_IMR(0)); - snapshot->reg.ring_esr = xe_hw_engine_mmio_read32(hwe, RING_ESR(0)); - snapshot->reg.ring_emr = xe_hw_engine_mmio_read32(hwe, RING_EMR(0)); - snapshot->reg.ring_eir = xe_hw_engine_mmio_read32(hwe, RING_EIR(0)); - snapshot->reg.ipehr = xe_hw_engine_mmio_read32(hwe, RING_IPEHR(0)); - xe_hw_engine_snapshot_instdone_capture(hwe, snapshot); - - if (snapshot->hwe->class == XE_ENGINE_CLASS_COMPUTE) - snapshot->reg.rcu_mode = xe_mmio_read32(&hwe->gt->mmio, RCU_MODE); + /* otherwise, do manual capture */ + xe_hw_engine_manual_capture(hwe, snapshot); + snapshot->source = XE_ENGINE_CAPTURE_SOURCE_MANUAL; + xe_gt_dbg(hwe->gt, "Proceeding with manual engine snapshot"); return snapshot; } @@ -1036,19 +1063,9 @@ xe_hw_engine_snapshot_instdone_print(struct xe_hw_engine_snapshot *snapshot, str } } -/** - * xe_hw_engine_snapshot_print - Print out a given Xe HW Engine snapshot. - * @snapshot: Xe HW Engine snapshot object. - * @p: drm_printer where it will be printed out. - * - * This function prints out a given Xe HW Engine snapshot object. - */ -void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, - struct drm_printer *p) +static void __xe_hw_engine_manual_print(struct xe_hw_engine_snapshot *snapshot, + struct drm_printer *p) { - if (!snapshot) - return; - drm_printf(p, "%s (physical), logical instance=%d\n", snapshot->name ? snapshot->name : "", snapshot->logical_instance); @@ -1086,6 +1103,24 @@ void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, snapshot->reg.rcu_mode); } +/** + * xe_hw_engine_snapshot_print - Print out a given Xe HW Engine snapshot. + * @snapshot: Xe HW Engine snapshot object. + * @p: drm_printer where it will be printed out. + * + * This function prints out a given Xe HW Engine snapshot object. + */ +void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, + struct drm_printer *p) +{ + if (!snapshot) + return; + + if (snapshot->source == XE_ENGINE_CAPTURE_SOURCE_MANUAL) + __xe_hw_engine_manual_print(snapshot, p); + else + xe_engine_guc_capture_print(snapshot, p); +} /** * xe_hw_engine_snapshot_free - Free all allocated objects for a given snapshot. * @snapshot: Xe HW Engine snapshot object. @@ -1119,7 +1154,7 @@ void xe_hw_engine_print(struct xe_hw_engine *hwe, struct drm_printer *p) { struct xe_hw_engine_snapshot *snapshot; - snapshot = xe_hw_engine_snapshot_capture(hwe); + snapshot = xe_hw_engine_snapshot_capture(hwe, NULL); xe_hw_engine_snapshot_print(snapshot, p); xe_hw_engine_snapshot_free(snapshot); } diff --git a/drivers/gpu/drm/xe/xe_hw_engine.h b/drivers/gpu/drm/xe/xe_hw_engine.h index 022819a4a8eb..c2428326a366 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.h +++ b/drivers/gpu/drm/xe/xe_hw_engine.h @@ -11,6 +11,7 @@ struct drm_printer; struct drm_xe_engine_class_instance; struct xe_device; +struct xe_sched_job; #ifdef CONFIG_DRM_XE_JOB_TIMEOUT_MIN #define XE_HW_ENGINE_JOB_TIMEOUT_MIN CONFIG_DRM_XE_JOB_TIMEOUT_MIN @@ -54,9 +55,8 @@ void xe_hw_engine_handle_irq(struct xe_hw_engine *hwe, u16 intr_vec); void xe_hw_engine_enable_ring(struct xe_hw_engine *hwe); u32 xe_hw_engine_mask_per_class(struct xe_gt *gt, enum xe_engine_class engine_class); - struct xe_hw_engine_snapshot * -xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe); +xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_sched_job *job); void xe_hw_engine_snapshot_free(struct xe_hw_engine_snapshot *snapshot); void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p); diff --git a/drivers/gpu/drm/xe/xe_hw_engine_types.h b/drivers/gpu/drm/xe/xe_hw_engine_types.h index be60edb3e673..55805c78d9d1 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine_types.h +++ b/drivers/gpu/drm/xe/xe_hw_engine_types.h @@ -152,6 +152,11 @@ struct xe_hw_engine { struct xe_hw_engine_group *hw_engine_group; }; +enum xe_hw_engine_snapshot_source_id { + XE_ENGINE_CAPTURE_SOURCE_MANUAL, + XE_ENGINE_CAPTURE_SOURCE_GUC +}; + /** * struct xe_hw_engine_snapshot - Hardware engine snapshot * @@ -160,6 +165,8 @@ struct xe_hw_engine { struct xe_hw_engine_snapshot { /** @name: name of the hw engine */ char *name; + /** @source: Data source, either manual or GuC */ + enum xe_hw_engine_snapshot_source_id source; /** @hwe: hw engine */ struct xe_hw_engine *hwe; /** @logical_instance: logical instance of this hw engine */ diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index f0976230012a..4f64c7f4e68d 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -38,24 +38,6 @@ #define LRC_INDIRECT_RING_STATE_SIZE SZ_4K -struct xe_lrc_snapshot { - struct xe_bo *lrc_bo; - void *lrc_snapshot; - unsigned long lrc_size, lrc_offset; - - u32 context_desc; - u32 indirect_context_desc; - u32 head; - struct { - u32 internal; - u32 memory; - } tail; - u32 start_seqno; - u32 seqno; - u32 ctx_timestamp; - u32 ctx_job_timestamp; -}; - static struct xe_device * lrc_to_xe(struct xe_lrc *lrc) { diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h index c24542e89318..40d8f6906d3e 100644 --- a/drivers/gpu/drm/xe/xe_lrc.h +++ b/drivers/gpu/drm/xe/xe_lrc.h @@ -17,9 +17,26 @@ enum xe_engine_class; struct xe_gt; struct xe_hw_engine; struct xe_lrc; -struct xe_lrc_snapshot; struct xe_vm; +struct xe_lrc_snapshot { + struct xe_bo *lrc_bo; + void *lrc_snapshot; + unsigned long lrc_size, lrc_offset; + + u32 context_desc; + u32 indirect_context_desc; + u32 head; + struct { + u32 internal; + u32 memory; + } tail; + u32 start_seqno; + u32 seqno; + u32 ctx_timestamp; + u32 ctx_job_timestamp; +}; + #define LRC_PPHWSP_SCRATCH_ADDR (0x34 * 4) struct xe_lrc *xe_lrc_create(struct xe_hw_engine *hwe, struct xe_vm *vm, -- GitLab From 0f1fdf5592259cc68ee5ec968c6cddb26d0ecf77 Mon Sep 17 00:00:00 2001 From: Zhanjun Dong <zhanjun.dong@intel.com> Date: Fri, 4 Oct 2024 12:34:28 -0700 Subject: [PATCH 775/970] drm/xe/guc: Save manual engine capture into capture list Save manual engine capture into capture list. This removes duplicate register definitions across manual-capture vs guc-err-capture. Signed-off-by: Zhanjun Dong <zhanjun.dong@intel.com> Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004193428.3311145-7-zhanjun.dong@intel.com --- drivers/gpu/drm/xe/xe_devcoredump.c | 2 +- drivers/gpu/drm/xe/xe_guc_capture.c | 153 +++++++++++++- drivers/gpu/drm/xe/xe_guc_capture.h | 3 +- drivers/gpu/drm/xe/xe_hw_engine.c | 254 +----------------------- drivers/gpu/drm/xe/xe_hw_engine.h | 2 - drivers/gpu/drm/xe/xe_hw_engine_types.h | 59 ------ 6 files changed, 163 insertions(+), 310 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c index 30f9e8cb328c..99842a35dbf0 100644 --- a/drivers/gpu/drm/xe/xe_devcoredump.c +++ b/drivers/gpu/drm/xe/xe_devcoredump.c @@ -117,7 +117,7 @@ static ssize_t __xe_devcoredump_read(char *buffer, size_t count, drm_puts(&p, "\n**** HW Engines ****\n"); for (i = 0; i < XE_NUM_HW_ENGINES; i++) if (ss->hwe[i]) - xe_hw_engine_snapshot_print(ss->hwe[i], &p); + xe_engine_snapshot_print(ss->hwe[i], &p); drm_puts(&p, "\n**** VM state ****\n"); xe_vm_snapshot_print(ss->vm, &p); diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c index 3853b778c4f0..41262bda20ed 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.c +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -935,7 +935,7 @@ guc_capture_init_node(struct xe_guc *guc, struct __guc_capture_parsed_output *no * guc->capture->cachelist and populated with the error-capture * data from GuC and then it's added into guc->capture->outlist linked * list. This list is used for matchup and printout by xe_devcoredump_read - * and xe_hw_engine_snapshot_print, (when user invokes the devcoredump sysfs). + * and xe_engine_snapshot_print, (when user invokes the devcoredump sysfs). * * GUC --> notify context reset: * ----------------------------- @@ -943,12 +943,13 @@ guc_capture_init_node(struct xe_guc *guc, struct __guc_capture_parsed_output *no * L--> xe_devcoredump * L--> devcoredump_snapshot * --> xe_hw_engine_snapshot_capture + * --> xe_engine_manual_capture(For manual capture) * * User Sysfs / Debugfs * -------------------- * --> xe_devcoredump_read-> * L--> xxx_snapshot_print - * L--> xe_hw_engine_snapshot_print + * L--> xe_engine_snapshot_print * Print register lists values saved at * guc->capture->outlist * @@ -1524,6 +1525,129 @@ guc_capture_create_prealloc_nodes(struct xe_guc *guc) __guc_capture_create_prealloc_nodes(guc); } +static void +read_reg_to_node(struct xe_hw_engine *hwe, const struct __guc_mmio_reg_descr_group *list, + struct guc_mmio_reg *regs) +{ + int i; + + if (!list || list->num_regs == 0) + return; + + if (!regs) + return; + + for (i = 0; i < list->num_regs; i++) { + struct __guc_mmio_reg_descr desc = list->list[i]; + u32 value; + + if (!list->list) + return; + + if (list->type == GUC_STATE_CAPTURE_TYPE_ENGINE_INSTANCE) { + value = xe_hw_engine_mmio_read32(hwe, desc.reg); + } else { + if (list->type == GUC_STATE_CAPTURE_TYPE_ENGINE_CLASS && + FIELD_GET(GUC_REGSET_STEERING_NEEDED, desc.flags)) { + int group, instance; + + group = FIELD_GET(GUC_REGSET_STEERING_GROUP, desc.flags); + instance = FIELD_GET(GUC_REGSET_STEERING_INSTANCE, desc.flags); + value = xe_gt_mcr_unicast_read(hwe->gt, XE_REG_MCR(desc.reg.addr), + group, instance); + } else { + value = xe_mmio_read32(&hwe->gt->mmio, desc.reg); + } + } + + regs[i].value = value; + regs[i].offset = desc.reg.addr; + regs[i].flags = desc.flags; + regs[i].mask = desc.mask; + } +} + +/** + * xe_engine_manual_capture - Take a manual engine snapshot from engine. + * @hwe: Xe HW Engine. + * @snapshot: The engine snapshot + * + * Take engine snapshot from engine read. + * + * Returns: None + */ +void +xe_engine_manual_capture(struct xe_hw_engine *hwe, struct xe_hw_engine_snapshot *snapshot) +{ + struct xe_gt *gt = hwe->gt; + struct xe_device *xe = gt_to_xe(gt); + struct xe_guc *guc = >->uc.guc; + struct xe_devcoredump *devcoredump = &xe->devcoredump; + enum guc_capture_list_class_type capture_class; + const struct __guc_mmio_reg_descr_group *list; + struct __guc_capture_parsed_output *new; + enum guc_state_capture_type type; + u16 guc_id = 0; + u32 lrca = 0; + + new = guc_capture_get_prealloc_node(guc); + if (!new) + return; + + capture_class = xe_engine_class_to_guc_capture_class(hwe->class); + for (type = GUC_STATE_CAPTURE_TYPE_GLOBAL; type < GUC_STATE_CAPTURE_TYPE_MAX; type++) { + struct gcap_reg_list_info *reginfo = &new->reginfo[type]; + /* + * regsinfo->regs is allocated based on guc->capture->max_mmio_per_node + * which is based on the descriptor list driving the population so + * should not overflow + */ + + /* Get register list for the type/class */ + list = xe_guc_capture_get_reg_desc_list(gt, GUC_CAPTURE_LIST_INDEX_PF, type, + capture_class, false); + if (!list) { + xe_gt_dbg(gt, "Empty GuC capture register descriptor for %s", + hwe->name); + continue; + } + + read_reg_to_node(hwe, list, reginfo->regs); + reginfo->num_regs = list->num_regs; + + /* Capture steering registers for rcs/ccs */ + if (capture_class == GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE) { + list = xe_guc_capture_get_reg_desc_list(gt, GUC_CAPTURE_LIST_INDEX_PF, + type, capture_class, true); + if (list) { + read_reg_to_node(hwe, list, ®info->regs[reginfo->num_regs]); + reginfo->num_regs += list->num_regs; + } + } + } + + if (devcoredump && devcoredump->captured) { + struct xe_guc_submit_exec_queue_snapshot *ge = devcoredump->snapshot.ge; + + if (ge) { + guc_id = ge->guc.id; + if (ge->lrc[0]) + lrca = ge->lrc[0]->context_desc; + } + } + + new->eng_class = xe_engine_class_to_guc_class(hwe->class); + new->eng_inst = hwe->instance; + new->guc_id = guc_id; + new->lrca = lrca; + new->is_partial = 0; + new->locked = 1; + new->source = XE_ENGINE_CAPTURE_SOURCE_MANUAL; + + guc_capture_add_node_to_outlist(guc->capture, new); + devcoredump->snapshot.matched_node = new; +} + static struct guc_mmio_reg * guc_capture_find_reg(struct gcap_reg_list_info *reginfo, u32 addr, u32 flags) { @@ -1609,7 +1733,7 @@ snapshot_print_by_list_order(struct xe_hw_engine_snapshot *snapshot, struct drm_ * * This function prints out a given Xe HW Engine snapshot object. */ -void xe_engine_guc_capture_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p) +void xe_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p) { const char *grptype[GUC_STATE_CAPTURE_GROUP_TYPE_MAX] = { "full-capture", @@ -1648,6 +1772,8 @@ void xe_engine_guc_capture_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printf(p, "\tCoverage: %s\n", grptype[devcore_snapshot->matched_node->is_partial]); drm_printf(p, "\tForcewake: domain 0x%x, ref %d\n", snapshot->forcewake.domain, snapshot->forcewake.ref); + drm_printf(p, "\tReserved: %s\n", + str_yes_no(snapshot->kernel_reserved)); for (type = GUC_STATE_CAPTURE_TYPE_GLOBAL; type < GUC_STATE_CAPTURE_TYPE_MAX; type++) { list = xe_guc_capture_get_reg_desc_list(gt, GUC_CAPTURE_LIST_INDEX_PF, type, @@ -1757,8 +1883,27 @@ xe_engine_snapshot_capture_for_job(struct xe_sched_job *job) continue; } - if (!coredump->snapshot.hwe[id]) + if (!coredump->snapshot.hwe[id]) { coredump->snapshot.hwe[id] = xe_hw_engine_snapshot_capture(hwe, job); + } else { + struct __guc_capture_parsed_output *new; + + new = xe_guc_capture_get_matching_and_lock(job); + if (new) { + struct xe_guc *guc = &q->gt->uc.guc; + + /* + * If we are in here, it means we found a fresh + * GuC-err-capture node for this engine after + * previously failing to find a match in the + * early part of guc_exec_queue_timedout_job. + * Thus we must free the manually captured node + */ + guc_capture_free_outlist_node(guc->capture, + coredump->snapshot.matched_node); + coredump->snapshot.matched_node = new; + } + } break; } diff --git a/drivers/gpu/drm/xe/xe_guc_capture.h b/drivers/gpu/drm/xe/xe_guc_capture.h index fe695ab08a74..97a795d13dd1 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.h +++ b/drivers/gpu/drm/xe/xe_guc_capture.h @@ -51,8 +51,9 @@ const struct __guc_mmio_reg_descr_group * xe_guc_capture_get_reg_desc_list(struct xe_gt *gt, u32 owner, u32 type, enum guc_capture_list_class_type capture_class, bool is_ext); struct __guc_capture_parsed_output *xe_guc_capture_get_matching_and_lock(struct xe_sched_job *job); +void xe_engine_manual_capture(struct xe_hw_engine *hwe, struct xe_hw_engine_snapshot *snapshot); +void xe_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p); void xe_engine_snapshot_capture_for_job(struct xe_sched_job *job); -void xe_engine_guc_capture_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p); void xe_guc_capture_steered_list_init(struct xe_guc *guc); void xe_guc_capture_put_matched_nodes(struct xe_guc *guc); int xe_guc_capture_init(struct xe_guc *guc); diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index 18a06c2f78d1..1557acee3523 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -826,117 +826,6 @@ void xe_hw_engine_handle_irq(struct xe_hw_engine *hwe, u16 intr_vec) xe_hw_fence_irq_run(hwe->fence_irq); } -static bool -is_slice_common_per_gslice(struct xe_device *xe) -{ - return GRAPHICS_VERx100(xe) >= 1255; -} - -static void -xe_hw_engine_snapshot_instdone_capture(struct xe_hw_engine *hwe, - struct xe_hw_engine_snapshot *snapshot) -{ - struct xe_gt *gt = hwe->gt; - struct xe_mmio *mmio = >->mmio; - struct xe_device *xe = gt_to_xe(gt); - unsigned int dss; - u16 group, instance; - - snapshot->reg.instdone.ring = xe_hw_engine_mmio_read32(hwe, RING_INSTDONE(0)); - - if (snapshot->hwe->class != XE_ENGINE_CLASS_RENDER) - return; - - if (is_slice_common_per_gslice(xe) == false) { - snapshot->reg.instdone.slice_common[0] = - xe_mmio_read32(mmio, SC_INSTDONE); - snapshot->reg.instdone.slice_common_extra[0] = - xe_mmio_read32(mmio, SC_INSTDONE_EXTRA); - snapshot->reg.instdone.slice_common_extra2[0] = - xe_mmio_read32(mmio, SC_INSTDONE_EXTRA2); - } else { - for_each_geometry_dss(dss, gt, group, instance) { - snapshot->reg.instdone.slice_common[dss] = - xe_gt_mcr_unicast_read(gt, XEHPG_SC_INSTDONE, group, instance); - snapshot->reg.instdone.slice_common_extra[dss] = - xe_gt_mcr_unicast_read(gt, XEHPG_SC_INSTDONE_EXTRA, group, instance); - snapshot->reg.instdone.slice_common_extra2[dss] = - xe_gt_mcr_unicast_read(gt, XEHPG_SC_INSTDONE_EXTRA2, group, instance); - } - } - - for_each_geometry_dss(dss, gt, group, instance) { - snapshot->reg.instdone.sampler[dss] = - xe_gt_mcr_unicast_read(gt, SAMPLER_INSTDONE, group, instance); - snapshot->reg.instdone.row[dss] = - xe_gt_mcr_unicast_read(gt, ROW_INSTDONE, group, instance); - - if (GRAPHICS_VERx100(xe) >= 1255) - snapshot->reg.instdone.geom_svg[dss] = - xe_gt_mcr_unicast_read(gt, XEHPG_INSTDONE_GEOM_SVGUNIT, - group, instance); - } -} - -static void -xe_hw_engine_manual_capture(struct xe_hw_engine *hwe, struct xe_hw_engine_snapshot *snapshot) -{ - u64 val; - - snapshot->reg.ring_execlist_status = - xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_STATUS_LO(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_STATUS_HI(0)); - snapshot->reg.ring_execlist_status |= val << 32; - - snapshot->reg.ring_execlist_sq_contents = - xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_SQ_CONTENTS_LO(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_EXECLIST_SQ_CONTENTS_HI(0)); - snapshot->reg.ring_execlist_sq_contents |= val << 32; - - snapshot->reg.ring_acthd = xe_hw_engine_mmio_read32(hwe, RING_ACTHD(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_ACTHD_UDW(0)); - snapshot->reg.ring_acthd |= val << 32; - - snapshot->reg.ring_bbaddr = xe_hw_engine_mmio_read32(hwe, RING_BBADDR(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_BBADDR_UDW(0)); - snapshot->reg.ring_bbaddr |= val << 32; - - snapshot->reg.ring_dma_fadd = - xe_hw_engine_mmio_read32(hwe, RING_DMA_FADD(0)); - val = xe_hw_engine_mmio_read32(hwe, RING_DMA_FADD_UDW(0)); - snapshot->reg.ring_dma_fadd |= val << 32; - - snapshot->reg.ring_hwstam = xe_hw_engine_mmio_read32(hwe, RING_HWSTAM(0)); - snapshot->reg.ring_hws_pga = xe_hw_engine_mmio_read32(hwe, RING_HWS_PGA(0)); - snapshot->reg.ring_start = xe_hw_engine_mmio_read32(hwe, RING_START(0)); - if (GRAPHICS_VERx100(hwe->gt->tile->xe) >= 2000) { - val = xe_hw_engine_mmio_read32(hwe, RING_START_UDW(0)); - snapshot->reg.ring_start |= val << 32; - } - if (xe_gt_has_indirect_ring_state(hwe->gt)) { - snapshot->reg.indirect_ring_state = - xe_hw_engine_mmio_read32(hwe, INDIRECT_RING_STATE(0)); - } - - snapshot->reg.ring_head = - xe_hw_engine_mmio_read32(hwe, RING_HEAD(0)) & HEAD_ADDR; - snapshot->reg.ring_tail = - xe_hw_engine_mmio_read32(hwe, RING_TAIL(0)) & TAIL_ADDR; - snapshot->reg.ring_ctl = xe_hw_engine_mmio_read32(hwe, RING_CTL(0)); - snapshot->reg.ring_mi_mode = - xe_hw_engine_mmio_read32(hwe, RING_MI_MODE(0)); - snapshot->reg.ring_mode = xe_hw_engine_mmio_read32(hwe, RING_MODE(0)); - snapshot->reg.ring_imr = xe_hw_engine_mmio_read32(hwe, RING_IMR(0)); - snapshot->reg.ring_esr = xe_hw_engine_mmio_read32(hwe, RING_ESR(0)); - snapshot->reg.ring_emr = xe_hw_engine_mmio_read32(hwe, RING_EMR(0)); - snapshot->reg.ring_eir = xe_hw_engine_mmio_read32(hwe, RING_EIR(0)); - snapshot->reg.ipehr = xe_hw_engine_mmio_read32(hwe, RING_IPEHR(0)); - xe_hw_engine_snapshot_instdone_capture(hwe, snapshot); - - if (snapshot->hwe->class == XE_ENGINE_CLASS_COMPUTE) - snapshot->reg.rcu_mode = xe_mmio_read32(&hwe->gt->mmio, RCU_MODE); -} - /** * xe_hw_engine_snapshot_capture - Take a quick snapshot of the HW Engine. * @hwe: Xe HW Engine. @@ -952,7 +841,6 @@ struct xe_hw_engine_snapshot * xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_sched_job *job) { struct xe_hw_engine_snapshot *snapshot; - size_t len; struct __guc_capture_parsed_output *node; if (!xe_hw_engine_is_valid(hwe)) @@ -963,28 +851,6 @@ xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_sched_job *job if (!snapshot) return NULL; - /* Because XE_MAX_DSS_FUSE_BITS is defined in xe_gt_types.h and it - * includes xe_hw_engine_types.h the length of this 3 registers can't be - * set in struct xe_hw_engine_snapshot, so here doing additional - * allocations. - */ - len = (XE_MAX_DSS_FUSE_BITS * sizeof(u32)); - snapshot->reg.instdone.slice_common = kzalloc(len, GFP_ATOMIC); - snapshot->reg.instdone.slice_common_extra = kzalloc(len, GFP_ATOMIC); - snapshot->reg.instdone.slice_common_extra2 = kzalloc(len, GFP_ATOMIC); - snapshot->reg.instdone.sampler = kzalloc(len, GFP_ATOMIC); - snapshot->reg.instdone.row = kzalloc(len, GFP_ATOMIC); - snapshot->reg.instdone.geom_svg = kzalloc(len, GFP_ATOMIC); - if (!snapshot->reg.instdone.slice_common || - !snapshot->reg.instdone.slice_common_extra || - !snapshot->reg.instdone.slice_common_extra2 || - !snapshot->reg.instdone.sampler || - !snapshot->reg.instdone.row || - !snapshot->reg.instdone.geom_svg) { - xe_hw_engine_snapshot_free(snapshot); - return NULL; - } - snapshot->name = kstrdup(hwe->name, GFP_ATOMIC); snapshot->hwe = hwe; snapshot->logical_instance = hwe->logical_instance; @@ -1013,114 +879,13 @@ xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_sched_job *job } /* otherwise, do manual capture */ - xe_hw_engine_manual_capture(hwe, snapshot); + xe_engine_manual_capture(hwe, snapshot); snapshot->source = XE_ENGINE_CAPTURE_SOURCE_MANUAL; xe_gt_dbg(hwe->gt, "Proceeding with manual engine snapshot"); return snapshot; } -static void -xe_hw_engine_snapshot_instdone_print(struct xe_hw_engine_snapshot *snapshot, struct drm_printer *p) -{ - struct xe_gt *gt = snapshot->hwe->gt; - struct xe_device *xe = gt_to_xe(gt); - u16 group, instance; - unsigned int dss; - - drm_printf(p, "\tRING_INSTDONE: 0x%08x\n", snapshot->reg.instdone.ring); - - if (snapshot->hwe->class != XE_ENGINE_CLASS_RENDER) - return; - - if (is_slice_common_per_gslice(xe) == false) { - drm_printf(p, "\tSC_INSTDONE[0]: 0x%08x\n", - snapshot->reg.instdone.slice_common[0]); - drm_printf(p, "\tSC_INSTDONE_EXTRA[0]: 0x%08x\n", - snapshot->reg.instdone.slice_common_extra[0]); - drm_printf(p, "\tSC_INSTDONE_EXTRA2[0]: 0x%08x\n", - snapshot->reg.instdone.slice_common_extra2[0]); - } else { - for_each_geometry_dss(dss, gt, group, instance) { - drm_printf(p, "\tSC_INSTDONE[%u]: 0x%08x\n", dss, - snapshot->reg.instdone.slice_common[dss]); - drm_printf(p, "\tSC_INSTDONE_EXTRA[%u]: 0x%08x\n", dss, - snapshot->reg.instdone.slice_common_extra[dss]); - drm_printf(p, "\tSC_INSTDONE_EXTRA2[%u]: 0x%08x\n", dss, - snapshot->reg.instdone.slice_common_extra2[dss]); - } - } - - for_each_geometry_dss(dss, gt, group, instance) { - drm_printf(p, "\tSAMPLER_INSTDONE[%u]: 0x%08x\n", dss, - snapshot->reg.instdone.sampler[dss]); - drm_printf(p, "\tROW_INSTDONE[%u]: 0x%08x\n", dss, - snapshot->reg.instdone.row[dss]); - - if (GRAPHICS_VERx100(xe) >= 1255) - drm_printf(p, "\tINSTDONE_GEOM_SVGUNIT[%u]: 0x%08x\n", - dss, snapshot->reg.instdone.geom_svg[dss]); - } -} - -static void __xe_hw_engine_manual_print(struct xe_hw_engine_snapshot *snapshot, - struct drm_printer *p) -{ - drm_printf(p, "%s (physical), logical instance=%d\n", - snapshot->name ? snapshot->name : "", - snapshot->logical_instance); - drm_printf(p, "\tForcewake: domain 0x%x, ref %d\n", - snapshot->forcewake.domain, snapshot->forcewake.ref); - drm_printf(p, "\tReserved: %s\n", - str_yes_no(snapshot->kernel_reserved)); - drm_printf(p, "\tHWSTAM: 0x%08x\n", snapshot->reg.ring_hwstam); - drm_printf(p, "\tRING_HWS_PGA: 0x%08x\n", snapshot->reg.ring_hws_pga); - drm_printf(p, "\tRING_EXECLIST_STATUS: 0x%016llx\n", - snapshot->reg.ring_execlist_status); - drm_printf(p, "\tRING_EXECLIST_SQ_CONTENTS: 0x%016llx\n", - snapshot->reg.ring_execlist_sq_contents); - drm_printf(p, "\tRING_START: 0x%016llx\n", snapshot->reg.ring_start); - drm_printf(p, "\tRING_HEAD: 0x%08x\n", snapshot->reg.ring_head); - drm_printf(p, "\tRING_TAIL: 0x%08x\n", snapshot->reg.ring_tail); - drm_printf(p, "\tRING_CTL: 0x%08x\n", snapshot->reg.ring_ctl); - drm_printf(p, "\tRING_MI_MODE: 0x%08x\n", snapshot->reg.ring_mi_mode); - drm_printf(p, "\tRING_MODE: 0x%08x\n", - snapshot->reg.ring_mode); - drm_printf(p, "\tRING_IMR: 0x%08x\n", snapshot->reg.ring_imr); - drm_printf(p, "\tRING_ESR: 0x%08x\n", snapshot->reg.ring_esr); - drm_printf(p, "\tRING_EMR: 0x%08x\n", snapshot->reg.ring_emr); - drm_printf(p, "\tRING_EIR: 0x%08x\n", snapshot->reg.ring_eir); - drm_printf(p, "\tACTHD: 0x%016llx\n", snapshot->reg.ring_acthd); - drm_printf(p, "\tBBADDR: 0x%016llx\n", snapshot->reg.ring_bbaddr); - drm_printf(p, "\tDMA_FADDR: 0x%016llx\n", snapshot->reg.ring_dma_fadd); - drm_printf(p, "\tINDIRECT_RING_STATE: 0x%08x\n", - snapshot->reg.indirect_ring_state); - drm_printf(p, "\tIPEHR: 0x%08x\n", snapshot->reg.ipehr); - xe_hw_engine_snapshot_instdone_print(snapshot, p); - - if (snapshot->hwe->class == XE_ENGINE_CLASS_COMPUTE) - drm_printf(p, "\tRCU_MODE: 0x%08x\n", - snapshot->reg.rcu_mode); -} - -/** - * xe_hw_engine_snapshot_print - Print out a given Xe HW Engine snapshot. - * @snapshot: Xe HW Engine snapshot object. - * @p: drm_printer where it will be printed out. - * - * This function prints out a given Xe HW Engine snapshot object. - */ -void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, - struct drm_printer *p) -{ - if (!snapshot) - return; - - if (snapshot->source == XE_ENGINE_CAPTURE_SOURCE_MANUAL) - __xe_hw_engine_manual_print(snapshot, p); - else - xe_engine_guc_capture_print(snapshot, p); -} /** * xe_hw_engine_snapshot_free - Free all allocated objects for a given snapshot. * @snapshot: Xe HW Engine snapshot object. @@ -1130,15 +895,18 @@ void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, */ void xe_hw_engine_snapshot_free(struct xe_hw_engine_snapshot *snapshot) { + struct xe_gt *gt; if (!snapshot) return; - kfree(snapshot->reg.instdone.slice_common); - kfree(snapshot->reg.instdone.slice_common_extra); - kfree(snapshot->reg.instdone.slice_common_extra2); - kfree(snapshot->reg.instdone.sampler); - kfree(snapshot->reg.instdone.row); - kfree(snapshot->reg.instdone.geom_svg); + gt = snapshot->hwe->gt; + /* + * xe_guc_capture_put_matched_nodes is called here and from + * xe_devcoredump_snapshot_free, to cover the 2 calling paths + * of hw_engines - debugfs and devcoredump free. + */ + xe_guc_capture_put_matched_nodes(>->uc.guc); + kfree(snapshot->name); kfree(snapshot); } @@ -1155,7 +923,7 @@ void xe_hw_engine_print(struct xe_hw_engine *hwe, struct drm_printer *p) struct xe_hw_engine_snapshot *snapshot; snapshot = xe_hw_engine_snapshot_capture(hwe, NULL); - xe_hw_engine_snapshot_print(snapshot, p); + xe_engine_snapshot_print(snapshot, p); xe_hw_engine_snapshot_free(snapshot); } diff --git a/drivers/gpu/drm/xe/xe_hw_engine.h b/drivers/gpu/drm/xe/xe_hw_engine.h index c2428326a366..da0a6922a26f 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.h +++ b/drivers/gpu/drm/xe/xe_hw_engine.h @@ -58,8 +58,6 @@ u32 xe_hw_engine_mask_per_class(struct xe_gt *gt, struct xe_hw_engine_snapshot * xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_sched_job *job); void xe_hw_engine_snapshot_free(struct xe_hw_engine_snapshot *snapshot); -void xe_hw_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, - struct drm_printer *p); void xe_hw_engine_print(struct xe_hw_engine *hwe, struct drm_printer *p); void xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe); diff --git a/drivers/gpu/drm/xe/xe_hw_engine_types.h b/drivers/gpu/drm/xe/xe_hw_engine_types.h index 55805c78d9d1..719f27ef00a5 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine_types.h +++ b/drivers/gpu/drm/xe/xe_hw_engine_types.h @@ -182,65 +182,6 @@ struct xe_hw_engine_snapshot { u32 mmio_base; /** @kernel_reserved: Engine reserved, can't be used by userspace */ bool kernel_reserved; - /** @reg: Useful MMIO register snapshot */ - struct { - /** @reg.ring_execlist_status: RING_EXECLIST_STATUS */ - u64 ring_execlist_status; - /** @reg.ring_execlist_sq_contents: RING_EXECLIST_SQ_CONTENTS */ - u64 ring_execlist_sq_contents; - /** @reg.ring_acthd: RING_ACTHD */ - u64 ring_acthd; - /** @reg.ring_bbaddr: RING_BBADDR */ - u64 ring_bbaddr; - /** @reg.ring_dma_fadd: RING_DMA_FADD */ - u64 ring_dma_fadd; - /** @reg.ring_hwstam: RING_HWSTAM */ - u32 ring_hwstam; - /** @reg.ring_hws_pga: RING_HWS_PGA */ - u32 ring_hws_pga; - /** @reg.ring_start: RING_START */ - u64 ring_start; - /** @reg.ring_head: RING_HEAD */ - u32 ring_head; - /** @reg.ring_tail: RING_TAIL */ - u32 ring_tail; - /** @reg.ring_ctl: RING_CTL */ - u32 ring_ctl; - /** @reg.ring_mi_mode: RING_MI_MODE */ - u32 ring_mi_mode; - /** @reg.ring_mode: RING_MODE */ - u32 ring_mode; - /** @reg.ring_imr: RING_IMR */ - u32 ring_imr; - /** @reg.ring_esr: RING_ESR */ - u32 ring_esr; - /** @reg.ring_emr: RING_EMR */ - u32 ring_emr; - /** @reg.ring_eir: RING_EIR */ - u32 ring_eir; - /** @reg.indirect_ring_state: INDIRECT_RING_STATE */ - u32 indirect_ring_state; - /** @reg.ipehr: IPEHR */ - u32 ipehr; - /** @reg.rcu_mode: RCU_MODE */ - u32 rcu_mode; - struct { - /** @reg.instdone.ring: RING_INSTDONE */ - u32 ring; - /** @reg.instdone.slice_common: SC_INSTDONE */ - u32 *slice_common; - /** @reg.instdone.slice_common_extra: SC_INSTDONE_EXTRA */ - u32 *slice_common_extra; - /** @reg.instdone.slice_common_extra2: SC_INSTDONE_EXTRA2 */ - u32 *slice_common_extra2; - /** @reg.instdone.sampler: SAMPLER_INSTDONE */ - u32 *sampler; - /** @reg.instdone.row: ROW_INSTDONE */ - u32 *row; - /** @reg.instdone.geom_svg: INSTDONE_GEOM_SVGUNIT */ - u32 *geom_svg; - } instdone; - } reg; }; #endif -- GitLab From 763dc2cdeb2ac5a5067972b614f9f0603f716f9b Mon Sep 17 00:00:00 2001 From: Frieder Schrempf <frieder.schrempf@kontron.de> Date: Wed, 28 Aug 2024 09:46:53 +0200 Subject: [PATCH 776/970] dt-bindings: vendor-prefixes: Add Jenson Display Add vendor prefix for manufacturer Jenson Display (http://jensondisplay.com). Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20240828074753.25401-2-frieder@fris.de Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240828074753.25401-2-frieder@fris.de --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index b320a39de7fe..46901c8d7eb0 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -752,6 +752,8 @@ patternProperties: description: Japan Display Inc. "^jedec,.*": description: JEDEC Solid State Technology Association + "^jenson,.*": + description: Jenson Display Co. Ltd. "^jesurun,.*": description: Shenzhen Jesurun Electronics Business Dept. "^jethome,.*": -- GitLab From 15bda06bc93fca828e5f11ca6b773fed19e45b8e Mon Sep 17 00:00:00 2001 From: Frieder Schrempf <frieder.schrempf@kontron.de> Date: Wed, 28 Aug 2024 09:46:54 +0200 Subject: [PATCH 777/970] dt-bindings: display: panel-lvds: Add compatible for Jenson BL-JT60050-01A The Jenson BL-JT60050-01A is a 7" 1024x600 LVDS display. Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> Acked-by: Conor Dooley <conor.dooley@microchip.com> Link: https://lore.kernel.org/r/20240828074753.25401-3-frieder@fris.de Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240828074753.25401-3-frieder@fris.de --- Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml index 155d8ffa8f6e..5af2d6930075 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-lvds.yaml @@ -50,6 +50,8 @@ properties: - hannstar,hsd101pww2 # Hydis Technologies 7" WXGA (800x1280) TFT LCD LVDS panel - hydis,hv070wx2-1e0 + # Jenson Display BL-JT60050-01A 7" WSVGA (1024x600) color TFT LCD LVDS panel + - jenson,bl-jt60050-01a - tbs,a711-panel - const: panel-lvds -- GitLab From b64e7d59ba75b1b080a65da20ffe0bae532854b5 Mon Sep 17 00:00:00 2001 From: Philipp Zabel <p.zabel@pengutronix.de> Date: Wed, 26 Jun 2024 16:40:38 +0200 Subject: [PATCH 778/970] =?UTF-8?q?drm/panel:=20ilitek-ili9881c:=20Explici?= =?UTF-8?q?tly=20set=20address=20mode,=20allow=20180=C2=B0=20rotation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can use horizontal and vertical flipping via the MIPI DCS address mode to rotate the display by 180° using the device tree "rotation" property. Since the tl050hdv35 panel has been defined as rotated, we have to invert the bits there. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626-drm-panel-ili9881c-rotation-v1-1-e0ff54173e32@pengutronix.de Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626-drm-panel-ili9881c-rotation-v1-1-e0ff54173e32@pengutronix.de --- drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index 084c37fa7348..b4565ff1a0de 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -42,6 +42,7 @@ struct ili9881c_desc { const size_t init_length; const struct drm_display_mode *mode; const unsigned long mode_flags; + u8 default_address_mode; }; struct ili9881c { @@ -53,6 +54,7 @@ struct ili9881c { struct gpio_desc *reset; enum drm_panel_orientation orientation; + u8 address_mode; }; #define ILI9881C_SWITCH_PAGE_INSTR(_page) \ @@ -815,8 +817,6 @@ static const struct ili9881c_instr tl050hdv35_init[] = { ILI9881C_COMMAND_INSTR(0xd1, 0x4b), ILI9881C_COMMAND_INSTR(0xd2, 0x60), ILI9881C_COMMAND_INSTR(0xd3, 0x39), - ILI9881C_SWITCH_PAGE_INSTR(0), - ILI9881C_COMMAND_INSTR(0x36, 0x03), }; static const struct ili9881c_instr w552946ab_init[] = { @@ -1299,6 +1299,14 @@ static int ili9881c_prepare(struct drm_panel *panel) if (ret) return ret; + if (ctx->address_mode) { + ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_ADDRESS_MODE, + &ctx->address_mode, + sizeof(ctx->address_mode)); + if (ret < 0) + return ret; + } + ret = mipi_dsi_dcs_set_tear_on(ctx->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); if (ret) return ret; @@ -1521,6 +1529,12 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) return ret; } + ctx->address_mode = ctx->desc->default_address_mode; + if (ctx->orientation == DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP) { + ctx->address_mode ^= 0x03; + ctx->orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; + } + ctx->panel.prepare_prev_first = true; ret = drm_panel_of_backlight(&ctx->panel); @@ -1572,6 +1586,7 @@ static const struct ili9881c_desc tl050hdv35_desc = { .mode = &tl050hdv35_default_mode, .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_LPM, + .default_address_mode = 0x03, }; static const struct ili9881c_desc w552946aba_desc = { -- GitLab From 655b92ca60a2d3fac83e8974fd786da6aea7fca2 Mon Sep 17 00:00:00 2001 From: Philipp Zabel <p.zabel@pengutronix.de> Date: Wed, 26 Jun 2024 16:40:39 +0200 Subject: [PATCH 779/970] drm/panel: ilitek-ili9881c: Report subpixel order according to rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assume a default RGB subpixel order and flip it around if 180° rotation is configured via address mode. Report subpixel order to userspace. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240626-drm-panel-ili9881c-rotation-v1-2-e0ff54173e32@pengutronix.de Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240626-drm-panel-ili9881c-rotation-v1-2-e0ff54173e32@pengutronix.de --- drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index b4565ff1a0de..28cd7560e5db 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -1471,6 +1471,10 @@ static int ili9881c_get_modes(struct drm_panel *panel, connector->display_info.width_mm = mode->width_mm; connector->display_info.height_mm = mode->height_mm; + if (ctx->address_mode == 0x3) + connector->display_info.subpixel_order = SubPixelHorizontalBGR; + else + connector->display_info.subpixel_order = SubPixelHorizontalRGB; /* * TODO: Remove once all drm drivers call -- GitLab From 975bdea8c470cf10637c58129edaae731fec9e93 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski <dsankouski@gmail.com> Date: Sun, 6 Oct 2024 21:18:19 +0300 Subject: [PATCH 780/970] drm/mipi-dsi: add mipi_dsi_compression_mode_multi mipi_dsi_compression_mode_multi can help with error handling. Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20241006-starqltechn_integration_upstream-v6-1-8336b9cd6c34@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241006-starqltechn_integration_upstream-v6-1-8336b9cd6c34@gmail.com --- drivers/gpu/drm/drm_mipi_dsi.c | 16 ++++++++++++++++ include/drm/drm_mipi_dsi.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 2bc3973d35a1..d8ee74701f1e 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -1520,6 +1520,22 @@ void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, } EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi); +/** + * mipi_dsi_compression_mode_multi() - enable/disable DSC on the peripheral + * @dsi: DSI peripheral device + * @enable: Whether to enable or disable the DSC + * + * Enable or disable Display Stream Compression on the peripheral using the + * default Picture Parameter Set and VESA DSC 1.1 algorithm. + */ +void mipi_dsi_compression_mode_multi(struct mipi_dsi_multi_context *ctx, + bool enable) +{ + return mipi_dsi_compression_mode_ext_multi(ctx, enable, + MIPI_DSI_COMPRESSION_DSC, 0); +} +EXPORT_SYMBOL(mipi_dsi_compression_mode_multi); + /** * mipi_dsi_dcs_nop_multi() - send DCS NOP packet * @ctx: Context for multiple DSI transactions diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index f725f8654611..94400a78031f 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -280,6 +280,8 @@ void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, bool enable, enum mipi_dsi_compression_algo algo, unsigned int pps_selector); +void mipi_dsi_compression_mode_multi(struct mipi_dsi_multi_context *ctx, + bool enable); void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, const struct drm_dsc_picture_parameter_set *pps); -- GitLab From d891e79861cd2b424e3bd19d3301f35be13bf118 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski <dsankouski@gmail.com> Date: Sun, 6 Oct 2024 21:18:20 +0300 Subject: [PATCH 781/970] dt-bindings: panel: add Samsung s6e3ha8 Add binding for the Samsung s6e3ha8 panel found in the Samsung S9. Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Link: https://lore.kernel.org/r/20241006-starqltechn_integration_upstream-v6-2-8336b9cd6c34@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241006-starqltechn_integration_upstream-v6-2-8336b9cd6c34@gmail.com --- .../display/panel/samsung,s6e3ha8.yaml | 75 +++++++++++++++++++ MAINTAINERS | 5 ++ 2 files changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml new file mode 100644 index 000000000000..05a78429aaea --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml @@ -0,0 +1,75 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,s6e3ha8.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung s6e3ha8 AMOLED DSI panel + +description: The s6e3ha8 is a 1440x2960 DPI display panel from Samsung Mobile + Displays (SMD). + +maintainers: + - Dzmitry Sankouski <dsankouski@gmail.com> + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: samsung,s6e3ha8 + + reg: + maxItems: 1 + + reset-gpios: true + + port: true + + vdd3-supply: + description: VDD regulator + + vci-supply: + description: VCI regulator + + vddr-supply: + description: VDDR regulator + +required: + - compatible + - reset-gpios + - vdd3-supply + - vci-supply + - vddr-supply + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,s6e3ha8"; + reg = <0>; + vci-supply = <&s2dos05_ldo4>; + vddr-supply = <&s2dos05_buck1>; + vdd3-supply = <&s2dos05_ldo1>; + te-gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&sde_dsi_active &sde_te_active_sleep>; + pinctrl-1 = <&sde_dsi_suspend &sde_te_active_sleep>; + pinctrl-names = "default", "sleep"; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 111da576cf16..b86e29f443f2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7383,6 +7383,11 @@ S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6d7aa0.yaml F: drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c +DRM DRIVER FOR SAMSUNG S6E3HA8 PANELS +M: Dzmitry Sankouski <dsankouski@gmail.com> +S: Maintained +F: Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml + DRM DRIVER FOR SITRONIX ST7586 PANELS M: David Lechner <david@lechnology.com> S: Maintained -- GitLab From 779679d3c1640d8f45c75b1e15831180ab2712e2 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski <dsankouski@gmail.com> Date: Sun, 6 Oct 2024 21:18:21 +0300 Subject: [PATCH 782/970] drm/panel: Add support for S6E3HA8 panel driver Add support for MIPI-DSI based S6E3HA8 AMOLED panel driver. This panel has 1440x2960 resolution, 5.8-inch physical size, and can be found in starqltechn device. Brightness regulation is not yet supported. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Link: https://lore.kernel.org/r/20241006-starqltechn_integration_upstream-v6-3-8336b9cd6c34@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241006-starqltechn_integration_upstream-v6-3-8336b9cd6c34@gmail.com --- MAINTAINERS | 1 + drivers/gpu/drm/panel/Kconfig | 7 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c | 342 ++++++++++++++++++ 4 files changed, 351 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c diff --git a/MAINTAINERS b/MAINTAINERS index b86e29f443f2..365fb0ce5117 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7387,6 +7387,7 @@ DRM DRIVER FOR SAMSUNG S6E3HA8 PANELS M: Dzmitry Sankouski <dsankouski@gmail.com> S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml +F: drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c DRM DRIVER FOR SITRONIX ST7586 PANELS M: David Lechner <david@lechnology.com> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 1077fd2307d4..7d3c9cbfe835 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -689,6 +689,13 @@ config DRM_PANEL_SAMSUNG_S6E3HA2 depends on BACKLIGHT_CLASS_DEVICE select VIDEOMODE_HELPERS +config DRM_PANEL_SAMSUNG_S6E3HA8 + tristate "Samsung S6E3HA8 DSI video mode panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + config DRM_PANEL_SAMSUNG_S6E63J0X03 tristate "Samsung S6E63J0X03 DSI command mode panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 987a08702410..8ee28f5a2213 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0) += panel-samsung-s6d7aa0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3FA7) += panel-samsung-s6e3fa7.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA8) += panel-samsung-s6e3ha8.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI) += panel-samsung-s6e63m0-spi.o diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c new file mode 100644 index 000000000000..76b5a6ea610d --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: +// Copyright (c) 2013, The Linux Foundation. All rights reserved. +// Copyright (c) 2024 Dzmitry Sankouski <dsankouski@gmail.com> + +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/display/drm_dsc.h> +#include <drm/display/drm_dsc_helper.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_panel.h> + +struct s6e3ha8 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct drm_dsc_config dsc; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; +}; + +const struct regulator_bulk_data s6e3ha8_supplies[] = { + { .supply = "vdd3" }, + { .supply = "vci" }, + { .supply = "vddr" }, +}; + +static inline +struct s6e3ha8 *to_s6e3ha8_amb577px01_wqhd(struct drm_panel *panel) +{ + return container_of(panel, struct s6e3ha8, panel); +} + +#define s6e3ha8_test_key_on_lvl2(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a) +#define s6e3ha8_test_key_off_lvl2(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5) +#define s6e3ha8_test_key_on_lvl3(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xfc, 0x5a, 0x5a) +#define s6e3ha8_test_key_off_lvl3(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xfc, 0xa5, 0xa5) +#define s6e3ha8_test_key_on_lvl1(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0x9f, 0xa5, 0xa5) +#define s6e3ha8_test_key_off_lvl1(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0x9f, 0x5a, 0x5a) +#define s6e3ha8_afc_off(ctx) \ + mipi_dsi_dcs_write_seq_multi(ctx, 0xe2, 0x00, 0x00) + +static void s6e3ha8_amb577px01_wqhd_reset(struct s6e3ha8 *priv) +{ + gpiod_set_value_cansleep(priv->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(priv->reset_gpio, 0); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(priv->reset_gpio, 1); + usleep_range(5000, 6000); +} + +static int s6e3ha8_amb577px01_wqhd_on(struct s6e3ha8 *priv) +{ + struct mipi_dsi_device *dsi = priv->dsi; + struct mipi_dsi_multi_context ctx = { .dsi = dsi }; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + s6e3ha8_test_key_on_lvl1(&ctx); + + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_compression_mode_multi(&ctx, true); + s6e3ha8_test_key_off_lvl2(&ctx); + + mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); + usleep_range(5000, 6000); + + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x13); + s6e3ha8_test_key_off_lvl2(&ctx); + usleep_range(10000, 11000); + + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x13); + s6e3ha8_test_key_off_lvl2(&ctx); + + /* OMOK setting 1 (Initial setting) - Scaler Latch Setting Guide */ + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x07); + /* latch setting 1 : Scaler on/off & address setting & PPS setting -> Image update latch */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x3c, 0x10); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0b); + /* latch setting 2 : Ratio change mode -> Image update latch */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x30); + /* OMOK setting 2 - Seamless setting guide : WQHD */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x00, 0x00, 0x05, 0x9f); /* CASET */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00, 0x00, 0x0b, 0x8f); /* PASET */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x01); /* scaler setup : scaler off */ + s6e3ha8_test_key_off_lvl2(&ctx); + + mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x00); /* TE Vsync ON */ + + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xed, 0x4c); /* ERR_FG */ + s6e3ha8_test_key_off_lvl2(&ctx); + + s6e3ha8_test_key_on_lvl3(&ctx); + /* FFC Setting 897.6Mbps */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x0d, 0x10, 0xb4, 0x3e, 0x01); + s6e3ha8_test_key_off_lvl3(&ctx); + + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, + 0x00, 0xb0, 0x81, 0x09, 0x00, 0x00, 0x00, + 0x11, 0x03); /* TSP HSYNC Setting */ + s6e3ha8_test_key_off_lvl2(&ctx); + + s6e3ha8_test_key_on_lvl2(&ctx); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x03); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf6, 0x43); + s6e3ha8_test_key_off_lvl2(&ctx); + + s6e3ha8_test_key_on_lvl2(&ctx); + /* Brightness condition set */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, + 0x07, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0x0c); /* AID Set : 0% */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, + 0x19, 0xdc, 0x16, 0x01, 0x34, 0x67, 0x9a, + 0xcd, 0x01, 0x22, 0x33, 0x44, 0x00, 0x00, + 0x05, 0x55, 0xcc, 0x0c, 0x01, 0x11, 0x11, + 0x10); /* MPS/ELVSS Setting */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf4, 0xeb, 0x28); /* VINT */ + mipi_dsi_dcs_write_seq_multi(&ctx, 0xf7, 0x03); /* Gamma, LTPS(AID) update */ + s6e3ha8_test_key_off_lvl2(&ctx); + + s6e3ha8_test_key_off_lvl1(&ctx); + + return ctx.accum_err; +} + +static int s6e3ha8_enable(struct drm_panel *panel) +{ + struct s6e3ha8 *priv = to_s6e3ha8_amb577px01_wqhd(panel); + struct mipi_dsi_device *dsi = priv->dsi; + struct mipi_dsi_multi_context ctx = { .dsi = dsi }; + + s6e3ha8_test_key_on_lvl1(&ctx); + mipi_dsi_dcs_set_display_on_multi(&ctx); + s6e3ha8_test_key_off_lvl1(&ctx); + + return ctx.accum_err; +} + +static int s6e3ha8_disable(struct drm_panel *panel) +{ + struct s6e3ha8 *priv = to_s6e3ha8_amb577px01_wqhd(panel); + struct mipi_dsi_device *dsi = priv->dsi; + struct mipi_dsi_multi_context ctx = { .dsi = dsi }; + + s6e3ha8_test_key_on_lvl1(&ctx); + mipi_dsi_dcs_set_display_off_multi(&ctx); + s6e3ha8_test_key_off_lvl1(&ctx); + mipi_dsi_msleep(&ctx, 20); + + s6e3ha8_test_key_on_lvl2(&ctx); + s6e3ha8_afc_off(&ctx); + s6e3ha8_test_key_off_lvl2(&ctx); + + mipi_dsi_msleep(&ctx, 160); + + return ctx.accum_err; +} + +static int s6e3ha8_amb577px01_wqhd_prepare(struct drm_panel *panel) +{ + struct s6e3ha8 *priv = to_s6e3ha8_amb577px01_wqhd(panel); + struct mipi_dsi_device *dsi = priv->dsi; + struct mipi_dsi_multi_context ctx = { .dsi = dsi }; + struct drm_dsc_picture_parameter_set pps; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(s6e3ha8_supplies), priv->supplies); + if (ret < 0) + return ret; + mipi_dsi_msleep(&ctx, 120); + s6e3ha8_amb577px01_wqhd_reset(priv); + + ret = s6e3ha8_amb577px01_wqhd_on(priv); + if (ret < 0) { + gpiod_set_value_cansleep(priv->reset_gpio, 1); + goto err; + } + + drm_dsc_pps_payload_pack(&pps, &priv->dsc); + + s6e3ha8_test_key_on_lvl1(&ctx); + mipi_dsi_picture_parameter_set_multi(&ctx, &pps); + s6e3ha8_test_key_off_lvl1(&ctx); + + mipi_dsi_msleep(&ctx, 28); + + return ctx.accum_err; +err: + regulator_bulk_disable(ARRAY_SIZE(s6e3ha8_supplies), priv->supplies); + return ret; +} + +static int s6e3ha8_amb577px01_wqhd_unprepare(struct drm_panel *panel) +{ + struct s6e3ha8 *priv = to_s6e3ha8_amb577px01_wqhd(panel); + + return regulator_bulk_disable(ARRAY_SIZE(s6e3ha8_supplies), priv->supplies); +} + +static const struct drm_display_mode s6e3ha8_amb577px01_wqhd_mode = { + .clock = (1440 + 116 + 44 + 120) * (2960 + 120 + 80 + 124) * 60 / 1000, + .hdisplay = 1440, + .hsync_start = 1440 + 116, + .hsync_end = 1440 + 116 + 44, + .htotal = 1440 + 116 + 44 + 120, + .vdisplay = 2960, + .vsync_start = 2960 + 120, + .vsync_end = 2960 + 120 + 80, + .vtotal = 2960 + 120 + 80 + 124, + .width_mm = 64, + .height_mm = 132, +}; + +static int s6e3ha8_amb577px01_wqhd_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &s6e3ha8_amb577px01_wqhd_mode); +} + +static const struct drm_panel_funcs s6e3ha8_amb577px01_wqhd_panel_funcs = { + .prepare = s6e3ha8_amb577px01_wqhd_prepare, + .unprepare = s6e3ha8_amb577px01_wqhd_unprepare, + .get_modes = s6e3ha8_amb577px01_wqhd_get_modes, + .enable = s6e3ha8_enable, + .disable = s6e3ha8_disable, +}; + +static int s6e3ha8_amb577px01_wqhd_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct s6e3ha8 *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(s6e3ha8_supplies), + s6e3ha8_supplies, + &priv->supplies); + if (ret < 0) { + dev_err(dev, "failed to get regulators: %d\n", ret); + return ret; + } + + priv->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(priv->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), + "Failed to get reset-gpios\n"); + + priv->dsi = dsi; + mipi_dsi_set_drvdata(dsi, priv); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS | + MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | + MIPI_DSI_MODE_VIDEO_NO_HSA | MIPI_DSI_MODE_NO_EOT_PACKET; + + drm_panel_init(&priv->panel, dev, &s6e3ha8_amb577px01_wqhd_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + priv->panel.prepare_prev_first = true; + + drm_panel_add(&priv->panel); + + /* This panel only supports DSC; unconditionally enable it */ + dsi->dsc = &priv->dsc; + + priv->dsc.dsc_version_major = 1; + priv->dsc.dsc_version_minor = 1; + + priv->dsc.slice_height = 40; + priv->dsc.slice_width = 720; + WARN_ON(1440 % priv->dsc.slice_width); + priv->dsc.slice_count = 1440 / priv->dsc.slice_width; + priv->dsc.bits_per_component = 8; + priv->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */ + priv->dsc.block_pred_enable = true; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&priv->panel); + return ret; + } + + return 0; +} + +static void s6e3ha8_amb577px01_wqhd_remove(struct mipi_dsi_device *dsi) +{ + struct s6e3ha8 *priv = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&priv->panel); +} + +static const struct of_device_id s6e3ha8_amb577px01_wqhd_of_match[] = { + { .compatible = "samsung,s6e3ha8" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, s6e3ha8_amb577px01_wqhd_of_match); + +static struct mipi_dsi_driver s6e3ha8_amb577px01_wqhd_driver = { + .probe = s6e3ha8_amb577px01_wqhd_probe, + .remove = s6e3ha8_amb577px01_wqhd_remove, + .driver = { + .name = "panel-s6e3ha8", + .of_match_table = s6e3ha8_amb577px01_wqhd_of_match, + }, +}; +module_mipi_dsi_driver(s6e3ha8_amb577px01_wqhd_driver); + +MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>"); +MODULE_DESCRIPTION("DRM driver for S6E3HA8 panel"); +MODULE_LICENSE("GPL"); -- GitLab From 66ae275365be4f118abe2254a0ced1d913af93f2 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve <hvilleneuve@dimonoff.com> Date: Mon, 30 Sep 2024 13:05:03 -0400 Subject: [PATCH 783/970] drm: panel: jd9365da-h3: Remove unused num_init_cmds structure member Now that the driver has been converted to use wrapped MIPI DCS functions, the num_init_cmds structure member is no longer needed, so remove it. Fixes: 35583e129995 ("drm/panel: panel-jadard-jd9365da-h3: use wrapped MIPI DCS functions") Cc: stable@vger.kernel.org Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com> Link: https://lore.kernel.org/r/20240930170503.1324560-1-hugo@hugovil.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240930170503.1324560-1-hugo@hugovil.com --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 44897e5218a6..45d09e6fa667 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -26,7 +26,6 @@ struct jadard_panel_desc { unsigned int lanes; enum mipi_dsi_pixel_format format; int (*init)(struct jadard *jadard); - u32 num_init_cmds; bool lp11_before_reset; bool reset_before_power_off_vcioo; unsigned int vcioo_to_lp11_delay_ms; -- GitLab From a62528aa539a405f76cc3478f6fd3f842e7c6a4e Mon Sep 17 00:00:00 2001 From: Danila Tikhonov <danila@jiaxyga.com> Date: Mon, 30 Sep 2024 23:24:47 +0300 Subject: [PATCH 784/970] dt-bindings: display: panel: Add Samsung AMS639RQ08 The Samsung AMS639RQ08 is a 6.39 inch 1080x2340 MIPI-DSI CMD mode AMOLED panel used in: - Xiaomi Mi 9 Lite / CC9 (sdm710-xiaomi-pyxis) - Xiaomi Mi 9T / Redmi K20 (sm7150-xiaomi-davinci) - Xiaomi Mi 9T Pro / Redmi K20 Pro (sm8150-xiaomi-raphael) Add a dt-binding for it. Signed-off-by: Danila Tikhonov <danila@jiaxyga.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20240930202448.188051-2-danila@jiaxyga.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240930202448.188051-2-danila@jiaxyga.com --- .../display/panel/samsung,ams639rq08.yaml | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ams639rq08.yaml diff --git a/Documentation/devicetree/bindings/display/panel/samsung,ams639rq08.yaml b/Documentation/devicetree/bindings/display/panel/samsung,ams639rq08.yaml new file mode 100644 index 000000000000..f5b6ecb96f99 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,ams639rq08.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,ams639rq08.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung AMS639RQ08 EA8076-based 6.39" 1080x2340 MIPI-DSI Panel + +maintainers: + - Danila Tikhonov <danila@jiaxyga.com> + - Jens Reidel <adrian@travitia.xyz> + +description: + The Samsung AMS639RQ08 is a 6.39 inch 1080x2340 MIPI-DSI CMD mode AMOLED panel. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: samsung,ams639rq08 + + reg: + maxItems: 1 + + vdd3p3-supply: + description: 3.3V source voltage rail + + vddio-supply: + description: I/O source voltage rail + + vsn-supply: + description: Negative source voltage rail + + vsp-supply: + description: Positive source voltage rail + + reset-gpios: true + port: true + +required: + - compatible + - reg + - vdd3p3-supply + - vddio-supply + - vsn-supply + - vsp-supply + - reset-gpios + - port + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,ams639rq08"; + reg = <0>; + + vdd3p3-supply = <&vreg_l18a_2p8>; + vddio-supply = <&vreg_l13a_1p8>; + vsn-supply = <&vreg_ibb>; + vsp-supply = <&vreg_lab>; + + reset-gpios = <&pm6150l_gpios 9 GPIO_ACTIVE_LOW>; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; + }; + +... -- GitLab From bd07dbb929f6c5bbda60d52a0003246e53f48c29 Mon Sep 17 00:00:00 2001 From: Danila Tikhonov <danila@jiaxyga.com> Date: Mon, 30 Sep 2024 23:24:48 +0300 Subject: [PATCH 785/970] drm/panel: Add Samsung AMS639RQ08 panel driver Add the driver for Samsung AMS639RQ08 FHD Plus CMD mode panel support found in: - Xiaomi Mi 9 Lite / CC9 (sdm710-xiaomi-pyxis) - Xiaomi Mi 9T / Redmi K20 (sm7150-xiaomi-davinci) - Xiaomi Mi 9T Pro / Redmi K20 Pro (sm8150-xiaomi-raphael) Tested-by: Degdag Mohamed <degdagmohamed@gmail.com> # xiaomi-raphael Tested-by: Jens Reidel <adrian@travitia.xyz> # xiaomi-davinci Signed-off-by: Danila Tikhonov <danila@jiaxyga.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240930202448.188051-3-danila@jiaxyga.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240930202448.188051-3-danila@jiaxyga.com --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-samsung-ams639rq08.c | 329 ++++++++++++++++++ 3 files changed, 339 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams639rq08.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 7d3c9cbfe835..ddfaa99ea9dd 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -614,6 +614,15 @@ config DRM_PANEL_RONBO_RB070D30 Say Y here if you want to enable support for Ronbo Electronics RB070D30 1024x600 DSI panel. +config DRM_PANEL_SAMSUNG_AMS639RQ08 + tristate "Samsung AMS639RQ08 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y or M here if you want to enable support for the + Samsung AMS639RQ08 FHD Plus (2340x1080@60Hz) CMD mode panel. + config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 tristate "Samsung AMS452EF01 panel with S6E88A0 DSI video mode controller" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 8ee28f5a2213..4b5eaf111676 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08) += panel-samsung-ams639rq08.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o diff --git a/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c b/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c new file mode 100644 index 000000000000..817365cb5e46 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-ams639rq08.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com> + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +/* Manufacturer Command Set */ +#define MCS_ACCESS_PROT_OFF 0xb0 +#define MCS_UNKNOWN_B7 0xb7 +#define MCS_BIAS_CURRENT_CTRL 0xd1 +#define MCS_PASSWD1 0xf0 +#define MCS_PASSWD2 0xfc +#define MCS_UNKNOWN_FF 0xff + +struct ams639rq08 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; +}; + +static const struct regulator_bulk_data ams639rq08_supplies[] = { + { .supply = "vdd3p3" }, + { .supply = "vddio" }, + { .supply = "vsn" }, + { .supply = "vsp" }, +}; + +static inline struct ams639rq08 *to_ams639rq08(struct drm_panel *panel) +{ + return container_of(panel, struct ams639rq08, panel); +} + +static void ams639rq08_reset(struct ams639rq08 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); +} + +static int ams639rq08_on(struct ams639rq08 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + /* Delay 2ms for VCI1 power */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD1, 0x5a, 0x5a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD2, 0x5a, 0x5a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x0c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_UNKNOWN_FF, 0x10); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x2f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_BIAS_CURRENT_CTRL, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD1, 0xa5, 0xa5); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD2, 0xa5, 0xa5); + + /* Sleep Out */ + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + usleep_range(10000, 11000); + + /* TE OUT (Vsync On) */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD1, 0x5a, 0x5a); + + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + + /* DBV Smooth Transition */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_UNKNOWN_B7, 0x01, 0x4b); + + /* Edge Dimming Speed Setting */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x06); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_UNKNOWN_B7, 0x10); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD1, 0xa5, 0xa5); + + /* Page Address Set */ + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x0923); + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD1, 0x5a, 0x5a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD2, 0x5a, 0x5a); + + /* Set DDIC internal HFP */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x23); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_BIAS_CURRENT_CTRL, 0x11); + + /* OFC Setting 84.1 Mhz */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe9, 0x11, 0x55, + 0xa6, 0x75, 0xa3, + 0xb9, 0xa1, 0x4a, + 0x00, 0x1a, 0xb8); + + /* Err_FG Setting */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe1, + 0x00, 0x00, 0x02, + 0x02, 0x42, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe2, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x0c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe1, 0x19); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD1, 0xa5, 0xa5); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD2, 0xa5, 0xa5); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); + + /* Brightness Control */ + mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0x0000); + + /* Display On */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + mipi_dsi_msleep(&dsi_ctx, 67); + + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + + return dsi_ctx.accum_err; +} + +static void ams639rq08_off(struct ams639rq08 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); +} + +static int ams639rq08_prepare(struct drm_panel *panel) +{ + struct ams639rq08 *ctx = to_ams639rq08(panel); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(ams639rq08_supplies), + ctx->supplies); + if (ret < 0) + return ret; + + ams639rq08_reset(ctx); + + ret = ams639rq08_on(ctx); + if (ret < 0) { + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ams639rq08_supplies), + ctx->supplies); + return ret; + } + + return 0; +} + +static int ams639rq08_unprepare(struct drm_panel *panel) +{ + struct ams639rq08 *ctx = to_ams639rq08(panel); + + ams639rq08_off(ctx); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ams639rq08_supplies), + ctx->supplies); + + return 0; +} + +static const struct drm_display_mode ams639rq08_mode = { + .clock = (1080 + 64 + 20 + 64) * (2340 + 64 + 20 + 64) * 60 / 1000, + .hdisplay = 1080, + .hsync_start = 1080 + 64, + .hsync_end = 1080 + 64 + 20, + .htotal = 1080 + 64 + 20 + 64, + .vdisplay = 2340, + .vsync_start = 2340 + 64, + .vsync_end = 2340 + 64 + 20, + .vtotal = 2340 + 64 + 20 + 64, + .width_mm = 68, + .height_mm = 147, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int ams639rq08_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &ams639rq08_mode); +} + +static const struct drm_panel_funcs ams639rq08_panel_funcs = { + .prepare = ams639rq08_prepare, + .unprepare = ams639rq08_unprepare, + .get_modes = ams639rq08_get_modes, +}; + +static int ams639rq08_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static int ams639rq08_bl_get_brightness(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return brightness; +} + +static const struct backlight_ops ams639rq08_bl_ops = { + .update_status = ams639rq08_bl_update_status, + .get_brightness = ams639rq08_bl_get_brightness, +}; + +static struct backlight_device * +ams639rq08_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 1023, + .max_brightness = 2047, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &ams639rq08_bl_ops, &props); +} + +static int ams639rq08_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct ams639rq08 *ctx; + int ret; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ret = devm_regulator_bulk_get_const(&dsi->dev, + ARRAY_SIZE(ams639rq08_supplies), + ams639rq08_supplies, + &ctx->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; + + drm_panel_init(&ctx->panel, dev, &ams639rq08_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + ctx->panel.prepare_prev_first = true; + + ctx->panel.backlight = ams639rq08_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void ams639rq08_remove(struct mipi_dsi_device *dsi) +{ + struct ams639rq08 *ctx = mipi_dsi_get_drvdata(dsi); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id ams639rq08_of_match[] = { + { .compatible = "samsung,ams639rq08" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ams639rq08_of_match); + +static struct mipi_dsi_driver ams639rq08_driver = { + .probe = ams639rq08_probe, + .remove = ams639rq08_remove, + .driver = { + .name = "panel-samsung-ams639rq08", + .of_match_table = ams639rq08_of_match, + }, +}; +module_mipi_dsi_driver(ams639rq08_driver); + +MODULE_AUTHOR("Danila Tikhonov <danila@jiaxyga.com>"); +MODULE_DESCRIPTION("DRM driver for SAMSUNG AMS639RQ08 cmd mode dsi panel"); +MODULE_LICENSE("GPL"); -- GitLab From 67ec9f87bd6c57db1251bb2244d242f7ca5a0b6a Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Mon, 7 Oct 2024 08:45:42 +0100 Subject: [PATCH 786/970] drm/xe/bmg: improve cache flushing behaviour The BSpec says that EN_L3_RW_CCS_CACHE_FLUSH must be toggled on for manual global invalidation to take effect and actually flush device cache, however this also turns on flushing for things like pipecontrol, which occurs between submissions for compute/render. This sounds like massive overkill for our needs, where we already have the manual flushing on the display side with the global invalidation. Some observations on BMG: 1. Disabling l2 caching for host writes and stubbing out the driver global invalidation but keeping EN_L3_RW_CCS_CACHE_FLUSH enabled, has no impact on wb-transient-vs-display IGT, which makes sense since the pipecontrol is now flushing the device cache after the render copy. Without EN_L3_RW_CCS_CACHE_FLUSH the test then fails, which is also expected since device cache is now dirty and display engine can't see the writes. 2. Disabling EN_L3_RW_CCS_CACHE_FLUSH, but keeping the driver global invalidation also has no impact on wb-transient-vs-display. This suggests that the global invalidation still works as expected and is flushing the device cache without EN_L3_RW_CCS_CACHE_FLUSH turned on. With that drop EN_L3_RW_CCS_CACHE_FLUSH. This helps some workloads since we no longer flush the device cache between submissions as part of pipecontrol. Edit: We now also have clarification from HW side that BSpec was indeed wrong here. v2: - Rebase and update commit message. BSpec: 71718 Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Vitasta Wattal <vitasta.wattal@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Cc: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241007074541.33937-2-matthew.auld@intel.com --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 --- drivers/gpu/drm/xe/xe_gt.c | 1 - 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 55092089bff6..f531eeeb8957 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -401,9 +401,6 @@ #define XE2_GLOBAL_INVAL XE_REG(0xb404) -#define SCRATCH1LPFC XE_REG(0xb474) -#define EN_L3_RW_CCS_CACHE_FLUSH REG_BIT(0) - #define XE2LPM_L3SQCREG2 XE_REG_MCR(0xb604) #define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 2d5e78311b76..1c79660fb086 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -108,7 +108,6 @@ static void xe_gt_enable_host_l2_vram(struct xe_gt *gt) return; if (!xe_gt_is_media_type(gt)) { - xe_mmio_write32(>->mmio, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH); reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL); reg |= CG_DIS_CNTLBUS; xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg); -- GitLab From 7a7593e5885bc172050a75ddf2bb6aeb96c8a8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom@linux.intel.com> Date: Fri, 4 Oct 2024 16:11:20 +0200 Subject: [PATCH 787/970] drm/xe/tests: Fix the shrinker test compiler warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xe_bo_shrink_kunit test has an uninitialized value and illegal integer size conversions on 32-bit. Fix. v2: - Use div64_u64 to ensure the u64 division compiles everywhere. (Matt Auld) Reported-by: Nathan Chancellor <nathan@kernel.org> Closes: https://lore.kernel.org/20240913195649.GA61514@thelio-3990X/ Fixes: 5a90b60db5e6 ("drm/xe: Add a xe_bo subtest for shrinking / swapping") Cc: dri-devel@lists.freedesktop.org Cc: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> #v1 Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004141121.186177-1-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/xe/tests/xe_bo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c index 7d3fd720478b..cd811aa2b227 100644 --- a/drivers/gpu/drm/xe/tests/xe_bo.c +++ b/drivers/gpu/drm/xe/tests/xe_bo.c @@ -7,6 +7,7 @@ #include <kunit/visibility.h> #include <linux/iosys-map.h> +#include <linux/math64.h> #include <linux/random.h> #include <linux/swap.h> @@ -440,7 +441,7 @@ static int shrink_test_run_device(struct xe_device *xe) LIST_HEAD(bos); struct xe_bo_link *link, *next; struct sysinfo si; - size_t ram, ram_and_swap, purgeable, alloced, to_alloc, limit; + u64 ram, ram_and_swap, purgeable = 0, alloced, to_alloc, limit; unsigned int interrupted = 0, successful = 0, count = 0; struct rnd_state prng; u64 rand_seed; @@ -469,7 +470,7 @@ static int shrink_test_run_device(struct xe_device *xe) ram_and_swap = ram + get_nr_swap_pages() * PAGE_SIZE; if (to_alloc > ram_and_swap) purgeable = to_alloc - ram_and_swap; - purgeable += purgeable / 5; + purgeable += div64_u64(purgeable, 5); kunit_info(test, "Free ram is %lu bytes. Will allocate twice of that.\n", (unsigned long)ram); -- GitLab From 01c29dbf9dfdf0ba8527e559bc78804a3ce4075d Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Wed, 2 Oct 2024 16:06:19 +0100 Subject: [PATCH 788/970] drm/vc4: Run default client setup for all variants. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 45903624e9fc ("drm/vc4: Run DRM default client setup") only added DRM_FBDEV_DMA_DRIVER_OPS for the vc4 (Pi0-3) driver definition, which caused an issue on vc5 (Pi4) as there was no fbdev_probe function defined. Fixes: 45903624e9fc ("drm/vc4: Run DRM default client setup") Reviewed-by: MaÃra Canal <mcanal@igalia.com> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20241002-vc4_fbdev_fix-v1-1-8737bd11b147@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 13a1ecddbca3..a238f76a6073 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -238,6 +238,7 @@ const struct drm_driver vc5_drm_driver = { #endif DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create), + DRM_FBDEV_DMA_DRIVER_OPS, .fops = &vc4_drm_fops, -- GitLab From cf1c87d978d47339a39bfa7a6133ecd3f8f87525 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Tue, 8 Oct 2024 17:44:34 +0100 Subject: [PATCH 789/970] drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_lut_load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 52efe364d196 ("drm/vc4: hvs: Don't write gamma luts on 2711") added a return path to vc4_hvs_lut_load that had called drm_dev_enter, but not drm_dev_exit. Ensure we call drm_dev_exit. Fixes: 52efe364d196 ("drm/vc4: hvs: Don't write gamma luts on 2711") Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Closes: https://lore.kernel.org/dri-devel/37051126-3921-4afe-a936-5f828bff5752@samsung.com/ Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008-drm-vc4-fixes-v1-1-9d0396ca9f42@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 2a366a607fcc..546ee11016b2 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -225,7 +225,7 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs, return; if (hvs->vc4->gen == VC4_GEN_4) - return; + goto exit; /* The LUT memory is laid out with each HVS channel in order, * each of which takes 256 writes for R, 256 for G, then 256 @@ -242,6 +242,7 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs, for (i = 0; i < crtc->gamma_size; i++) HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]); +exit: drm_dev_exit(idx); } -- GitLab From 6b0bd1b02ea24b10522c92b2503981970b26d1a2 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Tue, 8 Oct 2024 17:44:35 +0100 Subject: [PATCH 790/970] drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_atomic_flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 92c17d16476c ("drm/vc4: hvs: Ignore atomic_flush if we're disabled") added a path which returned early without having called drm_dev_exit. Ensure all paths call drm_dev_exit. Fixes: 92c17d16476c ("drm/vc4: hvs: Ignore atomic_flush if we're disabled") Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008-drm-vc4-fixes-v1-2-9d0396ca9f42@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 546ee11016b2..c5ebc317188a 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -603,7 +603,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, } if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) - return; + goto exit; if (debug_dump_regs) { DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc)); @@ -686,6 +686,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, vc4_hvs_dump_state(hvs); } +exit: drm_dev_exit(idx); } -- GitLab From 42aa18d1c3e7762bcebd89a5857ed7774e669d92 Mon Sep 17 00:00:00 2001 From: Dave Stevenson <dave.stevenson@raspberrypi.com> Date: Tue, 8 Oct 2024 17:44:36 +0100 Subject: [PATCH 791/970] drm/vc4: Correct generation check in vc4_hvs_lut_load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 24c5ed3ddf27 ("drm/vc4: Introduce generation number enum") incorrectly swapped a check of hvs->vc4->is_vc5 to hvs->vc4->gen == VC4_GEN_4 in vc4_hvs_lut_load, hence breaking loading the gamma look up table on Pi0-3. Correct that conditional. Fixes: 24c5ed3ddf27 ("drm/vc4: Introduce generation number enum") Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Closes: https://lore.kernel.org/dri-devel/37051126-3921-4afe-a936-5f828bff5752@samsung.com/ Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008-drm-vc4-fixes-v1-3-9d0396ca9f42@raspberrypi.com Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> --- drivers/gpu/drm/vc4/vc4_hvs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index c5ebc317188a..1edf6e3fa7e6 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -224,7 +224,7 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs, if (!drm_dev_enter(drm, &idx)) return; - if (hvs->vc4->gen == VC4_GEN_4) + if (hvs->vc4->gen != VC4_GEN_4) goto exit; /* The LUT memory is laid out with each HVS channel in order, -- GitLab From fc5d96670eb2540d2572a14351e82ffe45d5ac11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom@linux.intel.com> Date: Wed, 11 Sep 2024 14:18:58 +0200 Subject: [PATCH 792/970] drm/ttm: Move swapped objects off the manager's LRU list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resources of swapped objects remains on the TTM_PL_SYSTEM manager's LRU list, which is bad for the LRU walk efficiency. Rename the device-wide "pinned" list to "unevictable" and move also resources of swapped-out objects to that list. An alternative would be to create an "UNEVICTABLE" priority to be able to keep the pinned- and swapped objects on their respective manager's LRU without affecting the LRU walk efficiency. v2: - Remove a bogus WARN_ON (Christian König) - Update ttm_resource_[add|del] bulk move (Christian König) - Fix TTM KUNIT tests (Intel CI) v3: - Check for non-NULL bo->resource in ttm_bo_populate(). v4: - Don't move to LRU tail during swapout until the resource is properly swapped or there was a swapout failure. (Intel Ci) - Add a newline after checkpatch check. v5: - Introduce ttm_resource_is_swapped() to avoid a corner-case where a newly created resource was considered swapped. (Intel CI) v6: - Move an assert. Cc: Christian König <christian.koenig@amd.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <dri-devel@lists.freedesktop.org> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911121859.85387-2-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c | 4 +- drivers/gpu/drm/ttm/tests/ttm_bo_test.c | 4 +- drivers/gpu/drm/ttm/tests/ttm_resource_test.c | 6 +- drivers/gpu/drm/ttm/ttm_bo.c | 59 ++++++++++++++++++- drivers/gpu/drm/ttm/ttm_bo_util.c | 6 +- drivers/gpu/drm/ttm/ttm_bo_vm.c | 2 +- drivers/gpu/drm/ttm/ttm_device.c | 4 +- drivers/gpu/drm/ttm/ttm_resource.c | 28 +++++++-- drivers/gpu/drm/ttm/ttm_tt.c | 3 + drivers/gpu/drm/xe/xe_bo.c | 4 +- include/drm/ttm/ttm_bo.h | 2 + include/drm/ttm/ttm_device.h | 5 +- include/drm/ttm/ttm_tt.h | 5 ++ 15 files changed, 109 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 5c72462d1f57..7de284766f82 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -808,7 +808,7 @@ static int __i915_ttm_get_pages(struct drm_i915_gem_object *obj, } if (bo->ttm && !ttm_tt_is_populated(bo->ttm)) { - ret = ttm_tt_populate(bo->bdev, bo->ttm, &ctx); + ret = ttm_bo_populate(bo, &ctx); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 03b00a03a634..041dab543b78 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -624,7 +624,7 @@ int i915_ttm_move(struct ttm_buffer_object *bo, bool evict, /* Populate ttm with pages if needed. Typically system memory. */ if (ttm && (dst_man->use_tt || (ttm->page_flags & TTM_TT_FLAG_SWAPPED))) { - ret = ttm_tt_populate(bo->bdev, ttm, ctx); + ret = ttm_bo_populate(bo, ctx); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c index ad649523d5e0..61596cecce4d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c @@ -90,7 +90,7 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply, goto out_no_lock; backup_bo = i915_gem_to_ttm(backup); - err = ttm_tt_populate(backup_bo->bdev, backup_bo->ttm, &ctx); + err = ttm_bo_populate(backup_bo, &ctx); if (err) goto out_no_populate; @@ -189,7 +189,7 @@ static int i915_ttm_restore(struct i915_gem_apply_to_region *apply, if (!backup_bo->resource) err = ttm_bo_validate(backup_bo, i915_ttm_sys_placement(), &ctx); if (!err) - err = ttm_tt_populate(backup_bo->bdev, backup_bo->ttm, &ctx); + err = ttm_bo_populate(backup_bo, &ctx); if (!err) { err = i915_gem_obj_copy_ttm(obj, backup, pm_apply->allow_gpu, false); diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c index f0a7eb62116c..3139fd9128d8 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c @@ -308,11 +308,11 @@ static void ttm_bo_unreserve_pinned(struct kunit *test) err = ttm_resource_alloc(bo, place, &res2); KUNIT_ASSERT_EQ(test, err, 0); KUNIT_ASSERT_EQ(test, - list_is_last(&res2->lru.link, &priv->ttm_dev->pinned), 1); + list_is_last(&res2->lru.link, &priv->ttm_dev->unevictable), 1); ttm_bo_unreserve(bo); KUNIT_ASSERT_EQ(test, - list_is_last(&res1->lru.link, &priv->ttm_dev->pinned), 1); + list_is_last(&res1->lru.link, &priv->ttm_dev->unevictable), 1); ttm_resource_free(bo, &res1); ttm_resource_free(bo, &res2); diff --git a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c index 22260e7aea58..a9f4b81921c3 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c @@ -164,18 +164,18 @@ static void ttm_resource_init_pinned(struct kunit *test) res = kunit_kzalloc(test, sizeof(*res), GFP_KERNEL); KUNIT_ASSERT_NOT_NULL(test, res); - KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->pinned)); + KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->unevictable)); dma_resv_lock(bo->base.resv, NULL); ttm_bo_pin(bo); ttm_resource_init(bo, place, res); - KUNIT_ASSERT_TRUE(test, list_is_singular(&bo->bdev->pinned)); + KUNIT_ASSERT_TRUE(test, list_is_singular(&bo->bdev->unevictable)); ttm_bo_unpin(bo); ttm_resource_fini(man, res); dma_resv_unlock(bo->base.resv); - KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->pinned)); + KUNIT_ASSERT_TRUE(test, list_empty(&bo->bdev->unevictable)); } static void ttm_resource_fini_basic(struct kunit *test) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 320592435252..875b024913a0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -139,7 +139,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, goto out_err; if (mem->mem_type != TTM_PL_SYSTEM) { - ret = ttm_tt_populate(bo->bdev, bo->ttm, ctx); + ret = ttm_bo_populate(bo, ctx); if (ret) goto out_err; } @@ -1128,9 +1128,20 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) if (bo->bdev->funcs->swap_notify) bo->bdev->funcs->swap_notify(bo); - if (ttm_tt_is_populated(bo->ttm)) + if (ttm_tt_is_populated(bo->ttm)) { + spin_lock(&bo->bdev->lru_lock); + ttm_resource_del_bulk_move(bo->resource, bo); + spin_unlock(&bo->bdev->lru_lock); + ret = ttm_tt_swapout(bo->bdev, bo->ttm, swapout_walk->gfp_flags); + spin_lock(&bo->bdev->lru_lock); + if (ret) + ttm_resource_add_bulk_move(bo->resource, bo); + ttm_resource_move_to_lru_tail(bo->resource); + spin_unlock(&bo->bdev->lru_lock); + } + out: /* Consider -ENOMEM and -ENOSPC non-fatal. */ if (ret == -ENOMEM || ret == -ENOSPC) @@ -1180,3 +1191,47 @@ void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) ttm_tt_destroy(bo->bdev, bo->ttm); bo->ttm = NULL; } + +/** + * ttm_bo_populate() - Ensure that a buffer object has backing pages + * @bo: The buffer object + * @ctx: The ttm_operation_ctx governing the operation. + * + * For buffer objects in a memory type whose manager uses + * struct ttm_tt for backing pages, ensure those backing pages + * are present and with valid content. The bo's resource is also + * placed on the correct LRU list if it was previously swapped + * out. + * + * Return: 0 if successful, negative error code on failure. + * Note: May return -EINTR or -ERESTARTSYS if @ctx::interruptible + * is set to true. + */ +int ttm_bo_populate(struct ttm_buffer_object *bo, + struct ttm_operation_ctx *ctx) +{ + struct ttm_tt *tt = bo->ttm; + bool swapped; + int ret; + + dma_resv_assert_held(bo->base.resv); + + if (!tt) + return 0; + + swapped = ttm_tt_is_swapped(tt); + ret = ttm_tt_populate(bo->bdev, tt, ctx); + if (ret) + return ret; + + if (swapped && !ttm_tt_is_swapped(tt) && !bo->pin_count && + bo->resource) { + spin_lock(&bo->bdev->lru_lock); + ttm_resource_add_bulk_move(bo->resource, bo); + ttm_resource_move_to_lru_tail(bo->resource); + spin_unlock(&bo->bdev->lru_lock); + } + + return 0; +} +EXPORT_SYMBOL(ttm_bo_populate); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3c07f4712d5c..d939925efa81 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -163,7 +163,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, src_man = ttm_manager_type(bdev, src_mem->mem_type); if (ttm && ((ttm->page_flags & TTM_TT_FLAG_SWAPPED) || dst_man->use_tt)) { - ret = ttm_tt_populate(bdev, ttm, ctx); + ret = ttm_bo_populate(bo, ctx); if (ret) return ret; } @@ -350,7 +350,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, BUG_ON(!ttm); - ret = ttm_tt_populate(bo->bdev, ttm, &ctx); + ret = ttm_bo_populate(bo, &ctx); if (ret) return ret; @@ -507,7 +507,7 @@ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map) pgprot_t prot; void *vaddr; - ret = ttm_tt_populate(bo->bdev, ttm, &ctx); + ret = ttm_bo_populate(bo, &ctx); if (ret) return ret; diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 4212b8c91dd4..2c699ed1963a 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -224,7 +224,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, }; ttm = bo->ttm; - err = ttm_tt_populate(bdev, bo->ttm, &ctx); + err = ttm_bo_populate(bo, &ctx); if (err) { if (err == -EINTR || err == -ERESTARTSYS || err == -EAGAIN) diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c index e7cc4954c1bc..02e797fd1891 100644 --- a/drivers/gpu/drm/ttm/ttm_device.c +++ b/drivers/gpu/drm/ttm/ttm_device.c @@ -216,7 +216,7 @@ int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *func bdev->vma_manager = vma_manager; spin_lock_init(&bdev->lru_lock); - INIT_LIST_HEAD(&bdev->pinned); + INIT_LIST_HEAD(&bdev->unevictable); bdev->dev_mapping = mapping; mutex_lock(&ttm_global_mutex); list_add_tail(&bdev->device_list, &glob->device_list); @@ -283,7 +283,7 @@ void ttm_device_clear_dma_mappings(struct ttm_device *bdev) struct ttm_resource_manager *man; unsigned int i, j; - ttm_device_clear_lru_dma_mappings(bdev, &bdev->pinned); + ttm_device_clear_lru_dma_mappings(bdev, &bdev->unevictable); for (i = TTM_PL_SYSTEM; i < TTM_NUM_MEM_TYPES; ++i) { man = ttm_manager_type(bdev, i); diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 6d764ba88aab..a87665eb28a6 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -30,6 +30,7 @@ #include <drm/ttm/ttm_bo.h> #include <drm/ttm/ttm_placement.h> #include <drm/ttm/ttm_resource.h> +#include <drm/ttm/ttm_tt.h> #include <drm/drm_util.h> @@ -235,11 +236,26 @@ static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, } } +static bool ttm_resource_is_swapped(struct ttm_resource *res, struct ttm_buffer_object *bo) +{ + /* + * Take care when creating a new resource for a bo, that it is not considered + * swapped if it's not the current resource for the bo and is thus logically + * associated with the ttm_tt. Think a VRAM resource created to move a + * swapped-out bo to VRAM. + */ + if (bo->resource != res || !bo->ttm) + return false; + + dma_resv_assert_held(bo->base.resv); + return ttm_tt_is_swapped(bo->ttm); +} + /* Add the resource to a bulk move if the BO is configured for it */ void ttm_resource_add_bulk_move(struct ttm_resource *res, struct ttm_buffer_object *bo) { - if (bo->bulk_move && !bo->pin_count) + if (bo->bulk_move && !bo->pin_count && !ttm_resource_is_swapped(res, bo)) ttm_lru_bulk_move_add(bo->bulk_move, res); } @@ -247,7 +263,7 @@ void ttm_resource_add_bulk_move(struct ttm_resource *res, void ttm_resource_del_bulk_move(struct ttm_resource *res, struct ttm_buffer_object *bo) { - if (bo->bulk_move && !bo->pin_count) + if (bo->bulk_move && !bo->pin_count && !ttm_resource_is_swapped(res, bo)) ttm_lru_bulk_move_del(bo->bulk_move, res); } @@ -259,8 +275,8 @@ void ttm_resource_move_to_lru_tail(struct ttm_resource *res) lockdep_assert_held(&bo->bdev->lru_lock); - if (bo->pin_count) { - list_move_tail(&res->lru.link, &bdev->pinned); + if (bo->pin_count || ttm_resource_is_swapped(res, bo)) { + list_move_tail(&res->lru.link, &bdev->unevictable); } else if (bo->bulk_move) { struct ttm_lru_bulk_move_pos *pos = @@ -301,8 +317,8 @@ void ttm_resource_init(struct ttm_buffer_object *bo, man = ttm_manager_type(bo->bdev, place->mem_type); spin_lock(&bo->bdev->lru_lock); - if (bo->pin_count) - list_add_tail(&res->lru.link, &bo->bdev->pinned); + if (bo->pin_count || ttm_resource_is_swapped(res, bo)) + list_add_tail(&res->lru.link, &bo->bdev->unevictable); else list_add_tail(&res->lru.link, &man->lru[bo->priority]); man->usage += res->size; diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 4b51b9023126..3baf215eca23 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -367,7 +367,10 @@ int ttm_tt_populate(struct ttm_device *bdev, } return ret; } + +#if IS_ENABLED(CONFIG_DRM_TTM_KUNIT_TEST) EXPORT_SYMBOL(ttm_tt_populate); +#endif void ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm) { diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index f379df3a12bf..44ac78e8625b 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -901,7 +901,7 @@ int xe_bo_evict_pinned(struct xe_bo *bo) } } - ret = ttm_tt_populate(bo->ttm.bdev, bo->ttm.ttm, &ctx); + ret = ttm_bo_populate(&bo->ttm, &ctx); if (ret) goto err_res_free; @@ -954,7 +954,7 @@ int xe_bo_restore_pinned(struct xe_bo *bo) if (ret) return ret; - ret = ttm_tt_populate(bo->ttm.bdev, bo->ttm.ttm, &ctx); + ret = ttm_bo_populate(&bo->ttm, &ctx); if (ret) goto err_res_free; diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index 7b56d1ca36d7..5804408815be 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -462,5 +462,7 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo); pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, pgprot_t tmp); void ttm_bo_tt_destroy(struct ttm_buffer_object *bo); +int ttm_bo_populate(struct ttm_buffer_object *bo, + struct ttm_operation_ctx *ctx); #endif diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index c22f30535c84..438358f72716 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -252,9 +252,10 @@ struct ttm_device { spinlock_t lru_lock; /** - * @pinned: Buffer objects which are pinned and so not on any LRU list. + * @unevictable Buffer objects which are pinned or swapped and as such + * not on an LRU list. */ - struct list_head pinned; + struct list_head unevictable; /** * @dev_mapping: A pointer to the struct address_space for invalidating diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index 2b9d856ff388..991edafdb2dd 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -129,6 +129,11 @@ static inline bool ttm_tt_is_populated(struct ttm_tt *tt) return tt->page_flags & TTM_TT_FLAG_PRIV_POPULATED; } +static inline bool ttm_tt_is_swapped(const struct ttm_tt *tt) +{ + return tt->page_flags & TTM_TT_FLAG_SWAPPED; +} + /** * ttm_tt_create * -- GitLab From 4cce1373c17fc527b78ad22ddca3027042aea3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom@linux.intel.com> Date: Wed, 11 Sep 2024 14:18:59 +0200 Subject: [PATCH 793/970] drm/ttm: Move pinned objects off LRU lists when pinning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ttm_bo_pin() and ttm_bo_unpin() functions weren't moving their resources off the LRU list to the unevictable list. Make sure that happens so that pinned objects don't accidently linger on the LRU lists, and also make sure to move them back once they are unpinned. v2: - Removing from a bulk move must be done with the pin-count still zero. v3: - ttm_resource_move_to_lru_tail must be done after pinning with a non- NULL resource (Intel CI). v6: - Use a TAB instead of space (checkpatch.pl error). Cc: Christian König <christian.koenig@amd.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: <dri-devel@lists.freedesktop.org> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240911121859.85387-3-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/ttm/ttm_bo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 875b024913a0..48c5365efca1 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -594,7 +594,8 @@ void ttm_bo_pin(struct ttm_buffer_object *bo) spin_lock(&bo->bdev->lru_lock); if (bo->resource) ttm_resource_del_bulk_move(bo->resource, bo); - ++bo->pin_count; + if (!bo->pin_count++ && bo->resource) + ttm_resource_move_to_lru_tail(bo->resource); spin_unlock(&bo->bdev->lru_lock); } EXPORT_SYMBOL(ttm_bo_pin); @@ -613,9 +614,10 @@ void ttm_bo_unpin(struct ttm_buffer_object *bo) return; spin_lock(&bo->bdev->lru_lock); - --bo->pin_count; - if (bo->resource) + if (!--bo->pin_count && bo->resource) { ttm_resource_add_bulk_move(bo->resource, bo); + ttm_resource_move_to_lru_tail(bo->resource); + } spin_unlock(&bo->bdev->lru_lock); } EXPORT_SYMBOL(ttm_bo_unpin); -- GitLab From 967d226eaae8e40636d257bf8ae55d2c5a912f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> Date: Thu, 5 Sep 2024 15:51:54 +0200 Subject: [PATCH 794/970] dma-buf: add WARN_ON() illegal dma-fence signaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling the signaling a NULL fence is obviously a coding error in a driver. Those functions unfortunately just returned silently without raising a warning. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Simona Vetter <simona.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20240911085903.1496-2-christian.koenig@amd.com --- drivers/dma-buf/dma-fence.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index f8303ae99acf..f0cdd3e99d36 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -412,7 +412,7 @@ int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp) unsigned long flags; int ret; - if (!fence) + if (WARN_ON(!fence)) return -EINVAL; spin_lock_irqsave(fence->lock, flags); @@ -464,7 +464,7 @@ int dma_fence_signal(struct dma_fence *fence) int ret; bool tmp; - if (!fence) + if (WARN_ON(!fence)) return -EINVAL; tmp = dma_fence_begin_signalling(); -- GitLab From 4dc1aacc448bd6b1a33fa64d048c4bd9699b00f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> Date: Mon, 9 Sep 2024 12:12:34 +0200 Subject: [PATCH 795/970] dma-buf/sw_sync: remove pointless enable_signaling implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just returning true here is a no-op, remove the optional callback. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Simona Vetter <simona.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20240911085903.1496-3-christian.koenig@amd.com --- drivers/dma-buf/sw_sync.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index c353029789cf..f5905d67dedb 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -173,11 +173,6 @@ static bool timeline_fence_signaled(struct dma_fence *fence) return !__dma_fence_is_later(fence->seqno, parent->value, fence->ops); } -static bool timeline_fence_enable_signaling(struct dma_fence *fence) -{ - return true; -} - static void timeline_fence_value_str(struct dma_fence *fence, char *str, int size) { @@ -211,7 +206,6 @@ static void timeline_fence_set_deadline(struct dma_fence *fence, ktime_t deadlin static const struct dma_fence_ops timeline_fence_ops = { .get_driver_name = timeline_fence_get_driver_name, .get_timeline_name = timeline_fence_get_timeline_name, - .enable_signaling = timeline_fence_enable_signaling, .signaled = timeline_fence_signaled, .release = timeline_fence_release, .fence_value_str = timeline_fence_value_str, -- GitLab From 02c50fa60ca5991e3e8a688d7da1dbed8e3ba3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> Date: Mon, 9 Sep 2024 12:21:13 +0200 Subject: [PATCH 796/970] drm/writeback: remove pointless enable_signaling implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just returning true here is a no-op, remove the optional callback. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Simona Vetter <simona.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20240911085903.1496-4-christian.koenig@amd.com --- drivers/gpu/drm/drm_writeback.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index a031c335bdb9..33a3c98a962d 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -100,15 +100,9 @@ drm_writeback_fence_get_timeline_name(struct dma_fence *fence) return wb_connector->timeline_name; } -static bool drm_writeback_fence_enable_signaling(struct dma_fence *fence) -{ - return true; -} - static const struct dma_fence_ops drm_writeback_fence_ops = { .get_driver_name = drm_writeback_fence_get_driver_name, .get_timeline_name = drm_writeback_fence_get_timeline_name, - .enable_signaling = drm_writeback_fence_enable_signaling, }; static int create_writeback_properties(struct drm_device *dev) -- GitLab From 081cb8948cfe322076cd23f22f85ba68f73e2c4b Mon Sep 17 00:00:00 2001 From: Gustavo Sousa <gustavo.sousa@intel.com> Date: Tue, 8 Oct 2024 13:46:26 -0700 Subject: [PATCH 797/970] drm/xe/xe3: Add initial set of workarounds Implement the initial set of workarounds for Xe3 IPs. Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241008204626.55802-2-matthew.s.atwood@intel.com --- drivers/gpu/drm/xe/regs/xe_engine_regs.h | 1 + drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 ++ drivers/gpu/drm/xe/xe_wa.c | 47 ++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_wa_oob.rules | 1 + 4 files changed, 52 insertions(+) diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h b/drivers/gpu/drm/xe/regs/xe_engine_regs.h index 81b71903675e..7c78496e6213 100644 --- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h @@ -186,6 +186,7 @@ #define VDBOX_CGCTL3F10(base) XE_REG((base) + 0x3f10) #define IECPUNIT_CLKGATE_DIS REG_BIT(22) +#define RAMDFTUNIT_CLKGATE_DIS REG_BIT(9) #define VDBOX_CGCTL3F18(base) XE_REG((base) + 0x3f18) #define ALNUNIT_CLKGATE_DIS REG_BIT(13) diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index f531eeeb8957..42dc55cb23f4 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -286,6 +286,9 @@ #define GAMTLBVEBOX0_CLKGATE_DIS REG_BIT(16) #define LTCDD_CLKGATE_DIS REG_BIT(10) +#define UNSLCGCTL9454 XE_REG(0x9454) +#define LSCFE_CLKGATE_DIS REG_BIT(4) + #define XEHP_SLICE_UNIT_LEVEL_CLKGATE XE_REG_MCR(0x94d4) #define L3_CR2X_CLKGATE_DIS REG_BIT(17) #define L3_CLKGATE_DIS REG_BIT(16) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 94ea76b098ed..0ee532eb26d6 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -252,6 +252,34 @@ static const struct xe_rtp_entry_sr gt_was[] = { XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), }, + /* Xe3_LPG */ + + { XE_RTP_NAME("14021871409"), + XE_RTP_RULES(GRAPHICS_VERSION(3000), GRAPHICS_STEP(A0, B0)), + XE_RTP_ACTIONS(SET(UNSLCGCTL9454, LSCFE_CLKGATE_DIS)) + }, + + /* Xe3_LPM */ + + { XE_RTP_NAME("16021867713"), + XE_RTP_RULES(MEDIA_VERSION(3000), + ENGINE_CLASS(VIDEO_DECODE)), + XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F1C(0), MFXPIPE_CLKGATE_DIS)), + XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), + }, + { XE_RTP_NAME("16021865536"), + XE_RTP_RULES(MEDIA_VERSION(3000), + ENGINE_CLASS(VIDEO_DECODE)), + XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), IECPUNIT_CLKGATE_DIS)), + XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), + }, + { XE_RTP_NAME("14021486841"), + XE_RTP_RULES(MEDIA_VERSION(3000), MEDIA_STEP(A0, B0), + ENGINE_CLASS(VIDEO_DECODE)), + XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), RAMDFTUNIT_CLKGATE_DIS)), + XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), + }, + {} }; @@ -568,6 +596,13 @@ static const struct xe_rtp_entry_sr engine_was[] = { XE_RTP_ACTION_FLAG(ENGINE_BASE))) }, + /* Xe3_LPG */ + + { XE_RTP_NAME("14021402888"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001), FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE)) + }, + {} }; @@ -739,6 +774,18 @@ static const struct xe_rtp_entry_sr lrc_was[] = { XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX)) }, + /* Xe3_LPG */ + { XE_RTP_NAME("14021490052"), + XE_RTP_RULES(GRAPHICS_VERSION(3000), GRAPHICS_STEP(A0, B0), + ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(FF_MODE, + DIS_MESH_PARTIAL_AUTOSTRIP | + DIS_MESH_AUTOSTRIP), + SET(VFLSKPD, + DIS_PARTIAL_AUTOSTRIP | + DIS_AUTOSTRIP)) + }, + {} }; diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules index 0154fbe154e9..264d6e116499 100644 --- a/drivers/gpu/drm/xe/xe_wa_oob.rules +++ b/drivers/gpu/drm/xe/xe_wa_oob.rules @@ -33,6 +33,7 @@ GRAPHICS_VERSION(2004) 22019338487 MEDIA_VERSION(2000) GRAPHICS_VERSION(2001) + MEDIA_VERSION(3000), MEDIA_STEP(A0, B0) 22019338487_display PLATFORM(LUNARLAKE) 16023588340 GRAPHICS_VERSION(2001) 14019789679 GRAPHICS_VERSION(1255) -- GitLab From c3e91446a3580353672e965165ab37db2bf6a757 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 9 Oct 2024 17:03:00 +0300 Subject: [PATCH 798/970] drm/file: fix client_name_lock kernel-doc warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's client_name_lock, not name_lock. Also unify style while at it. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Closes: https://lore.kernel.org/r/20241009172650.29169e6f@canb.auug.org.au Fixes: 56c594d8df64 ("drm: add DRM_SET_CLIENT_NAME ioctl") Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241009140300.1980746-1-jani.nikula@intel.com Signed-off-by: Christian König <christian.koenig@amd.com> --- include/drm/drm_file.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index d4f1c115ea0f..f0ef32e9fa5e 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -395,7 +395,10 @@ struct drm_file { * Userspace-provided name; useful for accounting and debugging. */ const char *client_name; - /** @name_lock: Protects @client_name. */ + + /** + * @client_name_lock: Protects @client_name. + */ struct mutex client_name_lock; }; -- GitLab From 3639fadc7e98a5b0aef399d7beef24b028fdf898 Mon Sep 17 00:00:00 2001 From: Jani Nikula <jani.nikula@intel.com> Date: Wed, 9 Oct 2024 17:04:52 +0300 Subject: [PATCH 799/970] drm/imx: add forward declarations for types The imx.h header does not forward declare the types it uses, and the header is not self-contained. Fix it. Fixes: cc3e8a216d6b ("drm/imx: add internal bridge handling display-timings DT node") Cc: Philipp Zabel <p.zabel@pengutronix.de> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Cc: imx@lists.linux.dev Cc: linux-arm-kernel@lists.infradead.org Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Link: https://patchwork.freedesktop.org/patch/msgid/20241009140452.1981175-1-jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- include/drm/bridge/imx.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/drm/bridge/imx.h b/include/drm/bridge/imx.h index e14f429a9ca2..b93f719fe0e7 100644 --- a/include/drm/bridge/imx.h +++ b/include/drm/bridge/imx.h @@ -6,6 +6,10 @@ #ifndef DRM_IMX_BRIDGE_H #define DRM_IMX_BRIDGE_H +struct device; +struct device_node; +struct drm_bridge; + struct drm_bridge *devm_imx_drm_legacy_bridge(struct device *dev, struct device_node *np, int type); -- GitLab From 4c93ede2b0c73a7708f46a01669769d15d31e1d2 Mon Sep 17 00:00:00 2001 From: R Sundar <prosunofficial@gmail.com> Date: Thu, 3 Oct 2024 08:08:06 +0530 Subject: [PATCH 800/970] drm: Fix for kernel doc warning Added colon in kernel-doc comment to fix the warning. ./include/drm/drm_drv.h:372: warning: Incorrect use of kernel-doc format: * @fbdev_probe ./include/drm/drm_drv.h:435: warning: Function parameter or struct member 'fbdev_probe' not described in 'drm_driver' Signed-off-by: R Sundar <prosunofficial@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003023806.17537-1-prosunofficial@gmail.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- include/drm/drm_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 36a606af4ba1..1bbbcb8e2d23 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -369,7 +369,7 @@ struct drm_driver { uint64_t *offset); /** - * @fbdev_probe + * @fbdev_probe: * * Allocates and initialize the fb_info structure for fbdev emulation. * Furthermore it also needs to allocate the DRM framebuffer used to -- GitLab From 8fb1da9f9bfb02f710a7f826d50781b0b030cf53 Mon Sep 17 00:00:00 2001 From: Aradhya Bhatia <aradhya.bhatia@intel.com> Date: Wed, 9 Oct 2024 12:25:42 +0530 Subject: [PATCH 801/970] drm/xe/xe2lpg: Extend Wa_15016589081 for xe2lpg Add workaround (wa) 15016589081 which applies to Xe2_v3_LPG_MD. Xe2_v3_LPG_MD is a Lunar Lake platform with GFX version: 20.04. This wa is type: permanent, and hence is applicable on all steppings. Signed-off-by: Aradhya Bhatia <aradhya.bhatia@intel.com> Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241009065542.283151-1-aradhya.bhatia@intel.com --- drivers/gpu/drm/xe/xe_wa.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 0ee532eb26d6..0c90438e8e72 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -746,6 +746,10 @@ static const struct xe_rtp_entry_sr lrc_was[] = { DIS_PARTIAL_AUTOSTRIP | DIS_AUTOSTRIP)) }, + { XE_RTP_NAME("15016589081"), + XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX)) + }, /* Xe2_HPG */ { XE_RTP_NAME("15010599737"), -- GitLab From 6b3815c6815f07acc7eeffa8ae734d1a1c0ee817 Mon Sep 17 00:00:00 2001 From: Aleksandrs Vinarskis <alex.vinarskis@gmail.com> Date: Tue, 8 Oct 2024 09:30:14 +0200 Subject: [PATCH 802/970] drm/edp-panel: Add panels used by Dell XPS 13 9345 Introduce low-res IPS and OLED panels for mentioned device. SHP panel's timings were picked experimentally, without this patch or with `delay_200_500_e50` panel sometimes fails to boot/stays black on startup. LGD panel's timings were copied from other LGD panels and tested to be working. Particular laptop also comes in high-res IPS variant, which unfortunately I do not have access to verify. The raw edid for SHP panel is: 00 ff ff ff ff ff ff 00 4d 10 93 15 00 00 00 00 2c 21 01 04 a5 1d 12 78 07 ee 95 a3 54 4c 99 26 0f 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 f0 7b 80 90 70 b0 52 45 30 20 36 00 20 b4 10 00 00 18 00 00 00 fd 00 1e 78 9a 9a 20 01 0a 20 20 20 20 20 20 00 00 00 fe 00 4b 4a 46 47 52 80 4c 51 31 33 34 4e 31 00 00 00 00 00 02 41 0c 32 00 01 00 00 0b 41 0a 20 20 01 ef 70 20 79 02 00 20 00 13 8c 52 19 93 15 00 00 00 00 2c 17 07 4c 51 31 33 34 4e 31 21 00 1d 40 0b 08 07 80 07 b0 04 88 3d 8a 54 cd a4 99 66 62 0f 02 45 54 d0 5f d0 5f 00 34 12 78 26 00 09 02 00 00 00 00 00 01 00 00 22 00 14 5e d7 04 05 7f 07 8f 00 2f 00 1f 00 af 04 50 00 02 00 05 00 25 01 09 5e d7 04 5e d7 04 1e 78 80 81 00 0b e3 05 80 00 e6 06 01 01 6a 6a 39 00 00 00 00 00 00 ce 90 The raw edid for LGD panel is: 00 ff ff ff ff ff ff 00 30 e4 78 07 00 00 00 00 00 22 01 04 b5 1d 12 78 06 96 65 b0 4f 3c b9 23 0b 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ef 83 40 a0 b0 08 34 70 30 20 36 00 20 b4 10 00 00 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe 00 44 48 39 50 57 80 31 33 34 57 54 31 0a 00 00 00 00 00 04 04 03 28 00 01 00 00 2b 01 0a 20 20 01 d4 70 20 79 02 00 20 00 13 3c e6 24 78 07 00 00 00 00 00 18 07 31 33 34 57 54 31 0a 21 00 1d 41 0b 08 07 40 0b 08 07 88 06 6b 4f c3 a3 b9 35 82 0b 02 45 54 40 5e 1a 60 18 10 23 78 26 00 09 04 00 00 00 00 00 41 00 00 22 00 14 55 27 05 85 3f 0b 9f 00 2f 80 1f 00 07 07 33 00 02 00 05 00 25 01 09 55 27 05 55 27 05 3c 3c 00 81 00 0b e3 05 80 00 e6 06 05 01 6d 60 02 00 00 00 00 00 00 31 90 Signed-off-by: Aleksandrs Vinarskis <alex.vinarskis@gmail.com> Tested-by: Peter de Kraker <peterdekraker@umito.nl> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241008073014.16411-1-alex.vinarskis@gmail.com --- drivers/gpu/drm/panel/panel-edp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 767e47a2b0c1..8566e9cf2f82 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1977,11 +1977,13 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('L', 'G', 'D', 0x0567, &delay_200_500_e200_d200, "Unknown"), EDP_PANEL_ENTRY('L', 'G', 'D', 0x05af, &delay_200_500_e200_d200, "Unknown"), EDP_PANEL_ENTRY('L', 'G', 'D', 0x05f1, &delay_200_500_e200_d200, "Unknown"), + EDP_PANEL_ENTRY('L', 'G', 'D', 0x0778, &delay_200_500_e200_d200, "134WT1"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x1511, &delay_200_500_e50, "LQ140M1JW48"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &delay_80_500_e50, "LQ140M1JW46"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x153a, &delay_200_500_e50, "LQ140T1JH01"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"), + EDP_PANEL_ENTRY('S', 'H', 'P', 0x1593, &delay_200_500_p2e100, "LQ134N1"), EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"), -- GitLab From 2d6d8b138f241c29da7c122918556e45e67f2660 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Fri, 4 Oct 2024 09:52:47 +0200 Subject: [PATCH 803/970] drm/bochs: Return error from correct pointer In probe, return the error code from the variable bochs, not dev. The variable dev has not been initialized at this point. In the case of an allocation error, the returned value would have been undefined. Reported-by: Kees Bakker <kees@ijzerbout.nl> Closes: https://lore.kernel.org/dri-devel/8c5bfc12-cbcc-4102-9826-494060df4179@ijzerbout.nl/ Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Fixes: 04826f588682 ("drm/bochs: Allocate DRM device in struct bochs_device") Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: virtualization@lists.linux.dev Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004075404.41743-1-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 5d2d34976d4b..3ba7f09f3e7b 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -717,7 +717,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent bochs = devm_drm_dev_alloc(&pdev->dev, &bochs_driver, struct bochs_device, dev); if (IS_ERR(bochs)) - return PTR_ERR(dev); + return PTR_ERR(bochs); dev = &bochs->dev; ret = pcim_enable_device(pdev); -- GitLab From cfcbc0520d5055825f0647ab922b655688605183 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 9 Oct 2024 09:48:09 +0100 Subject: [PATCH 804/970] drm/xe: fix unbalanced rpm put() with fence_fini() Currently we can call fence_fini() twice if something goes wrong when sending the GuC CT for the tlb request, since we signal the fence and return an error, leading to the caller also calling fini() on the error path in the case of stack version of the flow, which leads to an extra rpm put() which might later cause device to enter suspend when it shouldn't. It looks like we can just drop the fini() call since the fence signaller side will already call this for us. There are known mysterious splats with device going to sleep even with an rpm ref, and this could be one candidate. v2 (Matt B): - Prefer warning if we detect double fini() Fixes: 0a382f9bc5dc ("drm/xe: Hold a PM ref when GT TLB invalidations are inflight") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241009084808.204432-3-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 29 +++++++++------------ drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h | 1 - drivers/gpu/drm/xe/xe_vm.c | 8 ++---- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c index 98616de0c5bb..a530a933eedc 100644 --- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c +++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c @@ -37,6 +37,15 @@ static long tlb_timeout_jiffies(struct xe_gt *gt) return hw_tlb_timeout + 2 * delay; } +static void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence) +{ + if (WARN_ON_ONCE(!fence->gt)) + return; + + xe_pm_runtime_put(gt_to_xe(fence->gt)); + fence->gt = NULL; /* fini() should be called once */ +} + static void __invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fence *fence) { @@ -204,7 +213,7 @@ static int send_tlb_invalidation(struct xe_guc *guc, tlb_timeout_jiffies(gt)); } spin_unlock_irq(>->tlb_invalidation.pending_lock); - } else if (ret < 0) { + } else { __invalidation_fence_signal(xe, fence); } if (!ret) { @@ -267,10 +276,8 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt) xe_gt_tlb_invalidation_fence_init(gt, &fence, true); ret = xe_gt_tlb_invalidation_guc(gt, &fence); - if (ret < 0) { - xe_gt_tlb_invalidation_fence_fini(&fence); + if (ret) return ret; - } xe_gt_tlb_invalidation_fence_wait(&fence); } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) { @@ -498,7 +505,8 @@ static const struct dma_fence_ops invalidation_fence_ops = { * @stack: fence is stack variable * * Initialize TLB invalidation fence for use. xe_gt_tlb_invalidation_fence_fini - * must be called if fence is not signaled. + * will be automatically called when fence is signalled (all fences must signal), + * even on error. */ void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, struct xe_gt_tlb_invalidation_fence *fence, @@ -518,14 +526,3 @@ void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, dma_fence_get(&fence->base); fence->gt = gt; } - -/** - * xe_gt_tlb_invalidation_fence_fini - Finalize TLB invalidation fence - * @fence: TLB invalidation fence to finalize - * - * Drop PM ref which fence took durinig init. - */ -void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence) -{ - xe_pm_runtime_put(gt_to_xe(fence->gt)); -} diff --git a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h index a84065fa324c..f430d5797af7 100644 --- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h +++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h @@ -28,7 +28,6 @@ int xe_guc_tlb_invalidation_done_handler(struct xe_guc *guc, u32 *msg, u32 len); void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt, struct xe_gt_tlb_invalidation_fence *fence, bool stack); -void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence); static inline void xe_gt_tlb_invalidation_fence_wait(struct xe_gt_tlb_invalidation_fence *fence) diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index ce9dca4d4e87..c99380271de6 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -3199,10 +3199,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma) ret = xe_gt_tlb_invalidation_vma(tile->primary_gt, &fence[fence_id], vma); - if (ret < 0) { - xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]); + if (ret) goto wait; - } ++fence_id; if (!tile->media_gt) @@ -3214,10 +3212,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma) ret = xe_gt_tlb_invalidation_vma(tile->media_gt, &fence[fence_id], vma); - if (ret < 0) { - xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]); + if (ret) goto wait; - } ++fence_id; } } -- GitLab From a187c1b0a800565a4db6372268692aff99df7f53 Mon Sep 17 00:00:00 2001 From: Matthew Auld <matthew.auld@intel.com> Date: Wed, 9 Oct 2024 09:48:10 +0100 Subject: [PATCH 805/970] drm/xe: fix unbalanced rpm put() with declare_wedged() Technically the or_reset() means we call the action on failure, however that would lead to unbalanced rpm put(). Move the get() earlier to fix this. It should be extremely unlikely to ever trigger this in practice. Fixes: 452bca0edbd0 ("drm/xe: Don't suspend device upon wedge") Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Nirmoy Das <nirmoy.das@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241009084808.204432-4-matthew.auld@intel.com --- drivers/gpu/drm/xe/xe_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index cd241a8e1838..962751c966d1 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -1016,13 +1016,13 @@ void xe_device_declare_wedged(struct xe_device *xe) return; } + xe_pm_runtime_get_noresume(xe); + if (drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe)) { drm_err(&xe->drm, "Failed to register xe_device_wedged_fini clean-up. Although device is wedged.\n"); return; } - xe_pm_runtime_get_noresume(xe); - if (!atomic_xchg(&xe->wedged.flag, 1)) { xe->needs_flr_on_fini = true; drm_err(&xe->drm, -- GitLab From a500f3751d3c861be7e4463c933cf467240cca5d Mon Sep 17 00:00:00 2001 From: Brahmajit Das <brahmajit.xyz@gmail.com> Date: Wed, 2 Oct 2024 14:53:11 +0530 Subject: [PATCH 806/970] drm/display: Fix building with GCC 15 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 15 enables -Werror=unterminated-string-initialization by default. This results in the following build error drivers/gpu/drm/display/drm_dp_dual_mode_helper.c: In function ‘is_hdmi_adaptor’: drivers/gpu/drm/display/drm_dp_dual_mode_helper.c:164:17: error: initializer-string for array of ‘char’ is too long [-Werror=unterminated-string-initialization] 164 | "DP-HDMI ADAPTOR\x04"; | ^~~~~~~~~~~~~~~~~~~~~ After discussion with Ville, the fix was to increase the size of dp_dual_mode_hdmi_id array by one, so that it can accommodate the NULL line character. This should let us build the kernel with GCC 15. Signed-off-by: Brahmajit Das <brahmajit.xyz@gmail.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241002092311.942822-1-brahmajit.xyz@gmail.com Signed-off-by: Jani Nikula <jani.nikula@intel.com> --- drivers/gpu/drm/display/drm_dp_dual_mode_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c index 14a2a8473682..c491e3203bf1 100644 --- a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c +++ b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c @@ -160,11 +160,11 @@ EXPORT_SYMBOL(drm_dp_dual_mode_write); static bool is_hdmi_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN]) { - static const char dp_dual_mode_hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] = + static const char dp_dual_mode_hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN + 1] = "DP-HDMI ADAPTOR\x04"; return memcmp(hdmi_id, dp_dual_mode_hdmi_id, - sizeof(dp_dual_mode_hdmi_id)) == 0; + DP_DUAL_MODE_HDMI_ID_LEN) == 0; } static bool is_type1_adaptor(uint8_t adaptor_id) -- GitLab From 33c255312660653cf54f8019896b5dca28e3c580 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski <dsankouski@gmail.com> Date: Thu, 10 Oct 2024 13:31:42 +0300 Subject: [PATCH 807/970] drm/mipi-dsi: fix kernel doc on mipi_dsi_compression_mode_multi Replace dsi parameter on ctx in kernel doc of mipi_dsi_compression_mode_multi function. Fixes: 975bdea8c470 ("drm/mipi-dsi: add mipi_dsi_compression_mode_multi") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202410092245.tfsuUllL-lkp@intel.com/ Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20241010-starqltechn_integration_upstream_drm_fix-v1-1-cf3cb1d1ce77@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241010-starqltechn_integration_upstream_drm_fix-v1-1-cf3cb1d1ce77@gmail.com --- drivers/gpu/drm/drm_mipi_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index d8ee74701f1e..5e5c5f84daac 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -1522,7 +1522,7 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi); /** * mipi_dsi_compression_mode_multi() - enable/disable DSC on the peripheral - * @dsi: DSI peripheral device + * @ctx: Context for multiple DSI transactions * @enable: Whether to enable or disable the DSC * * Enable or disable Display Stream Compression on the peripheral using the -- GitLab From a4293cc75348409f998c991c48cbe5532c438114 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Date: Mon, 30 Sep 2024 21:52:52 +0200 Subject: [PATCH 808/970] accel/ivpu: Update VPU FW API headers This commit bumps: - Boot API from 3.24.0 to 3.26.3 - JSM API from 3.16.0 to 3.25.0 Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Co-developed-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Signed-off-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-2-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_job.c | 2 +- drivers/accel/ivpu/ivpu_jsm_msg.c | 3 +- drivers/accel/ivpu/vpu_boot_api.h | 43 +++-- drivers/accel/ivpu/vpu_jsm_api.h | 303 +++++++++++++++++++++++++----- 4 files changed, 292 insertions(+), 59 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index be2e2bf0f43f..b00634af8bc3 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -354,7 +354,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) return -EBUSY; } - entry = &cmdq->jobq->job[tail]; + entry = &cmdq->jobq->slot[tail].job; entry->batch_buf_addr = job->cmd_buf_vpu_addr; entry->job_id = job->job_id; entry->flags = 0; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 46ef16c3c069..b06da8f50fd3 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -48,9 +48,10 @@ const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type) IVPU_CASE_TO_STR(VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP); IVPU_CASE_TO_STR(VPU_JSM_MSG_STATE_DUMP_RSP); - IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT); + IVPU_CASE_TO_STR(VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED); IVPU_CASE_TO_STR(VPU_JSM_MSG_DYNDBG_CONTROL); IVPU_CASE_TO_STR(VPU_JSM_MSG_JOB_DONE); + IVPU_CASE_TO_STR(VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED); IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_RESET_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_ENGINE_PREEMPT_DONE); IVPU_CASE_TO_STR(VPU_JSM_MSG_REGISTER_DB_DONE); diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h index d474bc7b15c0..908e68ea1c39 100644 --- a/drivers/accel/ivpu/vpu_boot_api.h +++ b/drivers/accel/ivpu/vpu_boot_api.h @@ -1,13 +1,12 @@ /* SPDX-License-Identifier: MIT */ /* - * Copyright (c) 2020-2023, Intel Corporation. + * Copyright (c) 2020-2024, Intel Corporation. */ #ifndef VPU_BOOT_API_H #define VPU_BOOT_API_H /* - * =========== FW API version information beginning ================ * The below values will be used to construct the version info this way: * fw_bin_header->api_version[VPU_BOOT_API_VER_ID] = (VPU_BOOT_API_VER_MAJOR << 16) | * VPU_BOOT_API_VER_MINOR; @@ -27,19 +26,18 @@ * Minor version changes when API backward compatibility is preserved. * Resets to 0 if Major version is incremented. */ -#define VPU_BOOT_API_VER_MINOR 24 +#define VPU_BOOT_API_VER_MINOR 26 /* * API header changed (field names, documentation, formatting) but API itself has not been changed */ -#define VPU_BOOT_API_VER_PATCH 0 +#define VPU_BOOT_API_VER_PATCH 3 /* * Index in the API version table * Must be unique for each API */ #define VPU_BOOT_API_VER_INDEX 0 -/* ------------ FW API version information end ---------------------*/ #pragma pack(push, 4) @@ -164,8 +162,6 @@ enum vpu_trace_destination { /* VPU 30xx HW component IDs are sequential, so define first and last IDs. */ #define VPU_TRACE_PROC_BIT_30XX_FIRST VPU_TRACE_PROC_BIT_LRT #define VPU_TRACE_PROC_BIT_30XX_LAST VPU_TRACE_PROC_BIT_SHV_15 -#define VPU_TRACE_PROC_BIT_KMB_FIRST VPU_TRACE_PROC_BIT_30XX_FIRST -#define VPU_TRACE_PROC_BIT_KMB_LAST VPU_TRACE_PROC_BIT_30XX_LAST struct vpu_boot_l2_cache_config { u8 use; @@ -199,6 +195,17 @@ struct vpu_warm_boot_section { */ #define POWER_PROFILE_SURVIVABILITY 0x1 +/** + * Enum for dvfs_mode boot param. + */ +enum vpu_governor { + VPU_GOV_DEFAULT = 0, /* Default Governor for the system */ + VPU_GOV_MAX_PERFORMANCE = 1, /* Maximum performance governor */ + VPU_GOV_ON_DEMAND = 2, /* On Demand frequency control governor */ + VPU_GOV_POWER_SAVE = 3, /* Power save governor */ + VPU_GOV_ON_DEMAND_PRIORITY_AWARE = 4 /* On Demand priority based governor */ +}; + struct vpu_boot_params { u32 magic; u32 vpu_id; @@ -301,7 +308,14 @@ struct vpu_boot_params { u32 temp_sensor_period_ms; /** PLL ratio for efficient clock frequency */ u32 pn_freq_pll_ratio; - /** DVFS Mode: Default: 0, Max Performance: 1, On Demand: 2, Power Save: 3 */ + /** + * DVFS Mode: + * 0 - Default, DVFS mode selected by the firmware + * 1 - Max Performance + * 2 - On Demand + * 3 - Power Save + * 4 - On Demand Priority Aware + */ u32 dvfs_mode; /** * Depending on DVFS Mode: @@ -332,8 +346,8 @@ struct vpu_boot_params { u64 d0i3_entry_vpu_ts; /* * The system time of the host operating system in microseconds. - * E.g the number of microseconds since 1st of January 1970, or whatever date the - * host operating system uses to maintain system time. + * E.g the number of microseconds since 1st of January 1970, or whatever + * date the host operating system uses to maintain system time. * This value will be used to track system time on the VPU. * The KMD is required to update this value on every VPU reset. */ @@ -382,10 +396,7 @@ struct vpu_boot_params { u32 pad6[734]; }; -/* - * Magic numbers set between host and vpu to detect corruptio of tracing init - */ - +/* Magic numbers set between host and vpu to detect corruption of tracing init */ #define VPU_TRACING_BUFFER_CANARY (0xCAFECAFE) /* Tracing buffer message format definitions */ @@ -405,7 +416,9 @@ struct vpu_tracing_buffer_header { u32 host_canary_start; /* offset from start of buffer for trace entries */ u32 read_index; - u32 pad_to_cache_line_size_0[14]; + /* keeps track of wrapping on the reader side */ + u32 read_wrap_count; + u32 pad_to_cache_line_size_0[13]; /* End of first cache line */ /** diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h index 33f462b1a25d..7215c144158c 100644 --- a/drivers/accel/ivpu/vpu_jsm_api.h +++ b/drivers/accel/ivpu/vpu_jsm_api.h @@ -22,7 +22,7 @@ /* * Minor version changes when API backward compatibility is preserved. */ -#define VPU_JSM_API_VER_MINOR 16 +#define VPU_JSM_API_VER_MINOR 25 /* * API header changed (field names, documentation, formatting) but API itself has not been changed @@ -36,7 +36,7 @@ /* * Number of Priority Bands for Hardware Scheduling - * Bands: RealTime, Focus, Normal, Idle + * Bands: Idle(0), Normal(1), Focus(2), RealTime(3) */ #define VPU_HWS_NUM_PRIORITY_BANDS 4 @@ -74,6 +74,7 @@ #define VPU_JSM_STATUS_MVNCI_INTERNAL_ERROR 0xCU /* Job status returned when the job was preempted mid-inference */ #define VPU_JSM_STATUS_PREEMPTED_MID_INFERENCE 0xDU +#define VPU_JSM_STATUS_MVNCI_CONTEXT_VIOLATION_HW 0xEU /* * Host <-> VPU IPC channels. @@ -86,18 +87,58 @@ /* * Job flags bit masks. */ -#define VPU_JOB_FLAGS_NULL_SUBMISSION_MASK 0x00000001 -#define VPU_JOB_FLAGS_PRIVATE_DATA_MASK 0xFF000000 +enum { + /* + * Null submission mask. + * When set, batch buffer's commands are not processed but returned as + * successful immediately, except fences and timestamps. + * When cleared, batch buffer's commands are processed normally. + * Used for testing and profiling purposes. + */ + VPU_JOB_FLAGS_NULL_SUBMISSION_MASK = (1 << 0U), + /* + * Inline command mask. + * When set, the object in job queue is an inline command (see struct vpu_inline_cmd below). + * When cleared, the object in job queue is a job (see struct vpu_job_queue_entry below). + */ + VPU_JOB_FLAGS_INLINE_CMD_MASK = (1 << 1U), + /* + * VPU private data mask. + * Reserved for the VPU to store private data about the job (or inline command) + * while being processed. + */ + VPU_JOB_FLAGS_PRIVATE_DATA_MASK = 0xFFFF0000U +}; /* - * Sizes of the reserved areas in jobs, in bytes. + * Job queue flags bit masks. */ -#define VPU_JOB_RESERVED_BYTES 8 +enum { + /* + * No job done notification mask. + * When set, indicates that no job done notification should be sent for any + * job from this queue. When cleared, indicates that job done notification + * should be sent for every job completed from this queue. + */ + VPU_JOB_QUEUE_FLAGS_NO_JOB_DONE_MASK = (1 << 0U), + /* + * Native fence usage mask. + * When set, indicates that job queue uses native fences (as inline commands + * in job queue). Such queues may also use legacy fences (as commands in batch buffers). + * When cleared, indicates the job queue only uses legacy fences. + * NOTE: For queues using native fences, VPU expects that all jobs in the queue + * are immediately followed by an inline command object. This object is expected + * to be a fence signal command in most cases, but can also be a NOP in case the host + * does not need per-job fence signalling. Other inline commands objects can be + * inserted between "job and inline command" pairs. + */ + VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U), -/* - * Sizes of the reserved areas in job queues, in bytes. - */ -#define VPU_JOB_QUEUE_RESERVED_BYTES 52 + /* + * Enable turbo mode for testing NPU performance; not recommended for regular usage. + */ + VPU_JOB_QUEUE_FLAGS_TURBO_MODE = (1 << 2U) +}; /* * Max length (including trailing NULL char) of trace entity name (e.g., the @@ -140,24 +181,113 @@ */ #define VPU_HWS_INVALID_CMDQ_HANDLE 0ULL +/* + * Inline commands types. + */ +/* + * NOP. + * VPU does nothing other than consuming the inline command object. + */ +#define VPU_INLINE_CMD_TYPE_NOP 0x0 +/* + * Fence wait. + * VPU waits for the fence current value to reach monitored value. + * Fence wait operations are executed upon job dispatching. While waiting for + * the fence to be satisfied, VPU blocks fetching of the next objects in the queue. + * Jobs present in the queue prior to the fence wait object may be processed + * concurrently. + */ +#define VPU_INLINE_CMD_TYPE_FENCE_WAIT 0x1 +/* + * Fence signal. + * VPU sets the fence current value to the provided value. If new current value + * is equal to or higher than monitored value, VPU sends fence signalled notification + * to the host. Fence signal operations are executed upon completion of all the jobs + * present in the queue prior to them, and in-order relative to each other in the queue. + * But jobs in-between them may be processed concurrently and may complete out-of-order. + */ +#define VPU_INLINE_CMD_TYPE_FENCE_SIGNAL 0x2 + +/* + * Job scheduling priority bands for both hardware scheduling and OS scheduling. + */ +enum vpu_job_scheduling_priority_band { + VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE = 0, + VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL = 1, + VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS = 2, + VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME = 3, + VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT = 4, +}; + /* * Job format. + * Jobs defines the actual workloads to be executed by a given engine. */ struct vpu_job_queue_entry { - u64 batch_buf_addr; /**< Address of VPU commands batch buffer */ - u32 job_id; /**< Job ID */ - u32 flags; /**< Flags bit field, see VPU_JOB_FLAGS_* above */ - u64 root_page_table_addr; /**< Address of root page table to use for this job */ - u64 root_page_table_update_counter; /**< Page tables update events counter */ - u64 primary_preempt_buf_addr; + /**< Address of VPU commands batch buffer */ + u64 batch_buf_addr; + /**< Job ID */ + u32 job_id; + /**< Flags bit field, see VPU_JOB_FLAGS_* above */ + u32 flags; + /** + * Doorbell ring timestamp taken by KMD from SoC's global system clock, in + * microseconds. NPU can convert this value to its own fixed clock's timebase, + * to match other profiling timestamps. + */ + u64 doorbell_timestamp; + /**< Extra id for job tracking, used only in the firmware perf traces */ + u64 host_tracking_id; /**< Address of the primary preemption buffer to use for this job */ - u32 primary_preempt_buf_size; + u64 primary_preempt_buf_addr; /**< Size of the primary preemption buffer to use for this job */ - u32 secondary_preempt_buf_size; + u32 primary_preempt_buf_size; /**< Size of secondary preemption buffer to use for this job */ - u64 secondary_preempt_buf_addr; + u32 secondary_preempt_buf_size; /**< Address of secondary preemption buffer to use for this job */ - u8 reserved_0[VPU_JOB_RESERVED_BYTES]; + u64 secondary_preempt_buf_addr; + u64 reserved_0; +}; + +/* + * Inline command format. + * Inline commands are the commands executed at scheduler level (typically, + * synchronization directives). Inline command and job objects must be of + * the same size and have flags field at same offset. + */ +struct vpu_inline_cmd { + u64 reserved_0; + /* Inline command type, see VPU_INLINE_CMD_TYPE_* defines. */ + u32 type; + /* Flags bit field, see VPU_JOB_FLAGS_* above. */ + u32 flags; + /* Inline command payload. Depends on inline command type. */ + union { + /* Fence (wait and signal) commands' payload. */ + struct { + /* Fence object handle. */ + u64 fence_handle; + /* User VA of the current fence value. */ + u64 current_value_va; + /* User VA of the monitored fence value (read-only). */ + u64 monitored_value_va; + /* Value to wait for or write in fence location. */ + u64 value; + /* User VA of the log buffer in which to add log entry on completion. */ + u64 log_buffer_va; + } fence; + /* Other commands do not have a payload. */ + /* Payload definition for future inline commands can be inserted here. */ + u64 reserved_1[6]; + } payload; +}; + +/* + * Job queue slots can be populated either with job objects or inline command objects. + */ +union vpu_jobq_slot { + struct vpu_job_queue_entry job; + struct vpu_inline_cmd inline_cmd; }; /* @@ -167,7 +297,21 @@ struct vpu_job_queue_header { u32 engine_idx; u32 head; u32 tail; - u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES]; + u32 flags; + /* Set to 1 to indicate priority_band field is valid */ + u32 priority_band_valid; + /* + * Priority for the work of this job queue, valid only if the HWS is NOT used + * and the `priority_band_valid` is set to 1. It is applied only during + * the VPU_JSM_MSG_REGISTER_DB message processing. + * The device firmware might use the `priority_band` to optimize the power + * management logic, but it will not affect the order of jobs. + * Available priority bands: @see enum vpu_job_scheduling_priority_band + */ + u32 priority_band; + /* Inside realtime band assigns a further priority, limited to 0..31 range */ + u32 realtime_priority_level; + u32 reserved_0[9]; }; /* @@ -175,7 +319,7 @@ struct vpu_job_queue_header { */ struct vpu_job_queue { struct vpu_job_queue_header header; - struct vpu_job_queue_entry job[]; + union vpu_jobq_slot slot[]; }; /** @@ -197,9 +341,7 @@ enum vpu_trace_entity_type { struct vpu_hws_log_buffer_header { /* Written by VPU after adding a log entry. Initialised by host to 0. */ u32 first_free_entry_index; - /* Incremented by VPU every time the VPU overwrites the 0th entry; - * initialised by host to 0. - */ + /* Incremented by VPU every time the VPU writes the 0th entry; initialised by host to 0. */ u32 wraparound_count; /* * This is the number of buffers that can be stored in the log buffer provided by the host. @@ -230,14 +372,80 @@ struct vpu_hws_log_buffer_entry { u64 operation_data[2]; }; +/* Native fence log buffer types. */ +enum vpu_hws_native_fence_log_type { + VPU_HWS_NATIVE_FENCE_LOG_TYPE_WAITS = 1, + VPU_HWS_NATIVE_FENCE_LOG_TYPE_SIGNALS = 2 +}; + +/* HWS native fence log buffer header. */ +struct vpu_hws_native_fence_log_header { + union { + struct { + /* Index of the first free entry in buffer. */ + u32 first_free_entry_idx; + /* Incremented each time NPU wraps around the buffer to write next entry. */ + u32 wraparound_count; + }; + /* Field allowing atomic update of both fields above. */ + u64 atomic_wraparound_and_entry_idx; + }; + /* Log buffer type, see enum vpu_hws_native_fence_log_type. */ + u64 type; + /* Allocated number of entries in the log buffer. */ + u64 entry_nb; + u64 reserved[2]; +}; + +/* Native fence log operation types. */ +enum vpu_hws_native_fence_log_op { + VPU_HWS_NATIVE_FENCE_LOG_OP_SIGNAL_EXECUTED = 0, + VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED = 1 +}; + +/* HWS native fence log entry. */ +struct vpu_hws_native_fence_log_entry { + /* Newly signaled/unblocked fence value. */ + u64 fence_value; + /* Native fence object handle to which this operation belongs. */ + u64 fence_handle; + /* Operation type, see enum vpu_hws_native_fence_log_op. */ + u64 op_type; + u64 reserved_0; + /* + * VPU_HWS_NATIVE_FENCE_LOG_OP_WAIT_UNBLOCKED only: Timestamp at which fence + * wait was started (in NPU SysTime). + */ + u64 fence_wait_start_ts; + u64 reserved_1; + /* Timestamp at which fence operation was completed (in NPU SysTime). */ + u64 fence_end_ts; +}; + +/* Native fence log buffer. */ +struct vpu_hws_native_fence_log_buffer { + struct vpu_hws_native_fence_log_header header; + struct vpu_hws_native_fence_log_entry entry[]; +}; + /* * Host <-> VPU IPC messages types. */ enum vpu_ipc_msg_type { VPU_JSM_MSG_UNKNOWN = 0xFFFFFFFF, + /* IPC Host -> Device, Async commands */ VPU_JSM_MSG_ASYNC_CMD = 0x1100, VPU_JSM_MSG_ENGINE_RESET = VPU_JSM_MSG_ASYNC_CMD, + /** + * Preempt engine. The NPU stops (preempts) all the jobs currently + * executing on the target engine making the engine become idle and ready to + * execute new jobs. + * NOTE: The NPU does not remove unstarted jobs (if any) from job queues of + * the target engine, but it stops processing them (until the queue doorbell + * is rung again); the host is responsible to reset the job queue, either + * after preemption or when resubmitting jobs to the queue. + */ VPU_JSM_MSG_ENGINE_PREEMPT = 0x1101, VPU_JSM_MSG_REGISTER_DB = 0x1102, VPU_JSM_MSG_UNREGISTER_DB = 0x1103, @@ -323,9 +531,10 @@ enum vpu_ipc_msg_type { * NOTE: Please introduce new ASYNC commands before this one. * */ VPU_JSM_MSG_STATE_DUMP = 0x11FF, + /* IPC Host -> Device, General commands */ VPU_JSM_MSG_GENERAL_CMD = 0x1200, - VPU_JSM_MSG_BLOB_DEINIT = VPU_JSM_MSG_GENERAL_CMD, + VPU_JSM_MSG_BLOB_DEINIT_DEPRECATED = VPU_JSM_MSG_GENERAL_CMD, /** * Control dyndbg behavior by executing a dyndbg command; equivalent to * Linux command: `echo '<dyndbg_cmd>' > <debugfs>/dynamic_debug/control`. @@ -335,8 +544,12 @@ enum vpu_ipc_msg_type { * Perform the save procedure for the D0i3 entry */ VPU_JSM_MSG_PWR_D0I3_ENTER = 0x1202, + /* IPC Device -> Host, Job completion */ VPU_JSM_MSG_JOB_DONE = 0x2100, + /* IPC Device -> Host, Fence signalled */ + VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED = 0x2101, + /* IPC Device -> Host, Async command completion */ VPU_JSM_MSG_ASYNC_CMD_DONE = 0x2200, VPU_JSM_MSG_ENGINE_RESET_DONE = VPU_JSM_MSG_ASYNC_CMD_DONE, @@ -422,6 +635,7 @@ enum vpu_ipc_msg_type { * NOTE: Please introduce new ASYNC responses before this one. * */ VPU_JSM_MSG_STATE_DUMP_RSP = 0x22FF, + /* IPC Device -> Host, General command completion */ VPU_JSM_MSG_GENERAL_CMD_DONE = 0x2300, VPU_JSM_MSG_BLOB_DEINIT_DONE = VPU_JSM_MSG_GENERAL_CMD_DONE, @@ -600,11 +814,6 @@ struct vpu_jsm_metric_streamer_update { u64 next_buffer_size; }; -struct vpu_ipc_msg_payload_blob_deinit { - /* 64-bit unique ID for the blob to be de-initialized. */ - u64 blob_id; -}; - struct vpu_ipc_msg_payload_job_done { /* Engine to which the job was submitted. */ u32 engine_idx; @@ -622,6 +831,21 @@ struct vpu_ipc_msg_payload_job_done { u64 cmdq_id; }; +/* + * Notification message upon native fence signalling. + * @see VPU_JSM_MSG_NATIVE_FENCE_SIGNALLED + */ +struct vpu_ipc_msg_payload_native_fence_signalled { + /* Engine ID. */ + u32 engine_idx; + /* Host SSID. */ + u32 host_ssid; + /* CMDQ ID */ + u64 cmdq_id; + /* Fence object handle. */ + u64 fence_handle; +}; + struct vpu_jsm_engine_reset_context { /* Host SSID */ u32 host_ssid; @@ -700,11 +924,6 @@ struct vpu_ipc_msg_payload_get_power_level_count_done { u8 power_limit[16]; }; -struct vpu_ipc_msg_payload_blob_deinit_done { - /* 64-bit unique ID for the blob de-initialized. */ - u64 blob_id; -}; - /* HWS priority band setup request / response */ struct vpu_ipc_msg_payload_hws_priority_band_setup { /* @@ -794,7 +1013,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties { u32 reserved_0; /* Command queue id */ u64 cmdq_id; - /* Priority band to assign to work of this context */ + /* + * Priority band to assign to work of this context. + * Available priority bands: @see enum vpu_job_scheduling_priority_band + */ u32 priority_band; /* Inside realtime band assigns a further priority */ u32 realtime_priority_level; @@ -869,9 +1091,7 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log { */ u64 notify_index; /* - * Enable extra events to be output to log for debug of scheduling algorithm. - * Interpreted by VPU as a boolean to enable or disable, expected values are - * 0 and 1. + * Field is now deprecated, will be removed when KMD is updated to support removal */ u32 enable_extra_events; /* Zero Padding */ @@ -1243,10 +1463,10 @@ union vpu_ipc_msg_payload { struct vpu_jsm_metric_streamer_start metric_streamer_start; struct vpu_jsm_metric_streamer_stop metric_streamer_stop; struct vpu_jsm_metric_streamer_update metric_streamer_update; - struct vpu_ipc_msg_payload_blob_deinit blob_deinit; struct vpu_ipc_msg_payload_ssid_release ssid_release; struct vpu_jsm_hws_register_db hws_register_db; struct vpu_ipc_msg_payload_job_done job_done; + struct vpu_ipc_msg_payload_native_fence_signalled native_fence_signalled; struct vpu_ipc_msg_payload_engine_reset_done engine_reset_done; struct vpu_ipc_msg_payload_engine_preempt_done engine_preempt_done; struct vpu_ipc_msg_payload_register_db_done register_db_done; @@ -1254,7 +1474,6 @@ union vpu_ipc_msg_payload { struct vpu_ipc_msg_payload_query_engine_hb_done query_engine_hb_done; struct vpu_ipc_msg_payload_get_power_level_count_done get_power_level_count_done; struct vpu_jsm_metric_streamer_done metric_streamer_done; - struct vpu_ipc_msg_payload_blob_deinit_done blob_deinit_done; struct vpu_ipc_msg_payload_trace_config trace_config; struct vpu_ipc_msg_payload_trace_capability_rsp trace_capability; struct vpu_ipc_msg_payload_trace_get_name trace_get_name; -- GitLab From 3a3fb8110c65d361cd9d750c9e16520f740c93f2 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:52:53 +0200 Subject: [PATCH 809/970] accel/ivpu: Rename ivpu_log_level to fw_log_level Rename module param ivpu_log_level to fw_log_level, so it is clear what log level is actually changed. Reviewed-by: Maciej Falkowski <maciej.falkowski@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-3-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_fw.c | 4 ++-- drivers/accel/ivpu/ivpu_fw_log.c | 12 ++++++------ drivers/accel/ivpu/ivpu_fw_log.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index ede6165e09d9..00e27e2c1477 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -208,7 +208,7 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->cold_boot_entry_point = fw_hdr->entry_point; fw->entry_point = fw->cold_boot_entry_point; - fw->trace_level = min_t(u32, ivpu_log_level, IVPU_FW_LOG_FATAL); + fw->trace_level = min_t(u32, ivpu_fw_log_level, IVPU_FW_LOG_FATAL); fw->trace_destination_mask = VPU_TRACE_DESTINATION_VERBOSE_TRACING; fw->trace_hw_component_mask = -1; @@ -311,7 +311,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) goto err_free_fw_mem; } - if (ivpu_log_level <= IVPU_FW_LOG_INFO) + if (ivpu_fw_log_level <= IVPU_FW_LOG_INFO) log_verb_size = IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE; else log_verb_size = IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE; diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index ef0adb5e0fbe..2f2d3242f21b 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include <linux/ctype.h> @@ -15,12 +15,12 @@ #include "ivpu_fw_log.h" #include "ivpu_gem.h" -#define IVPU_FW_LOG_LINE_LENGTH 256 +#define IVPU_FW_LOG_LINE_LENGTH 256 -unsigned int ivpu_log_level = IVPU_FW_LOG_ERROR; -module_param(ivpu_log_level, uint, 0444); -MODULE_PARM_DESC(ivpu_log_level, - "NPU firmware default trace level: debug=" __stringify(IVPU_FW_LOG_DEBUG) +unsigned int ivpu_fw_log_level = IVPU_FW_LOG_ERROR; +module_param_named(fw_log_level, ivpu_fw_log_level, uint, 0444); +MODULE_PARM_DESC(fw_log_level, + "NPU firmware default log level: debug=" __stringify(IVPU_FW_LOG_DEBUG) " info=" __stringify(IVPU_FW_LOG_INFO) " warn=" __stringify(IVPU_FW_LOG_WARN) " error=" __stringify(IVPU_FW_LOG_ERROR) diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index 0b2573f6f315..ccef4298e45b 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #ifndef __IVPU_FW_LOG_H__ @@ -19,12 +19,12 @@ #define IVPU_FW_LOG_ERROR 4 #define IVPU_FW_LOG_FATAL 5 -extern unsigned int ivpu_log_level; - #define IVPU_FW_VERBOSE_BUFFER_SMALL_SIZE SZ_1M #define IVPU_FW_VERBOSE_BUFFER_LARGE_SIZE SZ_8M #define IVPU_FW_CRITICAL_BUFFER_SIZE SZ_512K +extern unsigned int ivpu_fw_log_level; + void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); void ivpu_fw_log_clear(struct ivpu_device *vdev); -- GitLab From 4b4d9e394b6f45ac26ac6144b31604c76b7e3705 Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Date: Mon, 30 Sep 2024 21:52:54 +0200 Subject: [PATCH 810/970] accel/ivpu: Reset fw log on cold boot Add ivpu_fw_log_reset() that resets the read_index of all FW logs on cold boot so logs are properly read. Signed-off-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-4-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_fw_log.c | 14 ++++++++++++++ drivers/accel/ivpu/ivpu_fw_log.h | 1 + drivers/accel/ivpu/ivpu_pm.c | 1 + 3 files changed, 16 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 2f2d3242f21b..817210e35f70 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -140,3 +140,17 @@ void ivpu_fw_log_clear(struct ivpu_device *vdev) while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) log_header->read_index = log_header->write_index; } + +void ivpu_fw_log_reset(struct ivpu_device *vdev) +{ + struct vpu_tracing_buffer_header *log_header; + u32 next; + + next = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) + log_header->read_index = 0; + + next = 0; + while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) + log_header->read_index = 0; +} diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index ccef4298e45b..a033ce2d642f 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -27,6 +27,7 @@ extern unsigned int ivpu_fw_log_level; void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); void ivpu_fw_log_clear(struct ivpu_device *vdev); +void ivpu_fw_log_reset(struct ivpu_device *vdev); static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) { diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 59d3170f5e35..3c36b55c01d5 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -37,6 +37,7 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev) ivpu_cmdq_reset_all_contexts(vdev); ivpu_ipc_reset(vdev); + ivpu_fw_log_reset(vdev); ivpu_fw_load(vdev); fw->entry_point = fw->cold_boot_entry_point; } -- GitLab From 1fc1251149a76d3b75d7f4c94d9c4e081b7df6b4 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:52:55 +0200 Subject: [PATCH 811/970] accel/ivpu: Refactor functions in ivpu_fw_log.c Make function names more consistent and (arguably) readable in fw log code. Add fw_log_print_all_in_bo() that remove duplicated code in ivpu_fw_log_print(). Reviewed-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-5-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_debugfs.c | 2 +- drivers/accel/ivpu/ivpu_fw_log.c | 62 ++++++++++++++++--------------- drivers/accel/ivpu/ivpu_fw_log.h | 2 +- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 6f86f8df30db..cd3ac08f0409 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -192,7 +192,7 @@ fw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, l if (!size) return -EINVAL; - ivpu_fw_log_clear(vdev); + ivpu_fw_log_mark_read(vdev); return size; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 817210e35f70..343ebfd30d28 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -26,8 +26,8 @@ MODULE_PARM_DESC(fw_log_level, " error=" __stringify(IVPU_FW_LOG_ERROR) " fatal=" __stringify(IVPU_FW_LOG_FATAL)); -static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, - struct vpu_tracing_buffer_header **log_header) +static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, + struct vpu_tracing_buffer_header **out_log) { struct vpu_tracing_buffer_header *log; @@ -48,7 +48,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, return -EINVAL; } - *log_header = log; + *out_log = log; *offset += log->size; ivpu_dbg(vdev, FW_BOOT, @@ -59,7 +59,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, return 0; } -static void buffer_print(char *buffer, u32 size, struct drm_printer *p) +static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) { char line[IVPU_FW_LOG_LINE_LENGTH]; u32 index = 0; @@ -90,11 +90,11 @@ static void buffer_print(char *buffer, u32 size, struct drm_printer *p) drm_printf(p, "%s\n", line); } -static void fw_log_print_buffer(struct ivpu_device *vdev, struct vpu_tracing_buffer_header *log, - const char *prefix, bool only_new_msgs, struct drm_printer *p) +static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix, + bool only_new_msgs, struct drm_printer *p) { - char *log_buffer = (void *)log + log->header_size; - u32 log_size = log->size - log->header_size; + char *log_data = (void *)log + log->header_size; + u32 data_size = log->size - log->header_size; u32 log_start = log->read_index; u32 log_end = log->write_index; @@ -106,51 +106,55 @@ static void fw_log_print_buffer(struct ivpu_device *vdev, struct vpu_tracing_buf drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name); if (log->write_index > log->read_index) { - buffer_print(log_buffer + log_start, log_end - log_start, p); + fw_log_print_lines(log_data + log_start, log_end - log_start, p); } else { - buffer_print(log_buffer + log_end, log_size - log_end, p); - buffer_print(log_buffer, log_end, p); + fw_log_print_lines(log_data + log_end, data_size - log_end, p); + fw_log_print_lines(log_data, log_end, p); } drm_printf(p, "\x1b[0m"); drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name); } -void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p) +static void +fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name, + struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p) { - struct vpu_tracing_buffer_header *log_header; + struct vpu_tracing_buffer_header *log; u32 next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - fw_log_print_buffer(vdev, log_header, "NPU critical", only_new_msgs, p); + while (fw_log_from_bo(vdev, bo, &next, &log) == 0) + fw_log_print_buffer(log, name, only_new_msgs, p); +} - next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - fw_log_print_buffer(vdev, log_header, "NPU verbose", only_new_msgs, p); +void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p) +{ + fw_log_print_all_in_bo(vdev, "NPU critical", vdev->fw->mem_log_crit, only_new_msgs, p); + fw_log_print_all_in_bo(vdev, "NPU verbose", vdev->fw->mem_log_verb, only_new_msgs, p); } -void ivpu_fw_log_clear(struct ivpu_device *vdev) +void ivpu_fw_log_mark_read(struct ivpu_device *vdev) { - struct vpu_tracing_buffer_header *log_header; + struct vpu_tracing_buffer_header *log; u32 next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - log_header->read_index = log_header->write_index; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + log->read_index = log->write_index; next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - log_header->read_index = log_header->write_index; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + log->read_index = log->write_index; } void ivpu_fw_log_reset(struct ivpu_device *vdev) { - struct vpu_tracing_buffer_header *log_header; + struct vpu_tracing_buffer_header *log; u32 next; next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_crit, &next, &log_header) == 0) - log_header->read_index = 0; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + log->read_index = 0; next = 0; - while (fw_log_ptr(vdev, vdev->fw->mem_log_verb, &next, &log_header) == 0) - log_header->read_index = 0; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + log->read_index = 0; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index a033ce2d642f..41c85b74cc7f 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -26,7 +26,7 @@ extern unsigned int ivpu_fw_log_level; void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p); -void ivpu_fw_log_clear(struct ivpu_device *vdev); +void ivpu_fw_log_mark_read(struct ivpu_device *vdev); void ivpu_fw_log_reset(struct ivpu_device *vdev); static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) -- GitLab From 4bc988b47019536b3b1f7d9c5b83893c712d94d6 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:52:56 +0200 Subject: [PATCH 812/970] accel/ivpu: Fix fw log printing - Fix empty log detection that couldn't work without read_wrap_count - Start printing wrapped log from correct position (log_start) - Properly handle logs that are wrapped multiple times in reference to reader position - Don't add a newline when log buffer is wrapped - Always add a newline after printing a log buffer in case log does not end with one Reviewed-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-6-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_fw_log.c | 49 +++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 343ebfd30d28..337c906b0210 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -87,7 +87,7 @@ static void fw_log_print_lines(char *buffer, u32 size, struct drm_printer *p) } line[index] = 0; if (index != 0) - drm_printf(p, "%s\n", line); + drm_printf(p, "%s", line); } static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix, @@ -95,23 +95,29 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha { char *log_data = (void *)log + log->header_size; u32 data_size = log->size - log->header_size; - u32 log_start = log->read_index; - u32 log_end = log->write_index; + u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0; + u32 log_end = READ_ONCE(log->write_index); - if (!(log->write_index || log->wrap_count) || - (log->write_index == log->read_index && only_new_msgs)) { - drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); - return; + if (log->wrap_count == log->read_wrap_count) { + if (log_end <= log_start) { + drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); + return; + } + } else if (log->wrap_count == log->read_wrap_count + 1) { + if (log_end > log_start) + log_start = log_end; + } else { + log_start = log_end; } drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name); - if (log->write_index > log->read_index) { + if (log_end > log_start) { fw_log_print_lines(log_data + log_start, log_end - log_start, p); } else { - fw_log_print_lines(log_data + log_end, data_size - log_end, p); + fw_log_print_lines(log_data + log_start, data_size - log_start, p); fw_log_print_lines(log_data, log_end, p); } - drm_printf(p, "\x1b[0m"); + drm_printf(p, "\n\x1b[0m"); /* add new line and clear formatting */ drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name); } @@ -135,14 +141,19 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_ void ivpu_fw_log_mark_read(struct ivpu_device *vdev) { struct vpu_tracing_buffer_header *log; - u32 next = 0; + u32 next; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) - log->read_index = log->write_index; + next = 0; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) { + log->read_index = READ_ONCE(log->write_index); + log->read_wrap_count = READ_ONCE(log->wrap_count); + } next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) - log->read_index = log->write_index; + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) { + log->read_index = READ_ONCE(log->write_index); + log->read_wrap_count = READ_ONCE(log->wrap_count); + } } void ivpu_fw_log_reset(struct ivpu_device *vdev) @@ -151,10 +162,14 @@ void ivpu_fw_log_reset(struct ivpu_device *vdev) u32 next; next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) + while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) { log->read_index = 0; + log->read_wrap_count = 0; + } next = 0; - while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) + while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) { log->read_index = 0; + log->read_wrap_count = 0; + } } -- GitLab From 990b1e3d150104249115a0ad81ea77c53b28f0f8 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:52:57 +0200 Subject: [PATCH 813/970] accel/ivpu: Limit FW version string length Limit FW version string, when parsing FW binary, to 256 bytes and always add NULL-terminate it. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-7-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_fw.c | 7 ++++--- drivers/accel/ivpu/ivpu_fw.h | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 00e27e2c1477..7e8593c831ec 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -25,7 +25,6 @@ #define FW_SHAVE_NN_MAX_SIZE SZ_2M #define FW_RUNTIME_MIN_ADDR (FW_GLOBAL_MEM_START) #define FW_RUNTIME_MAX_ADDR (FW_GLOBAL_MEM_END - FW_SHARED_MEM_SIZE) -#define FW_VERSION_HEADER_SIZE SZ_4K #define FW_FILE_IMAGE_OFFSET (VPU_FW_HEADER_SIZE + FW_VERSION_HEADER_SIZE) #define WATCHDOG_MSS_REDIRECT 32 @@ -191,8 +190,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n", fw_hdr->header_version, fw_hdr->image_format); - ivpu_info(vdev, "Firmware: %s, version: %s", fw->name, - (const char *)fw_hdr + VPU_FW_HEADER_SIZE); + if (!scnprintf(fw->version, sizeof(fw->version), "%s", fw->file->data + VPU_FW_HEADER_SIZE)) + ivpu_warn(vdev, "Missing firmware version\n"); + + ivpu_info(vdev, "Firmware: %s, version: %s\n", fw->name, fw->version); if (IVPU_FW_CHECK_API_COMPAT(vdev, fw_hdr, BOOT, 3)) return -EINVAL; diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 40d9d17be3f5..5e8eb608b70f 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #ifndef __IVPU_FW_H__ #define __IVPU_FW_H__ +#define FW_VERSION_HEADER_SIZE SZ_4K +#define FW_VERSION_STR_SIZE SZ_256 + struct ivpu_device; struct ivpu_bo; struct vpu_boot_params; @@ -13,6 +16,7 @@ struct vpu_boot_params; struct ivpu_fw_info { const struct firmware *file; const char *name; + char version[FW_VERSION_STR_SIZE]; struct ivpu_bo *mem; struct ivpu_bo *mem_shave_nn; struct ivpu_bo *mem_log_crit; -- GitLab From bade0340526827d03d9c293450c0422beba77f04 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:52:58 +0200 Subject: [PATCH 814/970] accel/ivpu: Add coredump support Use coredump (if available) to collect FW logs in case of a FW crash. This makes dmesg more readable and allows to collect more log data. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-8-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/Kconfig | 1 + drivers/accel/ivpu/Makefile | 1 + drivers/accel/ivpu/ivpu_coredump.c | 39 ++++++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_coredump.h | 25 +++++++++++++++++++ drivers/accel/ivpu/ivpu_drv.c | 5 ++-- drivers/accel/ivpu/ivpu_fw_log.h | 8 ------ drivers/accel/ivpu/ivpu_pm.c | 9 ++++--- 7 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 drivers/accel/ivpu/ivpu_coredump.c create mode 100644 drivers/accel/ivpu/ivpu_coredump.h diff --git a/drivers/accel/ivpu/Kconfig b/drivers/accel/ivpu/Kconfig index 682c53245286..e4d418b44626 100644 --- a/drivers/accel/ivpu/Kconfig +++ b/drivers/accel/ivpu/Kconfig @@ -8,6 +8,7 @@ config DRM_ACCEL_IVPU select FW_LOADER select DRM_GEM_SHMEM_HELPER select GENERIC_ALLOCATOR + select WANT_DEV_COREDUMP help Choose this option if you have a system with an 14th generation Intel CPU (Meteor Lake) or newer. Intel NPU (formerly called Intel VPU) diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index ebd682a42eb1..232ea6d28c6e 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -19,5 +19,6 @@ intel_vpu-y := \ ivpu_sysfs.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o +intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o diff --git a/drivers/accel/ivpu/ivpu_coredump.c b/drivers/accel/ivpu/ivpu_coredump.c new file mode 100644 index 000000000000..16ad0c30818c --- /dev/null +++ b/drivers/accel/ivpu/ivpu_coredump.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#include <linux/devcoredump.h> +#include <linux/firmware.h> + +#include "ivpu_coredump.h" +#include "ivpu_fw.h" +#include "ivpu_gem.h" +#include "vpu_boot_api.h" + +#define CRASH_DUMP_HEADER "Intel NPU crash dump" +#define CRASH_DUMP_HEADERS_SIZE SZ_4K + +void ivpu_dev_coredump(struct ivpu_device *vdev) +{ + struct drm_print_iterator pi = {}; + struct drm_printer p; + size_t coredump_size; + char *coredump; + + coredump_size = CRASH_DUMP_HEADERS_SIZE + FW_VERSION_HEADER_SIZE + + ivpu_bo_size(vdev->fw->mem_log_crit) + ivpu_bo_size(vdev->fw->mem_log_verb); + coredump = vmalloc(coredump_size); + if (!coredump) + return; + + pi.data = coredump; + pi.remain = coredump_size; + p = drm_coredump_printer(&pi); + + drm_printf(&p, "%s\n", CRASH_DUMP_HEADER); + drm_printf(&p, "FW version: %s\n", vdev->fw->version); + ivpu_fw_log_print(vdev, false, &p); + + dev_coredumpv(vdev->drm.dev, coredump, pi.offset, GFP_KERNEL); +} diff --git a/drivers/accel/ivpu/ivpu_coredump.h b/drivers/accel/ivpu/ivpu_coredump.h new file mode 100644 index 000000000000..8efb09d02441 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_coredump.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#ifndef __IVPU_COREDUMP_H__ +#define __IVPU_COREDUMP_H__ + +#include <drm/drm_print.h> + +#include "ivpu_drv.h" +#include "ivpu_fw_log.h" + +#ifdef CONFIG_DEV_COREDUMP +void ivpu_dev_coredump(struct ivpu_device *vdev); +#else +static inline void ivpu_dev_coredump(struct ivpu_device *vdev) +{ + struct drm_printer p = drm_info_printer(vdev->drm.dev); + + ivpu_fw_log_print(vdev, false, &p); +} +#endif + +#endif /* __IVPU_COREDUMP_H__ */ diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index c91400ecf926..38b4158f5278 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -14,7 +14,7 @@ #include <drm/drm_ioctl.h> #include <drm/drm_prime.h> -#include "vpu_boot_api.h" +#include "ivpu_coredump.h" #include "ivpu_debugfs.h" #include "ivpu_drv.h" #include "ivpu_fw.h" @@ -29,6 +29,7 @@ #include "ivpu_ms.h" #include "ivpu_pm.h" #include "ivpu_sysfs.h" +#include "vpu_boot_api.h" #ifndef DRIVER_VERSION_STR #define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ @@ -382,7 +383,7 @@ int ivpu_boot(struct ivpu_device *vdev) ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); ivpu_hw_diagnose_failure(vdev); ivpu_mmu_evtq_dump(vdev); - ivpu_fw_log_dump(vdev); + ivpu_dev_coredump(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_fw_log.h b/drivers/accel/ivpu/ivpu_fw_log.h index 41c85b74cc7f..8bb528a73cb7 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.h +++ b/drivers/accel/ivpu/ivpu_fw_log.h @@ -8,8 +8,6 @@ #include <linux/types.h> -#include <drm/drm_print.h> - #include "ivpu_drv.h" #define IVPU_FW_LOG_DEFAULT 0 @@ -29,11 +27,5 @@ void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_ void ivpu_fw_log_mark_read(struct ivpu_device *vdev); void ivpu_fw_log_reset(struct ivpu_device *vdev); -static inline void ivpu_fw_log_dump(struct ivpu_device *vdev) -{ - struct drm_printer p = drm_info_printer(vdev->drm.dev); - - ivpu_fw_log_print(vdev, false, &p); -} #endif /* __IVPU_FW_LOG_H__ */ diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 3c36b55c01d5..bf77395ffcb7 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -9,17 +9,18 @@ #include <linux/pm_runtime.h> #include <linux/reboot.h> -#include "vpu_boot_api.h" +#include "ivpu_coredump.h" #include "ivpu_drv.h" -#include "ivpu_hw.h" #include "ivpu_fw.h" #include "ivpu_fw_log.h" +#include "ivpu_hw.h" #include "ivpu_ipc.h" #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_mmu.h" #include "ivpu_ms.h" #include "ivpu_pm.h" +#include "vpu_boot_api.h" static bool ivpu_disable_recovery; module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); @@ -124,7 +125,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work) if (ret) ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); - ivpu_fw_log_dump(vdev); + ivpu_dev_coredump(vdev); atomic_inc(&vdev->pm->reset_counter); atomic_set(&vdev->pm->reset_pending, 1); @@ -263,7 +264,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) if (!is_idle || ret_d0i3) { ivpu_err(vdev, "Forcing cold boot due to previous errors\n"); atomic_inc(&vdev->pm->reset_counter); - ivpu_fw_log_dump(vdev); + ivpu_dev_coredump(vdev); ivpu_pm_prepare_cold_boot(vdev); } else { ivpu_pm_prepare_warm_boot(vdev); -- GitLab From 5e162f872d7af8f041b143536617ab2563ea7de5 Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Date: Mon, 30 Sep 2024 21:52:59 +0200 Subject: [PATCH 815/970] accel/ivpu: Add FW state dump on TDR Send JSM state dump message at the beginning of TDR handler. This allows FW to collect debug info in the FW log before the state of the NPU is lost allowing to analyze the cause of a TDR. Wait a predefined timeout (10 ms) so the FW has a chance to write debug logs. We cannot wait for JSM response at this point because IRQs are already disabled before TDR handler is invoked. Signed-off-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-9-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.h | 1 + drivers/accel/ivpu/ivpu_hw.c | 3 +++ drivers/accel/ivpu/ivpu_ipc.c | 26 ++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_ipc.h | 2 ++ drivers/accel/ivpu/ivpu_jsm_msg.c | 8 ++++++++ drivers/accel/ivpu/ivpu_jsm_msg.h | 2 ++ drivers/accel/ivpu/ivpu_pm.c | 1 + 7 files changed, 43 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 63f13b697eed..2b30cc2e9272 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -152,6 +152,7 @@ struct ivpu_device { int tdr; int autosuspend; int d0i3_entry_msg; + int state_dump_msg; } timeout; }; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 27f0fe4d54e0..85219e959621 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -89,12 +89,14 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.tdr = 2000000; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 500; + vdev->timeout.state_dump_msg = 10; } else if (ivpu_is_simics(vdev)) { vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 100; + vdev->timeout.state_dump_msg = 10; } else { vdev->timeout.boot = 1000; vdev->timeout.jsm = 500; @@ -104,6 +106,7 @@ static void timeouts_init(struct ivpu_device *vdev) else vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 5; + vdev->timeout.state_dump_msg = 10; } } diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 78b32a823241..83b4ba4f3e20 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -364,6 +364,32 @@ int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, return ret; } +int ivpu_ipc_send_and_wait(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + u32 channel, unsigned long timeout_ms) +{ + struct ivpu_ipc_consumer cons; + int ret; + + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + + ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); + + ret = ivpu_ipc_send(vdev, &cons, req); + if (ret) { + ivpu_warn_ratelimited(vdev, "IPC send failed: %d\n", ret); + goto consumer_del; + } + + msleep(timeout_ms); + +consumer_del: + ivpu_ipc_consumer_del(vdev, &cons); + ivpu_rpm_put(vdev); + return ret; +} + static bool ivpu_ipc_match_consumer(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_hdr, struct vpu_jsm_msg *jsm_msg) diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index 4fe38141045e..6bbe6e32c874 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -108,5 +108,7 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); +int ivpu_ipc_send_and_wait(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + u32 channel, unsigned long timeout_ms); #endif /* __IVPU_IPC_H__ */ diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index b06da8f50fd3..cd33964d292b 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -559,3 +559,11 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } + +int ivpu_jsm_state_dump(struct ivpu_device *vdev) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_STATE_DUMP }; + + return ivpu_ipc_send_and_wait(vdev, &req, VPU_IPC_CHAN_ASYNC_CMD, + vdev->timeout.state_dump_msg); +} diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h index e4e42c0ff6e6..9e84d3526a14 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.h +++ b/drivers/accel/ivpu/ivpu_jsm_msg.h @@ -43,4 +43,6 @@ int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mas u64 buffer_size, u32 *sample_size, u64 *info_size); int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us); int ivpu_jsm_dct_disable(struct ivpu_device *vdev); +int ivpu_jsm_state_dump(struct ivpu_device *vdev); + #endif diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index bf77395ffcb7..b5a69941e6e0 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -125,6 +125,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work) if (ret) ivpu_err(vdev, "Failed to resume NPU: %d\n", ret); + ivpu_jsm_state_dump(vdev); ivpu_dev_coredump(vdev); atomic_inc(&vdev->pm->reset_counter); -- GitLab From 525a3858aad73a42683783eee1b462cf8d4076d0 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:00 +0200 Subject: [PATCH 816/970] accel/ivpu: Set 500 ns delay between power island TRICKLE and ENABLE Follow HW documentation recommendation of 500 ns delay between setting AON_PWR_ISLAND_TRICKLE_EN and AON_PWR_ISLAND_EN registers during power island enabling. Previously this was only done correctly for VPU 4+. VPU 3.7 had the delay added after power island disable where it is not needed. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-10-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_hw_ip.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index dfd2f4a5b526..cfcbb99168e6 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -311,9 +311,6 @@ static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val); REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val); - - if (enable) - ndelay(500); } static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable) @@ -326,9 +323,6 @@ static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val); REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val); - - if (!enable) - ndelay(500); } static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable) @@ -347,9 +341,11 @@ static void pwr_island_enable(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { pwr_island_trickle_drive_37xx(vdev, true); + ndelay(500); pwr_island_drive_37xx(vdev, true); } else { pwr_island_trickle_drive_40xx(vdev, true); + ndelay(500); pwr_island_drive_40xx(vdev, true); } } -- GitLab From 03b3b6657db541e41620050816c55f1750f07bd4 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:01 +0200 Subject: [PATCH 817/970] accel/ivpu: Turn on autosuspend on Simics With recent Simics update DVFS flows using cdyn were fixed and it is possible to enable D0i3/D3 entry flows on autosuspend. Set autosuspend timeout to 100 ms by default on Simics. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-11-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 85219e959621..1c259d717815 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -94,7 +94,7 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; - vdev->timeout.autosuspend = -1; + vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 100; vdev->timeout.state_dump_msg = 10; } else { -- GitLab From 2baf2143dd406ce7ffb847a03ad40e3cc99322fa Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:02 +0200 Subject: [PATCH 818/970] accel/ivpu: Add FW version debugfs entry Add debugfs that prints current firmware version string on read. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-12-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_debugfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index cd3ac08f0409..55dc2d883b44 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -45,6 +45,14 @@ static int fw_name_show(struct seq_file *s, void *v) return 0; } +static int fw_version_show(struct seq_file *s, void *v) +{ + struct ivpu_device *vdev = seq_to_ivpu(s); + + seq_printf(s, "%s\n", vdev->fw->version); + return 0; +} + static int fw_trace_capability_show(struct seq_file *s, void *v) { struct ivpu_device *vdev = seq_to_ivpu(s); @@ -111,6 +119,7 @@ static int reset_pending_show(struct seq_file *s, void *v) static const struct drm_debugfs_info vdev_debugfs_list[] = { {"bo_list", bo_list_show, 0}, {"fw_name", fw_name_show, 0}, + {"fw_version", fw_version_show, 0}, {"fw_trace_capability", fw_trace_capability_show, 0}, {"fw_trace_config", fw_trace_config_show, 0}, {"last_bootmode", last_bootmode_show, 0}, -- GitLab From e38501cee5364aeb3bd265b484a8e47baa6634aa Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:03 +0200 Subject: [PATCH 819/970] accel/ivpu: Stop using hardcoded DRIVER_DATE Hardcoded driver date is useless, so use kernel version as a driver date to make identifying .ko file easier. Also allow to pass DRIVER_DATE on build time to allow versioning the driver in case it is built out of the tree. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-13-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.c | 15 +++++++++++---- drivers/accel/ivpu/ivpu_drv.h | 1 - include/uapi/drm/ivpu_accel.h | 3 --- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 38b4158f5278..9fd371af5814 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -7,6 +7,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/pm_runtime.h> +#include <generated/utsrelease.h> #include <drm/drm_accel.h> #include <drm/drm_file.h> @@ -32,8 +33,7 @@ #include "vpu_boot_api.h" #ifndef DRIVER_VERSION_STR -#define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \ - __stringify(DRM_IVPU_DRIVER_MINOR) "." +#define DRIVER_VERSION_STR "1.0.0 " UTS_RELEASE #endif static struct lock_class_key submitted_jobs_xa_lock_class_key; @@ -447,9 +447,16 @@ static const struct drm_driver driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, + +#ifdef DRIVER_DATE .date = DRIVER_DATE, - .major = DRM_IVPU_DRIVER_MAJOR, - .minor = DRM_IVPU_DRIVER_MINOR, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +#else + .date = UTS_RELEASE, + .major = 1, +#endif }; static void ivpu_context_abort_invalid(struct ivpu_device *vdev) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 2b30cc2e9272..471478281021 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -21,7 +21,6 @@ #define DRIVER_NAME "intel_vpu" #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" -#define DRIVER_DATE "20230117" #define PCI_DEVICE_ID_MTL 0x7d1d #define PCI_DEVICE_ID_ARL 0xad1d diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 084fb529e1e9..234664d35250 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -12,9 +12,6 @@ extern "C" { #endif -#define DRM_IVPU_DRIVER_MAJOR 1 -#define DRM_IVPU_DRIVER_MINOR 0 - #define DRM_IVPU_GET_PARAM 0x00 #define DRM_IVPU_SET_PARAM 0x01 #define DRM_IVPU_BO_CREATE 0x02 -- GitLab From 378ed3b64d5409fa602e05f7ff49dfb4b08ff747 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:04 +0200 Subject: [PATCH 820/970] accel/ivpu: Remove 1-tile power up Simics workaround Previously Simics was not providing workpoint for configurations with 0 tiles enabled, that had to be worked around in the KMD. This got fixed in Simics and workaround is no longer needed. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-14-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_hw_btrs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 745e5248803d..cad2ce7f2e24 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -315,10 +315,6 @@ static void prepare_wp_request(struct ivpu_device *vdev, struct wp_request *wp, wp->cdyn = enable ? PLL_CDYN_DEFAULT : 0; wp->epp = enable ? PLL_EPP_DEFAULT : 0; } - - /* Simics cannot start without at least one tile */ - if (enable && ivpu_is_simics(vdev)) - wp->cfg = 1; } static int wait_for_pll_lock(struct ivpu_device *vdev, bool enable) -- GitLab From 9f3814e822133b9001d8deb7d3903e2adb656819 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Date: Mon, 30 Sep 2024 21:53:05 +0200 Subject: [PATCH 821/970] accel/ivpu: Allow reading dvfs_mode debugfs file Make the dvfs_mode read-write to allow checking current mode. Simplify the dvfs_mode implementation with the DEFINE_DEBUGFS_ATTRIBUTE. Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-15-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_debugfs.c | 33 +++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 55dc2d883b44..f873119e56fe 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -127,32 +127,23 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { {"reset_pending", reset_pending_show, 0}, }; -static ssize_t -dvfs_mode_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) +static int dvfs_mode_get(void *data, u64 *dvfs_mode) { - struct ivpu_device *vdev = file->private_data; - struct ivpu_fw_info *fw = vdev->fw; - u32 dvfs_mode; - int ret; + struct ivpu_device *vdev = (struct ivpu_device *)data; - ret = kstrtou32_from_user(user_buf, size, 0, &dvfs_mode); - if (ret < 0) - return ret; - - fw->dvfs_mode = dvfs_mode; + *dvfs_mode = vdev->fw->dvfs_mode; + return 0; +} - ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); - if (ret) - return ret; +static int dvfs_mode_set(void *data, u64 dvfs_mode) +{ + struct ivpu_device *vdev = (struct ivpu_device *)data; - return size; + vdev->fw->dvfs_mode = (u32)dvfs_mode; + return pci_try_reset_function(to_pci_dev(vdev->drm.dev)); } -static const struct file_operations dvfs_mode_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .write = dvfs_mode_fops_write, -}; +DEFINE_DEBUGFS_ATTRIBUTE(dvfs_mode_fops, dvfs_mode_get, dvfs_mode_set, "%llu\n"); static ssize_t fw_dyndbg_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) @@ -432,7 +423,7 @@ void ivpu_debugfs_init(struct ivpu_device *vdev) debugfs_create_file("force_recovery", 0200, debugfs_root, vdev, &ivpu_force_recovery_fops); - debugfs_create_file("dvfs_mode", 0200, debugfs_root, vdev, + debugfs_create_file("dvfs_mode", 0644, debugfs_root, vdev, &dvfs_mode_fops); debugfs_create_file("fw_dyndbg", 0200, debugfs_root, vdev, -- GitLab From 707542dd1a56d23387dbf978bf107793840310cc Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:06 +0200 Subject: [PATCH 822/970] accel/ivpu: Add one jiffy to bo_wait_ioctl timeout value Add one jiffy to ensure wait function never times out before intended timeout value, which could happen if absolute timeout value is less than (1s / CONFIG_HZ) in the future. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-16-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index 1b409dbd332d..d8e97a760fbc 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -384,6 +384,9 @@ int ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file timeout = drm_timeout_abs_to_jiffies(args->timeout_ns); + /* Add 1 jiffy to ensure the wait function never times out before intended timeout_ns */ + timeout += 1; + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -EINVAL; -- GitLab From 436b67d6936b5658426e40d0df8f147239bc532b Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:07 +0200 Subject: [PATCH 823/970] accel/ivpu: Add auto selection logic for job scheduler Add ivpu_fw_sched_mode_select() function that can select scheduling mode based on HW and FW versions. This prepares for a switch to HWS on selected platforms. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-17-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.c | 6 +++--- drivers/accel/ivpu/ivpu_drv.h | 2 ++ drivers/accel/ivpu/ivpu_fw.c | 15 +++++++++++++-- drivers/accel/ivpu/ivpu_fw.h | 3 +++ drivers/accel/ivpu/ivpu_hw.h | 1 - drivers/accel/ivpu/ivpu_hw_btrs.c | 2 -- drivers/accel/ivpu/ivpu_job.c | 14 +++++++------- drivers/accel/ivpu/ivpu_sysfs.c | 24 ++++++++++++++++++++++++ 8 files changed, 52 insertions(+), 15 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 9fd371af5814..fcf26e6d4e9c 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -54,9 +54,9 @@ u8 ivpu_pll_max_ratio = U8_MAX; module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644); MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set NPU frequency"); -int ivpu_sched_mode; +int ivpu_sched_mode = IVPU_SCHED_MODE_AUTO; module_param_named(sched_mode, ivpu_sched_mode, int, 0444); -MODULE_PARM_DESC(sched_mode, "Scheduler mode: 0 - Default scheduler, 1 - Force HW scheduler"); +MODULE_PARM_DESC(sched_mode, "Scheduler mode: -1 - Use default scheduler, 0 - Use OS scheduler, 1 - Use HW scheduler"); bool ivpu_disable_mmu_cont_pages; module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444); @@ -347,7 +347,7 @@ static int ivpu_hw_sched_init(struct ivpu_device *vdev) { int ret = 0; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_jsm_hws_setup_priority_bands(vdev); if (ret) { ivpu_err(vdev, "Failed to enable hw scheduler: %d", ret); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 471478281021..c4bd8757f8de 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -56,6 +56,8 @@ #define IVPU_PLATFORM_FPGA 3 #define IVPU_PLATFORM_INVALID 8 +#define IVPU_SCHED_MODE_AUTO -1 + #define IVPU_DBG_REG BIT(0) #define IVPU_DBG_IRQ BIT(1) #define IVPU_DBG_MMU BIT(2) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 7e8593c831ec..4d59dd19f684 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -134,6 +134,15 @@ static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range return true; } +static u32 +ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr) +{ + if (ivpu_sched_mode != IVPU_SCHED_MODE_AUTO) + return ivpu_sched_mode; + + return VPU_SCHEDULING_MODE_OS; +} + static int ivpu_fw_parse(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; @@ -215,8 +224,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) fw->dvfs_mode = 0; + fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr); fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size; fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size; + ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS"); if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address, fw_hdr->ro_section_size, @@ -605,8 +616,8 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->punit_telemetry_sram_base = ivpu_hw_telemetry_offset_get(vdev); boot_params->punit_telemetry_sram_size = ivpu_hw_telemetry_size_get(vdev); boot_params->vpu_telemetry_enable = ivpu_hw_telemetry_enable_get(vdev); - boot_params->vpu_scheduling_mode = vdev->hw->sched_mode; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) + boot_params->vpu_scheduling_mode = vdev->fw->sched_mode; + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) boot_params->vpu_focus_present_timer_ms = IVPU_FOCUS_PRESENT_TIMER_MS; boot_params->dvfs_mode = vdev->fw->dvfs_mode; if (!IVPU_WA(disable_d0i3_msg)) diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h index 5e8eb608b70f..1d0b2bd9d65c 100644 --- a/drivers/accel/ivpu/ivpu_fw.h +++ b/drivers/accel/ivpu/ivpu_fw.h @@ -6,6 +6,8 @@ #ifndef __IVPU_FW_H__ #define __IVPU_FW_H__ +#include "vpu_jsm_api.h" + #define FW_VERSION_HEADER_SIZE SZ_4K #define FW_VERSION_STR_SIZE SZ_256 @@ -36,6 +38,7 @@ struct ivpu_fw_info { u32 secondary_preempt_buf_size; u64 read_only_addr; u32 read_only_size; + u32 sched_mode; }; int ivpu_fw_init(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h index 1c0c98e3afb8..dc5518248c40 100644 --- a/drivers/accel/ivpu/ivpu_hw.h +++ b/drivers/accel/ivpu/ivpu_hw.h @@ -46,7 +46,6 @@ struct ivpu_hw_info { u32 profiling_freq; } pll; u32 tile_fuse; - u32 sched_mode; u32 sku; u16 config; int dma_bits; diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index cad2ce7f2e24..7dc8e333dcec 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -163,7 +163,6 @@ static int info_init_mtl(struct ivpu_device *vdev) hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH; hw->sku = BTRS_MTL_TILE_SKU_BOTH; hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO; - hw->sched_mode = ivpu_sched_mode; return 0; } @@ -178,7 +177,6 @@ static int info_init_lnl(struct ivpu_device *vdev) if (ret) return ret; - hw->sched_mode = ivpu_sched_mode; hw->tile_fuse = tile_fuse_config; hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index b00634af8bc3..b1abdca5891c 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -37,7 +37,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); struct ivpu_addr_range range; - if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX); @@ -68,7 +68,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) { - if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return; drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf); @@ -149,7 +149,7 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * struct ivpu_device *vdev = file_priv->vdev; int ret; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); else @@ -184,7 +184,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng jobq_header->tail = 0; wmb(); /* Flush WC buffer for jobq->header */ - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority); if (ret) return ret; @@ -211,7 +211,7 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm cmdq->db_registered = false; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id); if (!ret) ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id); @@ -335,7 +335,7 @@ void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) ivpu_cmdq_fini_all(file_priv); - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS) + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_OS) ivpu_jsm_context_release(vdev, file_priv->ctx.id); } @@ -361,7 +361,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW && + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c index 913669f1786e..616477fc17fa 100644 --- a/drivers/accel/ivpu/ivpu_sysfs.c +++ b/drivers/accel/ivpu/ivpu_sysfs.c @@ -6,6 +6,8 @@ #include <linux/device.h> #include <linux/err.h> +#include "ivpu_drv.h" +#include "ivpu_fw.h" #include "ivpu_hw.h" #include "ivpu_sysfs.h" @@ -39,8 +41,30 @@ npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *b static DEVICE_ATTR_RO(npu_busy_time_us); +/** + * DOC: sched_mode + * + * The sched_mode is used to report current NPU scheduling mode. + * + * It returns following strings: + * - "HW" - Hardware Scheduler mode + * - "OS" - Operating System Scheduler mode + * + */ +static ssize_t +sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct drm_device *drm = dev_get_drvdata(dev); + struct ivpu_device *vdev = to_ivpu_device(drm); + + return sysfs_emit(buf, "%s\n", vdev->fw->sched_mode ? "HW" : "OS"); +} + +static DEVICE_ATTR_RO(sched_mode); + static struct attribute *ivpu_dev_attrs[] = { &dev_attr_npu_busy_time_us.attr, + &dev_attr_sched_mode.attr, NULL, }; -- GitLab From 3886f9440aa3a5b55f2f2030f8a6fdab5b41fbd1 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:08 +0200 Subject: [PATCH 824/970] accel/ivpu: Print JSM message result in case of error Change debug message to error level in case of receiving non-successful result of JSM message. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-18-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 83b4ba4f3e20..e7bccc20e4e4 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -278,7 +278,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) { - ivpu_dbg(vdev, IPC, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); + ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); ret = -EBADMSG; } -- GitLab From c3b0ec0fe0c7ebc4eb42ba60f7340ecdb7aae1a2 Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Date: Mon, 30 Sep 2024 21:53:09 +0200 Subject: [PATCH 825/970] accel/ivpu: Make DB_ID and JOB_ID allocations incremental Save last used ID and use it to limit the possible values for the ID. This should decrease the rate at which the IDs are reused, which will make debugging easier. Signed-off-by: Tomasz Rusinowicz <tomasz.rusinowicz@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-19-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.c | 9 +++++++++ drivers/accel/ivpu/ivpu_drv.h | 7 +++++++ drivers/accel/ivpu/ivpu_job.c | 37 +++++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index fcf26e6d4e9c..ffb8309a4f65 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -260,6 +260,11 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) if (ret) goto err_xa_erase; + file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, + (file_priv->ctx.id - 1)); + file_priv->default_job_limit.max = file_priv->default_job_limit.min | IVPU_JOB_ID_JOB_MASK; + file_priv->job_limit = file_priv->default_job_limit; + mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -614,6 +619,10 @@ static int ivpu_dev_init(struct ivpu_device *vdev) lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); + vdev->default_db_limit.min = IVPU_MIN_DB; + vdev->default_db_limit.max = IVPU_MAX_DB; + vdev->db_limit = vdev->default_db_limit; + ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); if (ret) goto err_xa_destroy; diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index c4bd8757f8de..9acef14deab5 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -45,6 +45,9 @@ #define IVPU_MIN_DB 1 #define IVPU_MAX_DB 255 +#define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) +#define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) + #define IVPU_NUM_ENGINES 2 #define IVPU_NUM_PRIORITIES 4 #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) @@ -135,6 +138,8 @@ struct ivpu_device { struct xa_limit context_xa_limit; struct xarray db_xa; + struct xa_limit db_limit; + struct xa_limit default_db_limit; struct mutex bo_list_lock; /* Protects bo_list */ struct list_head bo_list; @@ -170,6 +175,8 @@ struct ivpu_file_priv { struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; + struct xa_limit job_limit; + struct xa_limit default_job_limit; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index b1abdca5891c..8798fb2046ab 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -21,8 +21,6 @@ #include "vpu_boot_api.h" #define CMD_BUF_IDX 0 -#define JOB_ID_JOB_MASK GENMASK(7, 0) -#define JOB_ID_CONTEXT_MASK GENMASK(31, 8) #define JOB_MAX_BUFFER_COUNT 65535 static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq) @@ -77,9 +75,28 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, ivpu_bo_free(cmdq->secondary_preempt_buf); } +static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, + const struct xa_limit default_limit) +{ + int ret; + + ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); + if (ret) { + limit->min = default_limit.min; + ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); + if (ret) + return ret; + } + + limit->min = *id + 1; + if (limit->min > limit->max) + limit->min = default_limit.min; + + return ret; +} + static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { - struct xa_limit db_xa_limit = {.max = IVPU_MAX_DB, .min = IVPU_MIN_DB}; struct ivpu_device *vdev = file_priv->vdev; struct ivpu_cmdq *cmdq; int ret; @@ -88,7 +105,10 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq) return NULL; - ret = xa_alloc(&vdev->db_xa, &cmdq->db_id, NULL, db_xa_limit, GFP_KERNEL); + xa_lock(&vdev->db_xa); /* lock here to protect db_limit */ + ret = ivpu_id_alloc(&vdev->db_xa, &cmdq->db_id, NULL, &vdev->db_limit, + vdev->default_db_limit); + xa_unlock(&vdev->db_xa); if (ret) { ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); goto err_free_cmdq; @@ -519,7 +539,6 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) { struct ivpu_file_priv *file_priv = job->file_priv; struct ivpu_device *vdev = job->vdev; - struct xa_limit job_id_range; struct ivpu_cmdq *cmdq; bool is_first_job; int ret; @@ -530,7 +549,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) mutex_lock(&file_priv->lock); - cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx, priority); + cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); if (!cmdq) { ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", file_priv->ctx.id, job->engine_idx, priority); @@ -538,12 +557,10 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) goto err_unlock_file_priv; } - job_id_range.min = FIELD_PREP(JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); - job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK; - xa_lock(&vdev->submitted_jobs_xa); is_first_job = xa_empty(&vdev->submitted_jobs_xa); - ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL); + ret = ivpu_id_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, &file_priv->job_limit, + file_priv->default_job_limit); if (ret) { ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", file_priv->ctx.id); -- GitLab From 7459211aa6352c219169c6bc9d1b0caf24e1ffd2 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Date: Mon, 30 Sep 2024 21:53:10 +0200 Subject: [PATCH 826/970] accel/ivpu: Add test_mode bit to force turbo Add new test_mode BIT(9) that forces firmware to enable turbo burst mode. Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-20-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.h | 1 + drivers/accel/ivpu/ivpu_job.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 9acef14deab5..151ab9f2ddc9 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -197,6 +197,7 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) #define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) +#define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 8798fb2046ab..dc5cf7ded943 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -202,6 +202,11 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng jobq_header->engine_idx = engine; jobq_header->head = 0; jobq_header->tail = 0; + if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { + ivpu_dbg(vdev, JOB, "Turbo mode enabled"); + jobq_header->flags = VPU_JOB_QUEUE_FLAGS_TURBO_MODE; + } + wmb(); /* Flush WC buffer for jobq->header */ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { -- GitLab From 8c3c5f84370cc076b1af2da09a89ce74292d186e Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:11 +0200 Subject: [PATCH 827/970] accel/ivpu: Remove skip of clock own resource ack on Simics With recent Simics model update CLOCK_RESOURCE_OWN_ACK signal was implemented as part of VPU STATUS register and workaround is no longer needed. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-21-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_hw_btrs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 7dc8e333dcec..6d5f1cc71143 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -459,9 +459,6 @@ int ivpu_hw_btrs_wait_for_clock_res_own_ack(struct ivpu_device *vdev) if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) return 0; - if (ivpu_is_simics(vdev)) - return 0; - return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US); } -- GitLab From 541a137254c71822e7a3ebdf8309c5a37b7de465 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Date: Mon, 30 Sep 2024 21:53:12 +0200 Subject: [PATCH 828/970] accel/ivpu: Fix reset_engine debugfs file logic The current reset_engine implementation unconditionally resets all engines. Improve implementation to reset only the engine requested by the user space to allow more granular testing. Also use DEFINE_DEBUGFS_ATTRIBUTE() to simplify implementation. Same changes applied to resume_engine debugfs file for consistency. Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-22-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_debugfs.c | 42 ++++++------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index f873119e56fe..8958145c49ad 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -337,49 +337,23 @@ static const struct file_operations ivpu_force_recovery_fops = { .write = ivpu_force_recovery_fn, }; -static ssize_t -ivpu_reset_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) +static int ivpu_reset_engine_fn(void *data, u64 val) { - struct ivpu_device *vdev = file->private_data; - - if (!size) - return -EINVAL; - - if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) - return -ENODEV; - if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COPY)) - return -ENODEV; + struct ivpu_device *vdev = (struct ivpu_device *)data; - return size; + return ivpu_jsm_reset_engine(vdev, (u32)val); } -static const struct file_operations ivpu_reset_engine_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .write = ivpu_reset_engine_fn, -}; +DEFINE_DEBUGFS_ATTRIBUTE(ivpu_reset_engine_fops, NULL, ivpu_reset_engine_fn, "0x%02llx\n"); -static ssize_t -ivpu_resume_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) +static int ivpu_resume_engine_fn(void *data, u64 val) { - struct ivpu_device *vdev = file->private_data; - - if (!size) - return -EINVAL; - - if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) - return -ENODEV; - if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COPY)) - return -ENODEV; + struct ivpu_device *vdev = (struct ivpu_device *)data; - return size; + return ivpu_jsm_hws_resume_engine(vdev, (u32)val); } -static const struct file_operations ivpu_resume_engine_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .write = ivpu_resume_engine_fn, -}; +DEFINE_DEBUGFS_ATTRIBUTE(ivpu_resume_engine_fops, NULL, ivpu_resume_engine_fn, "0x%02llx\n"); static int dct_active_get(void *data, u64 *active_percent) { -- GitLab From 5eaa497411197c41b0813d61ba3fbd6267049082 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:13 +0200 Subject: [PATCH 829/970] accel/ivpu: Prevent recovery invocation during probe and resume Refactor IPC send and receive functions to allow correct handling of operations that should not trigger a recovery process. Expose ivpu_send_receive_internal(), which is now utilized by the D0i3 entry, DCT initialization, and HWS initialization functions. These functions have been modified to return error codes gracefully, rather than initiating recovery. The updated functions are invoked within ivpu_probe() and ivpu_resume(), ensuring that any errors encountered during these stages result in a proper teardown or shutdown sequence. The previous approach of triggering recovery within these functions could lead to a race condition, potentially causing undefined behavior and kernel crashes due to null pointer dereferences. Fixes: 45e45362e095 ("accel/ivpu: Introduce ivpu_ipc_send_receive_active()") Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-23-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_ipc.c | 35 +++++++++++-------------------- drivers/accel/ivpu/ivpu_ipc.h | 7 +++---- drivers/accel/ivpu/ivpu_jsm_msg.c | 19 +++++++---------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index e7bccc20e4e4..a4ebb761354c 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -291,15 +291,16 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, return ret; } -static int +int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp_type, - struct vpu_jsm_msg *resp, u32 channel, - unsigned long timeout_ms) + struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms) { struct ivpu_ipc_consumer cons; int ret; + drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + ivpu_ipc_consumer_add(vdev, &cons, channel, NULL); ret = ivpu_ipc_send(vdev, &cons, req); @@ -325,19 +326,21 @@ ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req return ret; } -int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) +int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, + u32 channel, unsigned long timeout_ms) { struct vpu_jsm_msg hb_req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB }; struct vpu_jsm_msg hb_resp; int ret, hb_ret; - drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev)); + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp, resp, channel, timeout_ms); if (ret != -ETIMEDOUT) - return ret; + goto rpm_put; hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &hb_resp, VPU_IPC_CHAN_ASYNC_CMD, @@ -345,21 +348,7 @@ int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *r if (hb_ret == -ETIMEDOUT) ivpu_pm_trigger_recovery(vdev, "IPC timeout"); - return ret; -} - -int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms) -{ - int ret; - - ret = ivpu_rpm_get(vdev); - if (ret < 0) - return ret; - - ret = ivpu_ipc_send_receive_active(vdev, req, expected_resp, resp, channel, timeout_ms); - +rpm_put: ivpu_rpm_put(vdev); return ret; } diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h index 6bbe6e32c874..b4dfb504679b 100644 --- a/drivers/accel/ivpu/ivpu_ipc.h +++ b/drivers/accel/ivpu/ivpu_ipc.h @@ -101,10 +101,9 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg, unsigned long timeout_ms); - -int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req, - enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, - u32 channel, unsigned long timeout_ms); +int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req, + enum vpu_ipc_msg_type expected_resp_type, + struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req, enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms); diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index cd33964d292b..ae91ad24d10d 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -271,9 +271,8 @@ int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev) req.payload.pwr_d0i3_enter.send_response = 1; - ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, - &resp, VPU_IPC_CHAN_GEN_CMD, - vdev->timeout.d0i3_entry_msg); + ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, &resp, + VPU_IPC_CHAN_GEN_CMD, vdev->timeout.d0i3_entry_msg); if (ret) return ret; @@ -431,8 +430,8 @@ int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev) req.payload.hws_priority_band_setup.normal_band_percentage = 10; - ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, - &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP, + &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to set priority bands: %d\n", ret); @@ -545,9 +544,8 @@ int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us req.payload.pwr_dct_control.dct_active_us = active_us; req.payload.pwr_dct_control.dct_inactive_us = inactive_us; - return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, - &resp, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.jsm); + return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } int ivpu_jsm_dct_disable(struct ivpu_device *vdev) @@ -555,9 +553,8 @@ int ivpu_jsm_dct_disable(struct ivpu_device *vdev) struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_DISABLE }; struct vpu_jsm_msg resp; - return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, - &resp, VPU_IPC_CHAN_ASYNC_CMD, - vdev->timeout.jsm); + return ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); } int ivpu_jsm_state_dump(struct ivpu_device *vdev) -- GitLab From cc3c72c7e6101de86cdd7bee8d9765480d8a1720 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:14 +0200 Subject: [PATCH 830/970] accel/ivpu: Refactor failure diagnostics during boot Move diagnostic functions to common error handling within ivpu_boot() function to ensure diagnostics are gathered even in cases where NPU fails after successful boot (DCT and HWS init failures). Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-24-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ffb8309a4f65..14c2412c6f8e 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -386,10 +386,7 @@ int ivpu_boot(struct ivpu_device *vdev) ret = ivpu_wait_for_ready(vdev); if (ret) { ivpu_err(vdev, "Failed to boot the firmware: %d\n", ret); - ivpu_hw_diagnose_failure(vdev); - ivpu_mmu_evtq_dump(vdev); - ivpu_dev_coredump(vdev); - return ret; + goto err_diagnose_failure; } ivpu_hw_irq_clear(vdev); @@ -400,12 +397,20 @@ int ivpu_boot(struct ivpu_device *vdev) if (ivpu_fw_is_cold_boot(vdev)) { ret = ivpu_pm_dct_init(vdev); if (ret) - return ret; + goto err_diagnose_failure; - return ivpu_hw_sched_init(vdev); + ret = ivpu_hw_sched_init(vdev); + if (ret) + goto err_diagnose_failure; } return 0; + +err_diagnose_failure: + ivpu_hw_diagnose_failure(vdev); + ivpu_mmu_evtq_dump(vdev); + ivpu_dev_coredump(vdev); + return ret; } void ivpu_prepare_for_reset(struct ivpu_device *vdev) -- GitLab From 1bc92a517bb4ba3f1372793b782ea18e96432170 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:15 +0200 Subject: [PATCH 831/970] accel/ivpu: Remove invalid warnings Warn in ivpu_file_priv_put() checks a pointer that is previously accessed. Warn in ivpu_ipc_fini() can be triggered even in valid cases where IPC is disabled upon closing the device. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-25-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.c | 2 -- drivers/accel/ivpu/ivpu_ipc.c | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 14c2412c6f8e..dc983140128b 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -117,8 +117,6 @@ void ivpu_file_priv_put(struct ivpu_file_priv **link) struct ivpu_file_priv *file_priv = *link; struct ivpu_device *vdev = file_priv->vdev; - drm_WARN_ON(&vdev->drm, !file_priv); - ivpu_dbg(vdev, KREF, "file_priv put: ctx %u refcount %u\n", file_priv->ctx.id, kref_read(&file_priv->ref)); diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index a4ebb761354c..c8ae69a529c0 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -533,7 +533,6 @@ void ivpu_ipc_fini(struct ivpu_device *vdev) { struct ivpu_ipc_info *ipc = vdev->ipc; - drm_WARN_ON(&vdev->drm, ipc->on); drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cons_list)); drm_WARN_ON(&vdev->drm, !list_empty(&ipc->cb_msg_list)); drm_WARN_ON(&vdev->drm, atomic_read(&ipc->rx_msg_count) > 0); -- GitLab From 08eb99ce911d3ea202f79b42b96cd6e8498f7f69 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:16 +0200 Subject: [PATCH 832/970] accel/ivpu: Do not fail on cmdq if failed to allocate preemption buffers Allow to proceed with job command queue creation even if preemption buffers failed to be allocated, print warning that preemption on such command queue will be disabled. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-26-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_job.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index dc5cf7ded943..48272bc853e0 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -60,6 +60,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, err_free_primary: ivpu_bo_free(cmdq->primary_preempt_buf); + cmdq->primary_preempt_buf = NULL; return -ENOMEM; } @@ -69,10 +70,10 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return; - drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf); - drm_WARN_ON(&vdev->drm, !cmdq->secondary_preempt_buf); - ivpu_bo_free(cmdq->primary_preempt_buf); - ivpu_bo_free(cmdq->secondary_preempt_buf); + if (cmdq->primary_preempt_buf) + ivpu_bo_free(cmdq->primary_preempt_buf); + if (cmdq->secondary_preempt_buf) + ivpu_bo_free(cmdq->secondary_preempt_buf); } static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, @@ -120,12 +121,10 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); if (ret) - goto err_free_cmdq_mem; + ivpu_warn(vdev, "Failed to allocate preemption buffers, preemption limited\n"); return cmdq; -err_free_cmdq_mem: - ivpu_bo_free(cmdq->mem); err_erase_xa: xa_erase(&vdev->db_xa, cmdq->db_id); err_free_cmdq: @@ -388,10 +387,16 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { - entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; - entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); - entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; - entry->secondary_preempt_buf_size = ivpu_bo_size(cmdq->secondary_preempt_buf); + if (cmdq->primary_preempt_buf) { + entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; + entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); + } + + if (cmdq->secondary_preempt_buf) { + entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr; + entry->secondary_preempt_buf_size = + ivpu_bo_size(cmdq->secondary_preempt_buf); + } } wmb(); /* Ensure that tail is updated after filling entry */ -- GitLab From 755fb86789165dca776e69631a4ed332f0341e29 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Mon, 30 Sep 2024 21:53:17 +0200 Subject: [PATCH 833/970] accel/ivpu: Use whole user and shave ranges for preemption buffers Do not restrict range for preemption buffers allocation just to the end of user and shave ranges, use them whole instead to avoid situation where end of range might be already allocated causing preemption buffers allocation to fail. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-27-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_job.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 48272bc853e0..cd41b8771505 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -33,24 +33,19 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, { u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); - struct ivpu_addr_range range; if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) return 0; - range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX); - range.end = vdev->hw->ranges.user.end; - cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, primary_size, - DRM_IVPU_BO_WC); + cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, + primary_size, DRM_IVPU_BO_WC); if (!cmdq->primary_preempt_buf) { ivpu_err(vdev, "Failed to create primary preemption buffer\n"); return -ENOMEM; } - range.start = vdev->hw->ranges.shave.end - (secondary_size * IVPU_NUM_CMDQS_PER_CTX); - range.end = vdev->hw->ranges.shave.end; - cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, secondary_size, - DRM_IVPU_BO_WC); + cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.shave, + secondary_size, DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); goto err_free_primary; -- GitLab From 98110eb5924bd9a718a1e3a4e16527ed4f84910d Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:18 +0200 Subject: [PATCH 834/970] accel/ivpu: Increase MS info buffer size Increase MS info BO to 64KB to allow collecting more metrics. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-28-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index 2f9d37f5c208..ffe7b10f8a76 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -11,7 +11,7 @@ #include "ivpu_ms.h" #include "ivpu_pm.h" -#define MS_INFO_BUFFER_SIZE SZ_16K +#define MS_INFO_BUFFER_SIZE SZ_64K #define MS_NUM_BUFFERS 2 #define MS_READ_PERIOD_MULTIPLIER 2 #define MS_MIN_SAMPLE_PERIOD_NS 1000000 -- GitLab From ed3fb318fd681bc226be3b309a1c658d231a282b Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:19 +0200 Subject: [PATCH 835/970] accel/ivpu: Fix ivpu_jsm_dyndbg_control() Use correct channel for dyndbg JSM message. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-29-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_jsm_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index ae91ad24d10d..494ebc2475b1 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -197,7 +197,7 @@ int ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size strscpy(req.payload.dyndbg_control.dyndbg_cmd, command, VPU_DYNDBG_CMD_MAX_LEN); ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp, - VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + VPU_IPC_CHAN_GEN_CMD, vdev->timeout.jsm); if (ret) ivpu_warn_ratelimited(vdev, "Failed to send command \"%s\": ret %d\n", command, ret); -- GitLab From 3e521803e552e5cfee1a3011d14a5f75b938a0c2 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:20 +0200 Subject: [PATCH 836/970] accel/ivpu: Remove HWS_EXTRA_EVENTS from test modes IVPU_TEST_MODE_HWS_EXTRA_EVENTS was never used and can be safely removed Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-30-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.h | 1 - drivers/accel/ivpu/ivpu_jsm_msg.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 151ab9f2ddc9..5b43f91f2015 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -195,7 +195,6 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) #define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) -#define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) #define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 494ebc2475b1..8f5d904ca1ed 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -394,8 +394,6 @@ int ivpu_jsm_hws_set_scheduling_log(struct ivpu_device *vdev, u32 engine_idx, u3 req.payload.hws_set_scheduling_log.host_ssid = host_ssid; req.payload.hws_set_scheduling_log.vpu_log_buffer_va = vpu_log_buffer_va; req.payload.hws_set_scheduling_log.notify_index = 0; - req.payload.hws_set_scheduling_log.enable_extra_events = - ivpu_test_mode & IVPU_TEST_MODE_HWS_EXTRA_EVENTS; ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP, &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); -- GitLab From 7cb8d38a068291c9fdc182c177e42a1aa3eea97b Mon Sep 17 00:00:00 2001 From: Jakub Pawlak <jakub.pawlak@intel.com> Date: Mon, 30 Sep 2024 21:53:21 +0200 Subject: [PATCH 837/970] accel/ivpu: Add tracing for IPC/PM/JOB Add multiple trace points in couple of key places to enable tracing with ftrace. Signed-off-by: Jakub Pawlak <jakub.pawlak@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-31-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/Makefile | 5 +- drivers/accel/ivpu/ivpu_ipc.c | 3 ++ drivers/accel/ivpu/ivpu_job.c | 4 ++ drivers/accel/ivpu/ivpu_pm.c | 9 ++++ drivers/accel/ivpu/ivpu_trace.h | 73 ++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_trace_points.c | 9 ++++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 drivers/accel/ivpu/ivpu_trace.h create mode 100644 drivers/accel/ivpu/ivpu_trace_points.c diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index 232ea6d28c6e..e73937c86d9a 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -16,9 +16,12 @@ intel_vpu-y := \ ivpu_mmu_context.o \ ivpu_ms.o \ ivpu_pm.o \ - ivpu_sysfs.o + ivpu_sysfs.o \ + ivpu_trace_points.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o + +CFLAGS_ivpu_trace_points.o = -I$(src) diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index c8ae69a529c0..01ebf88fe6ef 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -15,6 +15,7 @@ #include "ivpu_ipc.h" #include "ivpu_jsm_msg.h" #include "ivpu_pm.h" +#include "ivpu_trace.h" #define IPC_MAX_RX_MSG 128 @@ -227,6 +228,7 @@ int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, stru goto unlock; ivpu_ipc_tx(vdev, cons->tx_vpu_addr); + trace_jsm("[tx]", req); unlock: mutex_unlock(&ipc->lock); @@ -284,6 +286,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, if (jsm_msg) memcpy(jsm_msg, rx_msg->jsm_msg, size); + trace_jsm("[rx]", rx_msg->jsm_msg); } ivpu_ipc_rx_msg_del(vdev, rx_msg); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index cd41b8771505..98e0b7b61407 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -18,6 +18,7 @@ #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_pm.h" +#include "ivpu_trace.h" #include "vpu_boot_api.h" #define CMD_BUF_IDX 0 @@ -482,6 +483,7 @@ ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) job->file_priv = ivpu_file_priv_get(file_priv); + trace_job("create", job); ivpu_dbg(vdev, JOB, "Job created: ctx %2d engine %d", file_priv->ctx.id, job->engine_idx); return job; @@ -521,6 +523,7 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job->bos[CMD_BUF_IDX]->job_status = job_status; dma_fence_signal(job->done_fence); + trace_job("done", job); ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n", job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status); @@ -588,6 +591,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) vdev->busy_start_ts = ktime_get(); } + trace_job("submit", job); ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n", job->job_id, file_priv->ctx.id, job->engine_idx, priority, job->cmd_buf_vpu_addr, cmdq->jobq->header.tail); diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index b5a69941e6e0..6d180c81e6df 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -20,6 +20,7 @@ #include "ivpu_mmu.h" #include "ivpu_ms.h" #include "ivpu_pm.h" +#include "ivpu_trace.h" #include "vpu_boot_api.h" static bool ivpu_disable_recovery; @@ -198,6 +199,7 @@ int ivpu_pm_suspend_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); unsigned long timeout; + trace_pm("suspend"); ivpu_dbg(vdev, PM, "Suspend..\n"); timeout = jiffies + msecs_to_jiffies(vdev->timeout.tdr); @@ -215,6 +217,7 @@ int ivpu_pm_suspend_cb(struct device *dev) ivpu_pm_prepare_warm_boot(vdev); ivpu_dbg(vdev, PM, "Suspend done.\n"); + trace_pm("suspend done"); return 0; } @@ -225,6 +228,7 @@ int ivpu_pm_resume_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); int ret; + trace_pm("resume"); ivpu_dbg(vdev, PM, "Resume..\n"); ret = ivpu_resume(vdev); @@ -232,6 +236,7 @@ int ivpu_pm_resume_cb(struct device *dev) ivpu_err(vdev, "Failed to resume: %d\n", ret); ivpu_dbg(vdev, PM, "Resume done.\n"); + trace_pm("resume done"); return ret; } @@ -246,6 +251,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa)); drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work)); + trace_pm("runtime suspend"); ivpu_dbg(vdev, PM, "Runtime suspend..\n"); ivpu_mmu_disable(vdev); @@ -272,6 +278,7 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev) } ivpu_dbg(vdev, PM, "Runtime suspend done.\n"); + trace_pm("runtime suspend done"); return 0; } @@ -282,6 +289,7 @@ int ivpu_pm_runtime_resume_cb(struct device *dev) struct ivpu_device *vdev = to_ivpu_device(drm); int ret; + trace_pm("runtime resume"); ivpu_dbg(vdev, PM, "Runtime resume..\n"); ret = ivpu_resume(vdev); @@ -289,6 +297,7 @@ int ivpu_pm_runtime_resume_cb(struct device *dev) ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret); ivpu_dbg(vdev, PM, "Runtime resume done.\n"); + trace_pm("runtime resume done"); return ret; } diff --git a/drivers/accel/ivpu/ivpu_trace.h b/drivers/accel/ivpu/ivpu_trace.h new file mode 100644 index 000000000000..eb792038e701 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_trace.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#if !defined(__IVPU_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) +#define __IVPU_TRACE_H__ + +#include <linux/tracepoint.h> +#include "ivpu_drv.h" +#include "ivpu_job.h" +#include "vpu_jsm_api.h" +#include "ivpu_jsm_msg.h" +#include "ivpu_ipc.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vpu +#define TRACE_INCLUDE_FILE ivpu_trace + +TRACE_EVENT(pm, + TP_PROTO(const char *event), + TP_ARGS(event), + TP_STRUCT__entry(__field(const char *, event)), + TP_fast_assign(__entry->event = event;), + TP_printk("%s", __entry->event) +); + +TRACE_EVENT(job, + TP_PROTO(const char *event, struct ivpu_job *job), + TP_ARGS(event, job), + TP_STRUCT__entry(__field(const char *, event) + __field(u32, ctx_id) + __field(u32, engine_id) + __field(u32, job_id) + ), + TP_fast_assign(__entry->event = event; + __entry->ctx_id = job->file_priv->ctx.id; + __entry->engine_id = job->engine_idx; + __entry->job_id = job->job_id;), + TP_printk("%s context:%d engine:%d job:%d", + __entry->event, + __entry->ctx_id, + __entry->engine_id, + __entry->job_id) +); + +TRACE_EVENT(jsm, + TP_PROTO(const char *event, struct vpu_jsm_msg *msg), + TP_ARGS(event, msg), + TP_STRUCT__entry(__field(const char *, event) + __field(const char *, type) + __field(enum vpu_ipc_msg_status, status) + __field(u32, request_id) + __field(u32, result) + ), + TP_fast_assign(__entry->event = event; + __entry->type = ivpu_jsm_msg_type_to_str(msg->type); + __entry->status = msg->status; + __entry->request_id = msg->request_id; + __entry->result = msg->result;), + TP_printk("%s type:%s, status:%#x, id:%#x, result:%#x", + __entry->event, + __entry->type, + __entry->status, + __entry->request_id, + __entry->result) +); + +#endif /* __IVPU_TRACE_H__ */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#include <trace/define_trace.h> diff --git a/drivers/accel/ivpu/ivpu_trace_points.c b/drivers/accel/ivpu/ivpu_trace_points.c new file mode 100644 index 000000000000..f8fb99de0de3 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_trace_points.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "ivpu_trace.h" +#endif -- GitLab From c4fd5979ce3149b1be37b162be25b9a031d8e7e1 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Date: Mon, 30 Sep 2024 21:53:22 +0200 Subject: [PATCH 838/970] accel/ivpu: Fix typos in ivpu_pm.c Replace "Filed" with an actual word. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-32-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 6d180c81e6df..e567df79a612 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -423,7 +423,7 @@ int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent) ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us); if (ret) { - ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret); + ivpu_err_ratelimited(vdev, "Failed to enable DCT: %d\n", ret); return ret; } @@ -440,7 +440,7 @@ int ivpu_pm_dct_disable(struct ivpu_device *vdev) ret = ivpu_jsm_dct_disable(vdev); if (ret) { - ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret); + ivpu_err_ratelimited(vdev, "Failed to disable DCT: %d\n", ret); return ret; } -- GitLab From c140244f0cfb9601dbc35e7ab90914954a76b3d1 Mon Sep 17 00:00:00 2001 From: Maciej Falkowski <maciej.falkowski@linux.intel.com> Date: Fri, 4 Oct 2024 18:25:04 +0200 Subject: [PATCH 839/970] accel/ivpu: Add initial Panther Lake support Add support for the 5th generation of Intel NPU that is going to be present in PTL_P (Panther Lake) CPUs. NPU5 code reuses almost all of previous driver code. Signed-off-by: Maciej Falkowski <maciej.falkowski@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004162505.1695605-2-maciej.falkowski@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_drv.c | 1 + drivers/accel/ivpu/ivpu_drv.h | 10 +++++++--- drivers/accel/ivpu/ivpu_fw.c | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index dc983140128b..e7d8967c02f2 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -742,6 +742,7 @@ static struct pci_device_id ivpu_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PTL_P) }, { } }; MODULE_DEVICE_TABLE(pci, ivpu_pci_ids); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 5b43f91f2015..f905021ac174 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -22,9 +22,10 @@ #define DRIVER_NAME "intel_vpu" #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" -#define PCI_DEVICE_ID_MTL 0x7d1d -#define PCI_DEVICE_ID_ARL 0xad1d -#define PCI_DEVICE_ID_LNL 0x643e +#define PCI_DEVICE_ID_MTL 0x7d1d +#define PCI_DEVICE_ID_ARL 0xad1d +#define PCI_DEVICE_ID_LNL 0x643e +#define PCI_DEVICE_ID_PTL_P 0xb03e #define IVPU_HW_IP_37XX 37 #define IVPU_HW_IP_40XX 40 @@ -224,6 +225,8 @@ static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev) return IVPU_HW_IP_37XX; case PCI_DEVICE_ID_LNL: return IVPU_HW_IP_40XX; + case PCI_DEVICE_ID_PTL_P: + return IVPU_HW_IP_50XX; default: dump_stack(); ivpu_err(vdev, "Unknown NPU IP generation\n"); @@ -238,6 +241,7 @@ static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev) case PCI_DEVICE_ID_ARL: return IVPU_HW_BTRS_MTL; case PCI_DEVICE_ID_LNL: + case PCI_DEVICE_ID_PTL_P: return IVPU_HW_BTRS_LNL; default: dump_stack(); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 4d59dd19f684..be367465e7df 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -57,11 +57,14 @@ static struct { { IVPU_HW_IP_37XX, "intel/vpu/vpu_37xx_v0.0.bin" }, { IVPU_HW_IP_40XX, "vpu_40xx.bin" }, { IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" }, + { IVPU_HW_IP_50XX, "vpu_50xx.bin" }, + { IVPU_HW_IP_50XX, "intel/vpu/vpu_50xx_v0.0.bin" }, }; /* Production fw_names from the table above */ MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin"); MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin"); +MODULE_FIRMWARE("intel/vpu/vpu_50xx_v0.0.bin"); static int ivpu_fw_request(struct ivpu_device *vdev) { -- GitLab From 88bdd1644ca28d48591b2a1e6e8b8c2b13f4bd3f Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Fri, 4 Oct 2024 18:25:05 +0200 Subject: [PATCH 840/970] accel/ivpu: Update power island delays Apply Hardware Architecture Specification compatible delays for main island power delivery for 50xx and above. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Signed-off-by: Maciej Falkowski <maciej.falkowski@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004162505.1695605-3-maciej.falkowski@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> --- drivers/accel/ivpu/ivpu_hw_40xx_reg.h | 2 ++ drivers/accel/ivpu/ivpu_hw_ip.c | 49 +++++++++++++++++---------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h index d0b795b344c7..fc0ee8d637f9 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h +++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h @@ -115,6 +115,8 @@ #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY 0x00030068u #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST_DLY_MASK GENMASK(7, 0) +#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST1_DLY_MASK GENMASK(15, 8) +#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST2_DLY_MASK GENMASK(23, 16) #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index cfcbb99168e6..b9b16f404143 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -8,15 +8,12 @@ #include "ivpu_hw.h" #include "ivpu_hw_37xx_reg.h" #include "ivpu_hw_40xx_reg.h" +#include "ivpu_hw_btrs.h" #include "ivpu_hw_ip.h" #include "ivpu_hw_reg_io.h" #include "ivpu_mmu.h" #include "ivpu_pm.h" -#define PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT 0 -#define PWR_ISLAND_EN_POST_DLY_FREQ_HIGH 18 -#define PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT 3 -#define PWR_ISLAND_STATUS_DLY_FREQ_HIGH 46 #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC) #define TIM_SAFE_ENABLE 0xf1d0dead @@ -268,20 +265,15 @@ void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev) idle_gen_drive_40xx(vdev, false); } -static void pwr_island_delay_set_50xx(struct ivpu_device *vdev) +static void +pwr_island_delay_set_50xx(struct ivpu_device *vdev, u32 post, u32 post1, u32 post2, u32 status) { - u32 val, post, status; - - if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT) { - post = PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT; - status = PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT; - } else { - post = PWR_ISLAND_EN_POST_DLY_FREQ_HIGH; - status = PWR_ISLAND_STATUS_DLY_FREQ_HIGH; - } + u32 val; val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY); val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val); + val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST1_DLY, post1, val); + val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST2_DLY, post2, val); REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val); val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY); @@ -682,13 +674,36 @@ static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable) REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val); } +static void pwr_island_delay_set(struct ivpu_device *vdev) +{ + bool high = vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_HIGH; + u32 post, post1, post2, status; + + if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX) + return; + + switch (ivpu_device_id(vdev)) { + case PCI_DEVICE_ID_PTL_P: + post = high ? 18 : 0; + post1 = 0; + post2 = 0; + status = high ? 46 : 3; + break; + + default: + dump_stack(); + ivpu_err(vdev, "Unknown device ID\n"); + return; + } + + pwr_island_delay_set_50xx(vdev, post, post1, post2, status); +} + int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev) { int ret; - if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_50XX) - pwr_island_delay_set_50xx(vdev); - + pwr_island_delay_set(vdev); pwr_island_enable(vdev); ret = wait_for_pwr_island_status(vdev, 0x1); -- GitLab From 65b5353193e5a8476814a184e8e1a2627d59f2b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom@linux.intel.com> Date: Thu, 10 Oct 2024 14:45:45 +0200 Subject: [PATCH 841/970] drm/ttm: Fix incorrect use of kernel-doc format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a missing colon. Cc: dri-devel@lists.freedesktop.org Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Closes: https://lore.kernel.org/linux-next/20241010160942.192caf60@canb.auug.org.au/ Fixes: fc5d96670eb2 ("drm/ttm: Move swapped objects off the manager's LRU list") Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Nirmoy Das <nirmoy.das@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241010124545.82023-1-thomas.hellstrom@linux.intel.com --- include/drm/ttm/ttm_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 438358f72716..39b8636b1845 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -252,7 +252,7 @@ struct ttm_device { spinlock_t lru_lock; /** - * @unevictable Buffer objects which are pinned or swapped and as such + * @unevictable: Buffer objects which are pinned or swapped and as such * not on an LRU list. */ struct list_head unevictable; -- GitLab From 1b1d5fe66ca591d34c5501aab8f5f09f347e8a3e Mon Sep 17 00:00:00 2001 From: Maaz Mombasawala <maaz.mombasawala@broadcom.com> Date: Wed, 1 May 2024 17:40:33 -0700 Subject: [PATCH 842/970] drm/vmwgfx: Stop using dev_private to store driver data. Currently vmwgfx uses the dev_private opaque pointer in drm_device to store driver data in vmw_private struct. Using dev_private is deprecated, and the recommendation is to embed struct drm_device in the larger per-device structure. The vmwgfx driver already embeds struct drm_device in its struct vmw_private, so switch to using that exclusively and stop using dev_private. Signed-off-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com> Reviewed-by: Zack Rusin <zack.rusin@broadcom.com> Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240502004033.107533-1-maaz.mombasawala@broadcom.com --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 -- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index cf7a89d002e4..2706d0b57a2b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -860,8 +860,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) bool refuse_dma = false; struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - dev_priv->drm.dev_private = dev_priv; - vmw_sw_context_init(dev_priv); mutex_init(&dev_priv->cmdbuf_mutex); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 3f4719b3c268..4054125aef7a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -639,7 +639,7 @@ static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res) static inline struct vmw_private *vmw_priv(struct drm_device *dev) { - return (struct vmw_private *)dev->dev_private; + return container_of(dev, struct vmw_private, drm); } static inline struct vmw_private *vmw_priv_from_ttm(struct ttm_device *bdev) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 288ed0bb75cb..50b2f233087e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -280,7 +280,7 @@ static void vmw_du_put_cursor_mob(struct vmw_cursor_plane *vcp, static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp, struct vmw_plane_state *vps) { - struct vmw_private *dev_priv = vcp->base.dev->dev_private; + struct vmw_private *dev_priv = vmw_priv(vcp->base.dev); u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h); u32 i; u32 cursor_max_dim, mob_max_size; @@ -519,7 +519,7 @@ void vmw_du_cursor_plane_destroy(struct drm_plane *plane) struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane); u32 i; - vmw_cursor_update_position(plane->dev->dev_private, false, 0, 0); + vmw_cursor_update_position(vmw_priv(plane->dev), false, 0, 0); for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) vmw_du_destroy_cursor_mob(&vcp->cursor_mobs[i]); -- GitLab From 2d343723c7e1f9f6d64f721f07cfdfc2993758d1 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Date: Wed, 8 Nov 2023 13:27:23 +0200 Subject: [PATCH 843/970] drm/bridge: tc358767: Fix link properties discovery When a display controller driver uses DRM_BRIDGE_ATTACH_NO_CONNECTOR, tc358767 will behave properly and skip the creation of the connector. However, tc_get_display_props(), which is used to find out about the DP monitor and link, is only called from two places: .atomic_enable() and tc_connector_get_modes(). The latter is only used when tc358767 creates its own connector, i.e. when DRM_BRIDGE_ATTACH_NO_CONNECTOR is _not_ set. Thus, the driver never finds out the link properties before get_edid() is called. With num_lanes of 0 and link_rate of 0 there are not many valid modes... Fix this by adding tc_get_display_props() call at the beginning of get_edid(), so that we have up to date information before looking at the modes. Reported-by: Jan Kiszka <jan.kiszka@siemens.com> Closes: https://lore.kernel.org/all/24282420-b4dd-45b3-bb1c-fc37fe4a8205@siemens.com/ Fixes: de5e6c027ae6 ("drm/bridge: tc358767: add drm_panel_bridge support") Reviewed-by: Aradhya Bhatia <a-bhatia1@ti.com> Tested-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231108-tc358767-v2-2-25c5f70a2159@ideasonboard.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/tc358767.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 159c95b26d33..0c48e747f5b0 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1714,6 +1714,13 @@ static const struct drm_edid *tc_edid_read(struct drm_bridge *bridge, struct drm_connector *connector) { struct tc_data *tc = bridge_to_tc(bridge); + int ret; + + ret = tc_get_display_props(tc); + if (ret < 0) { + dev_err(tc->dev, "failed to read display props: %d\n", ret); + return 0; + } return drm_edid_read_ddc(connector, &tc->aux.ddc); } -- GitLab From ac4627c304e7a09068d0e2dba34d21e492649f8d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 15 Jun 2024 20:53:30 +0300 Subject: [PATCH 844/970] drm/bridge: lt9611: use HDMI Connector helper to set InfoFrames Use new HDMI Connector helpers in the Lontium LT9611 bridge driver. Program InfoFrames using the helper's callbacks. Also use TMDS char rate validation callback to filter out modes, instead of hardcoding 4k@30. The Audio InfoFrame isn't yet handled by these helpers, it requires additional drm_bridge interface changes. Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240615-drm-bridge-hdmi-connector-v1-1-d59fc7865ab2@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/Kconfig | 2 + drivers/gpu/drm/bridge/lontium-lt9611.c | 173 ++++++++++++++++-------- 2 files changed, 120 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 683cb33805b2..609f4d0ac93d 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -140,6 +140,8 @@ config DRM_LONTIUM_LT9611 select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_MIPI_DSI + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_HDMI_STATE_HELPER select REGMAP_I2C help Driver for Lontium LT9611 DSI to HDMI bridge diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 73983f9b50cb..1b31fdebe164 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -23,6 +23,8 @@ #include <drm/drm_of.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> +#include <drm/display/drm_hdmi_helper.h> +#include <drm/display/drm_hdmi_state_helper.h> #define EDID_SEG_SIZE 256 #define EDID_LEN 32 @@ -333,49 +335,6 @@ static int lt9611_video_check(struct lt9611 *lt9611) return temp; } -static void lt9611_hdmi_set_infoframes(struct lt9611 *lt9611, - struct drm_connector *connector, - struct drm_display_mode *mode) -{ - union hdmi_infoframe infoframe; - ssize_t len; - u8 iframes = 0x0a; /* UD1 infoframe */ - u8 buf[32]; - int ret; - int i; - - ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe.avi, - connector, - mode); - if (ret < 0) - goto out; - - len = hdmi_infoframe_pack(&infoframe, buf, sizeof(buf)); - if (len < 0) - goto out; - - for (i = 0; i < len; i++) - regmap_write(lt9611->regmap, 0x8440 + i, buf[i]); - - ret = drm_hdmi_vendor_infoframe_from_display_mode(&infoframe.vendor.hdmi, - connector, - mode); - if (ret < 0) - goto out; - - len = hdmi_infoframe_pack(&infoframe, buf, sizeof(buf)); - if (len < 0) - goto out; - - for (i = 0; i < len; i++) - regmap_write(lt9611->regmap, 0x8474 + i, buf[i]); - - iframes |= 0x20; - -out: - regmap_write(lt9611->regmap, 0x843d, iframes); /* UD1 infoframe */ -} - static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi) { if (is_hdmi) @@ -719,7 +678,7 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge, } lt9611_mipi_input_analog(lt9611); - lt9611_hdmi_set_infoframes(lt9611, connector, mode); + drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); lt9611_hdmi_tx_digital(lt9611, connector->display_info.is_hdmi); lt9611_hdmi_tx_phy(lt9611); @@ -798,22 +757,25 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + unsigned long long rate; if (mode->hdisplay > 3840) return MODE_BAD_HVALUE; - if (mode->vdisplay > 2160) - return MODE_BAD_VVALUE; - - if (mode->hdisplay == 3840 && - mode->vdisplay == 2160 && - drm_mode_vrefresh(mode) > 30) - return MODE_CLOCK_HIGH; - if (mode->hdisplay > 2000 && !lt9611->dsi1_node) return MODE_PANEL; - else - return MODE_OK; + + rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + return bridge->funcs->hdmi_tmds_char_rate_valid(bridge, mode, rate); +} + +static int lt9611_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + return drm_atomic_helper_connector_hdmi_check(conn_state->connector, + conn_state->state); } static void lt9611_bridge_atomic_pre_enable(struct drm_bridge *bridge, @@ -887,6 +849,99 @@ lt9611_atomic_get_input_bus_fmts(struct drm_bridge *bridge, return input_fmts; } +/* + * Other working frames: + * - 0x01, 0x84df + * - 0x04, 0x84c0 + */ +#define LT9611_INFOFRAME_AUDIO 0x02 +#define LT9611_INFOFRAME_AVI 0x08 +#define LT9611_INFOFRAME_SPD 0x10 +#define LT9611_INFOFRAME_VENDOR 0x20 + +static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge, + enum hdmi_infoframe_type type) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + unsigned int mask; + + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + mask = LT9611_INFOFRAME_AVI; + break; + + case HDMI_INFOFRAME_TYPE_SPD: + mask = LT9611_INFOFRAME_SPD; + break; + + case HDMI_INFOFRAME_TYPE_VENDOR: + mask = LT9611_INFOFRAME_VENDOR; + break; + + default: + drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); + mask = 0; + break; + } + + if (mask) + regmap_update_bits(lt9611->regmap, 0x843d, mask, 0); + + return 0; +} + +static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + unsigned int mask, addr; + int i; + + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + mask = LT9611_INFOFRAME_AVI; + addr = 0x8440; + break; + + case HDMI_INFOFRAME_TYPE_SPD: + mask = LT9611_INFOFRAME_SPD; + addr = 0x8493; + break; + + case HDMI_INFOFRAME_TYPE_VENDOR: + mask = LT9611_INFOFRAME_VENDOR; + addr = 0x8474; + break; + + default: + drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); + mask = 0; + break; + } + + if (mask) { + for (i = 0; i < len; i++) + regmap_write(lt9611->regmap, addr + i, buffer[i]); + + regmap_update_bits(lt9611->regmap, 0x843d, mask, mask); + } + + return 0; +} + +static enum drm_mode_status +lt9611_hdmi_tmds_char_rate_valid(const struct drm_bridge *bridge, + const struct drm_display_mode *mode, + unsigned long long tmds_rate) +{ + /* 297 MHz for 4k@30 mode */ + if (tmds_rate > 297000000) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + static const struct drm_bridge_funcs lt9611_bridge_funcs = { .attach = lt9611_bridge_attach, .mode_valid = lt9611_bridge_mode_valid, @@ -894,6 +949,7 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = { .edid_read = lt9611_bridge_edid_read, .hpd_enable = lt9611_bridge_hpd_enable, + .atomic_check = lt9611_bridge_atomic_check, .atomic_pre_enable = lt9611_bridge_atomic_pre_enable, .atomic_enable = lt9611_bridge_atomic_enable, .atomic_disable = lt9611_bridge_atomic_disable, @@ -902,6 +958,10 @@ static const struct drm_bridge_funcs lt9611_bridge_funcs = { .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts, + + .hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid, + .hdmi_write_infoframe = lt9611_hdmi_write_infoframe, + .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe, }; static int lt9611_parse_dt(struct device *dev, @@ -1116,8 +1176,11 @@ static int lt9611_probe(struct i2c_client *client) lt9611->bridge.funcs = <9611_bridge_funcs; lt9611->bridge.of_node = client->dev.of_node; lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | - DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES; + DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES | + DRM_BRIDGE_OP_HDMI; lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + lt9611->bridge.vendor = "Lontium"; + lt9611->bridge.product = "LT9611"; drm_bridge_add(<9611->bridge); -- GitLab From 522bb461b1335e5999fe30838b03f0cec6a721de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> Date: Wed, 9 Oct 2024 11:12:05 -0300 Subject: [PATCH 845/970] =?UTF-8?q?MAINTAINERS:=20Add=20Ma=C3=ADra=20to=20?= =?UTF-8?q?VC4=20reviewers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although I don't hold expertise on the display side of VC4, I'd like to help reviewing patches that are related to the 3D side of the VC4 driver. As V3D maintainer, I hold some expertise with Broadcom GPUs and I'm constantly testing kernels on RPi 3-5. Signed-off-by: MaÃra Canal <mcanal@igalia.com> Acked-by: Maxime Ripard <mripard@kernel.org> Acked-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241009141240.1948482-1-mcanal@igalia.com --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 365fb0ce5117..a740b73e4ecf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7799,6 +7799,7 @@ F: include/uapi/drm/v3d_drm.h DRM DRIVERS FOR VC4 M: Maxime Ripard <mripard@kernel.org> M: Dave Stevenson <dave.stevenson@raspberrypi.com> +R: MaÃra Canal <mcanal@igalia.com> R: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com> S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git -- GitLab From 2af5deb614e7bc9367aadf9105e37c8299120af4 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo <quic_jhugo@quicinc.com> Date: Fri, 4 Oct 2024 10:40:33 -0600 Subject: [PATCH 846/970] accel/qaic: Add ipc_router channel The ipc_router channel allows AF_QIPCRTR clients and services to communicate with the AIC100 device. The ipc_router MHI transport layer expects the channel to be named exactly "IPCR". Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com> Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004164033.3825986-1-quic_jhugo@quicinc.com --- Documentation/accel/qaic/aic100.rst | 2 ++ drivers/accel/qaic/mhi_controller.c | 32 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Documentation/accel/qaic/aic100.rst b/Documentation/accel/qaic/aic100.rst index 590dae77ea12..273da6192fb3 100644 --- a/Documentation/accel/qaic/aic100.rst +++ b/Documentation/accel/qaic/aic100.rst @@ -229,6 +229,8 @@ of the defined channels, and their uses. | _PERIODIC | | | timestamps in the device side logs with| | | | | the host time source. | +----------------+---------+----------+----------------------------------------+ +| IPCR | 24 & 25 | AMSS | AF_QIPCRTR clients and servers. | ++----------------+---------+----------+----------------------------------------+ DMA Bridge ========== diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_controller.c index ada9b1eb0787..8ab82e78dd94 100644 --- a/drivers/accel/qaic/mhi_controller.c +++ b/drivers/accel/qaic/mhi_controller.c @@ -405,6 +405,38 @@ static const struct mhi_channel_config aic100_channels[] = { .auto_queue = false, .wake_capable = false, }, + { + .name = "IPCR", + .num = 24, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_TO_DEVICE, + .ee_mask = MHI_CH_EE_AMSS, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + .wake_capable = false, + }, + { + .name = "IPCR", + .num = 25, + .num_elements = 32, + .local_elements = 0, + .event_ring = 0, + .dir = DMA_FROM_DEVICE, + .ee_mask = MHI_CH_EE_AMSS, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = true, + .wake_capable = false, + }, }; static struct mhi_event_config aic100_events[] = { -- GitLab From b8128f7815ff135f0333c1b46dcdf1543c41b860 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo <quic_jhugo@quicinc.com> Date: Fri, 4 Oct 2024 13:52:09 -0600 Subject: [PATCH 847/970] accel/qaic: Add AIC080 support Add basic support for the new AIC080 product. The PCIe Device ID is 0xa080. AIC080 is a lower cost, lower performance SKU variant of AIC100. From the qaic perspective, it is the same as AIC100. Reviewed-by: Troy Hanson <quic_thanson@quicinc.com> Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004195209.3910996-1-quic_jhugo@quicinc.com --- Documentation/accel/qaic/aic080.rst | 14 ++++++++++++++ Documentation/accel/qaic/index.rst | 1 + drivers/accel/qaic/qaic_drv.c | 4 +++- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 Documentation/accel/qaic/aic080.rst diff --git a/Documentation/accel/qaic/aic080.rst b/Documentation/accel/qaic/aic080.rst new file mode 100644 index 000000000000..d563771ea6ce --- /dev/null +++ b/Documentation/accel/qaic/aic080.rst @@ -0,0 +1,14 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +=============================== + Qualcomm Cloud AI 80 (AIC080) +=============================== + +Overview +======== + +The Qualcomm Cloud AI 80/AIC080 family of products are a derivative of AIC100. +The number of NSPs and clock rates are reduced to fit within resource +constrained solutions. The PCIe Product ID is 0xa080. + +As a derivative product, all AIC100 documentation applies. diff --git a/Documentation/accel/qaic/index.rst b/Documentation/accel/qaic/index.rst index ad19b88d1a66..967b9dd8bace 100644 --- a/Documentation/accel/qaic/index.rst +++ b/Documentation/accel/qaic/index.rst @@ -10,4 +10,5 @@ accelerator cards. .. toctree:: qaic + aic080 aic100 diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index bf10156c334e..f139c564eadf 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -34,6 +34,7 @@ MODULE_IMPORT_NS(DMA_BUF); +#define PCI_DEV_AIC080 0xa080 #define PCI_DEV_AIC100 0xa100 #define QAIC_NAME "qaic" #define QAIC_DESC "Qualcomm Cloud AI Accelerators" @@ -365,7 +366,7 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev, const struct pci_de return NULL; qdev->dev_state = QAIC_OFFLINE; - if (id->device == PCI_DEV_AIC100) { + if (id->device == PCI_DEV_AIC080 || id->device == PCI_DEV_AIC100) { qdev->num_dbc = 16; qdev->dbc = devm_kcalloc(dev, qdev->num_dbc, sizeof(*qdev->dbc), GFP_KERNEL); if (!qdev->dbc) @@ -607,6 +608,7 @@ static struct mhi_driver qaic_mhi_driver = { }; static const struct pci_device_id qaic_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_QCOM, PCI_DEV_AIC080), }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, PCI_DEV_AIC100), }, { } }; -- GitLab From 2ad84af4cff9121827d3dd35e293478bdb0b58bb Mon Sep 17 00:00:00 2001 From: Miguel Ojeda <ojeda@kernel.org> Date: Fri, 4 Oct 2024 01:07:34 +0200 Subject: [PATCH 848/970] drm/panic: Select ZLIB_DEFLATE for DRM_PANIC_SCREEN_QR_CODE Under `CONFIG_DRM_PANIC_SCREEN_QR_CODE=y`, zlib is used: ld.lld: error: undefined symbol: zlib_deflate_workspacesize >>> referenced by drm_panic.c >>> drivers/gpu/drm/drm_panic.o:(drm_panic_qr_init) in archive vmlinux.a Thus select `CONFIG_ZLIB_DEFLATE`. Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen") Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003230734.653717-1-ojeda@kernel.org --- drivers/gpu/drm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 1df4e627e3d3..45f624b088da 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -152,6 +152,7 @@ config DRM_PANIC_SCREEN config DRM_PANIC_SCREEN_QR_CODE bool "Add a panic screen with a QR code" depends on DRM_PANIC && RUST + select ZLIB_DEFLATE help This option adds a QR code generator, and a panic screen with a QR code. The QR code will contain the last lines of kmsg and other debug -- GitLab From ea1d2a38fb6f0c02d02cc264909010c0102921ef Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:02:59 +0200 Subject: [PATCH 849/970] drm/amdgpu: Use video aperture helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-2-tzimmermann@suse.de --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index fd853dc843e9..128e086b4251 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -25,6 +25,8 @@ * Alex Deucher * Jerome Glisse */ + +#include <linux/aperture.h> #include <linux/power_supply.h> #include <linux/kthread.h> #include <linux/module.h> @@ -35,7 +37,6 @@ #include <linux/pci-p2pdma.h> #include <linux/apple-gmux.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> @@ -4199,7 +4200,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, return r; /* Get rid of things like offb */ - r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, &amdgpu_kms_driver); + r = aperture_remove_conflicting_pci_devices(adev->pdev, amdgpu_kms_driver.name); if (r) return r; -- GitLab From 16ef06807093c74738ef58929367642fb74e8114 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:00 +0200 Subject: [PATCH 850/970] drm/arm/hdlcd: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Liviu Dudau <liviu.dudau@arm.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-3-tzimmermann@suse.de --- drivers/gpu/drm/arm/hdlcd_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index f5d358f3893b..cd4389809d42 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -9,6 +9,7 @@ * ARM HDLCD Driver */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/spinlock.h> #include <linux/clk.h> @@ -21,7 +22,6 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_crtc.h> @@ -287,7 +287,7 @@ static int hdlcd_drm_bind(struct device *dev) */ if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) { hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); - drm_aperture_remove_framebuffers(&hdlcd_driver); + aperture_remove_all_conflicting_devices(hdlcd_driver.name); } drm_mode_config_reset(drm); -- GitLab From c05d784113745128b02f9318fef4e3d3a820ebe9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:01 +0200 Subject: [PATCH 851/970] drm/armada: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Russell King <linux@armlinux.org.uk> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-4-tzimmermann@suse.de --- drivers/gpu/drm/armada/armada_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 3dc5f0499e4c..5c26f0409478 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -3,6 +3,7 @@ * Copyright (C) 2012 Russell King */ +#include <linux/aperture.h> #include <linux/clk.h> #include <linux/component.h> #include <linux/module.h> @@ -10,7 +11,6 @@ #include <linux/of_graph.h> #include <linux/platform_device.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -93,7 +93,7 @@ static int armada_drm_bind(struct device *dev) } /* Remove early framebuffers */ - ret = drm_aperture_remove_framebuffers(&armada_drm_driver); + ret = aperture_remove_all_conflicting_devices(armada_drm_driver.name); if (ret) { dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n", __func__, ret); -- GitLab From 3bf66631a54b6537646fd3a2276c730236bd923d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:02 +0200 Subject: [PATCH 852/970] drm/ast: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Jocelyn Falempe <jfalempe@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-5-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 898c8b93c0b1..4afe4be072ef 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -26,11 +26,11 @@ * Authors: Dave Airlie <airlied@redhat.com> */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/of.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -281,7 +281,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct drm_device *drm; bool need_post = false; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &ast_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, ast_driver.name); if (ret) return ret; -- GitLab From 239af7de8f23ce757bd8081f5e8aca18e505868e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:03 +0200 Subject: [PATCH 853/970] drm/hisilicon/hibmc: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Xinliang Liu <xinliang.liu@linaro.org> Cc: Tian Tao <tiantao6@hisilicon.com> Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: Yongqin Liu <yongqin.liu@linaro.org> Cc: John Stultz <jstultz@google.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-6-tzimmermann@suse.de --- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 866a9ecaf8b9..8c488c98ac97 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -11,10 +11,10 @@ * Jianhua Li <lijianhua@huawei.com> */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -308,7 +308,7 @@ static int hibmc_pci_probe(struct pci_dev *pdev, struct drm_device *dev; int ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &hibmc_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, hibmc_driver.name); if (ret) return ret; -- GitLab From 37aeccf5f839c155e8c9100937a01059b24e61b5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:04 +0200 Subject: [PATCH 854/970] drm/hyperv-drm: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Deepak Rawat <drawat.floss@gmail.com> Reviewed-by: Deepak Rawat <drawat.floss@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-7-tzimmermann@suse.de --- drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index 3077ce5470f6..e0953777a206 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -3,12 +3,12 @@ * Copyright 2021 Microsoft */ +#include <linux/aperture.h> #include <linux/efi.h> #include <linux/hyperv.h> #include <linux/module.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -126,7 +126,7 @@ static int hyperv_vmbus_probe(struct hv_device *hdev, goto err_hv_set_drv_data; } - drm_aperture_remove_framebuffers(&hyperv_driver); + aperture_remove_all_conflicting_devices(hyperv_driver.name); ret = hyperv_setup_vram(hv, hdev); if (ret) -- GitLab From e4c80710d97c251f94a36228064c3a39fb75394b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:05 +0200 Subject: [PATCH 855/970] drm/i915: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Tvrtko Ursulin <tursulin@ursulin.net> Acked-by: Jani Nikula <jani.nikula@intel.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-8-tzimmermann@suse.de --- drivers/gpu/drm/i915/i915_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index a40f05b993da..74fa8f57f302 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -27,6 +27,7 @@ * */ +#include <linux/aperture.h> #include <linux/acpi.h> #include <linux/device.h> #include <linux/module.h> @@ -39,7 +40,6 @@ #include <linux/vga_switcheroo.h> #include <linux/vt.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> @@ -485,7 +485,7 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) if (ret) goto err_perf; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, dev_priv->drm.driver); + ret = aperture_remove_conflicting_pci_devices(pdev, dev_priv->drm.driver->name); if (ret) goto err_ggtt; -- GitLab From 902014e20f7cdc6ebb3113ef907d32bb2b3743ba Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:06 +0200 Subject: [PATCH 856/970] drm/loongson: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Sui Jingfeng <suijingfeng@loongson.cn> Acked-by: Sui Jingfeng <sui.jingfeng@linux.dev> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-9-tzimmermann@suse.de --- drivers/gpu/drm/loongson/lsdc_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c index a19dce35c839..b350bdcf1645 100644 --- a/drivers/gpu/drm/loongson/lsdc_drv.c +++ b/drivers/gpu/drm/loongson/lsdc_drv.c @@ -3,10 +3,10 @@ * Copyright (C) 2023 Loongson Technology Corporation Limited */ +#include <linux/aperture.h> #include <linux/pci.h> #include <linux/vgaarb.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> @@ -215,9 +215,9 @@ lsdc_create_device(struct pci_dev *pdev, return ERR_PTR(ret); } - ret = drm_aperture_remove_conflicting_framebuffers(ldev->vram_base, - ldev->vram_size, - driver); + ret = aperture_remove_conflicting_devices(ldev->vram_base, + ldev->vram_size, + driver->name); if (ret) { drm_err(ddev, "Remove firmware framebuffers failed: %d\n", ret); return ERR_PTR(ret); -- GitLab From 736db96696b6232d8002bfa1ef8fd5d7e1e0000e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:07 +0200 Subject: [PATCH 857/970] drm/meson: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Neil Armstrong <neil.armstrong@linaro.org> Cc: Kevin Hilman <khilman@baylibre.com> Cc: Jerome Brunet <jbrunet@baylibre.com> Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-10-tzimmermann@suse.de --- drivers/gpu/drm/meson/meson_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 2f76f48da38d..bbb662d2f184 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -8,6 +8,7 @@ * Jasper St. Pierre <jstpierre@mecheye.net> */ +#include <linux/aperture.h> #include <linux/component.h> #include <linux/module.h> #include <linux/of_graph.h> @@ -15,7 +16,6 @@ #include <linux/platform_device.h> #include <linux/soc/amlogic/meson-canvas.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -279,7 +279,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) * Remove early framebuffers (ie. simplefb). The framebuffer can be * located anywhere in RAM */ - ret = drm_aperture_remove_framebuffers(&meson_driver); + ret = aperture_remove_all_conflicting_devices(meson_driver.name); if (ret) goto free_canvas_vd1_2; -- GitLab From 2f85650d9db72c2950618c4dfa08d59be7c03ec1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:08 +0200 Subject: [PATCH 858/970] drm/mgag200: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Jocelyn Falempe <jfalempe@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-11-tzimmermann@suse.de --- drivers/gpu/drm/mgag200/mgag200_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 29087e2398df..42fabe817e21 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -6,10 +6,10 @@ * Dave Airlie */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -266,7 +266,7 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct drm_device *dev; int ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &mgag200_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, mgag200_driver.name); if (ret) return ret; -- GitLab From f5c31ce22e2ecd05c4e29df442c7df624d148ea5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:09 +0200 Subject: [PATCH 859/970] drm/msm: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Rob Clark <robdclark@gmail.com> Cc: Abhinav Kumar <quic_abhinavk@quicinc.com> Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Cc: Sean Paul <sean@poorly.run> Cc: Marijn Suijten <marijn.suijten@somainline.org> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-12-tzimmermann@suse.de --- drivers/gpu/drm/msm/msm_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c index af6a6fcb1173..f3326d09bdbc 100644 --- a/drivers/gpu/drm/msm/msm_kms.c +++ b/drivers/gpu/drm/msm/msm_kms.c @@ -5,11 +5,11 @@ * Author: Rob Clark <robdclark@gmail.com> */ +#include <linux/aperture.h> #include <linux/kthread.h> #include <linux/sched/mm.h> #include <uapi/linux/sched/types.h> -#include <drm/drm_aperture.h> #include <drm/drm_drv.h> #include <drm/drm_mode_config.h> #include <drm/drm_vblank.h> @@ -237,7 +237,7 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv) int ret; /* the fw fb could be anywhere in memory */ - ret = drm_aperture_remove_framebuffers(drv); + ret = aperture_remove_all_conflicting_devices(drv->name); if (ret) return ret; -- GitLab From 92f6453c9fd29722e382755f79cf40a10ca021bb Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:10 +0200 Subject: [PATCH 860/970] drm/nouveau: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Karol Herbst <kherbst@redhat.com> Cc: Lyude Paul <lyude@redhat.com> Cc: Danilo Krummrich <dakr@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-13-tzimmermann@suse.de --- drivers/gpu/drm/nouveau/nouveau_drm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 84d692d68817..02dd179a2f31 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ +#include <linux/aperture.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/pci.h> @@ -30,7 +31,6 @@ #include <linux/mmu_notifier.h> #include <linux/dynamic_debug.h> -#include <drm/drm_aperture.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> @@ -851,7 +851,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev, return ret; /* Remove conflicting drivers (vesafb, efifb etc). */ - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver_pci); + ret = aperture_remove_conflicting_pci_devices(pdev, driver_pci.name); if (ret) return ret; -- GitLab From 148efebdcf42b261a2ac80762fd937ac874cb721 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:11 +0200 Subject: [PATCH 861/970] drm/ofdrm: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-14-tzimmermann@suse.de --- drivers/gpu/drm/tiny/ofdrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index 04ffa93de44a..220c1244b3c0 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only +#include <linux/aperture.h> #include <linux/of_address.h> #include <linux/pci.h> #include <linux/platform_device.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_state_helper.h> #include <drm/drm_client_setup.h> @@ -1220,7 +1220,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, fb_pgbase = round_down(fb_base, PAGE_SIZE); fb_pgsize = fb_base - fb_pgbase + round_up(fb_size, PAGE_SIZE); - ret = devm_aperture_acquire_from_firmware(dev, fb_pgbase, fb_pgsize); + ret = devm_aperture_acquire_for_platform_device(pdev, fb_pgbase, fb_pgsize); if (ret) { drm_err(dev, "could not acquire memory range %pr: error %d\n", &res, ret); return ERR_PTR(ret); -- GitLab From 6569392c1dfd74b3fba61c9e8124ed5551890c5a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:12 +0200 Subject: [PATCH 862/970] drm/qxl: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-15-tzimmermann@suse.de --- drivers/gpu/drm/qxl/qxl_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 4ef1c134d6dd..21f752644242 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -29,12 +29,12 @@ #include "qxl_drv.h" +#include <linux/aperture.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/vgaarb.h> #include <drm/drm.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -92,7 +92,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &qxl_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, qxl_driver.name); if (ret) goto disable_pci; -- GitLab From fea5d61b80a107e80feb83651f73d6002cb565a4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:13 +0200 Subject: [PATCH 863/970] drm/radeon: Use video aperture helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-16-tzimmermann@suse.de --- drivers/gpu/drm/radeon/radeon_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 900b05d8aa5c..23d6d1a2586d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -29,7 +29,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ - +#include <linux/aperture.h> #include <linux/compat.h> #include <linux/module.h> #include <linux/pm_runtime.h> @@ -37,7 +37,6 @@ #include <linux/mmu_notifier.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> @@ -300,7 +299,7 @@ static int radeon_pci_probe(struct pci_dev *pdev, return -EPROBE_DEFER; /* Get rid of things like offb */ - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &kms_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, kms_driver.name); if (ret) return ret; -- GitLab From 634bd2985716bcb0b5b8b22a0a117bce283d1b08 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:14 +0200 Subject: [PATCH 864/970] drm/rockchip: Use video aperture helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Sandy Huang <hjc@rock-chips.com> Cc: "Heiko Stübner" <heiko@sntech.de> Cc: Andy Yan <andy.yan@rock-chips.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-17-tzimmermann@suse.de --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 4e080040ba01..2560b0eec9db 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -6,6 +6,7 @@ * based on exynos_drm_drv.c */ +#include <linux/aperture.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -16,7 +17,6 @@ #include <linux/console.h> #include <linux/iommu.h> -#include <drm/drm_aperture.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_dma.h> @@ -146,7 +146,7 @@ static int rockchip_drm_bind(struct device *dev) int ret; /* Remove existing drivers that may own the framebuffer memory. */ - ret = drm_aperture_remove_framebuffers(&rockchip_drm_driver); + ret = aperture_remove_all_conflicting_devices(rockchip_drm_driver.name); if (ret) { DRM_DEV_ERROR(dev, "Failed to remove existing framebuffers - %d.\n", -- GitLab From 40f853ebd55de7f90ad6d56e20ca2ff827ef5923 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:15 +0200 Subject: [PATCH 865/970] drm/simpledrm: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-18-tzimmermann@suse.de --- drivers/gpu/drm/tiny/simpledrm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index 484901e5e2f4..3182d32f1b8f 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only +#include <linux/aperture.h> #include <linux/clk.h> #include <linux/of_clk.h> #include <linux/minmax.h> @@ -9,7 +10,6 @@ #include <linux/pm_domain.h> #include <linux/regulator/consumer.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_state_helper.h> #include <drm/drm_client_setup.h> @@ -883,7 +883,8 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, if (mem) { void *screen_base; - ret = devm_aperture_acquire_from_firmware(dev, mem->start, resource_size(mem)); + ret = devm_aperture_acquire_for_platform_device(pdev, mem->start, + resource_size(mem)); if (ret) { drm_err(dev, "could not acquire memory range %pr: %d\n", mem, ret); return ERR_PTR(ret); @@ -903,7 +904,8 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, if (!res) return ERR_PTR(-EINVAL); - ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res)); + ret = devm_aperture_acquire_for_platform_device(pdev, res->start, + resource_size(res)); if (ret) { drm_err(dev, "could not acquire memory range %pr: %d\n", res, ret); return ERR_PTR(ret); -- GitLab From 0ec058adfab803ba597563066c4a1652468dbad9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:16 +0200 Subject: [PATCH 866/970] drm/stm: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Yannick Fertre <yannick.fertre@foss.st.com> Cc: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com> Cc: Philippe Cornu <philippe.cornu@foss.st.com> Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com> Cc: Alexandre Torgue <alexandre.torgue@foss.st.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-19-tzimmermann@suse.de --- drivers/gpu/drm/stm/drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index fee274a60623..478dc129d5c2 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -8,6 +8,7 @@ * Mickael Reulier <mickael.reulier@st.com> */ +#include <linux/aperture.h> #include <linux/component.h> #include <linux/dma-mapping.h> #include <linux/mod_devicetable.h> @@ -15,7 +16,6 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> @@ -191,7 +191,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev) DRM_DEBUG("%s\n", __func__); - ret = drm_aperture_remove_framebuffers(&drv_driver); + ret = aperture_remove_all_conflicting_devices(drv_driver.name); if (ret) return ret; -- GitLab From ea277eb35647a3461965703789f0bb531b039582 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:17 +0200 Subject: [PATCH 867/970] drm/sun4i: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Maxime Ripard <mripard@kernel.org> Cc: Chen-Yu Tsai <wens@csie.org> Cc: Jernej Skrabec <jernej.skrabec@gmail.com> Cc: Samuel Holland <samuel@sholland.org> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-20-tzimmermann@suse.de --- drivers/gpu/drm/sun4i/sun4i_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index c3342789e3b0..3f880d8a5666 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -6,6 +6,7 @@ * Maxime Ripard <maxime.ripard@free-electrons.com> */ +#include <linux/aperture.h> #include <linux/component.h> #include <linux/dma-mapping.h> #include <linux/kfifo.h> @@ -14,7 +15,6 @@ #include <linux/of_reserved_mem.h> #include <linux/platform_device.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -100,7 +100,7 @@ static int sun4i_drv_bind(struct device *dev) goto unbind_all; /* Remove early framebuffers (ie. simplefb) */ - ret = drm_aperture_remove_framebuffers(&sun4i_drv_driver); + ret = aperture_remove_all_conflicting_devices(sun4i_drv_driver.name); if (ret) goto unbind_all; -- GitLab From a29705e55e360ea8f26bd6a5aa7dadc89e12e680 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:18 +0200 Subject: [PATCH 868/970] drm/tegra: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Thierry Reding <thierry.reding@gmail.com> Cc: Mikko Perttunen <mperttunen@nvidia.com> Cc: Jonathan Hunter <jonathanh@nvidia.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-21-tzimmermann@suse.de --- drivers/gpu/drm/tegra/drm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index dd82ab71d4a9..babcb3958f86 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -4,6 +4,7 @@ * Copyright (C) 2012-2016 NVIDIA CORPORATION. All rights reserved. */ +#include <linux/aperture.h> #include <linux/bitops.h> #include <linux/host1x.h> #include <linux/idr.h> @@ -12,7 +13,6 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> @@ -1258,7 +1258,7 @@ static int host1x_drm_probe(struct host1x_device *dev) * will not expose any modesetting features. */ if (drm->mode_config.num_crtc > 0) { - err = drm_aperture_remove_framebuffers(&tegra_drm_driver); + err = aperture_remove_all_conflicting_devices(tegra_drm_driver.name); if (err < 0) goto hub; } else { -- GitLab From 7934a1c2509740e6cbfa899f750a0d5cbf9ba09d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:19 +0200 Subject: [PATCH 869/970] drm/bochs: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-22-tzimmermann@suse.de --- drivers/gpu/drm/tiny/bochs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 3ba7f09f3e7b..447989bb8201 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include <linux/aperture.h> #include <linux/module.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> @@ -711,7 +711,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent struct drm_device *dev; int ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &bochs_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, bochs_driver.name); if (ret) return ret; -- GitLab From c77ec6b18b0397cf1f0c270ea77310f70fe48081 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:20 +0200 Subject: [PATCH 870/970] drm/cirrus: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Dave Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-23-tzimmermann@suse.de --- drivers/gpu/drm/tiny/cirrus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c index 20c4479ed4c3..f06a2be71f60 100644 --- a/drivers/gpu/drm/tiny/cirrus.c +++ b/drivers/gpu/drm/tiny/cirrus.c @@ -16,6 +16,7 @@ * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> */ +#include <linux/aperture.h> #include <linux/iosys-map.h> #include <linux/module.h> #include <linux/pci.h> @@ -23,7 +24,6 @@ #include <video/cirrus.h> #include <video/vga.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_state_helper.h> @@ -673,7 +673,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev, struct cirrus_device *cirrus; int ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &cirrus_driver); + ret = aperture_remove_conflicting_pci_devices(pdev, cirrus_driver.name); if (ret) return ret; -- GitLab From 574c1c334c5a7ebc32eb635b8ed9b8ded3337150 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:21 +0200 Subject: [PATCH 871/970] drm/vboxvideo: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Hans de Goede <hdegoede@redhat.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-24-tzimmermann@suse.de --- drivers/gpu/drm/vboxvideo/vbox_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index 49dc337b3e01..a536c467e2b2 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -7,11 +7,12 @@ * Michael Thayer <michael.thayer@oracle.com, * Hans de Goede <hdegoede@redhat.com> */ + +#include <linux/aperture.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/vt_kern.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -45,7 +46,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!vbox_check_supported(VBE_DISPI_ID_HGSMI)) return -ENODEV; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); + ret = aperture_remove_conflicting_pci_devices(pdev, driver.name); if (ret) return ret; -- GitLab From 7e89e4365fd36ca006670788ec2c1527bfd0c61c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:22 +0200 Subject: [PATCH 872/970] drm/vc4: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Maxime Ripard <mripard@kernel.org> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com> Cc: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-25-tzimmermann@suse.de --- drivers/gpu/drm/vc4/vc4_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index a238f76a6073..d47e5967592f 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -20,6 +20,7 @@ * driver. */ +#include <linux/aperture.h> #include <linux/clk.h> #include <linux/component.h> #include <linux/device.h> @@ -30,7 +31,6 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -360,7 +360,7 @@ static int vc4_drm_bind(struct device *dev) } } - ret = drm_aperture_remove_framebuffers(driver); + ret = aperture_remove_all_conflicting_devices(driver->name); if (ret) goto err; -- GitLab From d2c323d00b0f22b11af3b8604b183fd9ec6010c7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:23 +0200 Subject: [PATCH 873/970] drm/virtgpu: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@redhat.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Gurchetan Singh <gurchetansingh@chromium.org> Cc: Chia-I Wu <olvaffe@gmail.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-26-tzimmermann@suse.de --- drivers/gpu/drm/virtio/virtgpu_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 1e08d91a4d17..ffca6e2e1c9a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -26,13 +26,13 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include <linux/aperture.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/poll.h> #include <linux/wait.h> #include <drm/drm.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> @@ -59,7 +59,7 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev) vga ? "virtio-vga" : "virtio-gpu-pci", pname); if (vga) { - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); + ret = aperture_remove_conflicting_pci_devices(pdev, driver.name); if (ret) return ret; } -- GitLab From 2fb05e8d7b9a28e48ef0fa00bee90b8b0a11000d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:24 +0200 Subject: [PATCH 874/970] drm/vmwgfx: Use video aperture helpers DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Zack Rusin <zack.rusin@broadcom.com> Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-27-tzimmermann@suse.de --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 2706d0b57a2b..2c46897876dd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -35,7 +35,6 @@ #include "vmwgfx_vkms.h" #include "ttm_object.h" -#include <drm/drm_aperture.h> #include <drm/drm_client_setup.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_ttm.h> @@ -50,6 +49,8 @@ #ifdef CONFIG_X86 #include <asm/hypervisor.h> #endif + +#include <linux/aperture.h> #include <linux/cc_platform.h> #include <linux/dma-mapping.h> #include <linux/module.h> @@ -1654,7 +1655,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct vmw_private *vmw; int ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); + ret = aperture_remove_conflicting_pci_devices(pdev, driver.name); if (ret) goto out_error; -- GitLab From a522000d9470e4149ca835e7bd9213bfad4d813c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:25 +0200 Subject: [PATCH 875/970] drm/xe: Use video aperture helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRM's aperture functions have long been implemented as helpers under drivers/video/ for use with fbdev. Avoid the DRM wrappers by calling the video functions directly. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-28-tzimmermann@suse.de --- drivers/gpu/drm/xe/xe_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 962751c966d1..088369897aa7 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -5,11 +5,11 @@ #include "xe_device.h" +#include <linux/aperture.h> #include <linux/delay.h> #include <linux/fault-inject.h> #include <linux/units.h> -#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_client.h> #include <drm/drm_gem_ttm_helper.h> @@ -311,7 +311,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, xe_display_driver_set_hooks(&driver); - err = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); + err = aperture_remove_conflicting_pci_devices(pdev, driver.name); if (err) return ERR_PTR(err); -- GitLab From 689274a56c0c088796d359f6c6267323931a2429 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 30 Sep 2024 15:03:26 +0200 Subject: [PATCH 876/970] drm: Remove DRM aperture helpers The DRM aperture helpers are wrappers around video helpers from <linux/aperture.h>. There are no callers of these functions. Remove them entirely. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jonathan Corbet <corbet@lwn.net> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930130921.689876-29-tzimmermann@suse.de --- Documentation/gpu/drm-internals.rst | 12 -- MAINTAINERS | 2 - drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/drm_aperture.c | 192 ---------------------------- include/drm/drm_aperture.h | 38 ------ 5 files changed, 245 deletions(-) delete mode 100644 drivers/gpu/drm/drm_aperture.c delete mode 100644 include/drm/drm_aperture.h diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 11d9a5730fb2..cb9ae282771c 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -75,18 +75,6 @@ Module Initialization .. kernel-doc:: include/drm/drm_module.h :doc: overview -Managing Ownership of the Framebuffer Aperture ----------------------------------------------- - -.. kernel-doc:: drivers/gpu/drm/drm_aperture.c - :doc: overview - -.. kernel-doc:: include/drm/drm_aperture.h - :internal: - -.. kernel-doc:: drivers/gpu/drm/drm_aperture.c - :export: - Device Instance and Driver Handling ----------------------------------- diff --git a/MAINTAINERS b/MAINTAINERS index 7d0b4335e263..e200e10696fd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7097,12 +7097,10 @@ M: Javier Martinez Canillas <javierm@redhat.com> L: dri-devel@lists.freedesktop.org S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git -F: drivers/gpu/drm/drm_aperture.c F: drivers/gpu/drm/tiny/ofdrm.c F: drivers/gpu/drm/tiny/simpledrm.c F: drivers/video/aperture.c F: drivers/video/nomodeset.c -F: include/drm/drm_aperture.h F: include/linux/aperture.h F: include/video/nomodeset.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 3894f43f6d47..31d8bf60a2fd 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -34,7 +34,6 @@ endif subdir-ccflags-$(CONFIG_DRM_WERROR) += -Werror drm-y := \ - drm_aperture.o \ drm_atomic.o \ drm_atomic_uapi.o \ drm_auth.o \ diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c deleted file mode 100644 index 5729f3bb4398..000000000000 --- a/drivers/gpu/drm/drm_aperture.c +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include <linux/aperture.h> -#include <linux/platform_device.h> - -#include <drm/drm_aperture.h> -#include <drm/drm_drv.h> -#include <drm/drm_print.h> - -/** - * DOC: overview - * - * A graphics device might be supported by different drivers, but only one - * driver can be active at any given time. Many systems load a generic - * graphics drivers, such as EFI-GOP or VESA, early during the boot process. - * During later boot stages, they replace the generic driver with a dedicated, - * hardware-specific driver. To take over the device the dedicated driver - * first has to remove the generic driver. DRM aperture functions manage - * ownership of DRM framebuffer memory and hand-over between drivers. - * - * DRM drivers should call drm_aperture_remove_conflicting_framebuffers() - * at the top of their probe function. The function removes any generic - * driver that is currently associated with the given framebuffer memory. - * If the framebuffer is located at PCI BAR 0, the rsp code looks as in the - * example given below. - * - * .. code-block:: c - * - * static const struct drm_driver example_driver = { - * ... - * }; - * - * static int remove_conflicting_framebuffers(struct pci_dev *pdev) - * { - * resource_size_t base, size; - * int ret; - * - * base = pci_resource_start(pdev, 0); - * size = pci_resource_len(pdev, 0); - * - * return drm_aperture_remove_conflicting_framebuffers(base, size, - * &example_driver); - * } - * - * static int probe(struct pci_dev *pdev) - * { - * int ret; - * - * // Remove any generic drivers... - * ret = remove_conflicting_framebuffers(pdev); - * if (ret) - * return ret; - * - * // ... and initialize the hardware. - * ... - * - * drm_dev_register(); - * - * return 0; - * } - * - * PCI device drivers should call - * drm_aperture_remove_conflicting_pci_framebuffers() and let it detect the - * framebuffer apertures automatically. Device drivers without knowledge of - * the framebuffer's location shall call drm_aperture_remove_framebuffers(), - * which removes all drivers for known framebuffer. - * - * Drivers that are susceptible to being removed by other drivers, such as - * generic EFI or VESA drivers, have to register themselves as owners of their - * given framebuffer memory. Ownership of the framebuffer memory is achieved - * by calling devm_aperture_acquire_from_firmware(). On success, the driver - * is the owner of the framebuffer range. The function fails if the - * framebuffer is already owned by another driver. See below for an example. - * - * .. code-block:: c - * - * static int acquire_framebuffers(struct drm_device *dev, struct platform_device *pdev) - * { - * resource_size_t base, size; - * - * mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - * if (!mem) - * return -EINVAL; - * base = mem->start; - * size = resource_size(mem); - * - * return devm_acquire_aperture_from_firmware(dev, base, size); - * } - * - * static int probe(struct platform_device *pdev) - * { - * struct drm_device *dev; - * int ret; - * - * // ... Initialize the device... - * dev = devm_drm_dev_alloc(); - * ... - * - * // ... and acquire ownership of the framebuffer. - * ret = acquire_framebuffers(dev, pdev); - * if (ret) - * return ret; - * - * drm_dev_register(dev, 0); - * - * return 0; - * } - * - * The generic driver is now subject to forced removal by other drivers. This - * only works for platform drivers that support hot unplug. - * When a driver calls drm_aperture_remove_conflicting_framebuffers() et al. - * for the registered framebuffer range, the aperture helpers call - * platform_device_unregister() and the generic driver unloads itself. It - * may not access the device's registers, framebuffer memory, ROM, etc - * afterwards. - */ - -/** - * devm_aperture_acquire_from_firmware - Acquires ownership of a firmware framebuffer - * on behalf of a DRM driver. - * @dev: the DRM device to own the framebuffer memory - * @base: the framebuffer's byte offset in physical memory - * @size: the framebuffer size in bytes - * - * Installs the given device as the new owner of the framebuffer. The function - * expects the framebuffer to be provided by a platform device that has been - * set up by firmware. Firmware can be any generic interface, such as EFI, - * VESA, VGA, etc. If the native hardware driver takes over ownership of the - * framebuffer range, the firmware state gets lost. Aperture helpers will then - * unregister the platform device automatically. Acquired apertures are - * released automatically if the underlying device goes away. - * - * The function fails if the framebuffer range, or parts of it, is currently - * owned by another driver. To evict current owners, callers should use - * drm_aperture_remove_conflicting_framebuffers() et al. before calling this - * function. The function also fails if the given device is not a platform - * device. - * - * Returns: - * 0 on success, or a negative errno value otherwise. - */ -int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t base, - resource_size_t size) -{ - struct platform_device *pdev; - - if (drm_WARN_ON(dev, !dev_is_platform(dev->dev))) - return -EINVAL; - - pdev = to_platform_device(dev->dev); - - return devm_aperture_acquire_for_platform_device(pdev, base, size); -} -EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); - -/** - * drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range - * @base: the aperture's base address in physical memory - * @size: aperture size in bytes - * @req_driver: requesting DRM driver - * - * This function removes graphics device drivers which use the memory range described by - * @base and @size. - * - * Returns: - * 0 on success, or a negative errno code otherwise - */ -int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - const struct drm_driver *req_driver) -{ - return aperture_remove_conflicting_devices(base, size, req_driver->name); -} -EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); - -/** - * drm_aperture_remove_conflicting_pci_framebuffers - remove existing framebuffers for PCI devices - * @pdev: PCI device - * @req_driver: requesting DRM driver - * - * This function removes graphics device drivers using the memory range configured - * for any of @pdev's memory bars. The function assumes that a PCI device with - * shadowed ROM drives a primary display and so kicks out vga16fb. - * - * Returns: - * 0 on success, or a negative errno code otherwise - */ -int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, - const struct drm_driver *req_driver) -{ - return aperture_remove_conflicting_pci_devices(pdev, req_driver->name); -} -EXPORT_SYMBOL(drm_aperture_remove_conflicting_pci_framebuffers); diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h deleted file mode 100644 index cbe33b49fd5d..000000000000 --- a/include/drm/drm_aperture.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#ifndef _DRM_APERTURE_H_ -#define _DRM_APERTURE_H_ - -#include <linux/types.h> - -struct drm_device; -struct drm_driver; -struct pci_dev; - -int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t base, - resource_size_t size); - -int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - const struct drm_driver *req_driver); - -int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, - const struct drm_driver *req_driver); - -/** - * drm_aperture_remove_framebuffers - remove all existing framebuffers - * @req_driver: requesting DRM driver - * - * This function removes all graphics device drivers. Use this function on systems - * that can have their framebuffer located anywhere in memory. - * - * Returns: - * 0 on success, or a negative errno code otherwise - */ -static inline int -drm_aperture_remove_framebuffers(const struct drm_driver *req_driver) -{ - return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, - req_driver); -} - -#endif -- GitLab From 16c51e4283c06e9329a58956f8fa97a715d3b68c Mon Sep 17 00:00:00 2001 From: Pintu Kumar <quic_pintu@quicinc.com> Date: Sat, 5 Oct 2024 23:39:55 +0530 Subject: [PATCH 877/970] dma-buf: fix S_IRUGO to 0444, block comments, func declaration These warnings/errors are reported by checkpatch. Fix them with minor changes to make it clean. No other functional changes. WARNING: Block comments use * on subsequent lines + /* only support discovering the end of the buffer, + but also allow SEEK_SET to maintain the idiomatic WARNING: Block comments use a trailing */ on a separate line + SEEK_END(0), SEEK_CUR(0) pattern */ WARNING: Block comments use a trailing */ on a separate line + * before passing the sgt back to the exporter. */ ERROR: "foo * bar" should be "foo *bar" +static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach, WARNING: Symbolic permissions 'S_IRUGO' are not preferred. Consider using octal permissions '0444'. + d = debugfs_create_file("bufinfo", S_IRUGO, dma_buf_debugfs_dir, total: 1 errors, 4 warnings, 1746 lines checked Signed-off-by: Pintu Kumar <quic_pintu@quicinc.com> Acked-by: John Stultz <jstultz@google.com> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241005180955.6523-1-quic_pintu@quicinc.com --- drivers/dma-buf/dma-buf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index fbbb750bc5b1..2472eb96c4b7 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -176,8 +176,9 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) dmabuf = file->private_data; /* only support discovering the end of the buffer, - but also allow SEEK_SET to maintain the idiomatic - SEEK_END(0), SEEK_CUR(0) pattern */ + * but also allow SEEK_SET to maintain the idiomatic + * SEEK_END(0), SEEK_CUR(0) pattern. + */ if (whence == SEEK_END) base = dmabuf->size; else if (whence == SEEK_SET) @@ -782,13 +783,14 @@ static void mangle_sg_table(struct sg_table *sg_table) /* To catch abuse of the underlying struct page by importers mix * up the bits, but take care to preserve the low SG_ bits to * not corrupt the sgt. The mixing is undone in __unmap_dma_buf - * before passing the sgt back to the exporter. */ + * before passing the sgt back to the exporter. + */ for_each_sgtable_sg(sg_table, sg, i) sg->page_link ^= ~0xffUL; #endif } -static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach, +static struct sg_table *__map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction direction) { struct sg_table *sg_table; @@ -1697,7 +1699,7 @@ static int dma_buf_init_debugfs(void) dma_buf_debugfs_dir = d; - d = debugfs_create_file("bufinfo", S_IRUGO, dma_buf_debugfs_dir, + d = debugfs_create_file("bufinfo", 0444, dma_buf_debugfs_dir, NULL, &dma_buf_debug_fops); if (IS_ERR(d)) { pr_debug("dma_buf: debugfs: failed to create node bufinfo\n"); -- GitLab From 4a1cb63bf321c1e498d3f19a6049e56838b18f82 Mon Sep 17 00:00:00 2001 From: Pintu Kumar <quic_pintu@quicinc.com> Date: Tue, 1 Oct 2024 23:20:57 +0530 Subject: [PATCH 878/970] dma-buf/heaps: replace kmap_atomic with kmap_local_page Use of kmap_atomic/kunmap_atomic is deprecated, use kmap_local_page/kunmap_local instead. This is reported by checkpatch. Also fix repeated word issue. WARNING: Deprecated use of 'kmap_atomic', prefer 'kmap_local_page' instead + void *vaddr = kmap_atomic(page); WARNING: Deprecated use of 'kunmap_atomic', prefer 'kunmap_local' instead + kunmap_atomic(vaddr); WARNING: Possible repeated word: 'by' + * has been killed by by SIGKILL total: 0 errors, 3 warnings, 405 lines checked Signed-off-by: Pintu Kumar <quic_pintu@quicinc.com> Reviewed-by: T.J. Mercier <tjmercier@google.com> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241001175057.27172-1-quic_pintu@quicinc.com --- drivers/dma-buf/heaps/cma_heap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 0e6e1982777c..9512d050563a 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -309,13 +309,13 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap, struct page *page = cma_pages; while (nr_clear_pages > 0) { - void *vaddr = kmap_atomic(page); + void *vaddr = kmap_local_page(page); memset(vaddr, 0, PAGE_SIZE); - kunmap_atomic(vaddr); + kunmap_local(vaddr); /* * Avoid wasting time zeroing memory if the process - * has been killed by by SIGKILL + * has been killed by SIGKILL. */ if (fatal_signal_pending(current)) goto free_cma; -- GitLab From 0654196d7ea20934f90a87d1b523ef3b77fb021b Mon Sep 17 00:00:00 2001 From: Uros Bizjak <ubizjak@gmail.com> Date: Mon, 7 Oct 2024 10:37:52 +0200 Subject: [PATCH 879/970] dma-buf: Use atomic64_inc_return() in dma_buf_getfile() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use atomic64_inc_return(&ref) instead of atomic64_add_return(1, &ref) to use optimized implementation and ease register pressure around the primitive for targets that implement optimized variant. Signed-off-by: Uros Bizjak <ubizjak@gmail.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: "Christian König" <christian.koenig@amd.com> Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241007083921.47525-1-ubizjak@gmail.com --- drivers/dma-buf/dma-buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 2472eb96c4b7..5ad0e9e2e1b9 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -559,7 +559,7 @@ static struct file *dma_buf_getfile(size_t size, int flags) * Override ->i_ino with the unique and dmabuffs specific * value. */ - inode->i_ino = atomic64_add_return(1, &dmabuf_inode); + inode->i_ino = atomic64_inc_return(&dmabuf_inode); flags &= O_ACCMODE | O_NONBLOCK; file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf", flags, &dma_buf_fops); -- GitLab From dca22e99706b70169534575fc82028bb6d44138a Mon Sep 17 00:00:00 2001 From: Danila Tikhonov <danila@jiaxyga.com> Date: Mon, 14 Oct 2024 00:24:01 +0300 Subject: [PATCH 880/970] dt-bindings: display: panel: Add Samsung AMS581VF01 The Samsung AMS581VF01 is a 5.81 inch 1080x2340 MIPI-DSI CMD mode OLED panel used in Google Pixel 4a (sm7150-google-sunfish) Add a dt-binding for it. Signed-off-by: Danila Tikhonov <danila@jiaxyga.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20241013212402.15624-2-danila@jiaxyga.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241013212402.15624-2-danila@jiaxyga.com --- .../display/panel/samsung,ams581vf01.yaml | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,ams581vf01.yaml diff --git a/Documentation/devicetree/bindings/display/panel/samsung,ams581vf01.yaml b/Documentation/devicetree/bindings/display/panel/samsung,ams581vf01.yaml new file mode 100644 index 000000000000..70dff9c0ef2b --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,ams581vf01.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/samsung,ams581vf01.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung AMS581VF01 SOFEF01-based 5.81" 1080x2340 MIPI-DSI Panel + +maintainers: + - Danila Tikhonov <danila@jiaxyga.com> + +description: + The Samsung AMS581VF01 is a 5.81 inch 1080x2340 MIPI-DSI CMD mode OLED panel. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: samsung,ams581vf01 + + reg: + maxItems: 1 + + vdd3p3-supply: + description: 3.3V source voltage rail + + vddio-supply: + description: I/O source voltage rail + + vsn-supply: + description: Negative source voltage rail + + vsp-supply: + description: Positive source voltage rail + + reset-gpios: true + port: true + +required: + - compatible + - reg + - vdd3p3-supply + - vddio-supply + - vsn-supply + - vsp-supply + - reset-gpios + - port + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "samsung,ams581vf01"; + reg = <0>; + + vdd3p3-supply = <&vreg_l7c_3p0>; + vddio-supply = <&vreg_l13a_1p8>; + vsn-supply = <&vreg_ibb>; + vsp-supply = <&vreg_lab>; + + reset-gpios = <&pm6150l_gpios 9 GPIO_ACTIVE_LOW>; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; + }; + +... -- GitLab From b330f3a069a20a5698ac840908579c325b7bdc4a Mon Sep 17 00:00:00 2001 From: Danila Tikhonov <danila@jiaxyga.com> Date: Mon, 14 Oct 2024 00:24:02 +0300 Subject: [PATCH 881/970] drm/panel: Add Samsung AMS581VF01 panel driver Add the driver for Samsung AMS581VF01 SOFEF01-based 5.81" FHD Plus CMD mode OLED panel support found in Google Pixel 4a (sm7150-google-sunfish) Signed-off-by: Danila Tikhonov <danila@jiaxyga.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://lore.kernel.org/r/20241013212402.15624-3-danila@jiaxyga.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241013212402.15624-3-danila@jiaxyga.com --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-samsung-ams581vf01.c | 283 ++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams581vf01.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ddfaa99ea9dd..f637dcc7a886 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -614,6 +614,15 @@ config DRM_PANEL_RONBO_RB070D30 Say Y here if you want to enable support for Ronbo Electronics RB070D30 1024x600 DSI panel. +config DRM_PANEL_SAMSUNG_AMS581VF01 + tristate "Samsung AMS581VF01 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y or M here if you want to enable support for the + Samsung AMS581VF01 FHD Plus (2340x1080@60Hz) CMD mode panel. + config DRM_PANEL_SAMSUNG_AMS639RQ08 tristate "Samsung AMS639RQ08 panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 4b5eaf111676..4db02c2411ae 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM692E5) += panel-raydium-rm692e5.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM69380) += panel-raydium-rm69380.o obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01) += panel-samsung-ams581vf01.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08) += panel-samsung-ams639rq08.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o diff --git a/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c b/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c new file mode 100644 index 000000000000..cf6186312252 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-ams581vf01.c @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com> + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +/* Manufacturer Command Set */ +#define MCS_ACCESS_PROT_OFF 0xb0 +#define MCS_PASSWD 0xf0 + +struct ams581vf01 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; +}; + +static const struct regulator_bulk_data ams581vf01_supplies[] = { + { .supply = "vdd3p3" }, + { .supply = "vddio" }, + { .supply = "vsn" }, + { .supply = "vsp" }, +}; + +static inline struct ams581vf01 *to_ams581vf01(struct drm_panel *panel) +{ + return container_of(panel, struct ams581vf01, panel); +} + +static void ams581vf01_reset(struct ams581vf01 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); +} + +static int ams581vf01_on(struct ams581vf01 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + /* Sleep Out, Wait 10ms */ + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + usleep_range(10000, 11000); + + /* TE On */ + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + + /* MIC Setting */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD, 0x5a, 0x5a); /* Unlock */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xeb, 0x17, + 0x41, 0x92, + 0x0e, 0x10, + 0x82, 0x5a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD, 0xa5, 0xa5); /* Lock */ + + /* Column & Page Address Setting */ + mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 0x0437); + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x0923); + + /* Brightness Setting */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20); + + /* Horizontal & Vertical sync Setting */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD, 0x5a, 0x5a); /* Unlock */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x09); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe8, 0x11, 0x30); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD, 0xa5, 0xa5); /* Lock */ + mipi_dsi_msleep(&dsi_ctx, 110); + + /* Display On */ + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + + return dsi_ctx.accum_err; +} + +static void ams581vf01_off(struct ams581vf01 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + /* Display Off & Sleep In */ + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + + /* VCI operating mode change */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD, 0x5a, 0x5a); /* Unlock */ + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_ACCESS_PROT_OFF, 0x05); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MCS_PASSWD, 0xa5, 0xa5); /* Lock */ + + mipi_dsi_msleep(&dsi_ctx, 120); +} + +static int ams581vf01_prepare(struct drm_panel *panel) +{ + struct ams581vf01 *ctx = to_ams581vf01(panel); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(ams581vf01_supplies), + ctx->supplies); + if (ret < 0) + return ret; + + ams581vf01_reset(ctx); + + ret = ams581vf01_on(ctx); + if (ret < 0) { + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ams581vf01_supplies), + ctx->supplies); + return ret; + } + + return 0; +} + +static int ams581vf01_unprepare(struct drm_panel *panel) +{ + struct ams581vf01 *ctx = to_ams581vf01(panel); + + ams581vf01_off(ctx); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ams581vf01_supplies), + ctx->supplies); + + return 0; +} + +static const struct drm_display_mode ams581vf01_mode = { + .clock = (1080 + 32 + 73 + 98) * (2340 + 8 + 1 + 8) * 60 / 1000, + .hdisplay = 1080, + .hsync_start = 1080 + 32, + .hsync_end = 1080 + 32 + 73, + .htotal = 1080 + 32 + 73 + 98, + .vdisplay = 2340, + .vsync_start = 2340 + 8, + .vsync_end = 2340 + 8 + 1, + .vtotal = 2340 + 8 + 1 + 8, + .width_mm = 62, + .height_mm = 134, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int ams581vf01_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &ams581vf01_mode); +} + +static const struct drm_panel_funcs ams581vf01_panel_funcs = { + .prepare = ams581vf01_prepare, + .unprepare = ams581vf01_unprepare, + .get_modes = ams581vf01_get_modes, +}; + +static int ams581vf01_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct backlight_ops ams581vf01_bl_ops = { + .update_status = ams581vf01_bl_update_status, +}; + +static struct backlight_device * +ams581vf01_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 511, + .max_brightness = 1023, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &ams581vf01_bl_ops, &props); +} + +static int ams581vf01_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct ams581vf01 *ctx; + int ret; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ret = devm_regulator_bulk_get_const(&dsi->dev, + ARRAY_SIZE(ams581vf01_supplies), + ams581vf01_supplies, + &ctx->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM; + + drm_panel_init(&ctx->panel, dev, &ams581vf01_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + ctx->panel.prepare_prev_first = true; + + ctx->panel.backlight = ams581vf01_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void ams581vf01_remove(struct mipi_dsi_device *dsi) +{ + struct ams581vf01 *ctx = mipi_dsi_get_drvdata(dsi); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id ams581vf01_of_match[] = { + { .compatible = "samsung,ams581vf01" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ams581vf01_of_match); + +static struct mipi_dsi_driver ams581vf01_driver = { + .probe = ams581vf01_probe, + .remove = ams581vf01_remove, + .driver = { + .name = "panel-samsung-ams581vf01", + .of_match_table = ams581vf01_of_match, + }, +}; +module_mipi_dsi_driver(ams581vf01_driver); + +MODULE_AUTHOR("Danila Tikhonov <danila@jiaxyga.com>"); +MODULE_DESCRIPTION("DRM driver for SAMSUNG AMS581VF01 cmd mode dsi panel"); +MODULE_LICENSE("GPL"); -- GitLab From fd3b2c5f40a1e028bc813284260d430257444334 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Tue, 15 Oct 2024 15:34:38 +0000 Subject: [PATCH 882/970] drm/panel: s6e3ha8: select CONFIG_DRM_DISPLAY_DSC_HELPER The new driver needs the dsc helper code to be available: x86_64-linux-ld: vmlinux.o: in function `s6e3ha8_amb577px01_wqhd_prepare': panel-samsung-s6e3ha8.c:(.text+0x16b1e65): undefined reference to `drm_dsc_pps_payload_pack' Select it from Kconfig as we do for other similar drivers. Fixes: 779679d3c164 ("drm/panel: Add support for S6E3HA8 panel driver") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com> Link: https://lore.kernel.org/r/20241015153442.3757061-1-arnd@kernel.org Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241015153442.3757061-1-arnd@kernel.org --- drivers/gpu/drm/panel/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index f637dcc7a886..bce4cb64184a 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -712,6 +712,7 @@ config DRM_PANEL_SAMSUNG_S6E3HA8 depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE + select DRM_DISPLAY_DSC_HELPER select VIDEOMODE_HELPERS config DRM_PANEL_SAMSUNG_S6E63J0X03 -- GitLab From d42a254633c773921884a19e8a1a0f53a31150c3 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Wed, 16 Oct 2024 13:20:09 +0100 Subject: [PATCH 883/970] drm/sched: Optimise drm_sched_entity_push_job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In FIFO mode (which is the default), both drm_sched_entity_push_job() and drm_sched_rq_update_fifo(), where the latter calls the former, are currently taking and releasing the same entity->rq_lock. We can avoid that design inelegance, and also have a miniscule efficiency improvement on the submit from idle path, by introducing a new drm_sched_rq_update_fifo_locked() helper and pulling up the lock taking to its callers. v2: * Remove drm_sched_rq_update_fifo() altogether. (Christian) v3: * Improved commit message. (Philipp) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Philipp Stanner <pstanner@redhat.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016122013.7857-2-tursulin@igalia.com --- drivers/gpu/drm/scheduler/sched_entity.c | 13 +++++++++---- drivers/gpu/drm/scheduler/sched_main.c | 6 +++--- include/drm/gpu_scheduler.h | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 2951fcc2e6b1..b72cba292839 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -514,8 +514,12 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) struct drm_sched_job *next; next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue)); - if (next) - drm_sched_rq_update_fifo(entity, next->submit_ts); + if (next) { + spin_lock(&entity->rq_lock); + drm_sched_rq_update_fifo_locked(entity, + next->submit_ts); + spin_unlock(&entity->rq_lock); + } } /* Jobs and entities might have different lifecycles. Since we're @@ -613,10 +617,11 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) sched = rq->sched; drm_sched_rq_add_entity(rq, entity); - spin_unlock(&entity->rq_lock); if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) - drm_sched_rq_update_fifo(entity, submit_ts); + drm_sched_rq_update_fifo_locked(entity, submit_ts); + + spin_unlock(&entity->rq_lock); drm_sched_wakeup(sched); } diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 36db5c7736fc..f2d47b382bdb 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -163,14 +163,15 @@ static inline void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *enti } } -void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts) +void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, ktime_t ts) { /* * Both locks need to be grabbed, one to protect from entity->rq change * for entity from within concurrent drm_sched_entity_select_rq and the * other to update the rb tree structure. */ - spin_lock(&entity->rq_lock); + lockdep_assert_held(&entity->rq_lock); + spin_lock(&entity->rq->lock); drm_sched_rq_remove_fifo_locked(entity); @@ -181,7 +182,6 @@ void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts) drm_sched_entity_compare_before); spin_unlock(&entity->rq->lock); - spin_unlock(&entity->rq_lock); } /** diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index e9f075f51db3..3658a6cb048e 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -593,7 +593,7 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq, void drm_sched_rq_remove_entity(struct drm_sched_rq *rq, struct drm_sched_entity *entity); -void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts); +void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, ktime_t ts); int drm_sched_entity_init(struct drm_sched_entity *entity, enum drm_sched_priority priority, -- GitLab From 6a313579eac899b34dc40b0c342f5bd91e44a081 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Wed, 16 Oct 2024 13:20:10 +0100 Subject: [PATCH 884/970] drm/sched: Stop setting current entity in FIFO mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It does not seem there is a need to set the current entity in FIFO mode since ot only serves as being a "cursor" in round-robin mode. Even if scheduling mode is changed at runtime the change in behaviour is simply to restart from the first entity, instead of continuing in RR mode from where FIFO left it, and that sounds completely fine. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Philipp Stanner <pstanner@redhat.com> Acked-by: Christian König <christian.koenig@amd.com> Reviewed-by: Philipp Stanner <pstanner@redhat.com> Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016122013.7857-3-tursulin@igalia.com --- drivers/gpu/drm/scheduler/sched_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index f2d47b382bdb..28083b0b05a9 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -349,7 +349,6 @@ drm_sched_rq_select_entity_fifo(struct drm_gpu_scheduler *sched, return ERR_PTR(-ENOSPC); } - rq->current_entity = entity; reinit_completion(&entity->entity_idle); break; } -- GitLab From a6f46283e952fe50dea5f932a1e4f0b6b2370968 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Wed, 16 Oct 2024 13:20:11 +0100 Subject: [PATCH 885/970] drm/sched: Re-order struct drm_sched_rq members for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current kerneldoc for struct drm_sched_rq incompletely documents what fields are protected by the lock. This is not good because it is misleading. Lets fix it by listing all the elements which are protected by the lock. While at it, lets also re-order the members so all protected by the lock are in a single group. v2: * Refer variables by kerneldoc syntax, more verbose commit text. (Philipp) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Philipp Stanner <pstanner@redhat.com> Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Philipp Stanner <pstanner@redhat.com> Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016122013.7857-4-tursulin@igalia.com --- include/drm/gpu_scheduler.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 3658a6cb048e..b6d095074c19 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -243,10 +243,10 @@ struct drm_sched_entity { /** * struct drm_sched_rq - queue of entities to be scheduled. * - * @lock: to modify the entities list. * @sched: the scheduler to which this rq belongs to. - * @entities: list of the entities to be scheduled. + * @lock: protects @entities, @rb_tree_root and @current_entity. * @current_entity: the entity which is to be scheduled. + * @entities: list of the entities to be scheduled. * @rb_tree_root: root of time based priority queue of entities for FIFO scheduling * * Run queue is a set of entities scheduling command submissions for @@ -254,10 +254,12 @@ struct drm_sched_entity { * the next entity to emit commands from. */ struct drm_sched_rq { - spinlock_t lock; struct drm_gpu_scheduler *sched; - struct list_head entities; + + spinlock_t lock; + /* Following members are protected by the @lock: */ struct drm_sched_entity *current_entity; + struct list_head entities; struct rb_root_cached rb_tree_root; }; -- GitLab From f93126f5d55920d1447ef00a3fbe6706f40f53de Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Wed, 16 Oct 2024 13:20:12 +0100 Subject: [PATCH 886/970] drm/sched: Re-group and rename the entity run-queue lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When writing to a drm_sched_entity's run-queue, writers are protected through the lock drm_sched_entity.rq_lock. This naming, however, frequently collides with the separate internal lock of struct drm_sched_rq, resulting in uses like this: spin_lock(&entity->rq_lock); spin_lock(&entity->rq->lock); Rename drm_sched_entity.rq_lock to improve readability. While at it, re-order that struct's members to make it more obvious what the lock protects. v2: * Rename some rq_lock straddlers in kerneldoc, improve commit text. (Philipp) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Suggested-by: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Philipp Stanner <pstanner@redhat.com> Reviewed-by: Christian König <christian.koenig@amd.com> [pstanner: Fix typo in docstring] Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016122013.7857-5-tursulin@igalia.com --- drivers/gpu/drm/scheduler/sched_entity.c | 28 ++++++++++++------------ drivers/gpu/drm/scheduler/sched_main.c | 2 +- include/drm/gpu_scheduler.h | 21 +++++++++--------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index b72cba292839..c013c2b49aa5 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -105,7 +105,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, /* We start in an idle state. */ complete_all(&entity->entity_idle); - spin_lock_init(&entity->rq_lock); + spin_lock_init(&entity->lock); spsc_queue_init(&entity->job_queue); atomic_set(&entity->fence_seq, 0); @@ -133,10 +133,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, { WARN_ON(!num_sched_list || !sched_list); - spin_lock(&entity->rq_lock); + spin_lock(&entity->lock); entity->sched_list = sched_list; entity->num_sched_list = num_sched_list; - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); } EXPORT_SYMBOL(drm_sched_entity_modify_sched); @@ -244,10 +244,10 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity) if (!entity->rq) return; - spin_lock(&entity->rq_lock); + spin_lock(&entity->lock); entity->stopped = true; drm_sched_rq_remove_entity(entity->rq, entity); - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); /* Make sure this entity is not used by the scheduler at the moment */ wait_for_completion(&entity->entity_idle); @@ -396,9 +396,9 @@ static void drm_sched_entity_wakeup(struct dma_fence *f, void drm_sched_entity_set_priority(struct drm_sched_entity *entity, enum drm_sched_priority priority) { - spin_lock(&entity->rq_lock); + spin_lock(&entity->lock); entity->priority = priority; - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); } EXPORT_SYMBOL(drm_sched_entity_set_priority); @@ -515,10 +515,10 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue)); if (next) { - spin_lock(&entity->rq_lock); + spin_lock(&entity->lock); drm_sched_rq_update_fifo_locked(entity, next->submit_ts); - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); } } @@ -559,14 +559,14 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity) if (fence && !dma_fence_is_signaled(fence)) return; - spin_lock(&entity->rq_lock); + spin_lock(&entity->lock); sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list); rq = sched ? sched->sched_rq[entity->priority] : NULL; if (rq != entity->rq) { drm_sched_rq_remove_entity(entity->rq, entity); entity->rq = rq; } - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); if (entity->num_sched_list == 1) entity->sched_list = NULL; @@ -605,9 +605,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) struct drm_sched_rq *rq; /* Add the entity to the run queue */ - spin_lock(&entity->rq_lock); + spin_lock(&entity->lock); if (entity->stopped) { - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); DRM_ERROR("Trying to push to a killed entity\n"); return; @@ -621,7 +621,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) drm_sched_rq_update_fifo_locked(entity, submit_ts); - spin_unlock(&entity->rq_lock); + spin_unlock(&entity->lock); drm_sched_wakeup(sched); } diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 28083b0b05a9..fb53a4918c23 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -170,7 +170,7 @@ void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, ktime_t ts * for entity from within concurrent drm_sched_entity_select_rq and the * other to update the rb tree structure. */ - lockdep_assert_held(&entity->rq_lock); + lockdep_assert_held(&entity->lock); spin_lock(&entity->rq->lock); diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index b6d095074c19..e2b612817e3b 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -96,14 +96,22 @@ struct drm_sched_entity { */ struct list_head list; + /** + * @lock: + * + * Lock protecting the run-queue (@rq) to which this entity belongs, + * @priority and the list of schedulers (@sched_list, @num_sched_list). + */ + spinlock_t lock; + /** * @rq: * * Runqueue on which this entity is currently scheduled. * * FIXME: Locking is very unclear for this. Writers are protected by - * @rq_lock, but readers are generally lockless and seem to just race - * with not even a READ_ONCE. + * @lock, but readers are generally lockless and seem to just race with + * not even a READ_ONCE. */ struct drm_sched_rq *rq; @@ -136,17 +144,10 @@ struct drm_sched_entity { * @priority: * * Priority of the entity. This can be modified by calling - * drm_sched_entity_set_priority(). Protected by &rq_lock. + * drm_sched_entity_set_priority(). Protected by @lock. */ enum drm_sched_priority priority; - /** - * @rq_lock: - * - * Lock to modify the runqueue to which this entity belongs. - */ - spinlock_t rq_lock; - /** * @job_queue: the list of jobs of this entity. */ -- GitLab From 134e71bd1edcc7252b64ca31efe88edfef86d784 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Date: Wed, 16 Oct 2024 13:20:13 +0100 Subject: [PATCH 887/970] drm/sched: Further optimise drm_sched_entity_push_job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having removed one re-lock cycle on the entity->lock in a patch titled "drm/sched: Optimise drm_sched_entity_push_job", with only a tiny bit larger refactoring we can do the same optimisation on the rq->lock. (Currently both drm_sched_rq_add_entity() and drm_sched_rq_update_fifo_locked() take and release the same lock.) To achieve this we make drm_sched_rq_update_fifo_locked() and drm_sched_rq_add_entity() expect the rq->lock to be held. We also align drm_sched_rq_update_fifo_locked(), drm_sched_rq_add_entity() and drm_sched_rq_remove_fifo_locked() function signatures, by adding rq as a parameter to the latter. v2: * Fix after rebase of the series. * Avoid naming inconsistency between drm_sched_rq_add/remove. (Christian) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Cc: Christian König <christian.koenig@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Luben Tuikov <ltuikov89@gmail.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Philipp Stanner <pstanner@redhat.com> Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Philipp Stanner <pstanner@redhat.com> Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016122013.7857-6-tursulin@igalia.com --- drivers/gpu/drm/scheduler/sched_entity.c | 11 +++++++-- drivers/gpu/drm/scheduler/sched_main.c | 29 ++++++++++++------------ include/drm/gpu_scheduler.h | 3 ++- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index c013c2b49aa5..69bcf0e99d57 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -515,9 +515,14 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue)); if (next) { + struct drm_sched_rq *rq; + spin_lock(&entity->lock); - drm_sched_rq_update_fifo_locked(entity, + rq = entity->rq; + spin_lock(&rq->lock); + drm_sched_rq_update_fifo_locked(entity, rq, next->submit_ts); + spin_unlock(&rq->lock); spin_unlock(&entity->lock); } } @@ -616,11 +621,13 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) rq = entity->rq; sched = rq->sched; + spin_lock(&rq->lock); drm_sched_rq_add_entity(rq, entity); if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) - drm_sched_rq_update_fifo_locked(entity, submit_ts); + drm_sched_rq_update_fifo_locked(entity, rq, submit_ts); + spin_unlock(&rq->lock); spin_unlock(&entity->lock); drm_sched_wakeup(sched); diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index fb53a4918c23..dab8cca79eb7 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -153,17 +153,18 @@ static __always_inline bool drm_sched_entity_compare_before(struct rb_node *a, return ktime_before(ent_a->oldest_job_waiting, ent_b->oldest_job_waiting); } -static inline void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *entity) +static void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *entity, + struct drm_sched_rq *rq) { - struct drm_sched_rq *rq = entity->rq; - if (!RB_EMPTY_NODE(&entity->rb_tree_node)) { rb_erase_cached(&entity->rb_tree_node, &rq->rb_tree_root); RB_CLEAR_NODE(&entity->rb_tree_node); } } -void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, ktime_t ts) +void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, + struct drm_sched_rq *rq, + ktime_t ts) { /* * Both locks need to be grabbed, one to protect from entity->rq change @@ -171,17 +172,14 @@ void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, ktime_t ts * other to update the rb tree structure. */ lockdep_assert_held(&entity->lock); + lockdep_assert_held(&rq->lock); - spin_lock(&entity->rq->lock); - - drm_sched_rq_remove_fifo_locked(entity); + drm_sched_rq_remove_fifo_locked(entity, rq); entity->oldest_job_waiting = ts; - rb_add_cached(&entity->rb_tree_node, &entity->rq->rb_tree_root, + rb_add_cached(&entity->rb_tree_node, &rq->rb_tree_root, drm_sched_entity_compare_before); - - spin_unlock(&entity->rq->lock); } /** @@ -213,15 +211,14 @@ static void drm_sched_rq_init(struct drm_gpu_scheduler *sched, void drm_sched_rq_add_entity(struct drm_sched_rq *rq, struct drm_sched_entity *entity) { + lockdep_assert_held(&entity->lock); + lockdep_assert_held(&rq->lock); + if (!list_empty(&entity->list)) return; - spin_lock(&rq->lock); - atomic_inc(rq->sched->score); list_add_tail(&entity->list, &rq->entities); - - spin_unlock(&rq->lock); } /** @@ -235,6 +232,8 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq, void drm_sched_rq_remove_entity(struct drm_sched_rq *rq, struct drm_sched_entity *entity) { + lockdep_assert_held(&entity->lock); + if (list_empty(&entity->list)) return; @@ -247,7 +246,7 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq *rq, rq->current_entity = NULL; if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) - drm_sched_rq_remove_fifo_locked(entity); + drm_sched_rq_remove_fifo_locked(entity, rq); spin_unlock(&rq->lock); } diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index e2b612817e3b..ab161289d1bf 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -596,7 +596,8 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq, void drm_sched_rq_remove_entity(struct drm_sched_rq *rq, struct drm_sched_entity *entity); -void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, ktime_t ts); +void drm_sched_rq_update_fifo_locked(struct drm_sched_entity *entity, + struct drm_sched_rq *rq, ktime_t ts); int drm_sched_entity_init(struct drm_sched_entity *entity, enum drm_sched_priority priority, -- GitLab From 5bd0d8e687bf04fdd3d4a733a6bb17e25d4a1de2 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Date: Wed, 16 Oct 2024 23:06:51 +0300 Subject: [PATCH 888/970] drm/bridge: synopsys: Add DW HDMI QP TX Controller support library The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller IP supports the following features, among others: * Fixed Rate Link (FRL) * Display Stream Compression (DSC) * 4K@120Hz and 8K@60Hz video modes * Variable Refresh Rate (VRR) including Quick Media Switching (QMS), aka Cinema VRR * Fast Vactive (FVA), aka Quick Frame Transport (QFT) * SCDC I2C DDC access * TMDS Scrambler enabling 2160p@60Hz with RGB/YCbCr4:4:4 * YCbCr4:2:0 enabling 2160p@60Hz at lower HDMI link speeds * Multi-stream audio * Enhanced Audio Return Channel (EARC) Add library containing common helpers to enable basic support, i.e. RGB output up to 4K@30Hz, without audio, CEC or any HDMI 2.1 specific features. Co-developed-by: Algea Cao <algea.cao@rock-chips.com> Signed-off-by: Algea Cao <algea.cao@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Acked-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241016-b4-rk3588-bridge-upstream-v10-1-87ef92a6d14e@collabora.com Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/bridge/synopsys/Kconfig | 8 + drivers/gpu/drm/bridge/synopsys/Makefile | 2 + drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 647 ++++++++++++++ drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h | 834 +++++++++++++++++++ include/drm/bridge/dw_hdmi_qp.h | 32 + 5 files changed, 1523 insertions(+) create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h create mode 100644 include/drm/bridge/dw_hdmi_qp.h diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig index 15fc182d05ef..ca416dab156d 100644 --- a/drivers/gpu/drm/bridge/synopsys/Kconfig +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig @@ -46,6 +46,14 @@ config DRM_DW_HDMI_CEC Support the CE interface which is part of the Synopsys Designware HDMI block. +config DRM_DW_HDMI_QP + tristate + select DRM_DISPLAY_HDMI_HELPER + select DRM_DISPLAY_HDMI_STATE_HELPER + select DRM_DISPLAY_HELPER + select DRM_KMS_HELPER + select REGMAP_MMIO + config DRM_DW_MIPI_DSI tristate select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile index ce715562e9e5..9869d9651ed1 100644 --- a/drivers/gpu/drm/bridge/synopsys/Makefile +++ b/drivers/gpu/drm/bridge/synopsys/Makefile @@ -5,4 +5,6 @@ obj-$(CONFIG_DRM_DW_HDMI_GP_AUDIO) += dw-hdmi-gp-audio.o obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o +obj-$(CONFIG_DRM_DW_HDMI_QP) += dw-hdmi-qp.o + obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c new file mode 100644 index 000000000000..181c5164b231 --- /dev/null +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -0,0 +1,647 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Collabora Ltd. + * + * Author: Algea Cao <algea.cao@rock-chips.com> + * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> + */ +#include <linux/completion.h> +#include <linux/hdmi.h> +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/workqueue.h> + +#include <drm/bridge/dw_hdmi_qp.h> +#include <drm/display/drm_hdmi_helper.h> +#include <drm/display/drm_hdmi_state_helper.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_connector.h> +#include <drm/drm_edid.h> +#include <drm/drm_modes.h> + +#include <sound/hdmi-codec.h> + +#include "dw-hdmi-qp.h" + +#define DDC_CI_ADDR 0x37 +#define DDC_SEGMENT_ADDR 0x30 + +#define HDMI14_MAX_TMDSCLK 340000000 + +#define SCRAMB_POLL_DELAY_MS 3000 + +struct dw_hdmi_qp_i2c { + struct i2c_adapter adap; + + struct mutex lock; /* used to serialize data transfers */ + struct completion cmp; + u8 stat; + + u8 slave_reg; + bool is_regaddr; + bool is_segment; +}; + +struct dw_hdmi_qp { + struct drm_bridge bridge; + + struct device *dev; + struct dw_hdmi_qp_i2c *i2c; + + struct { + const struct dw_hdmi_qp_phy_ops *ops; + void *data; + } phy; + + struct regmap *regm; +}; + +static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val, + int offset) +{ + regmap_write(hdmi->regm, offset, val); +} + +static unsigned int dw_hdmi_qp_read(struct dw_hdmi_qp *hdmi, int offset) +{ + unsigned int val = 0; + + regmap_read(hdmi->regm, offset, &val); + + return val; +} + +static void dw_hdmi_qp_mod(struct dw_hdmi_qp *hdmi, unsigned int data, + unsigned int mask, unsigned int reg) +{ + regmap_update_bits(hdmi->regm, reg, mask, data); +} + +static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi, + unsigned char *buf, unsigned int length) +{ + struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; + int stat; + + if (!i2c->is_regaddr) { + dev_dbg(hdmi->dev, "set read register address to 0\n"); + i2c->slave_reg = 0x00; + i2c->is_regaddr = true; + } + + while (length--) { + reinit_completion(&i2c->cmp); + + dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR, + I2CM_INTERFACE_CONTROL0); + + if (i2c->is_segment) + dw_hdmi_qp_mod(hdmi, I2CM_EXT_READ, I2CM_WR_MASK, + I2CM_INTERFACE_CONTROL0); + else + dw_hdmi_qp_mod(hdmi, I2CM_FM_READ, I2CM_WR_MASK, + I2CM_INTERFACE_CONTROL0); + + stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); + if (!stat) { + dev_err(hdmi->dev, "i2c read timed out\n"); + dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); + return -EAGAIN; + } + + /* Check for error condition on the bus */ + if (i2c->stat & I2CM_NACK_RCVD_IRQ) { + dev_err(hdmi->dev, "i2c read error\n"); + dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); + return -EIO; + } + + *buf++ = dw_hdmi_qp_read(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff; + dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0); + } + + i2c->is_segment = false; + + return 0; +} + +static int dw_hdmi_qp_i2c_write(struct dw_hdmi_qp *hdmi, + unsigned char *buf, unsigned int length) +{ + struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; + int stat; + + if (!i2c->is_regaddr) { + /* Use the first write byte as register address */ + i2c->slave_reg = buf[0]; + length--; + buf++; + i2c->is_regaddr = true; + } + + while (length--) { + reinit_completion(&i2c->cmp); + + dw_hdmi_qp_write(hdmi, *buf++, I2CM_INTERFACE_WRDATA_0_3); + dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR, + I2CM_INTERFACE_CONTROL0); + dw_hdmi_qp_mod(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK, + I2CM_INTERFACE_CONTROL0); + + stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); + if (!stat) { + dev_err(hdmi->dev, "i2c write time out!\n"); + dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); + return -EAGAIN; + } + + /* Check for error condition on the bus */ + if (i2c->stat & I2CM_NACK_RCVD_IRQ) { + dev_err(hdmi->dev, "i2c write nack!\n"); + dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); + return -EIO; + } + + dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0); + } + + return 0; +} + +static int dw_hdmi_qp_i2c_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct dw_hdmi_qp *hdmi = i2c_get_adapdata(adap); + struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; + u8 addr = msgs[0].addr; + int i, ret = 0; + + if (addr == DDC_CI_ADDR) + /* + * The internal I2C controller does not support the multi-byte + * read and write operations needed for DDC/CI. + * FIXME: Blacklist the DDC/CI address until we filter out + * unsupported I2C operations. + */ + return -EOPNOTSUPP; + + for (i = 0; i < num; i++) { + if (msgs[i].len == 0) { + dev_err(hdmi->dev, + "unsupported transfer %d/%d, no data\n", + i + 1, num); + return -EOPNOTSUPP; + } + } + + guard(mutex)(&i2c->lock); + + /* Unmute DONE and ERROR interrupts */ + dw_hdmi_qp_mod(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N, + I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N, + MAINUNIT_1_INT_MASK_N); + + /* Set slave device address taken from the first I2C message */ + if (addr == DDC_SEGMENT_ADDR && msgs[0].len == 1) + addr = DDC_ADDR; + + dw_hdmi_qp_mod(hdmi, addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0); + + /* Set slave device register address on transfer */ + i2c->is_regaddr = false; + + /* Set segment pointer for I2C extended read mode operation */ + i2c->is_segment = false; + + for (i = 0; i < num; i++) { + if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) { + i2c->is_segment = true; + dw_hdmi_qp_mod(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR, + I2CM_INTERFACE_CONTROL1); + dw_hdmi_qp_mod(hdmi, *msgs[i].buf << 7, I2CM_SEG_PTR, + I2CM_INTERFACE_CONTROL1); + } else { + if (msgs[i].flags & I2C_M_RD) + ret = dw_hdmi_qp_i2c_read(hdmi, msgs[i].buf, + msgs[i].len); + else + ret = dw_hdmi_qp_i2c_write(hdmi, msgs[i].buf, + msgs[i].len); + } + if (ret < 0) + break; + } + + if (!ret) + ret = num; + + /* Mute DONE and ERROR interrupts */ + dw_hdmi_qp_mod(hdmi, 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N, + MAINUNIT_1_INT_MASK_N); + + return ret; +} + +static u32 dw_hdmi_qp_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm dw_hdmi_qp_algorithm = { + .master_xfer = dw_hdmi_qp_i2c_xfer, + .functionality = dw_hdmi_qp_i2c_func, +}; + +static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi) +{ + struct dw_hdmi_qp_i2c *i2c; + struct i2c_adapter *adap; + int ret; + + i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return ERR_PTR(-ENOMEM); + + mutex_init(&i2c->lock); + init_completion(&i2c->cmp); + + adap = &i2c->adap; + adap->owner = THIS_MODULE; + adap->dev.parent = hdmi->dev; + adap->algo = &dw_hdmi_qp_algorithm; + strscpy(adap->name, "DesignWare HDMI QP", sizeof(adap->name)); + + i2c_set_adapdata(adap, hdmi); + + ret = devm_i2c_add_adapter(hdmi->dev, adap); + if (ret) { + dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); + devm_kfree(hdmi->dev, i2c); + return ERR_PTR(ret); + } + + hdmi->i2c = i2c; + dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); + + return adap; +} + +static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi, + const u8 *buffer, size_t len) +{ + u32 val, i, j; + + if (len != HDMI_INFOFRAME_SIZE(AVI)) { + dev_err(hdmi->dev, "failed to configure avi infoframe\n"); + return -EINVAL; + } + + /* + * DW HDMI QP IP uses a different byte format from standard AVI info + * frames, though generally the bits are in the correct bytes. + */ + val = buffer[1] << 8 | buffer[2] << 16; + dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0); + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + if (i * 4 + j >= 14) + break; + if (!j) + val = buffer[i * 4 + j + 3]; + val |= buffer[i * 4 + j + 3] << (8 * j); + } + + dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4); + } + + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1); + + dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, + PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN); + + return 0; +} + +static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi, + const u8 *buffer, size_t len) +{ + u32 val, i; + + if (len != HDMI_INFOFRAME_SIZE(DRM)) { + dev_err(hdmi->dev, "failed to configure drm infoframe\n"); + return -EINVAL; + } + + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); + + val = buffer[1] << 8 | buffer[2] << 16; + dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0); + + for (i = 0; i <= buffer[2]; i++) { + if (i % 4 == 0) + val = buffer[3 + i]; + val |= buffer[3 + i] << ((i % 4) * 8); + + if ((i % 4 == 3) || i == buffer[2]) + dw_hdmi_qp_write(hdmi, val, + PKT_DRMI_CONTENTS1 + ((i / 4) * 4)); + } + + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1); + dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN, + PKTSCHED_PKT_EN); + + return 0; +} + +static int dw_hdmi_qp_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + int ret; + + ret = drm_atomic_helper_connector_hdmi_check(conn_state->connector, + conn_state->state); + if (ret) + dev_dbg(hdmi->dev, "%s failed: %d\n", __func__, ret); + + return ret; +} + +static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + struct drm_atomic_state *state = old_state->base.state; + struct drm_connector_state *conn_state; + struct drm_connector *connector; + unsigned int op_mode; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + if (WARN_ON(!connector)) + return; + + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (WARN_ON(!conn_state)) + return; + + if (connector->display_info.is_hdmi) { + dev_dbg(hdmi->dev, "%s mode=HDMI rate=%llu\n", + __func__, conn_state->hdmi.tmds_char_rate); + op_mode = 0; + } else { + dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__); + op_mode = OPMODE_DVI; + } + + hdmi->phy.ops->init(hdmi, hdmi->phy.data); + + dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0); + dw_hdmi_qp_mod(hdmi, op_mode, OPMODE_DVI, LINK_CONFIG0); + + drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); +} + +static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + hdmi->phy.ops->disable(hdmi, hdmi->phy.data); +} + +static enum drm_connector_status +dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); +} + +static const struct drm_edid * +dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + const struct drm_edid *drm_edid; + + drm_edid = drm_edid_read_ddc(connector, bridge->ddc); + if (!drm_edid) + dev_dbg(hdmi->dev, "failed to get edid\n"); + + return drm_edid; +} + +static enum drm_mode_status +dw_hdmi_qp_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + unsigned long long rate; + + rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + if (rate > HDMI14_MAX_TMDSCLK) { + dev_dbg(hdmi->dev, "Unsupported mode clock: %d\n", mode->clock); + return MODE_CLOCK_HIGH; + } + + return MODE_OK; +} + +static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge, + enum hdmi_infoframe_type type) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, + PKTSCHED_PKT_EN); + break; + + case HDMI_INFOFRAME_TYPE_DRM: + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); + break; + + default: + dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); + } + + return 0; +} + +static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + struct dw_hdmi_qp *hdmi = bridge->driver_private; + + dw_hdmi_qp_bridge_clear_infoframe(bridge, type); + + switch (type) { + case HDMI_INFOFRAME_TYPE_AVI: + return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); + + case HDMI_INFOFRAME_TYPE_DRM: + return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); + + default: + dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); + return 0; + } +} + +static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = { + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_check = dw_hdmi_qp_bridge_atomic_check, + .atomic_enable = dw_hdmi_qp_bridge_atomic_enable, + .atomic_disable = dw_hdmi_qp_bridge_atomic_disable, + .detect = dw_hdmi_qp_bridge_detect, + .edid_read = dw_hdmi_qp_bridge_edid_read, + .mode_valid = dw_hdmi_qp_bridge_mode_valid, + .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, + .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, +}; + +static irqreturn_t dw_hdmi_qp_main_hardirq(int irq, void *dev_id) +{ + struct dw_hdmi_qp *hdmi = dev_id; + struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; + u32 stat; + + stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS); + + i2c->stat = stat & (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ | + I2CM_NACK_RCVD_IRQ); + + if (i2c->stat) { + dw_hdmi_qp_write(hdmi, i2c->stat, MAINUNIT_1_INT_CLEAR); + complete(&i2c->cmp); + } + + if (stat) + return IRQ_HANDLED; + + return IRQ_NONE; +} + +static const struct regmap_config dw_hdmi_qp_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = EARCRX_1_INT_FORCE, +}; + +static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi) +{ + dw_hdmi_qp_write(hdmi, 0, MAINUNIT_0_INT_MASK_N); + dw_hdmi_qp_write(hdmi, 0, MAINUNIT_1_INT_MASK_N); + dw_hdmi_qp_write(hdmi, 428571429, TIMER_BASE_CONFIG0); + + /* Software reset */ + dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); + + dw_hdmi_qp_write(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0); + + dw_hdmi_qp_mod(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0); + + /* Clear DONE and ERROR interrupts */ + dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR, + MAINUNIT_1_INT_CLEAR); + + if (hdmi->phy.ops->setup_hpd) + hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); +} + +struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, + struct drm_encoder *encoder, + const struct dw_hdmi_qp_plat_data *plat_data) +{ + struct device *dev = &pdev->dev; + struct dw_hdmi_qp *hdmi; + void __iomem *regs; + int ret; + + if (!plat_data->phy_ops || !plat_data->phy_ops->init || + !plat_data->phy_ops->disable || !plat_data->phy_ops->read_hpd) { + dev_err(dev, "Missing platform PHY ops\n"); + return ERR_PTR(-ENODEV); + } + + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return ERR_PTR(-ENOMEM); + + hdmi->dev = dev; + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return ERR_CAST(regs); + + hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config); + if (IS_ERR(hdmi->regm)) { + dev_err(dev, "Failed to configure regmap\n"); + return ERR_CAST(hdmi->regm); + } + + hdmi->phy.ops = plat_data->phy_ops; + hdmi->phy.data = plat_data->phy_data; + + dw_hdmi_qp_init_hw(hdmi); + + ret = devm_request_threaded_irq(dev, plat_data->main_irq, + dw_hdmi_qp_main_hardirq, NULL, + IRQF_SHARED, dev_name(dev), hdmi); + if (ret) + return ERR_PTR(ret); + + hdmi->bridge.driver_private = hdmi; + hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs; + hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_EDID | + DRM_BRIDGE_OP_HDMI | + DRM_BRIDGE_OP_HPD; + hdmi->bridge.of_node = pdev->dev.of_node; + hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + hdmi->bridge.vendor = "Synopsys"; + hdmi->bridge.product = "DW HDMI QP TX"; + + hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi); + if (IS_ERR(hdmi->bridge.ddc)) + return ERR_CAST(hdmi->bridge.ddc); + + ret = devm_drm_bridge_add(dev, &hdmi->bridge); + if (ret) + return ERR_PTR(ret); + + ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) + return ERR_PTR(ret); + + return hdmi; +} +EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind); + +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) +{ + dw_hdmi_qp_init_hw(hdmi); +} +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); + +MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>"); +MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>"); +MODULE_DESCRIPTION("DW HDMI QP transmitter library"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h new file mode 100644 index 000000000000..2115b8ef0bd6 --- /dev/null +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) Rockchip Electronics Co.Ltd + * Author: + * Algea Cao <algea.cao@rock-chips.com> + */ +#ifndef __DW_HDMI_QP_H__ +#define __DW_HDMI_QP_H__ + +#include <linux/bits.h> + +/* Main Unit Registers */ +#define CORE_ID 0x0 +#define VER_NUMBER 0x4 +#define VER_TYPE 0x8 +#define CONFIG_REG 0xc +#define CONFIG_CEC BIT(28) +#define CONFIG_AUD_UD BIT(23) +#define CORE_TIMESTAMP_HHMM 0x14 +#define CORE_TIMESTAMP_MMDD 0x18 +#define CORE_TIMESTAMP_YYYY 0x1c +/* Reset Manager Registers */ +#define GLOBAL_SWRESET_REQUEST 0x40 +#define EARCRX_CMDC_SWINIT_P BIT(27) +#define AVP_DATAPATH_PACKET_AUDIO_SWINIT_P BIT(10) +#define GLOBAL_SWDISABLE 0x44 +#define CEC_SWDISABLE BIT(17) +#define AVP_DATAPATH_PACKET_AUDIO_SWDISABLE BIT(10) +#define AVP_DATAPATH_VIDEO_SWDISABLE BIT(6) +#define RESET_MANAGER_CONFIG0 0x48 +#define RESET_MANAGER_STATUS0 0x50 +#define RESET_MANAGER_STATUS1 0x54 +#define RESET_MANAGER_STATUS2 0x58 +/* Timer Base Registers */ +#define TIMER_BASE_CONFIG0 0x80 +#define TIMER_BASE_STATUS0 0x84 +/* CMU Registers */ +#define CMU_CONFIG0 0xa0 +#define CMU_CONFIG1 0xa4 +#define CMU_CONFIG2 0xa8 +#define CMU_CONFIG3 0xac +#define CMU_STATUS 0xb0 +#define DISPLAY_CLK_MONITOR 0x3f +#define DISPLAY_CLK_LOCKED 0X15 +#define EARC_BPCLK_OFF BIT(9) +#define AUDCLK_OFF BIT(7) +#define LINKQPCLK_OFF BIT(5) +#define VIDQPCLK_OFF BIT(3) +#define IPI_CLK_OFF BIT(1) +#define CMU_IPI_CLK_FREQ 0xb4 +#define CMU_VIDQPCLK_FREQ 0xb8 +#define CMU_LINKQPCLK_FREQ 0xbc +#define CMU_AUDQPCLK_FREQ 0xc0 +#define CMU_EARC_BPCLK_FREQ 0xc4 +/* I2CM Registers */ +#define I2CM_SM_SCL_CONFIG0 0xe0 +#define I2CM_FM_SCL_CONFIG0 0xe4 +#define I2CM_CONFIG0 0xe8 +#define I2CM_CONTROL0 0xec +#define I2CM_STATUS0 0xf0 +#define I2CM_INTERFACE_CONTROL0 0xf4 +#define I2CM_ADDR 0xff000 +#define I2CM_SLVADDR 0xfe0 +#define I2CM_WR_MASK 0x1e +#define I2CM_EXT_READ BIT(4) +#define I2CM_SHORT_READ BIT(3) +#define I2CM_FM_READ BIT(2) +#define I2CM_FM_WRITE BIT(1) +#define I2CM_FM_EN BIT(0) +#define I2CM_INTERFACE_CONTROL1 0xf8 +#define I2CM_SEG_PTR 0x7f80 +#define I2CM_SEG_ADDR 0x7f +#define I2CM_INTERFACE_WRDATA_0_3 0xfc +#define I2CM_INTERFACE_WRDATA_4_7 0x100 +#define I2CM_INTERFACE_WRDATA_8_11 0x104 +#define I2CM_INTERFACE_WRDATA_12_15 0x108 +#define I2CM_INTERFACE_RDDATA_0_3 0x10c +#define I2CM_INTERFACE_RDDATA_4_7 0x110 +#define I2CM_INTERFACE_RDDATA_8_11 0x114 +#define I2CM_INTERFACE_RDDATA_12_15 0x118 +/* SCDC Registers */ +#define SCDC_CONFIG0 0x140 +#define SCDC_I2C_FM_EN BIT(12) +#define SCDC_UPD_FLAGS_AUTO_CLR BIT(6) +#define SCDC_UPD_FLAGS_POLL_EN BIT(4) +#define SCDC_CONTROL0 0x148 +#define SCDC_STATUS0 0x150 +#define STATUS_UPDATE BIT(0) +#define FRL_START BIT(4) +#define FLT_UPDATE BIT(5) +/* FLT Registers */ +#define FLT_CONFIG0 0x160 +#define FLT_CONFIG1 0x164 +#define FLT_CONFIG2 0x168 +#define FLT_CONTROL0 0x170 +/* Main Unit 2 Registers */ +#define MAINUNIT_STATUS0 0x180 +/* Video Interface Registers */ +#define VIDEO_INTERFACE_CONFIG0 0x800 +#define VIDEO_INTERFACE_CONFIG1 0x804 +#define VIDEO_INTERFACE_CONFIG2 0x808 +#define VIDEO_INTERFACE_CONTROL0 0x80c +#define VIDEO_INTERFACE_STATUS0 0x814 +/* Video Packing Registers */ +#define VIDEO_PACKING_CONFIG0 0x81c +/* Audio Interface Registers */ +#define AUDIO_INTERFACE_CONFIG0 0x820 +#define AUD_IF_SEL_MSK 0x3 +#define AUD_IF_SPDIF 0x2 +#define AUD_IF_I2S 0x1 +#define AUD_IF_PAI 0x0 +#define AUD_FIFO_INIT_ON_OVF_MSK BIT(2) +#define AUD_FIFO_INIT_ON_OVF_EN BIT(2) +#define I2S_LINES_EN_MSK GENMASK(7, 4) +#define I2S_LINES_EN(x) BIT((x) + 4) +#define I2S_BPCUV_RCV_MSK BIT(12) +#define I2S_BPCUV_RCV_EN BIT(12) +#define I2S_BPCUV_RCV_DIS 0 +#define SPDIF_LINES_EN GENMASK(19, 16) +#define AUD_FORMAT_MSK GENMASK(26, 24) +#define AUD_3DOBA (0x7 << 24) +#define AUD_3DASP (0x6 << 24) +#define AUD_MSOBA (0x5 << 24) +#define AUD_MSASP (0x4 << 24) +#define AUD_HBR (0x3 << 24) +#define AUD_DST (0x2 << 24) +#define AUD_OBA (0x1 << 24) +#define AUD_ASP (0x0 << 24) +#define AUDIO_INTERFACE_CONFIG1 0x824 +#define AUDIO_INTERFACE_CONTROL0 0x82c +#define AUDIO_FIFO_CLR_P BIT(0) +#define AUDIO_INTERFACE_STATUS0 0x834 +/* Frame Composer Registers */ +#define FRAME_COMPOSER_CONFIG0 0x840 +#define FRAME_COMPOSER_CONFIG1 0x844 +#define FRAME_COMPOSER_CONFIG2 0x848 +#define FRAME_COMPOSER_CONFIG3 0x84c +#define FRAME_COMPOSER_CONFIG4 0x850 +#define FRAME_COMPOSER_CONFIG5 0x854 +#define FRAME_COMPOSER_CONFIG6 0x858 +#define FRAME_COMPOSER_CONFIG7 0x85c +#define FRAME_COMPOSER_CONFIG8 0x860 +#define FRAME_COMPOSER_CONFIG9 0x864 +#define FRAME_COMPOSER_CONTROL0 0x86c +/* Video Monitor Registers */ +#define VIDEO_MONITOR_CONFIG0 0x880 +#define VIDEO_MONITOR_STATUS0 0x884 +#define VIDEO_MONITOR_STATUS1 0x888 +#define VIDEO_MONITOR_STATUS2 0x88c +#define VIDEO_MONITOR_STATUS3 0x890 +#define VIDEO_MONITOR_STATUS4 0x894 +#define VIDEO_MONITOR_STATUS5 0x898 +#define VIDEO_MONITOR_STATUS6 0x89c +/* HDCP2 Logic Registers */ +#define HDCP2LOGIC_CONFIG0 0x8e0 +#define HDCP2_BYPASS BIT(0) +#define HDCP2LOGIC_ESM_GPIO_IN 0x8e4 +#define HDCP2LOGIC_ESM_GPIO_OUT 0x8e8 +/* HDCP14 Registers */ +#define HDCP14_CONFIG0 0x900 +#define HDCP14_CONFIG1 0x904 +#define HDCP14_CONFIG2 0x908 +#define HDCP14_CONFIG3 0x90c +#define HDCP14_KEY_SEED 0x914 +#define HDCP14_KEY_H 0x918 +#define HDCP14_KEY_L 0x91c +#define HDCP14_KEY_STATUS 0x920 +#define HDCP14_AKSV_H 0x924 +#define HDCP14_AKSV_L 0x928 +#define HDCP14_AN_H 0x92c +#define HDCP14_AN_L 0x930 +#define HDCP14_STATUS0 0x934 +#define HDCP14_STATUS1 0x938 +/* Scrambler Registers */ +#define SCRAMB_CONFIG0 0x960 +/* Video Configuration Registers */ +#define LINK_CONFIG0 0x968 +#define OPMODE_FRL_4LANES BIT(8) +#define OPMODE_DVI BIT(4) +#define OPMODE_FRL BIT(0) +/* TMDS FIFO Registers */ +#define TMDS_FIFO_CONFIG0 0x970 +#define TMDS_FIFO_CONTROL0 0x974 +/* FRL RSFEC Registers */ +#define FRL_RSFEC_CONFIG0 0xa20 +#define FRL_RSFEC_STATUS0 0xa30 +/* FRL Packetizer Registers */ +#define FRL_PKTZ_CONFIG0 0xa40 +#define FRL_PKTZ_CONTROL0 0xa44 +#define FRL_PKTZ_CONTROL1 0xa50 +#define FRL_PKTZ_STATUS1 0xa54 +/* Packet Scheduler Registers */ +#define PKTSCHED_CONFIG0 0xa80 +#define PKTSCHED_PRQUEUE0_CONFIG0 0xa84 +#define PKTSCHED_PRQUEUE1_CONFIG0 0xa88 +#define PKTSCHED_PRQUEUE2_CONFIG0 0xa8c +#define PKTSCHED_PRQUEUE2_CONFIG1 0xa90 +#define PKTSCHED_PRQUEUE2_CONFIG2 0xa94 +#define PKTSCHED_PKT_CONFIG0 0xa98 +#define PKTSCHED_PKT_CONFIG1 0xa9c +#define PKTSCHED_DRMI_FIELDRATE BIT(13) +#define PKTSCHED_AVI_FIELDRATE BIT(12) +#define PKTSCHED_PKT_CONFIG2 0xaa0 +#define PKTSCHED_PKT_CONFIG3 0xaa4 +#define PKTSCHED_PKT_EN 0xaa8 +#define PKTSCHED_DRMI_TX_EN BIT(17) +#define PKTSCHED_AUDI_TX_EN BIT(15) +#define PKTSCHED_AVI_TX_EN BIT(13) +#define PKTSCHED_EMP_CVTEM_TX_EN BIT(10) +#define PKTSCHED_AMD_TX_EN BIT(8) +#define PKTSCHED_GCP_TX_EN BIT(3) +#define PKTSCHED_AUDS_TX_EN BIT(2) +#define PKTSCHED_ACR_TX_EN BIT(1) +#define PKTSCHED_NULL_TX_EN BIT(0) +#define PKTSCHED_PKT_CONTROL0 0xaac +#define PKTSCHED_PKT_SEND 0xab0 +#define PKTSCHED_PKT_STATUS0 0xab4 +#define PKTSCHED_PKT_STATUS1 0xab8 +#define PKT_NULL_CONTENTS0 0xb00 +#define PKT_NULL_CONTENTS1 0xb04 +#define PKT_NULL_CONTENTS2 0xb08 +#define PKT_NULL_CONTENTS3 0xb0c +#define PKT_NULL_CONTENTS4 0xb10 +#define PKT_NULL_CONTENTS5 0xb14 +#define PKT_NULL_CONTENTS6 0xb18 +#define PKT_NULL_CONTENTS7 0xb1c +#define PKT_ACP_CONTENTS0 0xb20 +#define PKT_ACP_CONTENTS1 0xb24 +#define PKT_ACP_CONTENTS2 0xb28 +#define PKT_ACP_CONTENTS3 0xb2c +#define PKT_ACP_CONTENTS4 0xb30 +#define PKT_ACP_CONTENTS5 0xb34 +#define PKT_ACP_CONTENTS6 0xb38 +#define PKT_ACP_CONTENTS7 0xb3c +#define PKT_ISRC1_CONTENTS0 0xb40 +#define PKT_ISRC1_CONTENTS1 0xb44 +#define PKT_ISRC1_CONTENTS2 0xb48 +#define PKT_ISRC1_CONTENTS3 0xb4c +#define PKT_ISRC1_CONTENTS4 0xb50 +#define PKT_ISRC1_CONTENTS5 0xb54 +#define PKT_ISRC1_CONTENTS6 0xb58 +#define PKT_ISRC1_CONTENTS7 0xb5c +#define PKT_ISRC2_CONTENTS0 0xb60 +#define PKT_ISRC2_CONTENTS1 0xb64 +#define PKT_ISRC2_CONTENTS2 0xb68 +#define PKT_ISRC2_CONTENTS3 0xb6c +#define PKT_ISRC2_CONTENTS4 0xb70 +#define PKT_ISRC2_CONTENTS5 0xb74 +#define PKT_ISRC2_CONTENTS6 0xb78 +#define PKT_ISRC2_CONTENTS7 0xb7c +#define PKT_GMD_CONTENTS0 0xb80 +#define PKT_GMD_CONTENTS1 0xb84 +#define PKT_GMD_CONTENTS2 0xb88 +#define PKT_GMD_CONTENTS3 0xb8c +#define PKT_GMD_CONTENTS4 0xb90 +#define PKT_GMD_CONTENTS5 0xb94 +#define PKT_GMD_CONTENTS6 0xb98 +#define PKT_GMD_CONTENTS7 0xb9c +#define PKT_AMD_CONTENTS0 0xba0 +#define PKT_AMD_CONTENTS1 0xba4 +#define PKT_AMD_CONTENTS2 0xba8 +#define PKT_AMD_CONTENTS3 0xbac +#define PKT_AMD_CONTENTS4 0xbb0 +#define PKT_AMD_CONTENTS5 0xbb4 +#define PKT_AMD_CONTENTS6 0xbb8 +#define PKT_AMD_CONTENTS7 0xbbc +#define PKT_VSI_CONTENTS0 0xbc0 +#define PKT_VSI_CONTENTS1 0xbc4 +#define PKT_VSI_CONTENTS2 0xbc8 +#define PKT_VSI_CONTENTS3 0xbcc +#define PKT_VSI_CONTENTS4 0xbd0 +#define PKT_VSI_CONTENTS5 0xbd4 +#define PKT_VSI_CONTENTS6 0xbd8 +#define PKT_VSI_CONTENTS7 0xbdc +#define PKT_AVI_CONTENTS0 0xbe0 +#define HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT BIT(4) +#define HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR 0x04 +#define HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR 0x08 +#define HDMI_FC_AVICONF2_IT_CONTENT_VALID 0x80 +#define PKT_AVI_CONTENTS1 0xbe4 +#define PKT_AVI_CONTENTS2 0xbe8 +#define PKT_AVI_CONTENTS3 0xbec +#define PKT_AVI_CONTENTS4 0xbf0 +#define PKT_AVI_CONTENTS5 0xbf4 +#define PKT_AVI_CONTENTS6 0xbf8 +#define PKT_AVI_CONTENTS7 0xbfc +#define PKT_SPDI_CONTENTS0 0xc00 +#define PKT_SPDI_CONTENTS1 0xc04 +#define PKT_SPDI_CONTENTS2 0xc08 +#define PKT_SPDI_CONTENTS3 0xc0c +#define PKT_SPDI_CONTENTS4 0xc10 +#define PKT_SPDI_CONTENTS5 0xc14 +#define PKT_SPDI_CONTENTS6 0xc18 +#define PKT_SPDI_CONTENTS7 0xc1c +#define PKT_AUDI_CONTENTS0 0xc20 +#define PKT_AUDI_CONTENTS1 0xc24 +#define PKT_AUDI_CONTENTS2 0xc28 +#define PKT_AUDI_CONTENTS3 0xc2c +#define PKT_AUDI_CONTENTS4 0xc30 +#define PKT_AUDI_CONTENTS5 0xc34 +#define PKT_AUDI_CONTENTS6 0xc38 +#define PKT_AUDI_CONTENTS7 0xc3c +#define PKT_NVI_CONTENTS0 0xc40 +#define PKT_NVI_CONTENTS1 0xc44 +#define PKT_NVI_CONTENTS2 0xc48 +#define PKT_NVI_CONTENTS3 0xc4c +#define PKT_NVI_CONTENTS4 0xc50 +#define PKT_NVI_CONTENTS5 0xc54 +#define PKT_NVI_CONTENTS6 0xc58 +#define PKT_NVI_CONTENTS7 0xc5c +#define PKT_DRMI_CONTENTS0 0xc60 +#define PKT_DRMI_CONTENTS1 0xc64 +#define PKT_DRMI_CONTENTS2 0xc68 +#define PKT_DRMI_CONTENTS3 0xc6c +#define PKT_DRMI_CONTENTS4 0xc70 +#define PKT_DRMI_CONTENTS5 0xc74 +#define PKT_DRMI_CONTENTS6 0xc78 +#define PKT_DRMI_CONTENTS7 0xc7c +#define PKT_GHDMI1_CONTENTS0 0xc80 +#define PKT_GHDMI1_CONTENTS1 0xc84 +#define PKT_GHDMI1_CONTENTS2 0xc88 +#define PKT_GHDMI1_CONTENTS3 0xc8c +#define PKT_GHDMI1_CONTENTS4 0xc90 +#define PKT_GHDMI1_CONTENTS5 0xc94 +#define PKT_GHDMI1_CONTENTS6 0xc98 +#define PKT_GHDMI1_CONTENTS7 0xc9c +#define PKT_GHDMI2_CONTENTS0 0xca0 +#define PKT_GHDMI2_CONTENTS1 0xca4 +#define PKT_GHDMI2_CONTENTS2 0xca8 +#define PKT_GHDMI2_CONTENTS3 0xcac +#define PKT_GHDMI2_CONTENTS4 0xcb0 +#define PKT_GHDMI2_CONTENTS5 0xcb4 +#define PKT_GHDMI2_CONTENTS6 0xcb8 +#define PKT_GHDMI2_CONTENTS7 0xcbc +/* EMP Packetizer Registers */ +#define PKT_EMP_CONFIG0 0xce0 +#define PKT_EMP_CONTROL0 0xcec +#define PKT_EMP_CONTROL1 0xcf0 +#define PKT_EMP_CONTROL2 0xcf4 +#define PKT_EMP_VTEM_CONTENTS0 0xd00 +#define PKT_EMP_VTEM_CONTENTS1 0xd04 +#define PKT_EMP_VTEM_CONTENTS2 0xd08 +#define PKT_EMP_VTEM_CONTENTS3 0xd0c +#define PKT_EMP_VTEM_CONTENTS4 0xd10 +#define PKT_EMP_VTEM_CONTENTS5 0xd14 +#define PKT_EMP_VTEM_CONTENTS6 0xd18 +#define PKT_EMP_VTEM_CONTENTS7 0xd1c +#define PKT0_EMP_CVTEM_CONTENTS0 0xd20 +#define PKT0_EMP_CVTEM_CONTENTS1 0xd24 +#define PKT0_EMP_CVTEM_CONTENTS2 0xd28 +#define PKT0_EMP_CVTEM_CONTENTS3 0xd2c +#define PKT0_EMP_CVTEM_CONTENTS4 0xd30 +#define PKT0_EMP_CVTEM_CONTENTS5 0xd34 +#define PKT0_EMP_CVTEM_CONTENTS6 0xd38 +#define PKT0_EMP_CVTEM_CONTENTS7 0xd3c +#define PKT1_EMP_CVTEM_CONTENTS0 0xd40 +#define PKT1_EMP_CVTEM_CONTENTS1 0xd44 +#define PKT1_EMP_CVTEM_CONTENTS2 0xd48 +#define PKT1_EMP_CVTEM_CONTENTS3 0xd4c +#define PKT1_EMP_CVTEM_CONTENTS4 0xd50 +#define PKT1_EMP_CVTEM_CONTENTS5 0xd54 +#define PKT1_EMP_CVTEM_CONTENTS6 0xd58 +#define PKT1_EMP_CVTEM_CONTENTS7 0xd5c +#define PKT2_EMP_CVTEM_CONTENTS0 0xd60 +#define PKT2_EMP_CVTEM_CONTENTS1 0xd64 +#define PKT2_EMP_CVTEM_CONTENTS2 0xd68 +#define PKT2_EMP_CVTEM_CONTENTS3 0xd6c +#define PKT2_EMP_CVTEM_CONTENTS4 0xd70 +#define PKT2_EMP_CVTEM_CONTENTS5 0xd74 +#define PKT2_EMP_CVTEM_CONTENTS6 0xd78 +#define PKT2_EMP_CVTEM_CONTENTS7 0xd7c +#define PKT3_EMP_CVTEM_CONTENTS0 0xd80 +#define PKT3_EMP_CVTEM_CONTENTS1 0xd84 +#define PKT3_EMP_CVTEM_CONTENTS2 0xd88 +#define PKT3_EMP_CVTEM_CONTENTS3 0xd8c +#define PKT3_EMP_CVTEM_CONTENTS4 0xd90 +#define PKT3_EMP_CVTEM_CONTENTS5 0xd94 +#define PKT3_EMP_CVTEM_CONTENTS6 0xd98 +#define PKT3_EMP_CVTEM_CONTENTS7 0xd9c +#define PKT4_EMP_CVTEM_CONTENTS0 0xda0 +#define PKT4_EMP_CVTEM_CONTENTS1 0xda4 +#define PKT4_EMP_CVTEM_CONTENTS2 0xda8 +#define PKT4_EMP_CVTEM_CONTENTS3 0xdac +#define PKT4_EMP_CVTEM_CONTENTS4 0xdb0 +#define PKT4_EMP_CVTEM_CONTENTS5 0xdb4 +#define PKT4_EMP_CVTEM_CONTENTS6 0xdb8 +#define PKT4_EMP_CVTEM_CONTENTS7 0xdbc +#define PKT5_EMP_CVTEM_CONTENTS0 0xdc0 +#define PKT5_EMP_CVTEM_CONTENTS1 0xdc4 +#define PKT5_EMP_CVTEM_CONTENTS2 0xdc8 +#define PKT5_EMP_CVTEM_CONTENTS3 0xdcc +#define PKT5_EMP_CVTEM_CONTENTS4 0xdd0 +#define PKT5_EMP_CVTEM_CONTENTS5 0xdd4 +#define PKT5_EMP_CVTEM_CONTENTS6 0xdd8 +#define PKT5_EMP_CVTEM_CONTENTS7 0xddc +/* Audio Packetizer Registers */ +#define AUDPKT_CONTROL0 0xe20 +#define AUDPKT_PBIT_FORCE_EN_MASK BIT(12) +#define AUDPKT_PBIT_FORCE_EN BIT(12) +#define AUDPKT_CHSTATUS_OVR_EN_MASK BIT(0) +#define AUDPKT_CHSTATUS_OVR_EN BIT(0) +#define AUDPKT_CONTROL1 0xe24 +#define AUDPKT_ACR_CONTROL0 0xe40 +#define AUDPKT_ACR_N_VALUE 0xfffff +#define AUDPKT_ACR_CONTROL1 0xe44 +#define AUDPKT_ACR_CTS_OVR_VAL_MSK GENMASK(23, 4) +#define AUDPKT_ACR_CTS_OVR_VAL(x) ((x) << 4) +#define AUDPKT_ACR_CTS_OVR_EN_MSK BIT(1) +#define AUDPKT_ACR_CTS_OVR_EN BIT(1) +#define AUDPKT_ACR_STATUS0 0xe4c +#define AUDPKT_CHSTATUS_OVR0 0xe60 +#define AUDPKT_CHSTATUS_OVR1 0xe64 +/* IEC60958 Byte 3: Sampleing frenuency Bits 24 to 27 */ +#define AUDPKT_CHSTATUS_SR_MASK GENMASK(3, 0) +#define AUDPKT_CHSTATUS_SR_22050 0x4 +#define AUDPKT_CHSTATUS_SR_24000 0x6 +#define AUDPKT_CHSTATUS_SR_32000 0x3 +#define AUDPKT_CHSTATUS_SR_44100 0x0 +#define AUDPKT_CHSTATUS_SR_48000 0x2 +#define AUDPKT_CHSTATUS_SR_88200 0x8 +#define AUDPKT_CHSTATUS_SR_96000 0xa +#define AUDPKT_CHSTATUS_SR_176400 0xc +#define AUDPKT_CHSTATUS_SR_192000 0xe +#define AUDPKT_CHSTATUS_SR_768000 0x9 +#define AUDPKT_CHSTATUS_SR_NOT_INDICATED 0x1 +/* IEC60958 Byte 4: Original Sampleing frenuency Bits 36 to 39 */ +#define AUDPKT_CHSTATUS_0SR_MASK GENMASK(15, 12) +#define AUDPKT_CHSTATUS_OSR_8000 0x6 +#define AUDPKT_CHSTATUS_OSR_11025 0xa +#define AUDPKT_CHSTATUS_OSR_12000 0x2 +#define AUDPKT_CHSTATUS_OSR_16000 0x8 +#define AUDPKT_CHSTATUS_OSR_22050 0xb +#define AUDPKT_CHSTATUS_OSR_24000 0x9 +#define AUDPKT_CHSTATUS_OSR_32000 0xc +#define AUDPKT_CHSTATUS_OSR_44100 0xf +#define AUDPKT_CHSTATUS_OSR_48000 0xd +#define AUDPKT_CHSTATUS_OSR_88200 0x7 +#define AUDPKT_CHSTATUS_OSR_96000 0x5 +#define AUDPKT_CHSTATUS_OSR_176400 0x3 +#define AUDPKT_CHSTATUS_OSR_192000 0x1 +#define AUDPKT_CHSTATUS_OSR_NOT_INDICATED 0x0 +#define AUDPKT_CHSTATUS_OVR2 0xe68 +#define AUDPKT_CHSTATUS_OVR3 0xe6c +#define AUDPKT_CHSTATUS_OVR4 0xe70 +#define AUDPKT_CHSTATUS_OVR5 0xe74 +#define AUDPKT_CHSTATUS_OVR6 0xe78 +#define AUDPKT_CHSTATUS_OVR7 0xe7c +#define AUDPKT_CHSTATUS_OVR8 0xe80 +#define AUDPKT_CHSTATUS_OVR9 0xe84 +#define AUDPKT_CHSTATUS_OVR10 0xe88 +#define AUDPKT_CHSTATUS_OVR11 0xe8c +#define AUDPKT_CHSTATUS_OVR12 0xe90 +#define AUDPKT_CHSTATUS_OVR13 0xe94 +#define AUDPKT_CHSTATUS_OVR14 0xe98 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC0 0xea0 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC1 0xea4 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC2 0xea8 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC3 0xeac +#define AUDPKT_USRDATA_OVR_MSG_GENERIC4 0xeb0 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC5 0xeb4 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC6 0xeb8 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC7 0xebc +#define AUDPKT_USRDATA_OVR_MSG_GENERIC8 0xec0 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC9 0xec4 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC10 0xec8 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC11 0xecc +#define AUDPKT_USRDATA_OVR_MSG_GENERIC12 0xed0 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC13 0xed4 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC14 0xed8 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC15 0xedc +#define AUDPKT_USRDATA_OVR_MSG_GENERIC16 0xee0 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC17 0xee4 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC18 0xee8 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC19 0xeec +#define AUDPKT_USRDATA_OVR_MSG_GENERIC20 0xef0 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC21 0xef4 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC22 0xef8 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC23 0xefc +#define AUDPKT_USRDATA_OVR_MSG_GENERIC24 0xf00 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC25 0xf04 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC26 0xf08 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC27 0xf0c +#define AUDPKT_USRDATA_OVR_MSG_GENERIC28 0xf10 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC29 0xf14 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC30 0xf18 +#define AUDPKT_USRDATA_OVR_MSG_GENERIC31 0xf1c +#define AUDPKT_USRDATA_OVR_MSG_GENERIC32 0xf20 +#define AUDPKT_VBIT_OVR0 0xf24 +/* CEC Registers */ +#define CEC_TX_CONTROL 0x1000 +#define CEC_STATUS 0x1004 +#define CEC_CONFIG 0x1008 +#define CEC_ADDR 0x100c +#define CEC_TX_COUNT 0x1020 +#define CEC_TX_DATA3_0 0x1024 +#define CEC_TX_DATA7_4 0x1028 +#define CEC_TX_DATA11_8 0x102c +#define CEC_TX_DATA15_12 0x1030 +#define CEC_RX_COUNT_STATUS 0x1040 +#define CEC_RX_DATA3_0 0x1044 +#define CEC_RX_DATA7_4 0x1048 +#define CEC_RX_DATA11_8 0x104c +#define CEC_RX_DATA15_12 0x1050 +#define CEC_LOCK_CONTROL 0x1054 +#define CEC_RXQUAL_BITTIME_CONFIG 0x1060 +#define CEC_RX_BITTIME_CONFIG 0x1064 +#define CEC_TX_BITTIME_CONFIG 0x1068 +/* eARC RX CMDC Registers */ +#define EARCRX_CMDC_CONFIG0 0x1800 +#define EARCRX_XACTREAD_STOP_CFG BIT(26) +#define EARCRX_XACTREAD_RETRY_CFG BIT(25) +#define EARCRX_CMDC_DSCVR_EARCVALID0_TO_DISC1 BIT(24) +#define EARCRX_CMDC_XACT_RESTART_EN BIT(18) +#define EARCRX_CMDC_CONFIG1 0x1804 +#define EARCRX_CMDC_CONTROL 0x1808 +#define EARCRX_CMDC_HEARTBEAT_LOSS_EN BIT(4) +#define EARCRX_CMDC_DISCOVERY_EN BIT(3) +#define EARCRX_CONNECTOR_HPD BIT(1) +#define EARCRX_CMDC_WHITELIST0_CONFIG 0x180c +#define EARCRX_CMDC_WHITELIST1_CONFIG 0x1810 +#define EARCRX_CMDC_WHITELIST2_CONFIG 0x1814 +#define EARCRX_CMDC_WHITELIST3_CONFIG 0x1818 +#define EARCRX_CMDC_STATUS 0x181c +#define EARCRX_CMDC_XACT_INFO 0x1820 +#define EARCRX_CMDC_XACT_ACTION 0x1824 +#define EARCRX_CMDC_HEARTBEAT_RXSTAT_SE 0x1828 +#define EARCRX_CMDC_HEARTBEAT_STATUS 0x182c +#define EARCRX_CMDC_XACT_WR0 0x1840 +#define EARCRX_CMDC_XACT_WR1 0x1844 +#define EARCRX_CMDC_XACT_WR2 0x1848 +#define EARCRX_CMDC_XACT_WR3 0x184c +#define EARCRX_CMDC_XACT_WR4 0x1850 +#define EARCRX_CMDC_XACT_WR5 0x1854 +#define EARCRX_CMDC_XACT_WR6 0x1858 +#define EARCRX_CMDC_XACT_WR7 0x185c +#define EARCRX_CMDC_XACT_WR8 0x1860 +#define EARCRX_CMDC_XACT_WR9 0x1864 +#define EARCRX_CMDC_XACT_WR10 0x1868 +#define EARCRX_CMDC_XACT_WR11 0x186c +#define EARCRX_CMDC_XACT_WR12 0x1870 +#define EARCRX_CMDC_XACT_WR13 0x1874 +#define EARCRX_CMDC_XACT_WR14 0x1878 +#define EARCRX_CMDC_XACT_WR15 0x187c +#define EARCRX_CMDC_XACT_WR16 0x1880 +#define EARCRX_CMDC_XACT_WR17 0x1884 +#define EARCRX_CMDC_XACT_WR18 0x1888 +#define EARCRX_CMDC_XACT_WR19 0x188c +#define EARCRX_CMDC_XACT_WR20 0x1890 +#define EARCRX_CMDC_XACT_WR21 0x1894 +#define EARCRX_CMDC_XACT_WR22 0x1898 +#define EARCRX_CMDC_XACT_WR23 0x189c +#define EARCRX_CMDC_XACT_WR24 0x18a0 +#define EARCRX_CMDC_XACT_WR25 0x18a4 +#define EARCRX_CMDC_XACT_WR26 0x18a8 +#define EARCRX_CMDC_XACT_WR27 0x18ac +#define EARCRX_CMDC_XACT_WR28 0x18b0 +#define EARCRX_CMDC_XACT_WR29 0x18b4 +#define EARCRX_CMDC_XACT_WR30 0x18b8 +#define EARCRX_CMDC_XACT_WR31 0x18bc +#define EARCRX_CMDC_XACT_WR32 0x18c0 +#define EARCRX_CMDC_XACT_WR33 0x18c4 +#define EARCRX_CMDC_XACT_WR34 0x18c8 +#define EARCRX_CMDC_XACT_WR35 0x18cc +#define EARCRX_CMDC_XACT_WR36 0x18d0 +#define EARCRX_CMDC_XACT_WR37 0x18d4 +#define EARCRX_CMDC_XACT_WR38 0x18d8 +#define EARCRX_CMDC_XACT_WR39 0x18dc +#define EARCRX_CMDC_XACT_WR40 0x18e0 +#define EARCRX_CMDC_XACT_WR41 0x18e4 +#define EARCRX_CMDC_XACT_WR42 0x18e8 +#define EARCRX_CMDC_XACT_WR43 0x18ec +#define EARCRX_CMDC_XACT_WR44 0x18f0 +#define EARCRX_CMDC_XACT_WR45 0x18f4 +#define EARCRX_CMDC_XACT_WR46 0x18f8 +#define EARCRX_CMDC_XACT_WR47 0x18fc +#define EARCRX_CMDC_XACT_WR48 0x1900 +#define EARCRX_CMDC_XACT_WR49 0x1904 +#define EARCRX_CMDC_XACT_WR50 0x1908 +#define EARCRX_CMDC_XACT_WR51 0x190c +#define EARCRX_CMDC_XACT_WR52 0x1910 +#define EARCRX_CMDC_XACT_WR53 0x1914 +#define EARCRX_CMDC_XACT_WR54 0x1918 +#define EARCRX_CMDC_XACT_WR55 0x191c +#define EARCRX_CMDC_XACT_WR56 0x1920 +#define EARCRX_CMDC_XACT_WR57 0x1924 +#define EARCRX_CMDC_XACT_WR58 0x1928 +#define EARCRX_CMDC_XACT_WR59 0x192c +#define EARCRX_CMDC_XACT_WR60 0x1930 +#define EARCRX_CMDC_XACT_WR61 0x1934 +#define EARCRX_CMDC_XACT_WR62 0x1938 +#define EARCRX_CMDC_XACT_WR63 0x193c +#define EARCRX_CMDC_XACT_WR64 0x1940 +#define EARCRX_CMDC_XACT_RD0 0x1960 +#define EARCRX_CMDC_XACT_RD1 0x1964 +#define EARCRX_CMDC_XACT_RD2 0x1968 +#define EARCRX_CMDC_XACT_RD3 0x196c +#define EARCRX_CMDC_XACT_RD4 0x1970 +#define EARCRX_CMDC_XACT_RD5 0x1974 +#define EARCRX_CMDC_XACT_RD6 0x1978 +#define EARCRX_CMDC_XACT_RD7 0x197c +#define EARCRX_CMDC_XACT_RD8 0x1980 +#define EARCRX_CMDC_XACT_RD9 0x1984 +#define EARCRX_CMDC_XACT_RD10 0x1988 +#define EARCRX_CMDC_XACT_RD11 0x198c +#define EARCRX_CMDC_XACT_RD12 0x1990 +#define EARCRX_CMDC_XACT_RD13 0x1994 +#define EARCRX_CMDC_XACT_RD14 0x1998 +#define EARCRX_CMDC_XACT_RD15 0x199c +#define EARCRX_CMDC_XACT_RD16 0x19a0 +#define EARCRX_CMDC_XACT_RD17 0x19a4 +#define EARCRX_CMDC_XACT_RD18 0x19a8 +#define EARCRX_CMDC_XACT_RD19 0x19ac +#define EARCRX_CMDC_XACT_RD20 0x19b0 +#define EARCRX_CMDC_XACT_RD21 0x19b4 +#define EARCRX_CMDC_XACT_RD22 0x19b8 +#define EARCRX_CMDC_XACT_RD23 0x19bc +#define EARCRX_CMDC_XACT_RD24 0x19c0 +#define EARCRX_CMDC_XACT_RD25 0x19c4 +#define EARCRX_CMDC_XACT_RD26 0x19c8 +#define EARCRX_CMDC_XACT_RD27 0x19cc +#define EARCRX_CMDC_XACT_RD28 0x19d0 +#define EARCRX_CMDC_XACT_RD29 0x19d4 +#define EARCRX_CMDC_XACT_RD30 0x19d8 +#define EARCRX_CMDC_XACT_RD31 0x19dc +#define EARCRX_CMDC_XACT_RD32 0x19e0 +#define EARCRX_CMDC_XACT_RD33 0x19e4 +#define EARCRX_CMDC_XACT_RD34 0x19e8 +#define EARCRX_CMDC_XACT_RD35 0x19ec +#define EARCRX_CMDC_XACT_RD36 0x19f0 +#define EARCRX_CMDC_XACT_RD37 0x19f4 +#define EARCRX_CMDC_XACT_RD38 0x19f8 +#define EARCRX_CMDC_XACT_RD39 0x19fc +#define EARCRX_CMDC_XACT_RD40 0x1a00 +#define EARCRX_CMDC_XACT_RD41 0x1a04 +#define EARCRX_CMDC_XACT_RD42 0x1a08 +#define EARCRX_CMDC_XACT_RD43 0x1a0c +#define EARCRX_CMDC_XACT_RD44 0x1a10 +#define EARCRX_CMDC_XACT_RD45 0x1a14 +#define EARCRX_CMDC_XACT_RD46 0x1a18 +#define EARCRX_CMDC_XACT_RD47 0x1a1c +#define EARCRX_CMDC_XACT_RD48 0x1a20 +#define EARCRX_CMDC_XACT_RD49 0x1a24 +#define EARCRX_CMDC_XACT_RD50 0x1a28 +#define EARCRX_CMDC_XACT_RD51 0x1a2c +#define EARCRX_CMDC_XACT_RD52 0x1a30 +#define EARCRX_CMDC_XACT_RD53 0x1a34 +#define EARCRX_CMDC_XACT_RD54 0x1a38 +#define EARCRX_CMDC_XACT_RD55 0x1a3c +#define EARCRX_CMDC_XACT_RD56 0x1a40 +#define EARCRX_CMDC_XACT_RD57 0x1a44 +#define EARCRX_CMDC_XACT_RD58 0x1a48 +#define EARCRX_CMDC_XACT_RD59 0x1a4c +#define EARCRX_CMDC_XACT_RD60 0x1a50 +#define EARCRX_CMDC_XACT_RD61 0x1a54 +#define EARCRX_CMDC_XACT_RD62 0x1a58 +#define EARCRX_CMDC_XACT_RD63 0x1a5c +#define EARCRX_CMDC_XACT_RD64 0x1a60 +#define EARCRX_CMDC_SYNC_CONFIG 0x1b00 +/* eARC RX DMAC Registers */ +#define EARCRX_DMAC_PHY_CONTROL 0x1c00 +#define EARCRX_DMAC_CONFIG 0x1c08 +#define EARCRX_DMAC_CONTROL0 0x1c0c +#define EARCRX_DMAC_AUDIO_EN BIT(1) +#define EARCRX_DMAC_EN BIT(0) +#define EARCRX_DMAC_CONTROL1 0x1c10 +#define EARCRX_DMAC_STATUS 0x1c14 +#define EARCRX_DMAC_CHSTATUS0 0x1c18 +#define EARCRX_DMAC_CHSTATUS1 0x1c1c +#define EARCRX_DMAC_CHSTATUS2 0x1c20 +#define EARCRX_DMAC_CHSTATUS3 0x1c24 +#define EARCRX_DMAC_CHSTATUS4 0x1c28 +#define EARCRX_DMAC_CHSTATUS5 0x1c2c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC0 0x1c30 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC1 0x1c34 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC2 0x1c38 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC3 0x1c3c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC4 0x1c40 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC5 0x1c44 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC6 0x1c48 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC7 0x1c4c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC8 0x1c50 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC9 0x1c54 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC10 0x1c58 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_AC11 0x1c5c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT0 0x1c60 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT1 0x1c64 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT2 0x1c68 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT3 0x1c6c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT4 0x1c70 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT5 0x1c74 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT6 0x1c78 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT7 0x1c7c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT8 0x1c80 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT9 0x1c84 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT10 0x1c88 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC1_PKT11 0x1c8c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT0 0x1c90 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT1 0x1c94 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT2 0x1c98 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT3 0x1c9c +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT4 0x1ca0 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT5 0x1ca4 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT6 0x1ca8 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT7 0x1cac +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT8 0x1cb0 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT9 0x1cb4 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT10 0x1cb8 +#define EARCRX_DMAC_USRDATA_MSG_HDMI_ISRC2_PKT11 0x1cbc +#define EARCRX_DMAC_USRDATA_MSG_GENERIC0 0x1cc0 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC1 0x1cc4 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC2 0x1cc8 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC3 0x1ccc +#define EARCRX_DMAC_USRDATA_MSG_GENERIC4 0x1cd0 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC5 0x1cd4 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC6 0x1cd8 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC7 0x1cdc +#define EARCRX_DMAC_USRDATA_MSG_GENERIC8 0x1ce0 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC9 0x1ce4 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC10 0x1ce8 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC11 0x1cec +#define EARCRX_DMAC_USRDATA_MSG_GENERIC12 0x1cf0 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC13 0x1cf4 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC14 0x1cf8 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC15 0x1cfc +#define EARCRX_DMAC_USRDATA_MSG_GENERIC16 0x1d00 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC17 0x1d04 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC18 0x1d08 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC19 0x1d0c +#define EARCRX_DMAC_USRDATA_MSG_GENERIC20 0x1d10 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC21 0x1d14 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC22 0x1d18 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC23 0x1d1c +#define EARCRX_DMAC_USRDATA_MSG_GENERIC24 0x1d20 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC25 0x1d24 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC26 0x1d28 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC27 0x1d2c +#define EARCRX_DMAC_USRDATA_MSG_GENERIC28 0x1d30 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC29 0x1d34 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC30 0x1d38 +#define EARCRX_DMAC_USRDATA_MSG_GENERIC31 0x1d3c +#define EARCRX_DMAC_USRDATA_MSG_GENERIC32 0x1d40 +#define EARCRX_DMAC_CHSTATUS_STREAMER0 0x1d44 +#define EARCRX_DMAC_CHSTATUS_STREAMER1 0x1d48 +#define EARCRX_DMAC_CHSTATUS_STREAMER2 0x1d4c +#define EARCRX_DMAC_CHSTATUS_STREAMER3 0x1d50 +#define EARCRX_DMAC_CHSTATUS_STREAMER4 0x1d54 +#define EARCRX_DMAC_CHSTATUS_STREAMER5 0x1d58 +#define EARCRX_DMAC_CHSTATUS_STREAMER6 0x1d5c +#define EARCRX_DMAC_CHSTATUS_STREAMER7 0x1d60 +#define EARCRX_DMAC_CHSTATUS_STREAMER8 0x1d64 +#define EARCRX_DMAC_CHSTATUS_STREAMER9 0x1d68 +#define EARCRX_DMAC_CHSTATUS_STREAMER10 0x1d6c +#define EARCRX_DMAC_CHSTATUS_STREAMER11 0x1d70 +#define EARCRX_DMAC_CHSTATUS_STREAMER12 0x1d74 +#define EARCRX_DMAC_CHSTATUS_STREAMER13 0x1d78 +#define EARCRX_DMAC_CHSTATUS_STREAMER14 0x1d7c +#define EARCRX_DMAC_USRDATA_STREAMER0 0x1d80 +/* Main Unit Interrupt Registers */ +#define MAIN_INTVEC_INDEX 0x3000 +#define MAINUNIT_0_INT_STATUS 0x3010 +#define MAINUNIT_0_INT_MASK_N 0x3014 +#define MAINUNIT_0_INT_CLEAR 0x3018 +#define MAINUNIT_0_INT_FORCE 0x301c +#define MAINUNIT_1_INT_STATUS 0x3020 +#define FLT_EXIT_TO_LTSL_IRQ BIT(22) +#define FLT_EXIT_TO_LTS4_IRQ BIT(21) +#define FLT_EXIT_TO_LTSP_IRQ BIT(20) +#define SCDC_NACK_RCVD_IRQ BIT(12) +#define SCDC_RR_REPLY_STOP_IRQ BIT(11) +#define SCDC_UPD_FLAGS_CLR_IRQ BIT(10) +#define SCDC_UPD_FLAGS_CHG_IRQ BIT(9) +#define SCDC_UPD_FLAGS_RD_IRQ BIT(8) +#define I2CM_NACK_RCVD_IRQ BIT(2) +#define I2CM_READ_REQUEST_IRQ BIT(1) +#define I2CM_OP_DONE_IRQ BIT(0) +#define MAINUNIT_1_INT_MASK_N 0x3024 +#define I2CM_NACK_RCVD_MASK_N BIT(2) +#define I2CM_READ_REQUEST_MASK_N BIT(1) +#define I2CM_OP_DONE_MASK_N BIT(0) +#define MAINUNIT_1_INT_CLEAR 0x3028 +#define I2CM_NACK_RCVD_CLEAR BIT(2) +#define I2CM_READ_REQUEST_CLEAR BIT(1) +#define I2CM_OP_DONE_CLEAR BIT(0) +#define MAINUNIT_1_INT_FORCE 0x302c +/* AVPUNIT Interrupt Registers */ +#define AVP_INTVEC_INDEX 0x3800 +#define AVP_0_INT_STATUS 0x3810 +#define AVP_0_INT_MASK_N 0x3814 +#define AVP_0_INT_CLEAR 0x3818 +#define AVP_0_INT_FORCE 0x381c +#define AVP_1_INT_STATUS 0x3820 +#define AVP_1_INT_MASK_N 0x3824 +#define HDCP14_AUTH_CHG_MASK_N BIT(6) +#define AVP_1_INT_CLEAR 0x3828 +#define AVP_1_INT_FORCE 0x382c +#define AVP_2_INT_STATUS 0x3830 +#define AVP_2_INT_MASK_N 0x3834 +#define AVP_2_INT_CLEAR 0x3838 +#define AVP_2_INT_FORCE 0x383c +#define AVP_3_INT_STATUS 0x3840 +#define AVP_3_INT_MASK_N 0x3844 +#define AVP_3_INT_CLEAR 0x3848 +#define AVP_3_INT_FORCE 0x384c +#define AVP_4_INT_STATUS 0x3850 +#define AVP_4_INT_MASK_N 0x3854 +#define AVP_4_INT_CLEAR 0x3858 +#define AVP_4_INT_FORCE 0x385c +#define AVP_5_INT_STATUS 0x3860 +#define AVP_5_INT_MASK_N 0x3864 +#define AVP_5_INT_CLEAR 0x3868 +#define AVP_5_INT_FORCE 0x386c +#define AVP_6_INT_STATUS 0x3870 +#define AVP_6_INT_MASK_N 0x3874 +#define AVP_6_INT_CLEAR 0x3878 +#define AVP_6_INT_FORCE 0x387c +/* CEC Interrupt Registers */ +#define CEC_INT_STATUS 0x4000 +#define CEC_INT_MASK_N 0x4004 +#define CEC_INT_CLEAR 0x4008 +#define CEC_INT_FORCE 0x400c +/* eARC RX Interrupt Registers */ +#define EARCRX_INTVEC_INDEX 0x4800 +#define EARCRX_0_INT_STATUS 0x4810 +#define EARCRX_CMDC_DISCOVERY_TIMEOUT_IRQ BIT(9) +#define EARCRX_CMDC_DISCOVERY_DONE_IRQ BIT(8) +#define EARCRX_0_INT_MASK_N 0x4814 +#define EARCRX_0_INT_CLEAR 0x4818 +#define EARCRX_0_INT_FORCE 0x481c +#define EARCRX_1_INT_STATUS 0x4820 +#define EARCRX_1_INT_MASK_N 0x4824 +#define EARCRX_1_INT_CLEAR 0x4828 +#define EARCRX_1_INT_FORCE 0x482c + +#endif /* __DW_HDMI_QP_H__ */ diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h new file mode 100644 index 000000000000..e9be6d507ad9 --- /dev/null +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Collabora Ltd. + */ + +#ifndef __DW_HDMI_QP__ +#define __DW_HDMI_QP__ + +struct device; +struct drm_encoder; +struct dw_hdmi_qp; +struct platform_device; + +struct dw_hdmi_qp_phy_ops { + int (*init)(struct dw_hdmi_qp *hdmi, void *data); + void (*disable)(struct dw_hdmi_qp *hdmi, void *data); + enum drm_connector_status (*read_hpd)(struct dw_hdmi_qp *hdmi, void *data); + void (*setup_hpd)(struct dw_hdmi_qp *hdmi, void *data); +}; + +struct dw_hdmi_qp_plat_data { + const struct dw_hdmi_qp_phy_ops *phy_ops; + void *phy_data; + int main_irq; +}; + +struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, + struct drm_encoder *encoder, + const struct dw_hdmi_qp_plat_data *plat_data); +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); +#endif /* __DW_HDMI_QP__ */ -- GitLab From c0d28332ff90f800ccd1a3b73cb50c3335b0286a Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Date: Wed, 16 Oct 2024 23:06:52 +0300 Subject: [PATCH 889/970] dt-bindings: display: rockchip: Add schema for RK3588 HDMI TX Controller Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX controller IP. Since this is a new IP block, quite different from those used in the previous generations of Rockchip SoCs, add a dedicated binding file. Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016-b4-rk3588-bridge-upstream-v10-2-87ef92a6d14e@collabora.com Signed-off-by: Maxime Ripard <mripard@kernel.org> --- .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml new file mode 100644 index 000000000000..d8e761865f27 --- /dev/null +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml @@ -0,0 +1,188 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip DW HDMI QP TX Encoder + +maintainers: + - Cristian Ciocaltea <cristian.ciocaltea@collabora.com> + +description: | + Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI QP TX controller + IP and a HDMI/eDP TX Combo PHY based on a Samsung IP block, providing the + following features, among others: + + * Fixed Rate Link (FRL) + * Display Stream Compression (DSC) + * 4K@120Hz and 8K@60Hz video modes + * Variable Refresh Rate (VRR) including Quick Media Switching (QMS) + * Fast Vactive (FVA) + * SCDC I2C DDC access + * Multi-stream audio + * Enhanced Audio Return Channel (EARC) + +allOf: + - $ref: /schemas/sound/dai-common.yaml# + +properties: + compatible: + enum: + - rockchip,rk3588-dw-hdmi-qp + + reg: + maxItems: 1 + + clocks: + items: + - description: Peripheral/APB bus clock + - description: EARC RX biphase clock + - description: Reference clock + - description: Audio interface clock + - description: TMDS/FRL link clock + - description: Video datapath clock + + clock-names: + items: + - const: pclk + - const: earc + - const: ref + - const: aud + - const: hdp + - const: hclk_vo1 + + interrupts: + items: + - description: AVP Unit interrupt + - description: CEC interrupt + - description: eARC RX interrupt + - description: Main Unit interrupt + - description: HPD interrupt + + interrupt-names: + items: + - const: avp + - const: cec + - const: earc + - const: main + - const: hpd + + phys: + maxItems: 1 + description: The HDMI/eDP PHY + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Video port for RGB/YUV input. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Video port for HDMI/eDP output. + + required: + - port@0 + - port@1 + + power-domains: + maxItems: 1 + + resets: + maxItems: 2 + + reset-names: + items: + - const: ref + - const: hdp + + "#sound-dai-cells": + const: 0 + + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Some HDMI QP related data is accessed through SYS GRF regs. + + rockchip,vo-grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Additional HDMI QP related data is accessed through VO GRF regs. + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - interrupt-names + - phys + - ports + - resets + - reset-names + - rockchip,grf + - rockchip,vo-grf + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/rockchip,rk3588-cru.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/power/rk3588-power.h> + #include <dt-bindings/reset/rockchip,rk3588-cru.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + + hdmi@fde80000 { + compatible = "rockchip,rk3588-dw-hdmi-qp"; + reg = <0x0 0xfde80000 0x0 0x20000>; + clocks = <&cru PCLK_HDMITX0>, + <&cru CLK_HDMITX0_EARC>, + <&cru CLK_HDMITX0_REF>, + <&cru MCLK_I2S5_8CH_TX>, + <&cru CLK_HDMIHDP0>, + <&cru HCLK_VO1>; + clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1"; + interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "avp", "cec", "earc", "main", "hpd"; + phys = <&hdptxphy_hdmi0>; + power-domains = <&power RK3588_PD_VO1>; + resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMIHDP0>; + reset-names = "ref", "hdp"; + rockchip,grf = <&sys_grf>; + rockchip,vo-grf = <&vo1_grf>; + #sound-dai-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hdmi0_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi0>; + }; + }; + + port@1 { + reg = <1>; + + hdmi0_out_con0: endpoint { + remote-endpoint = <&hdmi_con0_in>; + }; + }; + }; + }; + }; -- GitLab From 128a9bf8ace290d86d2805c06f3b0e4cfab75de0 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Date: Wed, 16 Oct 2024 23:06:53 +0300 Subject: [PATCH 890/970] drm/rockchip: Add basic RK3588 HDMI output support The RK3588 SoC family integrates the newer Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX controller IP and a HDMI/eDP TX Combo PHY based on a Samsung IP block. Add just the basic support for now, i.e. RGB output up to 4K@60Hz, without audio, CEC or any of the HDMI 2.1 specific features. Co-developed-by: Algea Cao <algea.cao@rock-chips.com> Signed-off-by: Algea Cao <algea.cao@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241016-b4-rk3588-bridge-upstream-v10-3-87ef92a6d14e@collabora.com Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/rockchip/Kconfig | 9 + drivers/gpu/drm/rockchip/Makefile | 1 + .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 424 ++++++++++++++++++ drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + 5 files changed, 437 insertions(+) create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 258dd38e1a8e..3ac579615749 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -9,6 +9,7 @@ config DRM_ROCKCHIP select VIDEOMODE_HELPERS select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP select DRM_DW_HDMI if ROCKCHIP_DW_HDMI + select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI @@ -64,6 +65,14 @@ config ROCKCHIP_DW_HDMI enable HDMI on RK3288 or RK3399 based SoC, you should select this option. +config ROCKCHIP_DW_HDMI_QP + bool "Rockchip specific extensions for Synopsys DW HDMI QP" + select DRM_BRIDGE_CONNECTOR + help + This selects support for Rockchip SoC specific extensions + for the Synopsys DesignWare HDMI QP driver. If you want to + enable HDMI on RK3588 based SoC, you should select this option. + config ROCKCHIP_DW_MIPI_DSI bool "Rockchip specific extensions for Synopsys DW MIPI DSI" select GENERIC_PHY_MIPI_DPHY diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile index 3ff7b21c0414..3eab662a5a1d 100644 --- a/drivers/gpu/drm/rockchip/Makefile +++ b/drivers/gpu/drm/rockchip/Makefile @@ -11,6 +11,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o +rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c new file mode 100644 index 000000000000..9c796ee4c303 --- /dev/null +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -0,0 +1,424 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Collabora Ltd. + * + * Author: Algea Cao <algea.cao@rock-chips.com> + * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> + */ + +#include <linux/clk.h> +#include <linux/gpio/consumer.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/phy/phy.h> +#include <linux/regmap.h> +#include <linux/workqueue.h> + +#include <drm/bridge/dw_hdmi_qp.h> +#include <drm/display/drm_hdmi_helper.h> +#include <drm/drm_bridge_connector.h> +#include <drm/drm_of.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_simple_kms_helper.h> + +#include "rockchip_drm_drv.h" + +#define RK3588_GRF_SOC_CON2 0x0308 +#define RK3588_HDMI0_HPD_INT_MSK BIT(13) +#define RK3588_HDMI0_HPD_INT_CLR BIT(12) +#define RK3588_GRF_SOC_CON7 0x031c +#define RK3588_SET_HPD_PATH_MASK GENMASK(13, 12) +#define RK3588_GRF_SOC_STATUS1 0x0384 +#define RK3588_HDMI0_LEVEL_INT BIT(16) +#define RK3588_GRF_VO1_CON3 0x000c +#define RK3588_SCLIN_MASK BIT(9) +#define RK3588_SDAIN_MASK BIT(10) +#define RK3588_MODE_MASK BIT(11) +#define RK3588_I2S_SEL_MASK BIT(13) +#define RK3588_GRF_VO1_CON9 0x0024 +#define RK3588_HDMI0_GRANT_SEL BIT(10) + +#define HIWORD_UPDATE(val, mask) ((val) | (mask) << 16) +#define HOTPLUG_DEBOUNCE_MS 150 + +struct rockchip_hdmi_qp { + struct device *dev; + struct regmap *regmap; + struct regmap *vo_regmap; + struct rockchip_encoder encoder; + struct clk *ref_clk; + struct dw_hdmi_qp *hdmi; + struct phy *phy; + struct gpio_desc *enable_gpio; + struct delayed_work hpd_work; +}; + +static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder) +{ + struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); + + return container_of(rkencoder, struct rockchip_hdmi_qp, encoder); +} + +static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) +{ + struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); + struct drm_crtc *crtc = encoder->crtc; + unsigned long long rate; + + /* Unconditionally switch to TMDS as FRL is not yet supported */ + gpiod_set_value(hdmi->enable_gpio, 1); + + if (crtc && crtc->state) { + rate = drm_hdmi_compute_mode_clock(&crtc->state->adjusted_mode, + 8, HDMI_COLORSPACE_RGB); + clk_set_rate(hdmi->ref_clk, rate); + /* + * FIXME: Temporary workaround to pass pixel clock rate + * to the PHY driver until phy_configure_opts_hdmi + * becomes available in the PHY API. See also the related + * comment in rk_hdptx_phy_power_on() from + * drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c + */ + phy_set_bus_width(hdmi->phy, rate / 100); + } +} + +static int +dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + s->output_type = DRM_MODE_CONNECTOR_HDMIA; + + return 0; +} + +static const struct +drm_encoder_helper_funcs dw_hdmi_qp_rockchip_encoder_helper_funcs = { + .enable = dw_hdmi_qp_rockchip_encoder_enable, + .atomic_check = dw_hdmi_qp_rockchip_encoder_atomic_check, +}; + +static int dw_hdmi_qp_rk3588_phy_init(struct dw_hdmi_qp *dw_hdmi, void *data) +{ + struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; + + return phy_power_on(hdmi->phy); +} + +static void dw_hdmi_qp_rk3588_phy_disable(struct dw_hdmi_qp *dw_hdmi, + void *data) +{ + struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; + + phy_power_off(hdmi->phy); +} + +static enum drm_connector_status +dw_hdmi_qp_rk3588_read_hpd(struct dw_hdmi_qp *dw_hdmi, void *data) +{ + struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; + u32 val; + + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &val); + + return val & RK3588_HDMI0_LEVEL_INT ? + connector_status_connected : connector_status_disconnected; +} + +static void dw_hdmi_qp_rk3588_setup_hpd(struct dw_hdmi_qp *dw_hdmi, void *data) +{ + struct rockchip_hdmi_qp *hdmi = (struct rockchip_hdmi_qp *)data; + + regmap_write(hdmi->regmap, + RK3588_GRF_SOC_CON2, + HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, + RK3588_HDMI0_HPD_INT_CLR | + RK3588_HDMI0_HPD_INT_MSK)); +} + +static const struct dw_hdmi_qp_phy_ops rk3588_hdmi_phy_ops = { + .init = dw_hdmi_qp_rk3588_phy_init, + .disable = dw_hdmi_qp_rk3588_phy_disable, + .read_hpd = dw_hdmi_qp_rk3588_read_hpd, + .setup_hpd = dw_hdmi_qp_rk3588_setup_hpd, +}; + +static void dw_hdmi_qp_rk3588_hpd_work(struct work_struct *work) +{ + struct rockchip_hdmi_qp *hdmi = container_of(work, + struct rockchip_hdmi_qp, + hpd_work.work); + struct drm_device *drm = hdmi->encoder.encoder.dev; + bool changed; + + if (drm) { + changed = drm_helper_hpd_irq_event(drm); + if (changed) + drm_dbg(hdmi, "connector status changed\n"); + } +} + +static irqreturn_t dw_hdmi_qp_rk3588_hardirq(int irq, void *dev_id) +{ + struct rockchip_hdmi_qp *hdmi = dev_id; + u32 intr_stat, val; + + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat); + + if (intr_stat) { + val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, + RK3588_HDMI0_HPD_INT_MSK); + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); + return IRQ_WAKE_THREAD; + } + + return IRQ_NONE; +} + +static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id) +{ + struct rockchip_hdmi_qp *hdmi = dev_id; + u32 intr_stat, val; + + regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat); + if (!intr_stat) + return IRQ_NONE; + + val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_CLR, + RK3588_HDMI0_HPD_INT_CLR); + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); + + mod_delayed_work(system_wq, &hdmi->hpd_work, + msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); + + val |= HIWORD_UPDATE(0, RK3588_HDMI0_HPD_INT_MSK); + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); + + return IRQ_HANDLED; +} + +static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = { + { .compatible = "rockchip,rk3588-dw-hdmi-qp", + .data = &rk3588_hdmi_phy_ops }, + {}, +}; +MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids); + +static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, + void *data) +{ + static const char * const clk_names[] = { + "pclk", "earc", "aud", "hdp", "hclk_vo1", + "ref" /* keep "ref" last */ + }; + struct platform_device *pdev = to_platform_device(dev); + struct dw_hdmi_qp_plat_data plat_data; + struct drm_device *drm = data; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct rockchip_hdmi_qp *hdmi; + struct clk *clk; + int ret, irq, i; + u32 val; + + if (!pdev->dev.of_node) + return -ENODEV; + + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + plat_data.phy_ops = of_device_get_match_data(dev); + if (!plat_data.phy_ops) + return -ENODEV; + + plat_data.phy_data = hdmi; + hdmi->dev = &pdev->dev; + + encoder = &hdmi->encoder.encoder; + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); + + rockchip_drm_encoder_set_crtc_endpoint_id(&hdmi->encoder, + dev->of_node, 0, 0); + /* + * If we failed to find the CRTC(s) which this encoder is + * supposed to be connected to, it's because the CRTC has + * not been registered yet. Defer probing, and hope that + * the required CRTC is added later. + */ + if (encoder->possible_crtcs == 0) + return -EPROBE_DEFER; + + hdmi->regmap = syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,grf"); + if (IS_ERR(hdmi->regmap)) { + drm_err(hdmi, "Unable to get rockchip,grf\n"); + return PTR_ERR(hdmi->regmap); + } + + hdmi->vo_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,vo-grf"); + if (IS_ERR(hdmi->vo_regmap)) { + drm_err(hdmi, "Unable to get rockchip,vo-grf\n"); + return PTR_ERR(hdmi->vo_regmap); + } + + for (i = 0; i < ARRAY_SIZE(clk_names); i++) { + clk = devm_clk_get_enabled(hdmi->dev, clk_names[i]); + + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + if (ret != -EPROBE_DEFER) + drm_err(hdmi, "Failed to get %s clock: %d\n", + clk_names[i], ret); + return ret; + } + } + hdmi->ref_clk = clk; + + hdmi->enable_gpio = devm_gpiod_get_optional(hdmi->dev, "enable", + GPIOD_OUT_HIGH); + if (IS_ERR(hdmi->enable_gpio)) { + ret = PTR_ERR(hdmi->enable_gpio); + drm_err(hdmi, "Failed to request enable GPIO: %d\n", ret); + return ret; + } + + hdmi->phy = devm_of_phy_get_by_index(dev, dev->of_node, 0); + if (IS_ERR(hdmi->phy)) { + ret = PTR_ERR(hdmi->phy); + if (ret != -EPROBE_DEFER) + drm_err(hdmi, "failed to get phy: %d\n", ret); + return ret; + } + + val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) | + HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) | + HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) | + HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK); + regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val); + + val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, + RK3588_SET_HPD_PATH_MASK); + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val); + + val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, + RK3588_HDMI0_GRANT_SEL); + regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val); + + val = HIWORD_UPDATE(RK3588_HDMI0_HPD_INT_MSK, RK3588_HDMI0_HPD_INT_MSK); + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON2, val); + + INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_qp_rk3588_hpd_work); + + plat_data.main_irq = platform_get_irq_byname(pdev, "main"); + if (plat_data.main_irq < 0) + return plat_data.main_irq; + + irq = platform_get_irq_byname(pdev, "hpd"); + if (irq < 0) + return irq; + + ret = devm_request_threaded_irq(hdmi->dev, irq, + dw_hdmi_qp_rk3588_hardirq, + dw_hdmi_qp_rk3588_irq, + IRQF_SHARED, "dw-hdmi-qp-hpd", + hdmi); + if (ret) + return ret; + + drm_encoder_helper_add(encoder, &dw_hdmi_qp_rockchip_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + + platform_set_drvdata(pdev, hdmi); + + hdmi->hdmi = dw_hdmi_qp_bind(pdev, encoder, &plat_data); + if (IS_ERR(hdmi->hdmi)) { + ret = PTR_ERR(hdmi->hdmi); + drm_encoder_cleanup(encoder); + return ret; + } + + connector = drm_bridge_connector_init(drm, encoder); + if (IS_ERR(connector)) { + ret = PTR_ERR(connector); + drm_err(hdmi, "failed to init bridge connector: %d\n", ret); + return ret; + } + + return drm_connector_attach_encoder(connector, encoder); +} + +static void dw_hdmi_qp_rockchip_unbind(struct device *dev, + struct device *master, + void *data) +{ + struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); + + cancel_delayed_work_sync(&hdmi->hpd_work); + + drm_encoder_cleanup(&hdmi->encoder.encoder); +} + +static const struct component_ops dw_hdmi_qp_rockchip_ops = { + .bind = dw_hdmi_qp_rockchip_bind, + .unbind = dw_hdmi_qp_rockchip_unbind, +}; + +static int dw_hdmi_qp_rockchip_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &dw_hdmi_qp_rockchip_ops); +} + +static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops); +} + +static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) +{ + struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); + u32 val; + + val = HIWORD_UPDATE(RK3588_SCLIN_MASK, RK3588_SCLIN_MASK) | + HIWORD_UPDATE(RK3588_SDAIN_MASK, RK3588_SDAIN_MASK) | + HIWORD_UPDATE(RK3588_MODE_MASK, RK3588_MODE_MASK) | + HIWORD_UPDATE(RK3588_I2S_SEL_MASK, RK3588_I2S_SEL_MASK); + regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON3, val); + + val = HIWORD_UPDATE(RK3588_SET_HPD_PATH_MASK, + RK3588_SET_HPD_PATH_MASK); + regmap_write(hdmi->regmap, RK3588_GRF_SOC_CON7, val); + + val = HIWORD_UPDATE(RK3588_HDMI0_GRANT_SEL, + RK3588_HDMI0_GRANT_SEL); + regmap_write(hdmi->vo_regmap, RK3588_GRF_VO1_CON9, val); + + dw_hdmi_qp_resume(dev, hdmi->hdmi); + + if (hdmi->encoder.encoder.dev) + drm_helper_hpd_irq_event(hdmi->encoder.encoder.dev); + + return 0; +} + +static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume) +}; + +struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = { + .probe = dw_hdmi_qp_rockchip_probe, + .remove = dw_hdmi_qp_rockchip_remove, + .driver = { + .name = "dwhdmiqp-rockchip", + .pm = &dw_hdmi_qp_rockchip_pm, + .of_match_table = dw_hdmi_qp_rockchip_dt_ids, + }, +}; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 2560b0eec9db..585355de696b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -532,6 +532,8 @@ static int __init rockchip_drm_init(void) ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP); ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver, CONFIG_ROCKCHIP_DW_HDMI); + ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_qp_rockchip_pltfm_driver, + CONFIG_ROCKCHIP_DW_HDMI_QP); ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver, CONFIG_ROCKCHIP_DW_MIPI_DSI); ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 8d566fcd80a2..24b4ce5ceaf1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -88,6 +88,7 @@ int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rencoder, int rockchip_drm_endpoint_is_subdriver(struct device_node *ep); extern struct platform_driver cdn_dp_driver; extern struct platform_driver dw_hdmi_rockchip_pltfm_driver; +extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver; extern struct platform_driver dw_mipi_dsi_rockchip_driver; extern struct platform_driver inno_hdmi_driver; extern struct platform_driver rockchip_dp_driver; -- GitLab From feda66ce0519311ee349fb002839e91eb8a5453f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:15 +0200 Subject: [PATCH 891/970] drm/i915: Select DRM_CLIENT_SELECTION The Kconfig token DRM_CLIENT_SELECTION will make DRM clients available to drivers. Select it from i915. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Tvrtko Ursulin <tursulin@ursulin.net> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-2-tzimmermann@suse.de --- drivers/gpu/drm/i915/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index db400aad88fa..1158a6b97f9a 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -10,6 +10,7 @@ config DRM_I915 # the shmem_readpage() which depends upon tmpfs select SHMEM select TMPFS + select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDCP_HELPER -- GitLab From f1d730cbafeb7deb5fb6bab0b81a73a6d92efc58 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:16 +0200 Subject: [PATCH 892/970] drm/xe: Select DRM_CLIENT_SELECTION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Kconfig token DRM_CLIENT_SELECTION will make DRM clients available to drivers. Select it from xe. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Lucas De Marchi <lucas.demarchi@intel.com> Cc: "Thomas Hellström" <thomas.hellstrom@linux.intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-3-tzimmermann@suse.de --- drivers/gpu/drm/xe/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index ebd0879e04d4..bac96c0dd66e 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -8,6 +8,7 @@ config DRM_XE select SHMEM select TMPFS select DRM_BUDDY + select DRM_CLIENT_SELECTION select DRM_EXEC select DRM_KMS_HELPER select DRM_KUNIT_TEST_HELPERS if DRM_XE_KUNIT_TEST != n -- GitLab From 67c40c9b2ec5f375bf78274d4e9ef0e3b8315bea Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:17 +0200 Subject: [PATCH 893/970] drm/fbdev-dma: Select FB_DEFERRED_IO Commit 808a40b69468 ("drm/fbdev-dma: Implement damage handling and deferred I/O") added deferred I/O for fbdev-dma. Also select the Kconfig symbol FB_DEFERRED_IO (via FB_DMAMEM_HELPERS_DEFERRED). Fixes build errors about missing fbdefio, such as drivers/gpu/drm/drm_fbdev_dma.c:218:26: error: 'struct drm_fb_helper' has no member named 'fbdefio' 218 | fb_helper->fbdefio.delay = HZ / 20; | ^~ drivers/gpu/drm/drm_fbdev_dma.c:219:26: error: 'struct drm_fb_helper' has no member named 'fbdefio' 219 | fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; | ^~ drivers/gpu/drm/drm_fbdev_dma.c:221:21: error: 'struct fb_info' has no member named 'fbdefio' 221 | info->fbdefio = &fb_helper->fbdefio; | ^~ drivers/gpu/drm/drm_fbdev_dma.c:221:43: error: 'struct drm_fb_helper' has no member named 'fbdefio' 221 | info->fbdefio = &fb_helper->fbdefio; | ^~ Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202410050241.Mox9QRjP-lkp@intel.com/ Fixes: 808a40b69468 ("drm/fbdev-dma: Implement damage handling and deferred I/O") Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: Javier Martinez Canillas <javierm@redhat.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: <stable@vger.kernel.org> # v6.11+ Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-4-tzimmermann@suse.de --- drivers/gpu/drm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 45f624b088da..1710e04e3986 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -339,7 +339,7 @@ config DRM_TTM_HELPER config DRM_GEM_DMA_HELPER tristate depends on DRM - select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION + select FB_DMAMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION help Choose this if you need the GEM DMA helper functions -- GitLab From 8058944f52262e8e8246af5f8408586b1ebfd2c6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:18 +0200 Subject: [PATCH 894/970] drm/fbdev: Select fbdev I/O helpers from modules that require them Fbdev emulation for SHMEM and TTM requires helpers from the fbdev subsystem. Select them from the modules that use them instead of the core DRM module. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-5-tzimmermann@suse.de --- drivers/gpu/drm/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 1710e04e3986..d4f33a924787 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -11,7 +11,6 @@ menuconfig DRM select DRM_PANEL_ORIENTATION_QUIRKS select DRM_KMS_HELPER if DRM_FBDEV_EMULATION select FB_CORE if DRM_FBDEV_EMULATION - select FB_SYSMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION select HDMI select I2C select DMA_SHARED_BUFFER @@ -333,6 +332,7 @@ config DRM_TTM_HELPER tristate depends on DRM select DRM_TTM + select FB_SYSMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION help Helpers for ttm-based gem objects @@ -346,6 +346,7 @@ config DRM_GEM_DMA_HELPER config DRM_GEM_SHMEM_HELPER tristate depends on DRM && MMU + select FB_SYSMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION help Choose this if you need the GEM shmem helper functions -- GitLab From df7e8b522a6090162ecb50fd298ebc4db137562b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:20 +0200 Subject: [PATCH 895/970] drm/client: Move client event handlers to drm_client_event.c A number of DRM-client functions serve as entry points from device operations to client code. Moving them info a separate file will later allow for a more fine-grained kernel configuration. For most of the users it is sufficient to include <drm/drm_client_event.h> instead of the full driver-side interface in <drm/drm_client.h> v2: - rename new files to drm_client_event.{c,h} Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Tvrtko Ursulin <tursulin@ursulin.net> Cc: Karol Herbst <kherbst@redhat.com> Cc: Lyude Paul <lyude@redhat.com> Cc: Danilo Krummrich <dakr@redhat.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-7-tzimmermann@suse.de --- Documentation/gpu/drm-client.rst | 3 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_client.c | 121 ---------------- drivers/gpu/drm/drm_client_event.c | 135 ++++++++++++++++++ drivers/gpu/drm/drm_drv.c | 2 +- drivers/gpu/drm/drm_file.c | 2 +- drivers/gpu/drm/drm_probe_helper.c | 2 +- .../drm/i915/display/intel_display_driver.c | 2 +- drivers/gpu/drm/nouveau/nouveau_vga.c | 2 +- include/drm/drm_client.h | 4 - include/drm/drm_client_event.h | 12 ++ 11 files changed, 156 insertions(+), 130 deletions(-) create mode 100644 drivers/gpu/drm/drm_client_event.c create mode 100644 include/drm/drm_client_event.h diff --git a/Documentation/gpu/drm-client.rst b/Documentation/gpu/drm-client.rst index 58b5a1d1219d..cbcfe30de777 100644 --- a/Documentation/gpu/drm-client.rst +++ b/Documentation/gpu/drm-client.rst @@ -13,3 +13,6 @@ Kernel clients .. kernel-doc:: drivers/gpu/drm/drm_client_modeset.c :export: + +.. kernel-doc:: drivers/gpu/drm/drm_client_event.c + :export: diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 31d8bf60a2fd..252188d2122c 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -41,6 +41,7 @@ drm-y := \ drm_bridge.o \ drm_cache.o \ drm_client.o \ + drm_client_event.o \ drm_client_modeset.o \ drm_color_mgmt.o \ drm_connector.o \ diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index bfedcbf516db..549b28a5918c 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -10,7 +10,6 @@ #include <linux/slab.h> #include <drm/drm_client.h> -#include <drm/drm_debugfs.h> #include <drm/drm_device.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> @@ -172,99 +171,6 @@ void drm_client_release(struct drm_client_dev *client) } EXPORT_SYMBOL(drm_client_release); -/** - * drm_client_dev_unregister - Unregister clients - * @dev: DRM device - * - * This function releases all clients by calling each client's - * &drm_client_funcs.unregister callback. The callback function - * is responsibe for releaseing all resources including the client - * itself. - * - * The helper drm_dev_unregister() calls this function. Drivers - * that use it don't need to call this function themselves. - */ -void drm_client_dev_unregister(struct drm_device *dev) -{ - struct drm_client_dev *client, *tmp; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - mutex_lock(&dev->clientlist_mutex); - list_for_each_entry_safe(client, tmp, &dev->clientlist, list) { - list_del(&client->list); - if (client->funcs && client->funcs->unregister) { - client->funcs->unregister(client); - } else { - drm_client_release(client); - kfree(client); - } - } - mutex_unlock(&dev->clientlist_mutex); -} -EXPORT_SYMBOL(drm_client_dev_unregister); - -/** - * drm_client_dev_hotplug - Send hotplug event to clients - * @dev: DRM device - * - * This function calls the &drm_client_funcs.hotplug callback on the attached clients. - * - * drm_kms_helper_hotplug_event() calls this function, so drivers that use it - * don't need to call this function themselves. - */ -void drm_client_dev_hotplug(struct drm_device *dev) -{ - struct drm_client_dev *client; - int ret; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - if (!dev->mode_config.num_connector) { - drm_dbg_kms(dev, "No connectors found, will not send hotplug events!\n"); - return; - } - - mutex_lock(&dev->clientlist_mutex); - list_for_each_entry(client, &dev->clientlist, list) { - if (!client->funcs || !client->funcs->hotplug) - continue; - - if (client->hotplug_failed) - continue; - - ret = client->funcs->hotplug(client); - drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); - if (ret) - client->hotplug_failed = true; - } - mutex_unlock(&dev->clientlist_mutex); -} -EXPORT_SYMBOL(drm_client_dev_hotplug); - -void drm_client_dev_restore(struct drm_device *dev) -{ - struct drm_client_dev *client; - int ret; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - mutex_lock(&dev->clientlist_mutex); - list_for_each_entry(client, &dev->clientlist, list) { - if (!client->funcs || !client->funcs->restore) - continue; - - ret = client->funcs->restore(client); - drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); - if (!ret) /* The first one to return zero gets the privilege to restore */ - break; - } - mutex_unlock(&dev->clientlist_mutex); -} - static void drm_client_buffer_delete(struct drm_client_buffer *buffer) { if (buffer->gem) { @@ -584,30 +490,3 @@ int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_re 0, 0, NULL, 0); } EXPORT_SYMBOL(drm_client_framebuffer_flush); - -#ifdef CONFIG_DEBUG_FS -static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data) -{ - struct drm_debugfs_entry *entry = m->private; - struct drm_device *dev = entry->dev; - struct drm_printer p = drm_seq_file_printer(m); - struct drm_client_dev *client; - - mutex_lock(&dev->clientlist_mutex); - list_for_each_entry(client, &dev->clientlist, list) - drm_printf(&p, "%s\n", client->name); - mutex_unlock(&dev->clientlist_mutex); - - return 0; -} - -static const struct drm_debugfs_info drm_client_debugfs_list[] = { - { "internal_clients", drm_client_debugfs_internal_clients, 0 }, -}; - -void drm_client_debugfs_init(struct drm_device *dev) -{ - drm_debugfs_add_files(dev, drm_client_debugfs_list, - ARRAY_SIZE(drm_client_debugfs_list)); -} -#endif diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c new file mode 100644 index 000000000000..d13d44320c5c --- /dev/null +++ b/drivers/gpu/drm/drm_client_event.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 or MIT +/* + * Copyright 2018 Noralf Trønnes + */ + +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/seq_file.h> + +#include <drm/drm_client.h> +#include <drm/drm_client_event.h> +#include <drm/drm_debugfs.h> +#include <drm/drm_device.h> +#include <drm/drm_drv.h> +#include <drm/drm_print.h> + +/** + * drm_client_dev_unregister - Unregister clients + * @dev: DRM device + * + * This function releases all clients by calling each client's + * &drm_client_funcs.unregister callback. The callback function + * is responsibe for releaseing all resources including the client + * itself. + * + * The helper drm_dev_unregister() calls this function. Drivers + * that use it don't need to call this function themselves. + */ +void drm_client_dev_unregister(struct drm_device *dev) +{ + struct drm_client_dev *client, *tmp; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry_safe(client, tmp, &dev->clientlist, list) { + list_del(&client->list); + if (client->funcs && client->funcs->unregister) { + client->funcs->unregister(client); + } else { + drm_client_release(client); + kfree(client); + } + } + mutex_unlock(&dev->clientlist_mutex); +} +EXPORT_SYMBOL(drm_client_dev_unregister); + +/** + * drm_client_dev_hotplug - Send hotplug event to clients + * @dev: DRM device + * + * This function calls the &drm_client_funcs.hotplug callback on the attached clients. + * + * drm_kms_helper_hotplug_event() calls this function, so drivers that use it + * don't need to call this function themselves. + */ +void drm_client_dev_hotplug(struct drm_device *dev) +{ + struct drm_client_dev *client; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + if (!dev->mode_config.num_connector) { + drm_dbg_kms(dev, "No connectors found, will not send hotplug events!\n"); + return; + } + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry(client, &dev->clientlist, list) { + if (!client->funcs || !client->funcs->hotplug) + continue; + + if (client->hotplug_failed) + continue; + + ret = client->funcs->hotplug(client); + drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); + if (ret) + client->hotplug_failed = true; + } + mutex_unlock(&dev->clientlist_mutex); +} +EXPORT_SYMBOL(drm_client_dev_hotplug); + +void drm_client_dev_restore(struct drm_device *dev) +{ + struct drm_client_dev *client; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry(client, &dev->clientlist, list) { + if (!client->funcs || !client->funcs->restore) + continue; + + ret = client->funcs->restore(client); + drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); + if (!ret) /* The first one to return zero gets the privilege to restore */ + break; + } + mutex_unlock(&dev->clientlist_mutex); +} + +#ifdef CONFIG_DEBUG_FS +static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data) +{ + struct drm_debugfs_entry *entry = m->private; + struct drm_device *dev = entry->dev; + struct drm_printer p = drm_seq_file_printer(m); + struct drm_client_dev *client; + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry(client, &dev->clientlist, list) + drm_printf(&p, "%s\n", client->name); + mutex_unlock(&dev->clientlist_mutex); + + return 0; +} + +static const struct drm_debugfs_info drm_client_debugfs_list[] = { + { "internal_clients", drm_client_debugfs_internal_clients, 0 }, +}; + +void drm_client_debugfs_init(struct drm_device *dev) +{ + drm_debugfs_add_files(dev, drm_client_debugfs_list, + ARRAY_SIZE(drm_client_debugfs_list)); +} +#endif diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ac30b0ec9d93..c2c172eb25df 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -38,7 +38,7 @@ #include <drm/drm_accel.h> #include <drm/drm_cache.h> -#include <drm/drm_client.h> +#include <drm/drm_client_event.h> #include <drm/drm_color_mgmt.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 2ee1c3233b0c..9011f8e16099 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -40,7 +40,7 @@ #include <linux/slab.h> #include <linux/vga_switcheroo.h> -#include <drm/drm_client.h> +#include <drm/drm_client_event.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> #include <drm/drm_gem.h> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 92f21764246f..96b266b37ba4 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -33,7 +33,7 @@ #include <linux/moduleparam.h> #include <drm/drm_bridge.h> -#include <drm/drm_client.h> +#include <drm/drm_client_event.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> #include <drm/drm_fourcc.h> diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 069426d9260b..44de2d8591cd 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -11,7 +11,7 @@ #include <acpi/video.h> #include <drm/display/drm_dp_mst_helper.h> #include <drm/drm_atomic_helper.h> -#include <drm/drm_client.h> +#include <drm/drm_client_event.h> #include <drm/drm_mode_config.h> #include <drm/drm_privacy_screen_consumer.h> #include <drm/drm_probe_helper.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index ab4e11dc0b8a..a6c375a24154 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -2,7 +2,7 @@ #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_client_event.h> #include "nouveau_drv.h" #include "nouveau_acpi.h" diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index bc0e66f9c425..dfd5afcc9463 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -121,10 +121,6 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, void drm_client_release(struct drm_client_dev *client); void drm_client_register(struct drm_client_dev *client); -void drm_client_dev_unregister(struct drm_device *dev); -void drm_client_dev_hotplug(struct drm_device *dev); -void drm_client_dev_restore(struct drm_device *dev); - /** * struct drm_client_buffer - DRM client buffer */ diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h new file mode 100644 index 000000000000..2c8915241120 --- /dev/null +++ b/include/drm/drm_client_event.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 or MIT */ + +#ifndef _DRM_CLIENT_EVENT_H_ +#define _DRM_CLIENT_EVENT_H_ + +struct drm_device; + +void drm_client_dev_unregister(struct drm_device *dev); +void drm_client_dev_hotplug(struct drm_device *dev); +void drm_client_dev_restore(struct drm_device *dev); + +#endif -- GitLab From bf17766f108309027aac2bfe184df6088dfd7384 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:21 +0200 Subject: [PATCH 896/970] drm/client: Move suspend/resume into DRM client callbacks Suspend and resume is still tied to fbdev emulation. Modeset helpers and several drivers call drm_fb_helper_set_suspend_unlocked() to inform the fbdev client about suspend/resume events. To make it work with arbitrary clients, add per-client callback functions for suspend and resume. Implement them for fbdev emulation with the existing drm_fb_helper_set_suspend_unlocked(). Then update DRM's modeset helpers to call the new interface. Clients that are not fbdev can now implement suspend/resume to their requirements. The callback parameter holds_console_lock is a workaround for i915, radeon and xe, which possibly call the interface while having the console lock acquired. Even though the commit doesn't modify these drivers, it already adds the flag to avoid churn later on. New code should not hold the console lock. v4: - clarify holds_console_lock in commit description (Jonathan) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-8-tzimmermann@suse.de --- drivers/gpu/drm/drm_client_event.c | 60 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_fbdev_client.c | 30 +++++++++++++- drivers/gpu/drm/drm_modeset_helper.c | 14 ++++--- include/drm/drm_client.h | 35 ++++++++++++++++ include/drm/drm_client_event.h | 2 + 5 files changed, 133 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c index d13d44320c5c..c52e93643672 100644 --- a/drivers/gpu/drm/drm_client_event.c +++ b/drivers/gpu/drm/drm_client_event.c @@ -107,6 +107,66 @@ void drm_client_dev_restore(struct drm_device *dev) mutex_unlock(&dev->clientlist_mutex); } +static int drm_client_suspend(struct drm_client_dev *client, bool holds_console_lock) +{ + struct drm_device *dev = client->dev; + int ret = 0; + + if (drm_WARN_ON_ONCE(dev, client->suspended)) + return 0; + + if (client->funcs && client->funcs->suspend) + ret = client->funcs->suspend(client, holds_console_lock); + drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); + + client->suspended = true; + + return ret; +} + +void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock) +{ + struct drm_client_dev *client; + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry(client, &dev->clientlist, list) { + if (!client->suspended) + drm_client_suspend(client, holds_console_lock); + } + mutex_unlock(&dev->clientlist_mutex); +} +EXPORT_SYMBOL(drm_client_dev_suspend); + +static int drm_client_resume(struct drm_client_dev *client, bool holds_console_lock) +{ + struct drm_device *dev = client->dev; + int ret = 0; + + if (drm_WARN_ON_ONCE(dev, !client->suspended)) + return 0; + + if (client->funcs && client->funcs->resume) + ret = client->funcs->resume(client, holds_console_lock); + drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret); + + client->suspended = false; + + return ret; +} + +void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock) +{ + struct drm_client_dev *client; + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry(client, &dev->clientlist, list) { + if (client->suspended) + drm_client_resume(client, holds_console_lock); + } + mutex_unlock(&dev->clientlist_mutex); +} +EXPORT_SYMBOL(drm_client_dev_resume); + #ifdef CONFIG_DEBUG_FS static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data) { diff --git a/drivers/gpu/drm/drm_fbdev_client.c b/drivers/gpu/drm/drm_fbdev_client.c index a09382afe2fb..246fb63ab250 100644 --- a/drivers/gpu/drm/drm_fbdev_client.c +++ b/drivers/gpu/drm/drm_fbdev_client.c @@ -61,11 +61,37 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client) return ret; } +static int drm_fbdev_client_suspend(struct drm_client_dev *client, bool holds_console_lock) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (holds_console_lock) + drm_fb_helper_set_suspend(fb_helper, true); + else + drm_fb_helper_set_suspend_unlocked(fb_helper, true); + + return 0; +} + +static int drm_fbdev_client_resume(struct drm_client_dev *client, bool holds_console_lock) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (holds_console_lock) + drm_fb_helper_set_suspend(fb_helper, false); + else + drm_fb_helper_set_suspend_unlocked(fb_helper, false); + + return 0; +} + static const struct drm_client_funcs drm_fbdev_client_funcs = { .owner = THIS_MODULE, .unregister = drm_fbdev_client_unregister, .restore = drm_fbdev_client_restore, .hotplug = drm_fbdev_client_hotplug, + .suspend = drm_fbdev_client_suspend, + .resume = drm_fbdev_client_resume, }; /** @@ -76,8 +102,8 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = { * * This function sets up fbdev emulation. Restore, hotplug events and * teardown are all taken care of. Drivers that do suspend/resume need - * to call drm_fb_helper_set_suspend_unlocked() themselves. Simple - * drivers might use drm_mode_config_helper_suspend(). + * to call drm_client_dev_suspend() and drm_client_dev_resume() by + * themselves. Simple drivers might use drm_mode_config_helper_suspend(). * * This function is safe to call even when there are no connectors present. * Setup will be retried on the next hotplug event. diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c index 2c582020cb42..5565464c1734 100644 --- a/drivers/gpu/drm/drm_modeset_helper.c +++ b/drivers/gpu/drm/drm_modeset_helper.c @@ -21,7 +21,7 @@ */ #include <drm/drm_atomic_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_client_event.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_modeset_helper.h> @@ -185,7 +185,7 @@ EXPORT_SYMBOL(drm_crtc_init); * Zero on success, negative error code on error. * * See also: - * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked(). + * drm_kms_helper_poll_disable() and drm_client_dev_suspend(). */ int drm_mode_config_helper_suspend(struct drm_device *dev) { @@ -199,10 +199,11 @@ int drm_mode_config_helper_suspend(struct drm_device *dev) if (dev->mode_config.poll_enabled) drm_kms_helper_poll_disable(dev); - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1); + drm_client_dev_suspend(dev, false); state = drm_atomic_helper_suspend(dev); if (IS_ERR(state)) { - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); + drm_client_dev_resume(dev, false); + /* * Don't enable polling if it was never initialized */ @@ -230,7 +231,7 @@ EXPORT_SYMBOL(drm_mode_config_helper_suspend); * Zero on success, negative error code on error. * * See also: - * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable(). + * drm_client_dev_resume() and drm_kms_helper_poll_enable(). */ int drm_mode_config_helper_resume(struct drm_device *dev) { @@ -247,7 +248,8 @@ int drm_mode_config_helper_resume(struct drm_device *dev) DRM_ERROR("Failed to resume (%d)\n", ret); dev->mode_config.suspend_state = NULL; - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); + drm_client_dev_resume(dev, false); + /* * Don't enable polling if it is not initialized */ diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index dfd5afcc9463..c03c4b0f3e94 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -63,6 +63,34 @@ struct drm_client_funcs { * This callback is optional. */ int (*hotplug)(struct drm_client_dev *client); + + /** + * @suspend: + * + * Called when suspending the device. + * + * This callback is optional. + * + * FIXME: Some callers hold the console lock when invoking this + * function. This interferes with fbdev emulation, which + * also tries to acquire the lock. Push the console lock + * into the callback and remove 'holds_console_lock'. + */ + int (*suspend)(struct drm_client_dev *client, bool holds_console_lock); + + /** + * @resume: + * + * Called when resuming the device from suspend. + * + * This callback is optional. + * + * FIXME: Some callers hold the console lock when invoking this + * function. This interferes with fbdev emulation, which + * also tries to acquire the lock. Push the console lock + * into the callback and remove 'holds_console_lock'. + */ + int (*resume)(struct drm_client_dev *client, bool holds_console_lock); }; /** @@ -107,6 +135,13 @@ struct drm_client_dev { */ struct drm_mode_set *modesets; + /** + * @suspended: + * + * The client has been suspended. + */ + bool suspended; + /** * @hotplug_failed: * diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h index 2c8915241120..72c97d111169 100644 --- a/include/drm/drm_client_event.h +++ b/include/drm/drm_client_event.h @@ -8,5 +8,7 @@ struct drm_device; void drm_client_dev_unregister(struct drm_device *dev); void drm_client_dev_hotplug(struct drm_device *dev); void drm_client_dev_restore(struct drm_device *dev); +void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock); +void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock); #endif -- GitLab From 4cf50bae0506dd37b5c593ecaf837ac0c3d894c7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:22 +0200 Subject: [PATCH 897/970] drm/amdgpu: Suspend and resume internal clients with client helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace calls to drm_fb_helper_set_suspend_unlocked() with calls to the client functions drm_client_dev_suspend() and drm_client_dev_resume(). Any registered in-kernel client will now receive suspend and resume events. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-9-tzimmermann@suse.de --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 128e086b4251..5a1ae08817ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -38,8 +38,8 @@ #include <linux/apple-gmux.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_event.h> #include <drm/drm_crtc_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_probe_helper.h> #include <drm/amdgpu_drm.h> #include <linux/device.h> @@ -4712,13 +4712,13 @@ int amdgpu_device_prepare(struct drm_device *dev) * amdgpu_device_suspend - initiate device suspend * * @dev: drm dev pointer - * @fbcon : notify the fbdev of suspend + * @notify_clients: notify in-kernel DRM clients * * Puts the hw in the suspend state (all asics). * Returns 0 for success or an error on failure. * Called at driver suspend. */ -int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) +int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients) { struct amdgpu_device *adev = drm_to_adev(dev); int r = 0; @@ -4738,8 +4738,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3)) DRM_WARN("smart shift update failed\n"); - if (fbcon) - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); + if (notify_clients) + drm_client_dev_suspend(adev_to_drm(adev), false); cancel_delayed_work_sync(&adev->delayed_init_work); @@ -4774,13 +4774,13 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) * amdgpu_device_resume - initiate device resume * * @dev: drm dev pointer - * @fbcon : notify the fbdev of resume + * @notify_clients: notify in-kernel DRM clients * * Bring the hw back to operating state (all asics). * Returns 0 for success or an error on failure. * Called at driver resume. */ -int amdgpu_device_resume(struct drm_device *dev, bool fbcon) +int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) { struct amdgpu_device *adev = drm_to_adev(dev); int r = 0; @@ -4836,8 +4836,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) /* Make sure IB tests flushed */ flush_delayed_work(&adev->delayed_init_work); - if (fbcon) - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false); + if (notify_clients) + drm_client_dev_resume(adev_to_drm(adev), false); amdgpu_ras_resume(adev); @@ -5449,7 +5449,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, if (r) goto out; - drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, false); + drm_client_dev_resume(adev_to_drm(tmp_adev), false); /* * The GPU enters bad state once faulty pages @@ -5735,7 +5735,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, */ amdgpu_unregister_gpu_instance(tmp_adev); - drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, true); + drm_client_dev_suspend(adev_to_drm(tmp_adev), false); /* disable ras on ALL IPs */ if (!need_emergency_restart && -- GitLab From 4785658660d507b1e026ea2873caa2ea11486a74 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:23 +0200 Subject: [PATCH 898/970] drm/nouveau: Suspend and resume clients with client helpers Replace calls to drm_fb_helper_set_suspend_unlocked() with calls to the client functions drm_client_dev_suspend() and drm_client_dev_resume(). Any registered in-kernel client will now receive suspend and resume events. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Karol Herbst <kherbst@redhat.com> Cc: Lyude Paul <lyude@redhat.com> Cc: Danilo Krummrich <dakr@redhat.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-10-tzimmermann@suse.de --- drivers/gpu/drm/nouveau/nouveau_display.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index e2fd561cd23f..619a3efbe8c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -28,8 +28,8 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_client_event.h> #include <drm/drm_crtc_helper.h> -#include <drm/drm_fb_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_probe_helper.h> @@ -804,8 +804,7 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime) { struct nouveau_display *disp = nouveau_display(dev); - /* Disable console. */ - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, true); + drm_client_dev_suspend(dev, false); if (drm_drv_uses_atomic_modeset(dev)) { if (!runtime) { @@ -836,8 +835,7 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) } } - /* Enable console. */ - drm_fb_helper_set_suspend_unlocked(dev->fb_helper, false); + drm_client_dev_resume(dev, false); } int -- GitLab From 88c79de8575c0061a5cdf23c65f8b1ae6202f0d5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:24 +0200 Subject: [PATCH 899/970] drm/radeon: Suspend and resume clients with client helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace calls to radeon_fbdev_set_suspend() with calls to the client functions drm_client_dev_suspend() and drm_client_dev_resume(). Any registered in-kernel client will now receive suspend and resume events. v4: - refer to radeon_fbdev_set_suspend() in commit description (Jonathan) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-11-tzimmermann@suse.de --- drivers/gpu/drm/radeon/radeon_device.c | 19 ++++++++++--------- drivers/gpu/drm/radeon/radeon_fbdev.c | 6 ------ drivers/gpu/drm/radeon/radeon_mode.h | 3 --- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 554b236c2328..6f071e61f764 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -35,6 +35,7 @@ #include <linux/vgaarb.h> #include <drm/drm_cache.h> +#include <drm/drm_client_event.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_device.h> #include <drm/drm_file.h> @@ -1542,7 +1543,7 @@ void radeon_device_fini(struct radeon_device *rdev) * Called at driver suspend. */ int radeon_suspend_kms(struct drm_device *dev, bool suspend, - bool fbcon, bool freeze) + bool notify_clients, bool freeze) { struct radeon_device *rdev; struct pci_dev *pdev; @@ -1634,9 +1635,9 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, pci_set_power_state(pdev, PCI_D3hot); } - if (fbcon) { + if (notify_clients) { console_lock(); - radeon_fbdev_set_suspend(rdev, 1); + drm_client_dev_suspend(dev, true); console_unlock(); } return 0; @@ -1649,7 +1650,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, * Returns 0 for success or an error on failure. * Called at driver resume. */ -int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) +int radeon_resume_kms(struct drm_device *dev, bool resume, bool notify_clients) { struct drm_connector *connector; struct radeon_device *rdev = dev->dev_private; @@ -1660,14 +1661,14 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (fbcon) { + if (notify_clients) { console_lock(); } if (resume) { pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); if (pci_enable_device(pdev)) { - if (fbcon) + if (notify_clients) console_unlock(); return -1; } @@ -1730,7 +1731,7 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) /* reset hpd state */ radeon_hpd_init(rdev); /* blat the mode back in */ - if (fbcon) { + if (notify_clients) { drm_helper_resume_force_mode(dev); /* turn on display hw */ drm_modeset_lock_all(dev); @@ -1746,8 +1747,8 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) radeon_pm_compute_clocks(rdev); - if (fbcon) { - radeon_fbdev_set_suspend(rdev, 0); + if (notify_clients) { + drm_client_dev_resume(dev, true); console_unlock(); } diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c index 0aa20c8df546..d4a58bd679db 100644 --- a/drivers/gpu/drm/radeon/radeon_fbdev.c +++ b/drivers/gpu/drm/radeon/radeon_fbdev.c @@ -288,12 +288,6 @@ int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, return ret; } -void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) -{ - if (rdev_to_drm(rdev)->fb_helper) - drm_fb_helper_set_suspend(rdev_to_drm(rdev)->fb_helper, state); -} - bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) { struct drm_fb_helper *fb_helper = rdev_to_drm(rdev)->fb_helper; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 12a1d99a1815..4063d3801e81 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -942,13 +942,10 @@ int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes); #define RADEON_FBDEV_DRIVER_OPS \ .fbdev_probe = radeon_fbdev_driver_fbdev_probe -void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); #else #define RADEON_FBDEV_DRIVER_OPS \ .fbdev_probe = NULL -static inline void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) -{ } static inline bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) { return false; -- GitLab From 1f828b4dd40264028d9b481c0412e63837d968f6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:25 +0200 Subject: [PATCH 900/970] drm/client: Make client support optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only build client code if DRM_CLIENT has been selected. Automatially do so if one of the default clients has been enabled. If client support has been disabled, the helpers for client-related events are empty and the regular client functions are not present. Amdgpu has an internal DRM client, so it has to select DRM_CLIENT by itself unconditionally. v3: - provide empty drm_client_debugfs_init() if DRM_CLIENT=n (kernel test robot) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: "Christian König" <christian.koenig@amd.com> Cc: Xinhui Pan <Xinhui.Pan@amd.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-12-tzimmermann@suse.de --- drivers/gpu/drm/Kconfig | 10 ++++++++++ drivers/gpu/drm/Makefile | 7 ++++--- drivers/gpu/drm/amd/amdgpu/Kconfig | 1 + drivers/gpu/drm/drm_client_event.c | 2 ++ drivers/gpu/drm/drm_debugfs.c | 1 - drivers/gpu/drm/drm_internal.h | 8 ++++++++ include/drm/drm_client.h | 2 -- include/drm/drm_client_event.h | 13 +++++++++++++ 8 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index d4f33a924787..5cbb0b2a4c18 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -210,6 +210,15 @@ config DRM_DEBUG_MODESET_LOCK If in doubt, say "N". +config DRM_CLIENT + bool + depends on DRM + help + Enables support for DRM clients. DRM drivers that need + struct drm_client_dev and its interfaces should select this + option. Drivers that support the default clients should + select DRM_CLIENT_SELECTION instead. + config DRM_CLIENT_SELECTION bool depends on DRM @@ -225,6 +234,7 @@ config DRM_CLIENT_SETUP config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" depends on DRM + select DRM_CLIENT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE default FB help diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 252188d2122c..fcb447cafe41 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -40,9 +40,6 @@ drm-y := \ drm_blend.o \ drm_bridge.o \ drm_cache.o \ - drm_client.o \ - drm_client_event.o \ - drm_client_modeset.o \ drm_color_mgmt.o \ drm_connector.o \ drm_crtc.o \ @@ -76,6 +73,10 @@ drm-y := \ drm_vblank_work.o \ drm_vma_manager.o \ drm_writeback.o +drm-$(CONFIG_DRM_CLIENT) += \ + drm_client.o \ + drm_client_event.o \ + drm_client_modeset.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_PANEL) += drm_panel.o diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 680a94c361ba..41fa3377d9cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -5,6 +5,7 @@ config DRM_AMDGPU depends on DRM && PCI && MMU depends on !UML select FW_LOADER + select DRM_CLIENT select DRM_CLIENT_SELECTION select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_DSC_HELPER diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c index c52e93643672..e303de564485 100644 --- a/drivers/gpu/drm/drm_client_event.c +++ b/drivers/gpu/drm/drm_client_event.c @@ -14,6 +14,8 @@ #include <drm/drm_drv.h> #include <drm/drm_print.h> +#include "drm_internal.h" + /** * drm_client_dev_unregister - Unregister clients * @dev: DRM device diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 52783eac078e..536409a35df4 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -32,7 +32,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_auth.h> #include <drm/drm_bridge.h> -#include <drm/drm_client.h> #include <drm/drm_debugfs.h> #include <drm/drm_device.h> #include <drm/drm_drv.h> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 1705bfc90b1e..b2b6a8e49dda 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -48,6 +48,14 @@ struct drm_prime_file_private; struct drm_printer; struct drm_vblank_crtc; +/* drm_client_event.c */ +#if defined(CONFIG_DRM_CLIENT) +void drm_client_debugfs_init(struct drm_device *dev); +#else +static inline void drm_client_debugfs_init(struct drm_device *dev) +{ } +#endif + /* drm_file.c */ extern struct mutex drm_global_mutex; bool drm_dev_needs_global_mutex(struct drm_device *dev); diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index c03c4b0f3e94..3b13cf29ed55 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -236,6 +236,4 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); drm_for_each_connector_iter(connector, iter) \ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) -void drm_client_debugfs_init(struct drm_device *dev); - #endif diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h index 72c97d111169..99863554b055 100644 --- a/include/drm/drm_client_event.h +++ b/include/drm/drm_client_event.h @@ -5,10 +5,23 @@ struct drm_device; +#if defined(CONFIG_DRM_CLIENT) void drm_client_dev_unregister(struct drm_device *dev); void drm_client_dev_hotplug(struct drm_device *dev); void drm_client_dev_restore(struct drm_device *dev); void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock); void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock); +#else +static inline void drm_client_dev_unregister(struct drm_device *dev) +{ } +static inline void drm_client_dev_hotplug(struct drm_device *dev) +{ } +static inline void drm_client_dev_restore(struct drm_device *dev) +{ } +static inline void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock) +{ } +static inline void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock) +{ } +#endif #endif -- GitLab From dadd28d4142f9ad39eefb7b45ee7518bd4d2459c Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann <tzimmermann@suse.de> Date: Mon, 14 Oct 2024 10:55:26 +0200 Subject: [PATCH 901/970] drm/client: Add client-lib module Add drm_client_lib.ko to contain DRM's built-in client. Move the existing client for fbdev emulation into the new module. Protect the new module behind CONFIG_DRM_CLIENT_LIB. The Kconfig rules separate the DRM drivers from the DRM clients. A driver can opt into the default clients, but the user configures each client individually. To do so, DRM drivers still select DRM_CLIENT_SELECTION. The option is now a tristate that further selects all dependencies of the enabled DRM clients. There's a menu option for each client. Enabling at least one client also selects DRM_CLIENT_SETUP, so that drivers call drm_client_setup(). New DRM clients should depend on DRM_CLIENT_SELECTION. There are existing kernel options in drm_fb_helper.o, so leave this file in the KMS-helper module for now. v5: - leave fbdev helpers in drm_kms_helper.ko for now v3: - fix commit changelog v2: - keep client code in core - protect lib with DRM_CLIENT_LIB - remove duplicate line from Makefile (Jocelyn) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241014085740.582287-13-tzimmermann@suse.de --- drivers/gpu/drm/Kconfig | 26 +++++++++++++++++++++----- drivers/gpu/drm/Makefile | 14 +++++++++----- drivers/gpu/drm/drm_client_setup.c | 3 +++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 5cbb0b2a4c18..5504721007cc 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -9,8 +9,6 @@ menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA select DRM_PANEL_ORIENTATION_QUIRKS - select DRM_KMS_HELPER if DRM_FBDEV_EMULATION - select FB_CORE if DRM_FBDEV_EMULATION select HDMI select I2C select DMA_SHARED_BUFFER @@ -219,10 +217,19 @@ config DRM_CLIENT option. Drivers that support the default clients should select DRM_CLIENT_SELECTION instead. +config DRM_CLIENT_LIB + tristate + depends on DRM + select DRM_KMS_HELPER if DRM_FBDEV_EMULATION + select FB_CORE if DRM_FBDEV_EMULATION + help + This option enables the DRM client library and selects all + modules and components according to the enabled clients. + config DRM_CLIENT_SELECTION - bool + tristate depends on DRM - select DRM_CLIENT_SETUP if DRM_FBDEV_EMULATION + select DRM_CLIENT_LIB if DRM_FBDEV_EMULATION help Drivers that support in-kernel DRM clients have to select this option. @@ -230,11 +237,18 @@ config DRM_CLIENT_SELECTION config DRM_CLIENT_SETUP bool depends on DRM_CLIENT_SELECTION + help + Enables the DRM client selection. DRM drivers that support the + default clients should select DRM_CLIENT_SELECTION instead. + +menu "Supported DRM clients" + depends on DRM_CLIENT_SELECTION config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" - depends on DRM + depends on DRM_CLIENT_SELECTION select DRM_CLIENT + select DRM_CLIENT_SETUP select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE default FB help @@ -273,6 +287,8 @@ config DRM_FBDEV_LEAK_PHYS_SMEM If in doubt, say "N" or spread the word to your closed source library vendor. +endmenu + config DRM_LOAD_EDID_FIRMWARE bool "Allow to specify an EDID data set instead of probing for it" depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index fcb447cafe41..463afad1b5ca 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -144,14 +144,18 @@ drm_kms_helper-y := \ drm_probe_helper.o \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o -drm_kms_helper-$(CONFIG_DRM_CLIENT_SETUP) += \ - drm_client_setup.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o -drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \ - drm_fbdev_client.o \ - drm_fb_helper.o +drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o +# +# DRM clients +# + +drm_client_lib-y := drm_client_setup.o +drm_client_lib-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_client.o +obj-$(CONFIG_DRM_CLIENT_LIB) += drm_client_lib.o + # # Drivers and the rest # diff --git a/drivers/gpu/drm/drm_client_setup.c b/drivers/gpu/drm/drm_client_setup.c index 5969c4ffe31b..c14221ca5a0d 100644 --- a/drivers/gpu/drm/drm_client_setup.c +++ b/drivers/gpu/drm/drm_client_setup.c @@ -64,3 +64,6 @@ void drm_client_setup_with_color_mode(struct drm_device *dev, unsigned int color drm_client_setup_with_fourcc(dev, fourcc); } EXPORT_SYMBOL(drm_client_setup_with_color_mode); + +MODULE_DESCRIPTION("In-kernel DRM clients"); +MODULE_LICENSE("GPL and additional rights"); -- GitLab From 2063ca42486bc07b49bc145b5dfcb421f4deebaf Mon Sep 17 00:00:00 2001 From: Jean Delvare <jdelvare@suse.de> Date: Tue, 15 Oct 2024 13:46:06 +0200 Subject: [PATCH 902/970] drm/display: Drop obsolete dependency on COMPILE_TEST Since commit 0166dc11be91 ("of: make CONFIG_OF user selectable"), it is possible to test-build any driver which depends on OF on any architecture by explicitly selecting OF. Therefore depending on COMPILE_TEST as an alternative is no longer needed. To avoid reintroducing the randconfig bug originally fixed by commit 876271118aa4 ("drm/display: Fix build error without CONFIG_OF"), DRM_MSM which selects DRM_DISPLAY_DP_HELPER must explicitly depend on OF. This is consistent with what all other DRM drivers are doing. Signed-off-by: Jean Delvare <jdelvare@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Cc: David Airlie <airlied@gmail.com> Cc: Daniel Vetter <daniel@ffwll.ch> Acked-by: Douglas Anderson <dianders@chromium.org> Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241015134606.5b87093e@endymion.delvare Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/display/Kconfig | 2 +- drivers/gpu/drm/msm/Kconfig | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 0f07cf1483ff..6a4e892afcf8 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -3,7 +3,7 @@ config DRM_DISPLAY_DP_AUX_BUS tristate depends on DRM - depends on OF || COMPILE_TEST + depends on OF config DRM_DISPLAY_HELPER tristate diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index f16d7c00e089..7ec833b6d829 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -6,6 +6,7 @@ config DRM_MSM depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST depends on COMMON_CLK depends on IOMMU_SUPPORT + depends on OF depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n depends on QCOM_OCMEM || QCOM_OCMEM=n depends on QCOM_LLCC || QCOM_LLCC=n -- GitLab From 11fc5ce6e2a6316b7d02746c035ee1e51bf10718 Mon Sep 17 00:00:00 2001 From: Simon Horman <horms@kernel.org> Date: Fri, 11 Oct 2024 10:57:12 +0100 Subject: [PATCH 903/970] accel/qaic: Pass string literal as format argument of alloc_workqueue() Recently I noticed that both gcc-14 and clang-18 report that passing a non-string literal as the format argument of alloc_workqueue() is potentially insecure. E.g. clang-18 says: .../qaic_drv.c:61:23: warning: format string is not a string literal (potentially insecure) [-Wformat-security] 61 | wq = alloc_workqueue(fmt, WQ_UNBOUND, 0); | ^~~ .../qaic_drv.c:61:23: note: treat the string as an argument to avoid this 61 | wq = alloc_workqueue(fmt, WQ_UNBOUND, 0); | ^ | "%s", It is always the case where the contents of fmt is safe to pass as the format argument. That is, in my understanding, it never contains any format escape sequences. But, it seems better to be safe than sorry. And, as a bonus, compiler output becomes less verbose by addressing this issue as suggested by clang-18. Also, change the name of the parameter of qaicm_wq_init from fmt to name to better reflect it's purpose. Compile tested only. Signed-off-by: Simon Horman <horms@kernel.org> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Tested-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241011-string-thing-v1-3-acc506568033@kernel.org --- drivers/accel/qaic/qaic_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index f139c564eadf..3575e0c984d6 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -54,12 +54,12 @@ static void qaicm_wq_release(struct drm_device *dev, void *res) destroy_workqueue(wq); } -static struct workqueue_struct *qaicm_wq_init(struct drm_device *dev, const char *fmt) +static struct workqueue_struct *qaicm_wq_init(struct drm_device *dev, const char *name) { struct workqueue_struct *wq; int ret; - wq = alloc_workqueue(fmt, WQ_UNBOUND, 0); + wq = alloc_workqueue("%s", WQ_UNBOUND, 0, name); if (!wq) return ERR_PTR(-ENOMEM); ret = drmm_add_action_or_reset(dev, qaicm_wq_release, wq); -- GitLab From 12f6baa472e097d4d55dfef9eacc36b04071bdc1 Mon Sep 17 00:00:00 2001 From: Alex Lanzano <lanzano.alex@gmail.com> Date: Tue, 15 Oct 2024 19:05:43 -0400 Subject: [PATCH 904/970] dt-bindings: display: Add Sharp Memory LCD bindings Add device tree bindings for the monochrome Sharp Memory LCD Co-developed-by: Mehdi Djait <mehdi.djait@bootlin.com> Signed-off-by: Mehdi Djait <mehdi.djait@bootlin.com> Signed-off-by: Alex Lanzano <lanzano.alex@gmail.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241015230617.3020230-2-lanzano.alex@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- .../bindings/display/sharp,ls010b7dh04.yaml | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/sharp,ls010b7dh04.yaml diff --git a/Documentation/devicetree/bindings/display/sharp,ls010b7dh04.yaml b/Documentation/devicetree/bindings/display/sharp,ls010b7dh04.yaml new file mode 100644 index 000000000000..8097f091c2a5 --- /dev/null +++ b/Documentation/devicetree/bindings/display/sharp,ls010b7dh04.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/sharp,ls010b7dh04.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sharp Memory LCD panels + +maintainers: + - Alex Lanzano <lanzano.alex@gmail.com> + +description: + Sharp Memory LCDs are a series of monochrome displays that operate over + a SPI bus. The displays require a signal (VCOM) to be generated to prevent + DC bias build up resulting in pixels being unable to change. Three modes + can be used to provide the VCOM signal ("software", "external", "pwm"). + +properties: + compatible: + enum: + - sharp,ls010b7dh04 + - sharp,ls011b7dh03 + - sharp,ls012b7dd01 + - sharp,ls013b7dh03 + - sharp,ls013b7dh05 + - sharp,ls018b7dh02 + - sharp,ls027b7dh01 + - sharp,ls027b7dh01a + - sharp,ls032b7dd02 + - sharp,ls044q7dh01 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 2000000 + + sharp,vcom-mode: + $ref: /schemas/types.yaml#/definitions/string + description: | + software - This mode relies on a software operation to send a + "maintain display" message to the display, toggling the vcom + bit on and off with each message + + external - This mode relies on an external clock to generate + the signal on the EXTCOMM pin + + pwm - This mode relies on a pwm device to generate the signal + on the EXTCOMM pin + + enum: [software, external, pwm] + + enable-gpios: true + + pwms: + maxItems: 1 + description: External VCOM signal + +required: + - compatible + - reg + - sharp,vcom-mode + +allOf: + - $ref: panel/panel-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + + - if: + properties: + sharp,vcom-mode: + const: pwm + then: + required: + - pwms + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + display@0 { + compatible = "sharp,ls013b7dh03"; + reg = <0>; + spi-cs-high; + spi-max-frequency = <1000000>; + sharp,vcom-mode = "software"; + }; + }; +... -- GitLab From b8f9f21716fecac41d083ec8c77809ecd0b100d8 Mon Sep 17 00:00:00 2001 From: Alex Lanzano <lanzano.alex@gmail.com> Date: Tue, 15 Oct 2024 19:05:44 -0400 Subject: [PATCH 905/970] drm/tiny: Add driver for Sharp Memory LCD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the monochrome Sharp Memory LCDs. Co-developed-by: Mehdi Djait <mehdi.djait@bootlin.com> Signed-off-by: Mehdi Djait <mehdi.djait@bootlin.com> Signed-off-by: Alex Lanzano <lanzano.alex@gmail.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241015230617.3020230-3-lanzano.alex@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- MAINTAINERS | 6 + drivers/gpu/drm/tiny/Kconfig | 21 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/sharp-memory.c | 671 ++++++++++++++++++++++++++++ 4 files changed, 699 insertions(+) create mode 100644 drivers/gpu/drm/tiny/sharp-memory.c diff --git a/MAINTAINERS b/MAINTAINERS index e200e10696fd..8b993d6de0f3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7387,6 +7387,12 @@ S: Maintained F: Documentation/devicetree/bindings/display/panel/samsung,s6e3ha8.yaml F: drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c +DRM DRIVER FOR SHARP MEMORY LCD +M: Alex Lanzano <lanzano.alex@gmail.com> +S: Maintained +F: Documentation/devicetree/bindings/display/sharp,ls010b7dh04.yaml +F: drivers/gpu/drm/tiny/sharp-memory.c + DRM DRIVER FOR SITRONIX ST7586 PANELS M: David Lechner <david@lechnology.com> S: Maintained diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index f542aae334d5..94cbdb1337c0 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -198,6 +198,27 @@ config TINYDRM_REPAPER If M is selected the module will be called repaper. +config TINYDRM_SHARP_MEMORY + tristate "DRM support for Sharp Memory LCD panels" + depends on DRM && SPI + select DRM_CLIENT_SELECTION + select DRM_GEM_DMA_HELPER + select DRM_KMS_HELPER + help + DRM Driver for the following Sharp Memory Panels: + * 1.00" Sharp Memory LCD (LS010B7DH04) + * 1.10" Sharp Memory LCD (LS011B7DH03) + * 1.20" Sharp Memory LCD (LS012B7DD01) + * 1.28" Sharp Memory LCD (LS013B7DH03) + * 1.26" Sharp Memory LCD (LS013B7DH05) + * 1.80" Sharp Memory LCD (LS018B7DH02) + * 2.70" Sharp Memory LCD (LS027B7DH01) + * 2.70" Sharp Memory LCD (LS027B7DH01A) + * 3.20" Sharp Memory LCD (LS032B7DD02) + * 4.40" Sharp Memory LCD (LS044Q7DH01) + + If M is selected the module will be called sharp_memory. + config TINYDRM_ST7586 tristate "DRM support for Sitronix ST7586 display panels" depends on DRM && SPI diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 76dde89a044b..4aaf56f8707d 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_TINYDRM_ILI9341) += ili9341.o obj-$(CONFIG_TINYDRM_ILI9486) += ili9486.o obj-$(CONFIG_TINYDRM_MI0283QT) += mi0283qt.o obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o +obj-$(CONFIG_TINYDRM_SHARP_MEMORY) += sharp-memory.o obj-$(CONFIG_TINYDRM_ST7586) += st7586.o obj-$(CONFIG_TINYDRM_ST7735R) += st7735r.o diff --git a/drivers/gpu/drm/tiny/sharp-memory.c b/drivers/gpu/drm/tiny/sharp-memory.c new file mode 100644 index 000000000000..2d2315bd6aef --- /dev/null +++ b/drivers/gpu/drm/tiny/sharp-memory.c @@ -0,0 +1,671 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_client_setup.h> +#include <drm/drm_connector.h> +#include <drm/drm_damage_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_fb_dma_helper.h> +#include <drm/drm_fbdev_dma.h> +#include <drm/drm_format_helper.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_gem_atomic_helper.h> +#include <drm/drm_gem_dma_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> +#include <drm/drm_managed.h> +#include <drm/drm_modes.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_rect.h> +#include <linux/bitrev.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/kthread.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/pwm.h> +#include <linux/spi/spi.h> + +#define SHARP_MODE_PERIOD 8 +#define SHARP_ADDR_PERIOD 8 +#define SHARP_DUMMY_PERIOD 8 + +#define SHARP_MEMORY_DISPLAY_MAINTAIN_MODE 0 +#define SHARP_MEMORY_DISPLAY_UPDATE_MODE 1 +#define SHARP_MEMORY_DISPLAY_CLEAR_MODE 4 + +enum sharp_memory_model { + LS010B7DH04, + LS011B7DH03, + LS012B7DD01, + LS013B7DH03, + LS013B7DH05, + LS018B7DH02, + LS027B7DH01, + LS027B7DH01A, + LS032B7DD02, + LS044Q7DH01, +}; + +enum sharp_memory_vcom_mode { + SHARP_MEMORY_SOFTWARE_VCOM, + SHARP_MEMORY_EXTERNAL_VCOM, + SHARP_MEMORY_PWM_VCOM +}; + +struct sharp_memory_device { + struct drm_device drm; + struct spi_device *spi; + + const struct drm_display_mode *mode; + + struct drm_crtc crtc; + struct drm_plane plane; + struct drm_encoder encoder; + struct drm_connector connector; + + struct gpio_desc *enable_gpio; + + struct task_struct *sw_vcom_signal; + struct pwm_device *pwm_vcom_signal; + + enum sharp_memory_vcom_mode vcom_mode; + u8 vcom; + + u32 pitch; + u32 tx_buffer_size; + u8 *tx_buffer; + + /* When vcom_mode == "software" a kthread is used to periodically send a + * 'maintain display' message over spi. This mutex ensures tx_buffer access + * and spi bus usage is synchronized in this case. + */ + struct mutex tx_mutex; +}; + +static inline int sharp_memory_spi_write(struct spi_device *spi, void *buf, size_t len) +{ + /* Reverse the bit order */ + for (u8 *b = buf; b < ((u8 *)buf) + len; ++b) + *b = bitrev8(*b); + + return spi_write(spi, buf, len); +} + +static inline struct sharp_memory_device *drm_to_sharp_memory_device(struct drm_device *drm) +{ + return container_of(drm, struct sharp_memory_device, drm); +} + +DEFINE_DRM_GEM_DMA_FOPS(sharp_memory_fops); + +static const struct drm_driver sharp_memory_drm_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .fops = &sharp_memory_fops, + DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, + .name = "sharp_memory_display", + .desc = "Sharp Display Memory LCD", + .date = "20231129", + .major = 1, + .minor = 0, +}; + +static inline void sharp_memory_set_tx_buffer_mode(u8 *buffer, u8 mode, u8 vcom) +{ + *buffer = mode | (vcom << 1); +} + +static inline void sharp_memory_set_tx_buffer_addresses(u8 *buffer, + struct drm_rect clip, + u32 pitch) +{ + for (u32 line = 0; line < clip.y2; ++line) + buffer[line * pitch] = line + 1; +} + +static void sharp_memory_set_tx_buffer_data(u8 *buffer, + struct drm_framebuffer *fb, + struct drm_rect clip, + u32 pitch, + struct drm_format_conv_state *fmtcnv_state) +{ + int ret; + struct iosys_map dst, vmap; + struct drm_gem_dma_object *dma_obj = drm_fb_dma_get_gem_obj(fb, 0); + + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + return; + + iosys_map_set_vaddr(&dst, buffer); + iosys_map_set_vaddr(&vmap, dma_obj->vaddr); + + drm_fb_xrgb8888_to_mono(&dst, &pitch, &vmap, fb, &clip, fmtcnv_state); + + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); +} + +static int sharp_memory_update_display(struct sharp_memory_device *smd, + struct drm_framebuffer *fb, + struct drm_rect clip, + struct drm_format_conv_state *fmtcnv_state) +{ + int ret; + u32 pitch = smd->pitch; + u8 vcom = smd->vcom; + u8 *tx_buffer = smd->tx_buffer; + u32 tx_buffer_size = smd->tx_buffer_size; + + mutex_lock(&smd->tx_mutex); + + /* Populate the transmit buffer with frame data */ + sharp_memory_set_tx_buffer_mode(&tx_buffer[0], + SHARP_MEMORY_DISPLAY_UPDATE_MODE, vcom); + sharp_memory_set_tx_buffer_addresses(&tx_buffer[1], clip, pitch); + sharp_memory_set_tx_buffer_data(&tx_buffer[2], fb, clip, pitch, fmtcnv_state); + + ret = sharp_memory_spi_write(smd->spi, tx_buffer, tx_buffer_size); + + mutex_unlock(&smd->tx_mutex); + + return ret; +} + +static int sharp_memory_maintain_display(struct sharp_memory_device *smd) +{ + int ret; + u8 vcom = smd->vcom; + u8 *tx_buffer = smd->tx_buffer; + + mutex_lock(&smd->tx_mutex); + + sharp_memory_set_tx_buffer_mode(&tx_buffer[0], SHARP_MEMORY_DISPLAY_MAINTAIN_MODE, vcom); + tx_buffer[1] = 0; /* Write dummy data */ + ret = sharp_memory_spi_write(smd->spi, tx_buffer, 2); + + mutex_unlock(&smd->tx_mutex); + + return ret; +} + +static int sharp_memory_clear_display(struct sharp_memory_device *smd) +{ + int ret; + u8 vcom = smd->vcom; + u8 *tx_buffer = smd->tx_buffer; + + mutex_lock(&smd->tx_mutex); + + sharp_memory_set_tx_buffer_mode(&tx_buffer[0], SHARP_MEMORY_DISPLAY_CLEAR_MODE, vcom); + tx_buffer[1] = 0; /* write dummy data */ + ret = sharp_memory_spi_write(smd->spi, tx_buffer, 2); + + mutex_unlock(&smd->tx_mutex); + + return ret; +} + +static void sharp_memory_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect, + struct drm_format_conv_state *fmtconv_state) +{ + struct drm_rect clip; + struct sharp_memory_device *smd = drm_to_sharp_memory_device(fb->dev); + + /* Always update a full line regardless of what is dirty */ + clip.x1 = 0; + clip.x2 = fb->width; + clip.y1 = rect->y1; + clip.y2 = rect->y2; + + sharp_memory_update_display(smd, fb, clip, fmtconv_state); +} + +static int sharp_memory_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct sharp_memory_device *smd; + struct drm_crtc_state *crtc_state; + + smd = container_of(plane, struct sharp_memory_device, plane); + crtc_state = drm_atomic_get_new_crtc_state(state, &smd->crtc); + + return drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); +} + +static void sharp_memory_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_plane_state *plane_state = plane->state; + struct drm_format_conv_state fmtcnv_state = DRM_FORMAT_CONV_STATE_INIT; + struct sharp_memory_device *smd; + struct drm_rect rect; + + smd = container_of(plane, struct sharp_memory_device, plane); + if (!smd->crtc.state->active) + return; + + if (drm_atomic_helper_damage_merged(old_state, plane_state, &rect)) + sharp_memory_fb_dirty(plane_state->fb, &rect, &fmtcnv_state); + + drm_format_conv_state_release(&fmtcnv_state); +} + +static const struct drm_plane_helper_funcs sharp_memory_plane_helper_funcs = { + .prepare_fb = drm_gem_plane_helper_prepare_fb, + .atomic_check = sharp_memory_plane_atomic_check, + .atomic_update = sharp_memory_plane_atomic_update, +}; + +static bool sharp_memory_format_mod_supported(struct drm_plane *plane, + u32 format, + u64 modifier) +{ + return modifier == DRM_FORMAT_MOD_LINEAR; +} + +static const struct drm_plane_funcs sharp_memory_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, + .format_mod_supported = sharp_memory_format_mod_supported, +}; + +static enum drm_mode_status sharp_memory_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) +{ + struct sharp_memory_device *smd = drm_to_sharp_memory_device(crtc->dev); + + return drm_crtc_helper_mode_valid_fixed(crtc, mode, smd->mode); +} + +static int sharp_memory_crtc_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + int ret; + + if (!crtc_state->enable) + goto out; + + ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state); + if (ret) + return ret; + +out: + return drm_atomic_add_affected_planes(state, crtc); +} + +static int sharp_memory_sw_vcom_signal_thread(void *data) +{ + struct sharp_memory_device *smd = data; + + while (!kthread_should_stop()) { + smd->vcom ^= 1; /* Toggle vcom */ + sharp_memory_maintain_display(smd); + msleep(1000); + } + + return 0; +} + +static void sharp_memory_crtc_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct sharp_memory_device *smd = drm_to_sharp_memory_device(crtc->dev); + + sharp_memory_clear_display(smd); + + if (smd->enable_gpio) + gpiod_set_value(smd->enable_gpio, 1); +} + +static void sharp_memory_crtc_disable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct sharp_memory_device *smd = drm_to_sharp_memory_device(crtc->dev); + + sharp_memory_clear_display(smd); + + if (smd->enable_gpio) + gpiod_set_value(smd->enable_gpio, 0); +} + +static const struct drm_crtc_helper_funcs sharp_memory_crtc_helper_funcs = { + .mode_valid = sharp_memory_crtc_mode_valid, + .atomic_check = sharp_memory_crtc_check, + .atomic_enable = sharp_memory_crtc_enable, + .atomic_disable = sharp_memory_crtc_disable, +}; + +static const struct drm_crtc_funcs sharp_memory_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +}; + +static const struct drm_encoder_funcs sharp_memory_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static int sharp_memory_connector_get_modes(struct drm_connector *connector) +{ + struct sharp_memory_device *smd = drm_to_sharp_memory_device(connector->dev); + + return drm_connector_helper_get_modes_fixed(connector, smd->mode); +} + +static const struct drm_connector_helper_funcs sharp_memory_connector_hfuncs = { + .get_modes = sharp_memory_connector_get_modes, +}; + +static const struct drm_connector_funcs sharp_memory_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + +}; + +static const struct drm_mode_config_funcs sharp_memory_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static const struct drm_display_mode sharp_memory_ls010b7dh04_mode = { + DRM_SIMPLE_MODE(128, 128, 18, 18), +}; + +static const struct drm_display_mode sharp_memory_ls011b7dh03_mode = { + DRM_SIMPLE_MODE(160, 68, 25, 10), +}; + +static const struct drm_display_mode sharp_memory_ls012b7dd01_mode = { + DRM_SIMPLE_MODE(184, 38, 29, 6), +}; + +static const struct drm_display_mode sharp_memory_ls013b7dh03_mode = { + DRM_SIMPLE_MODE(128, 128, 23, 23), +}; + +static const struct drm_display_mode sharp_memory_ls013b7dh05_mode = { + DRM_SIMPLE_MODE(144, 168, 20, 24), +}; + +static const struct drm_display_mode sharp_memory_ls018b7dh02_mode = { + DRM_SIMPLE_MODE(230, 303, 27, 36), +}; + +static const struct drm_display_mode sharp_memory_ls027b7dh01_mode = { + DRM_SIMPLE_MODE(400, 240, 58, 35), +}; + +static const struct drm_display_mode sharp_memory_ls032b7dd02_mode = { + DRM_SIMPLE_MODE(336, 536, 42, 68), +}; + +static const struct drm_display_mode sharp_memory_ls044q7dh01_mode = { + DRM_SIMPLE_MODE(320, 240, 89, 67), +}; + +static const struct spi_device_id sharp_memory_ids[] = { + {"ls010b7dh04", (kernel_ulong_t)&sharp_memory_ls010b7dh04_mode}, + {"ls011b7dh03", (kernel_ulong_t)&sharp_memory_ls011b7dh03_mode}, + {"ls012b7dd01", (kernel_ulong_t)&sharp_memory_ls012b7dd01_mode}, + {"ls013b7dh03", (kernel_ulong_t)&sharp_memory_ls013b7dh03_mode}, + {"ls013b7dh05", (kernel_ulong_t)&sharp_memory_ls013b7dh05_mode}, + {"ls018b7dh02", (kernel_ulong_t)&sharp_memory_ls018b7dh02_mode}, + {"ls027b7dh01", (kernel_ulong_t)&sharp_memory_ls027b7dh01_mode}, + {"ls027b7dh01a", (kernel_ulong_t)&sharp_memory_ls027b7dh01_mode}, + {"ls032b7dd02", (kernel_ulong_t)&sharp_memory_ls032b7dd02_mode}, + {"ls044q7dh01", (kernel_ulong_t)&sharp_memory_ls044q7dh01_mode}, + {}, +}; +MODULE_DEVICE_TABLE(spi, sharp_memory_ids); + +static const struct of_device_id sharp_memory_of_match[] = { + {.compatible = "sharp,ls010b7dh04", &sharp_memory_ls010b7dh04_mode}, + {.compatible = "sharp,ls011b7dh03", &sharp_memory_ls011b7dh03_mode}, + {.compatible = "sharp,ls012b7dd01", &sharp_memory_ls012b7dd01_mode}, + {.compatible = "sharp,ls013b7dh03", &sharp_memory_ls013b7dh03_mode}, + {.compatible = "sharp,ls013b7dh05", &sharp_memory_ls013b7dh05_mode}, + {.compatible = "sharp,ls018b7dh02", &sharp_memory_ls018b7dh02_mode}, + {.compatible = "sharp,ls027b7dh01", &sharp_memory_ls027b7dh01_mode}, + {.compatible = "sharp,ls027b7dh01a", &sharp_memory_ls027b7dh01_mode}, + {.compatible = "sharp,ls032b7dd02", &sharp_memory_ls032b7dd02_mode}, + {.compatible = "sharp,ls044q7dh01", &sharp_memory_ls044q7dh01_mode}, + {}, +}; +MODULE_DEVICE_TABLE(of, sharp_memory_of_match); + +static const u32 sharp_memory_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +static int sharp_memory_pipe_init(struct drm_device *dev, + struct sharp_memory_device *smd, + const u32 *formats, unsigned int format_count, + const u64 *format_modifiers) +{ + int ret; + struct drm_encoder *encoder = &smd->encoder; + struct drm_plane *plane = &smd->plane; + struct drm_crtc *crtc = &smd->crtc; + struct drm_connector *connector = &smd->connector; + + drm_plane_helper_add(plane, &sharp_memory_plane_helper_funcs); + ret = drm_universal_plane_init(dev, plane, 0, + &sharp_memory_plane_funcs, + formats, format_count, + format_modifiers, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) + return ret; + + drm_crtc_helper_add(crtc, &sharp_memory_crtc_helper_funcs); + ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, + &sharp_memory_crtc_funcs, NULL); + if (ret) + return ret; + + encoder->possible_crtcs = drm_crtc_mask(crtc); + ret = drm_encoder_init(dev, encoder, &sharp_memory_encoder_funcs, + DRM_MODE_ENCODER_NONE, NULL); + if (ret) + return ret; + + ret = drm_connector_init(&smd->drm, &smd->connector, + &sharp_memory_connector_funcs, + DRM_MODE_CONNECTOR_SPI); + if (ret) + return ret; + + drm_connector_helper_add(&smd->connector, + &sharp_memory_connector_hfuncs); + + return drm_connector_attach_encoder(connector, encoder); +} + +static int sharp_memory_init_pwm_vcom_signal(struct sharp_memory_device *smd) +{ + int ret; + struct device *dev = &smd->spi->dev; + struct pwm_state pwm_state; + + smd->pwm_vcom_signal = devm_pwm_get(dev, NULL); + if (IS_ERR(smd->pwm_vcom_signal)) + return dev_err_probe(dev, PTR_ERR(smd->pwm_vcom_signal), + "Could not get pwm device\n"); + + pwm_init_state(smd->pwm_vcom_signal, &pwm_state); + pwm_set_relative_duty_cycle(&pwm_state, 1, 10); + pwm_state.enabled = true; + ret = pwm_apply_might_sleep(smd->pwm_vcom_signal, &pwm_state); + if (ret) + return dev_err_probe(dev, -EINVAL, "Could not apply pwm state\n"); + + return 0; +} + +static int sharp_memory_probe(struct spi_device *spi) +{ + int ret; + struct device *dev; + struct sharp_memory_device *smd; + struct drm_device *drm; + const char *vcom_mode_str; + + dev = &spi->dev; + + ret = spi_setup(spi); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to setup spi device\n"); + + if (!dev->coherent_dma_mask) { + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return dev_err_probe(dev, ret, "Failed to set dma mask\n"); + } + + smd = devm_drm_dev_alloc(dev, &sharp_memory_drm_driver, + struct sharp_memory_device, drm); + if (!smd) + return -ENOMEM; + + spi_set_drvdata(spi, smd); + + smd->spi = spi; + drm = &smd->drm; + ret = drmm_mode_config_init(drm); + if (ret) + return dev_err_probe(dev, ret, "Failed to initialize drm config\n"); + + smd->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (!smd->enable_gpio) + dev_warn(dev, "Enable gpio not defined\n"); + + drm->mode_config.funcs = &sharp_memory_mode_config_funcs; + smd->mode = spi_get_device_match_data(spi); + + smd->pitch = (SHARP_ADDR_PERIOD + smd->mode->hdisplay + SHARP_DUMMY_PERIOD) / 8; + smd->tx_buffer_size = (SHARP_MODE_PERIOD + + (SHARP_ADDR_PERIOD + (smd->mode->hdisplay) + SHARP_DUMMY_PERIOD) * + smd->mode->vdisplay) / 8; + + smd->tx_buffer = devm_kzalloc(dev, smd->tx_buffer_size, GFP_KERNEL); + if (!smd->tx_buffer) + return -ENOMEM; + + mutex_init(&smd->tx_mutex); + + /* + * VCOM is a signal that prevents DC bias from being built up in + * the panel resulting in pixels being forever stuck in one state. + * + * This driver supports three different methods to generate this + * signal depending on EXTMODE pin: + * + * software (EXTMODE = L) - This mode uses a kthread to + * periodically send a "maintain display" message to the display, + * toggling the vcom bit on and off with each message + * + * external (EXTMODE = H) - This mode relies on an external + * clock to generate the signal on the EXTCOMM pin + * + * pwm (EXTMODE = H) - This mode uses a pwm device to generate + * the signal on the EXTCOMM pin + * + */ + if (device_property_read_string(dev, "sharp,vcom-mode", &vcom_mode_str)) + return dev_err_probe(dev, -EINVAL, + "Unable to find sharp,vcom-mode node in device tree\n"); + + if (!strcmp("software", vcom_mode_str)) { + smd->vcom_mode = SHARP_MEMORY_SOFTWARE_VCOM; + smd->sw_vcom_signal = kthread_run(sharp_memory_sw_vcom_signal_thread, + smd, "sw_vcom_signal"); + + } else if (!strcmp("external", vcom_mode_str)) { + smd->vcom_mode = SHARP_MEMORY_EXTERNAL_VCOM; + + } else if (!strcmp("pwm", vcom_mode_str)) { + smd->vcom_mode = SHARP_MEMORY_PWM_VCOM; + ret = sharp_memory_init_pwm_vcom_signal(smd); + if (ret) + return ret; + } else { + return dev_err_probe(dev, -EINVAL, "Invalid value set for vcom-mode\n"); + } + + drm->mode_config.min_width = smd->mode->hdisplay; + drm->mode_config.max_width = smd->mode->hdisplay; + drm->mode_config.min_height = smd->mode->vdisplay; + drm->mode_config.max_height = smd->mode->vdisplay; + + ret = sharp_memory_pipe_init(drm, smd, sharp_memory_formats, + ARRAY_SIZE(sharp_memory_formats), + NULL); + if (ret) + return dev_err_probe(dev, ret, "Failed to initialize display pipeline.\n"); + + drm_plane_enable_fb_damage_clips(&smd->plane); + drm_mode_config_reset(drm); + + ret = drm_dev_register(drm, 0); + if (ret) + return dev_err_probe(dev, ret, "Failed to register drm device.\n"); + + drm_client_setup(drm, NULL); + + return 0; +} + +static void sharp_memory_remove(struct spi_device *spi) +{ + struct sharp_memory_device *smd = spi_get_drvdata(spi); + + drm_dev_unplug(&smd->drm); + drm_atomic_helper_shutdown(&smd->drm); + + switch (smd->vcom_mode) { + case SHARP_MEMORY_SOFTWARE_VCOM: + kthread_stop(smd->sw_vcom_signal); + break; + + case SHARP_MEMORY_EXTERNAL_VCOM: + break; + + case SHARP_MEMORY_PWM_VCOM: + pwm_disable(smd->pwm_vcom_signal); + break; + } +} + +static struct spi_driver sharp_memory_spi_driver = { + .driver = { + .name = "sharp_memory", + .of_match_table = sharp_memory_of_match, + }, + .probe = sharp_memory_probe, + .remove = sharp_memory_remove, + .id_table = sharp_memory_ids, +}; +module_spi_driver(sharp_memory_spi_driver); + +MODULE_AUTHOR("Alex Lanzano <lanzano.alex@gmail.com>"); +MODULE_DESCRIPTION("SPI Protocol driver for the sharp_memory display"); +MODULE_LICENSE("GPL"); -- GitLab From b895a1805e0b01d523afa71818cb97a5d2655fcf Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 17:42:40 +0200 Subject: [PATCH 906/970] drm/bridge: dpc3433: Constify struct regmap_config `dlpc_regmap_config` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925-drm-const-regmap-v1-1-e609d502401b@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/ti-dlpc3433.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-dlpc3433.c b/drivers/gpu/drm/bridge/ti-dlpc3433.c index 6b559e071301..a0a1b5dd794e 100644 --- a/drivers/gpu/drm/bridge/ti-dlpc3433.c +++ b/drivers/gpu/drm/bridge/ti-dlpc3433.c @@ -94,7 +94,7 @@ static const struct regmap_access_table dlpc_volatile_table = { .n_yes_ranges = ARRAY_SIZE(dlpc_volatile_ranges), }; -static struct regmap_config dlpc_regmap_config = { +static const struct regmap_config dlpc_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = WR_DSI_PORT_EN, -- GitLab From 9239d961ce9d95ec13e241407d0320228e664d68 Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 17:42:41 +0200 Subject: [PATCH 907/970] drm/fsl-dcu: Constify struct regmap_config `fsl_tcon_regmap_config` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925-drm-const-regmap-v1-2-e609d502401b@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/fsl-dcu/fsl_tcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_tcon.c b/drivers/gpu/drm/fsl-dcu/fsl_tcon.c index 9eb5abaf7d66..49bbd00c77ae 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_tcon.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_tcon.c @@ -29,7 +29,7 @@ void fsl_tcon_bypass_enable(struct fsl_tcon *tcon) FSL_TCON_CTRL1_TCON_BYPASS); } -static struct regmap_config fsl_tcon_regmap_config = { +static const struct regmap_config fsl_tcon_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, -- GitLab From 02f686d17c4305a0b5e2a9de749664dfe9c0f63e Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 17:42:42 +0200 Subject: [PATCH 908/970] drm/mediatek: dp: Constify struct regmap_config `mtk_dp_regmap_config` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240925-drm-const-regmap-v1-3-e609d502401b@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/mediatek/mtk_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index d8796a904eca..f0f6f402994a 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -311,7 +311,7 @@ static const struct mtk_dp_efuse_fmt mt8195_dp_efuse_fmt[MTK_DP_CAL_MAX] = { }, }; -static struct regmap_config mtk_dp_regmap_config = { +static const struct regmap_config mtk_dp_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, -- GitLab From 0bcbddb7ef0edb8b4ca994033128e955bb8b1b74 Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 17:42:43 +0200 Subject: [PATCH 909/970] drm/meson: Constify struct regmap_config `meson_regmap_config` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925-drm-const-regmap-v1-4-e609d502401b@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/meson/meson_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index bbb662d2f184..7cace75a38af 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -128,7 +128,7 @@ static bool meson_vpu_has_available_connectors(struct device *dev) return false; } -static struct regmap_config meson_regmap_config = { +static const struct regmap_config meson_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, -- GitLab From 6a92271233fb4789f69a9ba9410b23e2e5ab30e2 Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 17:42:44 +0200 Subject: [PATCH 910/970] drm/panel: ili9322: Constify struct regmap_bus `ili9322_regmap_bus` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925-drm-const-regmap-v1-5-e609d502401b@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/panel/panel-ilitek-ili9322.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c index 4a6dcfd781e8..94b7dfef3b5e 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -318,7 +318,7 @@ static int ili9322_regmap_spi_read(void *context, const void *reg, return spi_write_then_read(spi, buf, 1, val, 1); } -static struct regmap_bus ili9322_regmap_bus = { +static const struct regmap_bus ili9322_regmap_bus = { .write = ili9322_regmap_spi_write, .read = ili9322_regmap_spi_read, .reg_format_endian_default = REGMAP_ENDIAN_BIG, -- GitLab From 420fb223fe6049f5eecac0d28136df5bc5699ea2 Mon Sep 17 00:00:00 2001 From: Javier Carrasco <javier.carrasco.cruz@gmail.com> Date: Wed, 25 Sep 2024 17:42:45 +0200 Subject: [PATCH 911/970] drm/sprd: Constify struct regmap_bus `regmap_txt_io` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240925-drm-const-regmap-v1-6-e609d502401b@gmail.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/sprd/sprd_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sprd/sprd_dsi.c b/drivers/gpu/drm/sprd/sprd_dsi.c index 0b69c140eab3..44a7a579660f 100644 --- a/drivers/gpu/drm/sprd/sprd_dsi.c +++ b/drivers/gpu/drm/sprd/sprd_dsi.c @@ -209,7 +209,7 @@ static int regmap_tst_io_read(void *context, u32 reg, u32 *val) return 0; } -static struct regmap_bus regmap_tst_io = { +static const struct regmap_bus regmap_tst_io = { .reg_write = regmap_tst_io_write, .reg_read = regmap_tst_io_read, }; -- GitLab From 5b7abfb20ba15c0d6c52672874b99d9564ca876b Mon Sep 17 00:00:00 2001 From: Alexander Stein <alexander.stein@ew.tq-group.com> Date: Thu, 26 Sep 2024 07:55:50 +0200 Subject: [PATCH 912/970] drm: fsl-dcu: Use dev_err_probe fsl_dcu_drm_modeset_init can return -EPROBE_DEFER, so use dev_err_probe to remove an invalid error message and add it to deferral description. Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240926055552.1632448-1-alexander.stein@ew.tq-group.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 2b3f15f0dc56..e62f58128283 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -104,10 +104,8 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) int ret; ret = fsl_dcu_drm_modeset_init(fsl_dev); - if (ret < 0) { - dev_err(dev->dev, "failed to initialize mode setting\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(dev->dev, ret, "failed to initialize mode setting\n"); ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret < 0) { -- GitLab From ffcde9e44d3e18fde3d18bfff8d9318935413bfd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer <matthias.schiffer@tq-group.com> Date: Thu, 26 Sep 2024 07:55:51 +0200 Subject: [PATCH 913/970] drm: fsl-dcu: enable PIXCLK on LS1021A The PIXCLK needs to be enabled in SCFG before accessing certain DCU registers, or the access will hang. For simplicity, the PIXCLK is enabled unconditionally, resulting in increased power consumption. Signed-off-by: Matthias Schiffer <matthias.schiffer@tq-group.com> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Fixes: 109eee2f2a18 ("drm/layerscape: Add Freescale DCU DRM driver") Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240926055552.1632448-2-alexander.stein@ew.tq-group.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/fsl-dcu/Kconfig | 1 + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 15 +++++++++++++++ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 3 +++ 3 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig index 588ce2420af2..0e0f910ceb9f 100644 --- a/drivers/gpu/drm/fsl-dcu/Kconfig +++ b/drivers/gpu/drm/fsl-dcu/Kconfig @@ -9,6 +9,7 @@ config DRM_FSL_DCU select DRM_PANEL select REGMAP_MMIO select VIDEOMODE_HELPERS + select MFD_SYSCON if SOC_LS1021A help Choose this option if you have an Freescale DCU chipset. If M is selected the module will be called fsl-dcu-drm. diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index e62f58128283..6886487adc94 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -101,12 +101,27 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev) static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; + struct regmap *scfg; int ret; ret = fsl_dcu_drm_modeset_init(fsl_dev); if (ret < 0) return dev_err_probe(dev->dev, ret, "failed to initialize mode setting\n"); + scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg"); + if (PTR_ERR(scfg) != -ENODEV) { + /* + * For simplicity, enable the PIXCLK unconditionally, + * resulting in increased power consumption. Disabling + * the clock in PM or on unload could be implemented as + * a future improvement. + */ + ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN, + SCFG_PIXCLKCR_PXCEN); + if (ret < 0) + return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n"); + } + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret < 0) { dev_err(dev->dev, "failed to initialize vblank\n"); diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h index e2049a0e8a92..566396013c04 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h @@ -160,6 +160,9 @@ #define FSL_DCU_ARGB4444 12 #define FSL_DCU_YUV422 14 +#define SCFG_PIXCLKCR 0x28 +#define SCFG_PIXCLKCR_PXCEN BIT(31) + #define VF610_LAYER_REG_NUM 9 #define LS1021A_LAYER_REG_NUM 10 -- GitLab From c3f0b90f6ffc178bf158aeccae268276363d6945 Mon Sep 17 00:00:00 2001 From: Manikandan Muralidharan <manikandan.m@microchip.com> Date: Thu, 19 Sep 2024 14:45:47 +0530 Subject: [PATCH 914/970] dt-bindings: display: panel-simple: Document support for Microchip AC69T88A Add Microchip AC69T88A 5" LVDS interface (800x480) TFT LCD panel compatible string Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com> Acked-by: Rob Herring (Arm) <robh@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240919091548.430285-1-manikandan.m@microchip.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index b89e39790579..18b63f356bb4 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -200,6 +200,8 @@ properties: - logictechno,lttd800480070-l2rt # Logic Technologies LTTD800480070-L6WH-RT 7†800x480 TFT Resistive Touch Module - logictechno,lttd800480070-l6wh-rt + # Microchip AC69T88A 5" 800X480 LVDS interface TFT LCD Panel + - microchip,ac69t88a # Mitsubishi "AA070MC01 7.0" WVGA TFT LCD panel - mitsubishi,aa070mc01-ca1 # Mitsubishi AA084XE01 8.4" XGA TFT LCD panel -- GitLab From 40da1463cd6879f542238b36c1148f517927c595 Mon Sep 17 00:00:00 2001 From: Manikandan Muralidharan <manikandan.m@microchip.com> Date: Thu, 19 Sep 2024 14:45:48 +0530 Subject: [PATCH 915/970] drm/panel: simple: Add Microchip AC69T88A LVDS Display panel Add support for Microchip AC69T88A 5 inch TFT LCD 800x480 Display module with LVDS interface.The panel uses the Sitronix ST7262 800x480 Display driver Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com> Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240919091548.430285-2-manikandan.m@microchip.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/panel/panel-simple.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 86735430462f..06381c628209 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -4565,6 +4565,31 @@ static const struct panel_desc yes_optoelectronics_ytc700tlag_05_201c = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct drm_display_mode mchp_ac69t88a_mode = { + .clock = 25000, + .hdisplay = 800, + .hsync_start = 800 + 88, + .hsync_end = 800 + 88 + 5, + .htotal = 800 + 88 + 5 + 40, + .vdisplay = 480, + .vsync_start = 480 + 23, + .vsync_end = 480 + 23 + 5, + .vtotal = 480 + 23 + 5 + 1, +}; + +static const struct panel_desc mchp_ac69t88a = { + .modes = &mchp_ac69t88a_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 108, + .height = 65, + }, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode arm_rtsm_mode[] = { { .clock = 65000, @@ -5048,6 +5073,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "yes-optoelectronics,ytc700tlag-05-201c", .data = &yes_optoelectronics_ytc700tlag_05_201c, + }, { + .compatible = "microchip,ac69t88a", + .data = &mchp_ac69t88a, }, { /* Must be the last entry */ .compatible = "panel-dpi", -- GitLab From 4b173d34e35726d7727d3e5edc43bcab12654ab0 Mon Sep 17 00:00:00 2001 From: Chen Ni <nichen@iscas.ac.cn> Date: Wed, 18 Sep 2024 15:48:41 +0800 Subject: [PATCH 916/970] drm/fsl-dcu: Remove redundant dev_err() There is no need to call the dev_err() function directly to print a custom message when handling an error from platform_get_irq() function as it is going to display an appropriate error message in case of a failure. Signed-off-by: Chen Ni <nichen@iscas.ac.cn> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Acked-by: Alison Wang <alison.wang@nxp.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918074841.2221210-1-nichen@iscas.ac.cn Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 6886487adc94..91a48d774cf7 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -287,10 +287,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev) } fsl_dev->irq = platform_get_irq(pdev, 0); - if (fsl_dev->irq < 0) { - dev_err(dev, "failed to get irq\n"); + if (fsl_dev->irq < 0) return fsl_dev->irq; - } fsl_dev->regmap = devm_regmap_init_mmio(dev, base, &fsl_dcu_regmap_config); -- GitLab From 45608a3eb4902f32010a8328c0a01ccda4b38c9b Mon Sep 17 00:00:00 2001 From: Ryan Walklin <ryan@testtoast.com> Date: Sun, 20 Oct 2024 21:37:41 +1300 Subject: [PATCH 917/970] drm: panel: nv3052c: correct spi_device_id for RG35XX panel The Anbernic RG35XX devices use an SPI LCD panel from an unknown OEM, with an NV3052C driver chip. As discussed previously, the integrating vendor and device name are preferred instead of the OEM serial. A previous patch corrected the device tree binding and of_device_id in the NV3052C driver, however the spi_device_id also needs correction. Correct the spi_device_id for the RG35XX panel. Signed-off-by: Ryan Walklin <ryan@testtoast.com> Fixes: 76dce2a96c0f ("drm: panel: nv3052c: Correct WL-355608-A8 panel compatible") Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241020083836.175733-1-ryan@testtoast.com [DB: corrected the Fixes tag] Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/panel/panel-newvision-nv3052c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c index d3baccfe6286..06e16a7c14a7 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -917,7 +917,7 @@ static const struct nv3052c_panel_info wl_355608_a8_panel_info = { static const struct spi_device_id nv3052c_ids[] = { { "ltk035c5444t", }, { "fs035vg158", }, - { "wl-355608-a8", }, + { "rg35xx-plus-panel", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, nv3052c_ids); -- GitLab From 23f59d7baa1fe31823d223afe9cace1494bdf5b1 Mon Sep 17 00:00:00 2001 From: Randy Dunlap <rdunlap@infradead.org> Date: Wed, 16 Oct 2024 19:48:13 -0700 Subject: [PATCH 918/970] drm/fbdev-dma: remove obsolete kernel-doc references The kernel-doc comments in these 3 files was removed so remove the references to these files to prevent kernel-doc warnings. drivers/gpu/drm/drm_fbdev_dma.c:1: warning: no structured comments found drivers/gpu/drm/drm_fbdev_shmem.c:1: warning: no structured comments found drivers/gpu/drm/drm_fbdev_ttm.c:1: warning: no structured comments found Fixes: 731fddf4302e ("drm/fbdev-dma: Remove obsolete setup function") Signed-off-by: Randy Dunlap <rdunlap@infradead.org> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Closes: https://lore.kernel.org/all/20241002142250.07e1c46c@canb.auug.org.au/ Cc: David Airlie <airlied@gmail.com> Cc: Simona Vetter <simona@ffwll.ch> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: dri-devel@lists.freedesktop.org Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20241017024813.61908-1-rdunlap@infradead.org --- Documentation/gpu/drm-kms-helpers.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index c3e58856f75b..8cf2f041af47 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -110,15 +110,6 @@ fbdev Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :doc: fbdev helpers -.. kernel-doc:: drivers/gpu/drm/drm_fbdev_dma.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_fbdev_shmem.c - :export: - -.. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c - :export: - .. kernel-doc:: include/drm/drm_fb_helper.h :internal: -- GitLab From d9c12481f980bdad9cf6fdb742e49c5b50622795 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Date: Sun, 8 Sep 2024 16:21:31 +0200 Subject: [PATCH 919/970] drm/meson: drop unused static dw_hdmi_dwc_write_bits static inline dw_hdmi_dwc_write_bits() function is not used at all: drivers/gpu/drm/meson/meson_dw_hdmi.c:276:20: error: unused function 'dw_hdmi_dwc_write_bits' [-Werror,-Wunused-function] Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240908-regmap-config-const-v1-1-28f349004811@linaro.org [narmstrong: s/staitc/static/] Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20240908-regmap-config-const-v1-1-28f349004811@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20240902113320.903147-2-liaochen4@huawei.com --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 5565f7777529..b75db829b1da 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -272,20 +272,6 @@ static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi, writeb(data, dw_hdmi->hdmitx + addr); } -/* Helper to change specific bits in controller registers */ -static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, - unsigned int addr, - unsigned int mask, - unsigned int val) -{ - unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr); - - data &= ~mask; - data |= val; - - dw_hdmi->data->dwc_write(dw_hdmi, addr, data); -} - /* Bridge */ /* Setup PHY bandwidth modes */ -- GitLab From d704a2fe530caa7023949b513b8d1c364b5832fb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Date: Thu, 3 Oct 2024 15:39:03 +0200 Subject: [PATCH 920/970] dt-bindings: display: bridge: tc358768: switch to bus-width "data-lines" property is way too similar to "data-lanes". It is also duplicating "bus-width" from video-interfaces.yaml schema. Deprecate "data-lines" and use the common property. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20241003133904.69244-1-krzysztof.kozlowski@linaro.org Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241003133904.69244-1-krzysztof.kozlowski@linaro.org --- .../devicetree/bindings/display/bridge/toshiba,tc358768.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml index 779d8c57f854..bb5d3b543800 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358768.yaml @@ -60,6 +60,10 @@ properties: data-lines: $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 16, 18, 24 ] + deprecated: true + + bus-width: + enum: [ 16, 18, 24 ] port@1: $ref: /schemas/graph.yaml#/properties/port -- GitLab From bf7c079902c34f8b16ea3484de080a7bb4ad0367 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Date: Thu, 3 Oct 2024 15:39:04 +0200 Subject: [PATCH 921/970] drm/bridge: tc358768: switch to bus-width "data-lines" property is way too similar to "data-lanes". It is also duplicating "bus-width" from video-interfaces.yaml schema. "data-lines" was deprecated in the bindings and "bus-width" is preferred, so parse it instead while keeping things backwards compatible. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20241003133904.69244-2-krzysztof.kozlowski@linaro.org Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241003133904.69244-2-krzysztof.kozlowski@linaro.org --- drivers/gpu/drm/bridge/tc358768.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 0e8813278a2f..fc96fa5aab54 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -443,7 +443,9 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, ret = -EINVAL; ep = of_graph_get_endpoint_by_regs(host->dev->of_node, 0, 0); if (ep) { - ret = of_property_read_u32(ep, "data-lines", &priv->pd_lines); + ret = of_property_read_u32(ep, "bus-width", &priv->pd_lines); + if (ret) + ret = of_property_read_u32(ep, "data-lines", &priv->pd_lines); of_node_put(ep); } -- GitLab From c7671949791fb1142d0ae37343759d608a21bf28 Mon Sep 17 00:00:00 2001 From: Liu Ying <victor.liu@nxp.com> Date: Thu, 10 Oct 2024 17:26:43 +0800 Subject: [PATCH 922/970] drm/bridge: ite-it66121: Drop hdmi_avi_infoframe_init() function call drm_hdmi_avi_infoframe_from_display_mode() called from it66121_bridge_mode_set() already calls hdmi_avi_infoframe_init() to initialize an HDMI AVI infoframe. So, drop the redundant hdmi_avi_infoframe_init() function call from it66121_bridge_mode_set(). Signed-off-by: Liu Ying <victor.liu@nxp.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Link: https://lore.kernel.org/r/20241010092643.1048116-1-victor.liu@nxp.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241010092643.1048116-1-victor.liu@nxp.com --- drivers/gpu/drm/bridge/ite-it66121.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 925e42f46cd8..35ae3f0e8f51 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -770,8 +770,6 @@ void it66121_bridge_mode_set(struct drm_bridge *bridge, mutex_lock(&ctx->lock); - hdmi_avi_infoframe_init(&ctx->hdmi_avi_infoframe); - ret = drm_hdmi_avi_infoframe_from_display_mode(&ctx->hdmi_avi_infoframe, ctx->connector, adjusted_mode); if (ret) { -- GitLab From 096d518c43341c5d8b80948f6fbc90e916ffc7f2 Mon Sep 17 00:00:00 2001 From: Wadim Egorov <w.egorov@phytec.de> Date: Thu, 17 Oct 2024 10:55:55 +0200 Subject: [PATCH 923/970] dt-bindings: display: bridge: sil,sii9022: Add bus-width The SI9022 HDMI transmitter can be configured with a bus-width of 16, 18, or 24 bits. Introduce a bus-width property to the input endpoint, specifying the number of parallel RGB input bits connected to the transmitter. Signed-off-by: Wadim Egorov <w.egorov@phytec.de> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20241017085556.3045686-2-w.egorov@phytec.de Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241017085556.3045686-2-w.egorov@phytec.de --- .../bindings/display/bridge/sil,sii9022.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/sil,sii9022.yaml b/Documentation/devicetree/bindings/display/bridge/sil,sii9022.yaml index 5a69547ad3d7..1509c4535e53 100644 --- a/Documentation/devicetree/bindings/display/bridge/sil,sii9022.yaml +++ b/Documentation/devicetree/bindings/display/bridge/sil,sii9022.yaml @@ -81,9 +81,22 @@ properties: properties: port@0: - $ref: /schemas/graph.yaml#/properties/port + unevaluatedProperties: false + $ref: /schemas/graph.yaml#/$defs/port-base description: Parallel RGB input port + properties: + endpoint: + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false + + properties: + bus-width: + description: + Endpoint bus width. + enum: [ 16, 18, 24 ] + default: 24 + port@1: $ref: /schemas/graph.yaml#/properties/port description: HDMI output port -- GitLab From d284ccd8588c9b87222ec666a1da57f197023e5f Mon Sep 17 00:00:00 2001 From: Wadim Egorov <w.egorov@phytec.de> Date: Thu, 17 Oct 2024 10:55:56 +0200 Subject: [PATCH 924/970] drm/bridge: sii902x: Set input bus format based on bus-width Introduce a bus-width property to define the number of parallel RGB input pins connected to the transmitter. The input bus formats are updated accordingly. If the property is not specified, default to 24-bit bus-width. Signed-off-by: Wadim Egorov <w.egorov@phytec.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20241017085556.3045686-3-w.egorov@phytec.de Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241017085556.3045686-3-w.egorov@phytec.de --- drivers/gpu/drm/bridge/sii902x.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index 7f91b0db161e..9be9cc5b9025 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -180,6 +180,8 @@ struct sii902x { struct gpio_desc *reset_gpio; struct i2c_mux_core *i2cmux; bool sink_is_hdmi; + u32 bus_width; + /* * Mutex protects audio and video functions from interfering * each other, by keeping their i2c command sequences atomic. @@ -477,6 +479,8 @@ static u32 *sii902x_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, u32 output_fmt, unsigned int *num_input_fmts) { + + struct sii902x *sii902x = bridge_to_sii902x(bridge); u32 *input_fmts; *num_input_fmts = 0; @@ -485,7 +489,20 @@ static u32 *sii902x_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, if (!input_fmts) return NULL; - input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; + switch (sii902x->bus_width) { + case 16: + input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16; + break; + case 18: + input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18; + break; + case 24: + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; + break; + default: + return NULL; + } + *num_input_fmts = 1; return input_fmts; @@ -1167,6 +1184,11 @@ static int sii902x_probe(struct i2c_client *client) return PTR_ERR(sii902x->reset_gpio); } + sii902x->bus_width = 24; + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); + if (endpoint) + of_property_read_u32(endpoint, "bus-width", &sii902x->bus_width); + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1); if (endpoint) { struct device_node *remote = of_graph_get_remote_port_parent(endpoint); -- GitLab From 3ccddc3991beef2705e8097b01ae07054bf11022 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Mon, 21 Oct 2024 16:37:46 +0300 Subject: [PATCH 925/970] drm/fbdev: fix drm_fb_helper_deferred_io() build failure The drm_fb_helper_deferred_io() uses struct fb_deferred_io_pageref, which isn't available without CONFIG_FB_DEFERRED_IO. Put the function under corresponding #ifdef to fix build failure if deferred I/O isn't enabled. Fixes: 8058944f5226 ("drm/fbdev: Select fbdev I/O helpers from modules that require them") Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20241021-fix-drm-deferred-v2-1-db1de4c6b042@linaro.org --- drivers/gpu/drm/drm_fb_helper.c | 2 ++ include/drm/drm_fb_helper.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d5e8994345bb..c9008113111b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -697,6 +697,7 @@ void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u3 } EXPORT_SYMBOL(drm_fb_helper_damage_area); +#ifdef CONFIG_FB_DEFERRED_IO /** * drm_fb_helper_deferred_io() - fbdev deferred_io callback function * @info: fb_info struct pointer @@ -740,6 +741,7 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli } } EXPORT_SYMBOL(drm_fb_helper_deferred_io); +#endif /** * drm_fb_helper_set_suspend - wrapper around fb_set_suspend diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 699f2790b9ac..8426b9921a03 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -256,7 +256,9 @@ void drm_fb_helper_fill_info(struct fb_info *info, void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len); void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height); +#ifdef CONFIG_FB_DEFERRED_IO void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist); +#endif void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend); void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, @@ -361,10 +363,12 @@ static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, return 0; } +#ifdef CONFIG_FB_DEFERRED_IO static inline void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagelist) { } +#endif static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) -- GitLab From ef214002e6b38c428cb2b973951c254ba3260de6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Tue, 15 Oct 2024 07:29:57 +0000 Subject: [PATCH 926/970] drm/imx: parallel-display: add legacy bridge Kconfig dependency The driver now uses the legacy bridge helper code but can be configured to get built without it: ERROR: modpost: "devm_imx_drm_legacy_bridge" [drivers/gpu/drm/imx/ipuv3/parallel-display.ko] undefined! Add the required dependency, same as in the ldb driver. Fixes: f94b9707a1c9 ("drm/imx: parallel-display: switch to imx_legacy_bridge / drm_bridge_connector") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Robert Foss <rfoss@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241015073004.4066457-1-arnd@kernel.org --- drivers/gpu/drm/imx/ipuv3/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/imx/ipuv3/Kconfig b/drivers/gpu/drm/imx/ipuv3/Kconfig index 0ea1feb84672..acaf25089001 100644 --- a/drivers/gpu/drm/imx/ipuv3/Kconfig +++ b/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -15,6 +15,7 @@ config DRM_IMX_PARALLEL_DISPLAY depends on DRM_IMX select DRM_BRIDGE select DRM_BRIDGE_CONNECTOR + select DRM_IMX_LEGACY_BRIDGE select DRM_PANEL_BRIDGE select VIDEOMODE_HELPERS -- GitLab From df606be44c168417604a708e3d895f94b262d407 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann <arnd@arndb.de> Date: Tue, 15 Oct 2024 07:29:58 +0000 Subject: [PATCH 927/970] drm/imx: legacy-bridge: add MODULE_DESCRIPTION Every module should have a description, without this we get a build time warning. Fixes: cc3e8a216d6b ("drm/imx: add internal bridge handling display-timings DT node") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Robert Foss <rfoss@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241015073004.4066457-2-arnd@kernel.org --- drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c b/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c index 07a78a02a884..3ebf0b9866de 100644 --- a/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c +++ b/drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c @@ -85,3 +85,4 @@ struct drm_bridge *devm_imx_drm_legacy_bridge(struct device *dev, EXPORT_SYMBOL_GPL(devm_imx_drm_legacy_bridge); MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Freescale i.MX DRM bridge driver for legacy DT bindings"); -- GitLab From 2320c9e6a768d135c7b0039995182bb1a4e4fd22 Mon Sep 17 00:00:00 2001 From: Philipp Stanner <pstanner@redhat.com> Date: Mon, 21 Oct 2024 12:50:28 +0200 Subject: [PATCH 928/970] drm/sched: memset() 'job' in drm_sched_job_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_sched_job_init() has no control over how users allocate struct drm_sched_job. Unfortunately, the function can also not set some struct members such as job->sched. This could theoretically lead to UB by users dereferencing the struct's pointer members too early. It is easier to debug such issues if these pointers are initialized to NULL, so dereferencing them causes a NULL pointer exception. Accordingly, drm_sched_entity_init() does precisely that and initializes its struct with memset(). Initialize parameter "job" to 0 in drm_sched_job_init(). Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241021105028.19794-2-pstanner@redhat.com Reviewed-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/scheduler/sched_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index dab8cca79eb7..2e0e5a9577d1 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -796,6 +796,14 @@ int drm_sched_job_init(struct drm_sched_job *job, return -EINVAL; } + /* + * We don't know for sure how the user has allocated. Thus, zero the + * struct so that unallowed (i.e., too early) usage of pointers that + * this function does not set is guaranteed to lead to a NULL pointer + * exception instead of UB. + */ + memset(job, 0, sizeof(*job)); + job->entity = entity; job->credits = credits; job->s_fence = drm_sched_fence_alloc(entity, owner); -- GitLab From 91e21479c81dd4e9e22a78d7446f92f6b96a7284 Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski <dsankouski@gmail.com> Date: Mon, 21 Oct 2024 16:52:36 +0300 Subject: [PATCH 929/970] drm/panel: s6e3ha8: add static modifier to supply list Add 'static' modifier to panel supply list. Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202410160810.0jaNgxB2-lkp@intel.com/ Fixes: 779679d3c164 ("drm/panel: Add support for S6E3HA8 panel driver") Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20241021-starqltechn_upstream_integration_panel_fix-v1-1-81776e89052a@gmail.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241021-starqltechn_upstream_integration_panel_fix-v1-1-81776e89052a@gmail.com --- drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c index 76b5a6ea610d..64c6f7d45bed 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha8.c @@ -24,7 +24,7 @@ struct s6e3ha8 { struct regulator_bulk_data *supplies; }; -const struct regulator_bulk_data s6e3ha8_supplies[] = { +static const struct regulator_bulk_data s6e3ha8_supplies[] = { { .supply = "vdd3" }, { .supply = "vci" }, { .supply = "vddr" }, -- GitLab From 3ced1c68751299c0cdf6a1ceeafdbe77db7d4956 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 19 Oct 2024 00:49:12 +0300 Subject: [PATCH 930/970] drm/display: bridge_connector: handle ycbcr_420_allowed Follow the interlace_allowed example and calculate drm_connector's ycbcr_420_allowed flag as AND of all drm_bridge's ycbcr_420_allowed flags in a chain. This is one of the gaps between several bridge-specific connector implementations and drm_bridge_connector. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241019-bridge-yuv420-v1-1-d74efac9e4e6@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/display/drm_bridge_connector.c | 6 ++++-- include/drm/drm_bridge.h | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 3da5b8bf8259..320c297008aa 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -397,11 +397,11 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, bridge_connector->encoder = encoder; /* - * TODO: Handle doublescan_allowed, stereo_allowed and - * ycbcr_420_allowed. + * TODO: Handle doublescan_allowed and stereo_allowed. */ connector = &bridge_connector->base; connector->interlace_allowed = true; + connector->ycbcr_420_allowed = true; /* * Initialise connector status handling. First locate the furthest @@ -414,6 +414,8 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, drm_for_each_bridge_in_chain(encoder, bridge) { if (!bridge->interlace_allowed) connector->interlace_allowed = false; + if (!bridge->ycbcr_420_allowed) + connector->ycbcr_420_allowed = false; if (bridge->ops & DRM_BRIDGE_OP_EDID) bridge_connector->bridge_edid = bridge; diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 75019d16be64..e8d735b7f6a4 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -802,6 +802,11 @@ struct drm_bridge { * modes. */ bool interlace_allowed; + /** + * @ycbcr_420_allowed: Indicate that the bridge can handle YCbCr 420 + * output. + */ + bool ycbcr_420_allowed; /** * @pre_enable_prev_first: The bridge requires that the prev * bridge @pre_enable function is called before its @pre_enable, -- GitLab From 58e6d652d138ef163d0b6b4d19f0fc9d4e8519fa Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 19 Oct 2024 00:49:13 +0300 Subject: [PATCH 931/970] drm/atomic: add interlaced and ycbcr_420 flags to connector's state dump Although the interlace_allowed and ycbcr_420_allowed flags are a part of the struct drm_connector rather than struct drm_connector_state, still include them into state dump in order to ease debugging of the setup issues. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241019-bridge-yuv420-v1-2-d74efac9e4e6@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/drm_atomic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 0fc99da93afe..9ea2611770f4 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1132,6 +1132,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name); drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)"); drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware); + drm_printf(p, "\tinterlace_allowed=%d\n", connector->interlace_allowed); + drm_printf(p, "\tycbcr_420_allowed=%d\n", connector->ycbcr_420_allowed); drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace)); -- GitLab From d5cd8280c52bad44d5943fa7501bf9f20718d432 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 19 Oct 2024 00:49:14 +0300 Subject: [PATCH 932/970] drm/bridge: display-connector: allow YCbCr 420 for HDMI and DP Allow YCbCr 420 output for HDMI and DisplayPort connectors. Other bridges in the chain still might limit YCbCr 420 support on the corresponding connector. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241019-bridge-yuv420-v1-3-d74efac9e4e6@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/display-connector.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c index ab8e00baf3f1..aab9ce7be94c 100644 --- a/drivers/gpu/drm/bridge/display-connector.c +++ b/drivers/gpu/drm/bridge/display-connector.c @@ -270,6 +270,10 @@ static int display_connector_probe(struct platform_device *pdev) /* All the supported connector types support interlaced modes. */ conn->bridge.interlace_allowed = true; + if (type == DRM_MODE_CONNECTOR_HDMIA || + type == DRM_MODE_CONNECTOR_DisplayPort) + conn->bridge.ycbcr_420_allowed = true; + /* Get the optional connector label. */ of_property_read_string(pdev->dev.of_node, "label", &label); -- GitLab From c44a0faf5397134b3100c00cc8a8d72528bc422a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 19 Oct 2024 00:49:15 +0300 Subject: [PATCH 933/970] drm/bridge: aux: allow interlaced and YCbCr 420 output As both aux bridges are merely passthrough bridges, mark them as supporting interlaced and YCbCr 420 data. Other bridges in the chain still might limit interlaced and YCbCr 420 data support on the corresponding connector. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241019-bridge-yuv420-v1-4-d74efac9e4e6@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/aux-bridge.c | 4 ++++ drivers/gpu/drm/bridge/aux-hpd-bridge.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c index b29980f95379..e3e95ccec1ae 100644 --- a/drivers/gpu/drm/bridge/aux-bridge.c +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -120,6 +120,10 @@ static int drm_aux_bridge_probe(struct auxiliary_device *auxdev, data->bridge.funcs = &drm_aux_bridge_funcs; data->bridge.of_node = data->dev->of_node; + /* passthrough data, allow everything */ + data->bridge.interlace_allowed = true; + data->bridge.ycbcr_420_allowed = true; + return devm_drm_bridge_add(data->dev, &data->bridge); } diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c index 6886db2d9e00..48f297c78ee6 100644 --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c @@ -180,6 +180,10 @@ static int drm_aux_hpd_bridge_probe(struct auxiliary_device *auxdev, data->bridge.ops = DRM_BRIDGE_OP_HPD; data->bridge.type = id->driver_data; + /* passthrough data, allow everything */ + data->bridge.interlace_allowed = true; + data->bridge.ycbcr_420_allowed = true; + auxiliary_set_drvdata(auxdev, data); return devm_drm_bridge_add(data->dev, &data->bridge); -- GitLab From 785324db2d7a44e866161b6309fbda9a2178d455 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 19 Oct 2024 00:49:16 +0300 Subject: [PATCH 934/970] drm/msm/dp: migrate the ycbcr_420_allowed to drm_bridge Instead of forcing the ycbcr_420_allowed flag to be set on the created drm_connector, set it on the drm_bridge instance and allow drm_bridge_connecgtor to propagate it to the drm_connector. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Acked-by: Abhinav Kumar <quic_abhinavk@quicinc.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241019-bridge-yuv420-v1-5-d74efac9e4e6@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/msm/dp/dp_display.c | 4 ++-- drivers/gpu/drm/msm/dp/dp_drm.c | 10 ++++------ drivers/gpu/drm/msm/dp/dp_drm.h | 7 ++++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index e1228fb093ee..0ddd8abca499 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1467,14 +1467,14 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, dp_priv = container_of(dp_display, struct dp_display_private, dp_display); - ret = dp_bridge_init(dp_display, dev, encoder); + ret = dp_bridge_init(dp_display, dev, encoder, yuv_supported); if (ret) { DRM_DEV_ERROR(dev->dev, "failed to create dp bridge: %d\n", ret); return ret; } - dp_display->connector = dp_drm_connector_init(dp_display, encoder, yuv_supported); + dp_display->connector = dp_drm_connector_init(dp_display, encoder); if (IS_ERR(dp_display->connector)) { ret = PTR_ERR(dp_display->connector); DRM_DEV_ERROR(dev->dev, diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 1b9be5bd97f1..7eb1621f9e7f 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -289,7 +289,7 @@ static const struct drm_bridge_funcs edp_bridge_ops = { }; int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, - struct drm_encoder *encoder) + struct drm_encoder *encoder, bool yuv_supported) { int rc; struct msm_dp_bridge *dp_bridge; @@ -304,6 +304,7 @@ int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, bridge = &dp_bridge->bridge; bridge->funcs = dp_display->is_edp ? &edp_bridge_ops : &dp_bridge_ops; bridge->type = dp_display->connector_type; + bridge->ycbcr_420_allowed = yuv_supported; /* * Many ops only make sense for DP. Why? @@ -351,8 +352,8 @@ int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, } /* connector initialization */ -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder, - bool yuv_supported) +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, + struct drm_encoder *encoder) { struct drm_connector *connector = NULL; @@ -363,9 +364,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct dr if (!dp_display->is_edp) drm_connector_attach_dp_subconnector_property(connector); - if (yuv_supported) - connector->ycbcr_420_allowed = true; - drm_connector_attach_encoder(connector, encoder); return connector; diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h index 45e57ac25a4d..ae632fcc407c 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.h +++ b/drivers/gpu/drm/msm/dp/dp_drm.h @@ -19,10 +19,11 @@ struct msm_dp_bridge { #define to_dp_bridge(x) container_of((x), struct msm_dp_bridge, bridge) -struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder, - bool yuv_supported); +struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, + struct drm_encoder *encoder); int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, - struct drm_encoder *encoder); + struct drm_encoder *encoder, + bool yuv_supported); void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, struct drm_bridge_state *old_bridge_state); -- GitLab From 8a8fed657d0427f6765a48c93152a8d86cfe613c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Date: Sat, 19 Oct 2024 00:49:17 +0300 Subject: [PATCH 935/970] drm/bridge: dw-hdmi: set bridge's ycbcr_420_allowed flag Set the drm_bridge's ycbcr_420_allowed flag if the YCbCr 420 output is supported by the hardware. Cc: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241019-bridge-yuv420-v1-6-d74efac9e4e6@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 0031f3c54882..996733ed2c00 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -3503,6 +3503,9 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, hdmi->bridge.of_node = pdev->dev.of_node; hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; + if (hdmi->version >= 0x200a) + hdmi->bridge.ycbcr_420_allowed = plat_data->ycbcr_420_allowed; + memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.parent = dev; pdevinfo.id = PLATFORM_DEVID_AUTO; -- GitLab From f2cab5a0e8c3a4a49dc5b0f7088bcc12d65e71e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 3 Oct 2024 14:18:47 +0300 Subject: [PATCH 936/970] drm/imx/dcss: Fix 64bit divisions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the appropriate 64bit division helpers to make the code build on 32bit architectures. Cc: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> Cc: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003111851.10453-7-ville.syrjala@linux.intel.com Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> --- drivers/gpu/drm/imx/dcss/dcss-scaler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-scaler.c b/drivers/gpu/drm/imx/dcss/dcss-scaler.c index 825728c356ff..32c3f46b21da 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-scaler.c +++ b/drivers/gpu/drm/imx/dcss/dcss-scaler.c @@ -136,7 +136,7 @@ static int div_q(int A, int B) else temp -= B / 2; - result = (int)(temp / B); + result = div_s64(temp, B); return result; } @@ -239,7 +239,7 @@ static void dcss_scaler_gaussian_filter(int fc_q, bool use_5_taps, ll_temp = coef[phase][i]; ll_temp <<= PSC_COEFF_PRECISION; ll_temp += sum >> 1; - ll_temp /= sum; + ll_temp = div_s64(ll_temp, sum); coef[phase][i] = (int)ll_temp; } } -- GitLab From 004555a18d57fbad42553c2e98e00a054bbe618c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 3 Oct 2024 14:18:48 +0300 Subject: [PATCH 937/970] drm/imx/dcss: Allow build with COMPILE_TEST=y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow imx/dcss to be built with COMPILE_TEST=y for greater coverage. Builds fine on x86/x86_64 at least. Cc: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> Cc: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003111851.10453-8-ville.syrjala@linux.intel.com Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> --- drivers/gpu/drm/imx/dcss/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/dcss/Kconfig b/drivers/gpu/drm/imx/dcss/Kconfig index 9d58f41bd00c..e014ed3ae66c 100644 --- a/drivers/gpu/drm/imx/dcss/Kconfig +++ b/drivers/gpu/drm/imx/dcss/Kconfig @@ -7,7 +7,7 @@ config DRM_IMX_DCSS select DRM_BRIDGE_CONNECTOR select DRM_GEM_DMA_HELPER select VIDEOMODE_HELPERS - depends on DRM && ARCH_MXC && ARM64 + depends on DRM && ((ARCH_MXC && ARM64) || COMPILE_TEST) help Choose this if you have a NXP i.MX8MQ based system and want to use the Display Controller Subsystem. This option enables DCSS support. -- GitLab From d2db0b8fd70bb216eb96ad1a32c158889e247c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 3 Oct 2024 14:18:50 +0300 Subject: [PATCH 938/970] drm/mediatek: Allow build with COMPILE_TEST=y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow mediatek to be built with COMPILE_TEST=y for greater coverage. Builds fine on x86/x86_64 at least. Cc: Chun-Kuang Hu <chunkuang.hu@kernel.org> Cc: Philipp Zabel <p.zabel@pengutronix.de> Cc: linux-mediatek@lists.infradead.org Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003111851.10453-10-ville.syrjala@linux.intel.com Reviewed-by: CK Hu <ck.hu@mediatek.com> --- drivers/gpu/drm/mediatek/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig index 3d2436272ff2..2e0e7c4079b6 100644 --- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig @@ -2,9 +2,9 @@ config DRM_MEDIATEK tristate "DRM Support for Mediatek SoCs" depends on DRM - depends on ARCH_MEDIATEK || (ARM && COMPILE_TEST) + depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST depends on COMMON_CLK - depends on HAVE_ARM_SMCCC + depends on HAVE_ARM_SMCCC || COMPILE_TEST depends on OF depends on MTK_MMSYS select DRM_CLIENT_SELECTION -- GitLab From d4e4e498bec6c16d303ff55c0211d5c11e81e379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> Date: Thu, 3 Oct 2024 14:18:51 +0300 Subject: [PATCH 939/970] drm/meson: Allow build with COMPILE_TEST=y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow meson to be built with COMPILE_TEST=y for greater coverage. Builds fine on x86/x86_64 at least. Cc: Neil Armstrong <neil.armstrong@linaro.org> Cc: linux-amlogic@lists.infradead.org Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241003111851.10453-11-ville.syrjala@linux.intel.com Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> --- drivers/gpu/drm/meson/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index b410e0d8015a..417f79829cf8 100644 --- a/drivers/gpu/drm/meson/Kconfig +++ b/drivers/gpu/drm/meson/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config DRM_MESON tristate "DRM Support for Amlogic Meson Display Controller" - depends on DRM && OF && (ARM || ARM64) + depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST) depends on ARCH_MESON || COMPILE_TEST select DRM_CLIENT_SELECTION select DRM_KMS_HELPER -- GitLab From 581d1f8248550f2b67847e6d84f29fbe3751ea0a Mon Sep 17 00:00:00 2001 From: Steven Price <steven.price@arm.com> Date: Fri, 25 Oct 2024 15:00:07 +0100 Subject: [PATCH 940/970] drm/panfrost: Remove unused id_mask from struct panfrost_model The id_mask field of struct panfrost_model has never been used. Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") Signed-off-by: Steven Price <steven.price@arm.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241025140008.385081-1-steven.price@arm.com --- drivers/gpu/drm/panfrost/panfrost_gpu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c index f19f918e2330..f5abde3866fb 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -177,7 +177,6 @@ static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev) struct panfrost_model { const char *name; u32 id; - u32 id_mask; u64 features; u64 issues; struct { -- GitLab From 3ae80b375739495e36fc6143ff27716fe390a13e Mon Sep 17 00:00:00 2001 From: Philipp Stanner <pstanner@redhat.com> Date: Wed, 23 Oct 2024 16:15:31 +0200 Subject: [PATCH 941/970] drm/sched: warn about drm_sched_job_init()'s partial init drm_sched_job_init()'s name suggests that after the function succeeded, parameter "job" will be fully initialized. This is not the case; some members are only later set, notably drm_sched_job.sched by drm_sched_job_arm(). Document that drm_sched_job_init() does not set all struct members. Document the lifetime of drm_sched_job.sched. Reviewed-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Philipp Stanner <pstanner@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241023141530.113370-2-pstanner@redhat.com --- drivers/gpu/drm/scheduler/sched_main.c | 4 ++++ include/drm/gpu_scheduler.h | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 2e0e5a9577d1..2f1b514ff4cf 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -771,6 +771,10 @@ EXPORT_SYMBOL(drm_sched_resubmit_jobs); * Drivers must make sure drm_sched_job_cleanup() if this function returns * successfully, even when @job is aborted before drm_sched_job_arm() is called. * + * Note that this function does not assign a valid value to each struct member + * of struct drm_sched_job. Take a look at that struct's documentation to see + * who sets which struct member with what lifetime. + * * WARNING: amdgpu abuses &drm_sched.ready to signal when the hardware * has died, which can mean that there's no valid runqueue for a @entity. * This function returns -ENOENT in this case (which probably should be -EIO as diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index ab161289d1bf..95e17504e46a 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -340,6 +340,14 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); struct drm_sched_job { struct spsc_node queue_node; struct list_head list; + + /** + * @sched: + * + * The scheduler this job is or will be scheduled on. Gets set by + * drm_sched_job_arm(). Valid until drm_sched_backend_ops.free_job() + * has finished. + */ struct drm_gpu_scheduler *sched; struct drm_sched_fence *s_fence; -- GitLab From 93accc16a8d45a44e1f51fdf2c6014feedb13d27 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo <quic_jhugo@quicinc.com> Date: Mon, 21 Oct 2024 14:03:55 -0600 Subject: [PATCH 942/970] accel/qaic: Add crashdump to Sahara The Sahara protocol has a crashdump functionality. In the hello exchange, the device can advertise it has a memory dump available for the host to collect. Instead of the device making requests of the host, the host requests data from the device which can be later analyzed. Implement this functionality and utilize the devcoredump framework for handing the dump over to userspace. Similar to how firmware loading in Sahara involves multiple files, crashdump can consist of multiple files for different parts of the dump. Structure these into a single buffer that userspace can parse and extract the original files from. Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com> Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Reviewed-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241021200355.544126-1-quic_jhugo@quicinc.com --- drivers/accel/qaic/sahara.c | 388 +++++++++++++++++++++++++++++++++++- 1 file changed, 381 insertions(+), 7 deletions(-) diff --git a/drivers/accel/qaic/sahara.c b/drivers/accel/qaic/sahara.c index bf94bbab6be5..6d772143d612 100644 --- a/drivers/accel/qaic/sahara.c +++ b/drivers/accel/qaic/sahara.c @@ -2,6 +2,7 @@ /* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ +#include <linux/devcoredump.h> #include <linux/firmware.h> #include <linux/limits.h> #include <linux/mhi.h> @@ -9,6 +10,7 @@ #include <linux/mod_devicetable.h> #include <linux/overflow.h> #include <linux/types.h> +#include <linux/vmalloc.h> #include <linux/workqueue.h> #include "sahara.h" @@ -36,12 +38,14 @@ #define SAHARA_PACKET_MAX_SIZE 0xffffU /* MHI_MAX_MTU */ #define SAHARA_TRANSFER_MAX_SIZE 0x80000 +#define SAHARA_READ_MAX_SIZE 0xfff0U /* Avoid unaligned requests */ #define SAHARA_NUM_TX_BUF DIV_ROUND_UP(SAHARA_TRANSFER_MAX_SIZE,\ SAHARA_PACKET_MAX_SIZE) #define SAHARA_IMAGE_ID_NONE U32_MAX #define SAHARA_VERSION 2 #define SAHARA_SUCCESS 0 +#define SAHARA_TABLE_ENTRY_STR_LEN 20 #define SAHARA_MODE_IMAGE_TX_PENDING 0x0 #define SAHARA_MODE_IMAGE_TX_COMPLETE 0x1 @@ -53,6 +57,8 @@ #define SAHARA_END_OF_IMAGE_LENGTH 0x10 #define SAHARA_DONE_LENGTH 0x8 #define SAHARA_RESET_LENGTH 0x8 +#define SAHARA_MEM_DEBUG64_LENGTH 0x18 +#define SAHARA_MEM_READ64_LENGTH 0x18 struct sahara_packet { __le32 cmd; @@ -80,18 +86,95 @@ struct sahara_packet { __le32 image; __le32 status; } end_of_image; + struct { + __le64 table_address; + __le64 table_length; + } memory_debug64; + struct { + __le64 memory_address; + __le64 memory_length; + } memory_read64; }; }; +struct sahara_debug_table_entry64 { + __le64 type; + __le64 address; + __le64 length; + char description[SAHARA_TABLE_ENTRY_STR_LEN]; + char filename[SAHARA_TABLE_ENTRY_STR_LEN]; +}; + +struct sahara_dump_table_entry { + u64 type; + u64 address; + u64 length; + char description[SAHARA_TABLE_ENTRY_STR_LEN]; + char filename[SAHARA_TABLE_ENTRY_STR_LEN]; +}; + +#define SAHARA_DUMP_V1_MAGIC 0x1234567890abcdef +#define SAHARA_DUMP_V1_VER 1 +struct sahara_memory_dump_meta_v1 { + u64 magic; + u64 version; + u64 dump_size; + u64 table_size; +}; + +/* + * Layout of crashdump provided to user via devcoredump + * +------------------------------------------+ + * | Crashdump Meta structure | + * | type: struct sahara_memory_dump_meta_v1 | + * +------------------------------------------+ + * | Crashdump Table | + * | type: array of struct | + * | sahara_dump_table_entry | + * | | + * | | + * +------------------------------------------+ + * | Crashdump | + * | | + * | | + * | | + * | | + * | | + * +------------------------------------------+ + * + * First is the metadata header. Userspace can use the magic number to verify + * the content type, and then check the version for the rest of the format. + * New versions should keep the magic number location/value, and version + * location, but increment the version value. + * + * For v1, the metadata lists the size of the entire dump (header + table + + * dump) and the size of the table. Then the dump image table, which describes + * the contents of the dump. Finally all the images are listed in order, with + * no deadspace in between. Userspace can use the sizes listed in the image + * table to reconstruct the individual images. + */ + struct sahara_context { struct sahara_packet *tx[SAHARA_NUM_TX_BUF]; struct sahara_packet *rx; - struct work_struct work; + struct work_struct fw_work; + struct work_struct dump_work; struct mhi_device *mhi_dev; const char **image_table; u32 table_size; u32 active_image_id; const struct firmware *firmware; + u64 dump_table_address; + u64 dump_table_length; + size_t rx_size; + size_t rx_size_requested; + void *mem_dump; + size_t mem_dump_sz; + struct sahara_dump_table_entry *dump_image; + u64 dump_image_offset; + void *mem_dump_freespace; + u64 dump_images_left; + bool is_mem_dump_mode; }; static const char *aic100_image_table[] = { @@ -153,6 +236,8 @@ static void sahara_send_reset(struct sahara_context *context) { int ret; + context->is_mem_dump_mode = false; + context->tx[0]->cmd = cpu_to_le32(SAHARA_RESET_CMD); context->tx[0]->length = cpu_to_le32(SAHARA_RESET_LENGTH); @@ -186,7 +271,8 @@ static void sahara_hello(struct sahara_context *context) } if (le32_to_cpu(context->rx->hello.mode) != SAHARA_MODE_IMAGE_TX_PENDING && - le32_to_cpu(context->rx->hello.mode) != SAHARA_MODE_IMAGE_TX_COMPLETE) { + le32_to_cpu(context->rx->hello.mode) != SAHARA_MODE_IMAGE_TX_COMPLETE && + le32_to_cpu(context->rx->hello.mode) != SAHARA_MODE_MEMORY_DEBUG) { dev_err(&context->mhi_dev->dev, "Unsupported hello packet - mode %d\n", le32_to_cpu(context->rx->hello.mode)); return; @@ -320,9 +406,70 @@ static void sahara_end_of_image(struct sahara_context *context) dev_dbg(&context->mhi_dev->dev, "Unable to send done response %d\n", ret); } +static void sahara_memory_debug64(struct sahara_context *context) +{ + int ret; + + dev_dbg(&context->mhi_dev->dev, + "MEMORY DEBUG64 cmd received. length:%d table_address:%#llx table_length:%#llx\n", + le32_to_cpu(context->rx->length), + le64_to_cpu(context->rx->memory_debug64.table_address), + le64_to_cpu(context->rx->memory_debug64.table_length)); + + if (le32_to_cpu(context->rx->length) != SAHARA_MEM_DEBUG64_LENGTH) { + dev_err(&context->mhi_dev->dev, "Malformed memory debug64 packet - length %d\n", + le32_to_cpu(context->rx->length)); + return; + } + + context->dump_table_address = le64_to_cpu(context->rx->memory_debug64.table_address); + context->dump_table_length = le64_to_cpu(context->rx->memory_debug64.table_length); + + if (context->dump_table_length % sizeof(struct sahara_debug_table_entry64) != 0 || + !context->dump_table_length) { + dev_err(&context->mhi_dev->dev, "Malformed memory debug64 packet - table length %lld\n", + context->dump_table_length); + return; + } + + /* + * From this point, the protocol flips. We make memory_read requests to + * the device, and the device responds with the raw data. If the device + * has an error, it will send an End of Image command. First we need to + * request the memory dump table so that we know where all the pieces + * of the dump are that we can consume. + */ + + context->is_mem_dump_mode = true; + + /* + * Assume that the table is smaller than our MTU so that we can read it + * in one shot. The spec does not put an upper limit on the table, but + * no known device will exceed this. + */ + if (context->dump_table_length > SAHARA_PACKET_MAX_SIZE) { + dev_err(&context->mhi_dev->dev, "Memory dump table length %lld exceeds supported size. Discarding dump\n", + context->dump_table_length); + sahara_send_reset(context); + return; + } + + context->tx[0]->cmd = cpu_to_le32(SAHARA_MEM_READ64_CMD); + context->tx[0]->length = cpu_to_le32(SAHARA_MEM_READ64_LENGTH); + context->tx[0]->memory_read64.memory_address = cpu_to_le64(context->dump_table_address); + context->tx[0]->memory_read64.memory_length = cpu_to_le64(context->dump_table_length); + + context->rx_size_requested = context->dump_table_length; + + ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0], + SAHARA_MEM_READ64_LENGTH, MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, "Unable to send read for dump table %d\n", ret); +} + static void sahara_processing(struct work_struct *work) { - struct sahara_context *context = container_of(work, struct sahara_context, work); + struct sahara_context *context = container_of(work, struct sahara_context, fw_work); int ret; switch (le32_to_cpu(context->rx->cmd)) { @@ -338,6 +485,12 @@ static void sahara_processing(struct work_struct *work) case SAHARA_DONE_RESP_CMD: /* Intentional do nothing as we don't need to exit an app */ break; + case SAHARA_RESET_RESP_CMD: + /* Intentional do nothing as we don't need to exit an app */ + break; + case SAHARA_MEM_DEBUG64_CMD: + sahara_memory_debug64(context); + break; default: dev_err(&context->mhi_dev->dev, "Unknown command %d\n", le32_to_cpu(context->rx->cmd)); @@ -350,6 +503,217 @@ static void sahara_processing(struct work_struct *work) dev_err(&context->mhi_dev->dev, "Unable to requeue rx buf %d\n", ret); } +static void sahara_parse_dump_table(struct sahara_context *context) +{ + struct sahara_dump_table_entry *image_out_table; + struct sahara_debug_table_entry64 *dev_table; + struct sahara_memory_dump_meta_v1 *dump_meta; + u64 table_nents; + u64 dump_length; + int ret; + u64 i; + + table_nents = context->dump_table_length / sizeof(*dev_table); + context->dump_images_left = table_nents; + dump_length = 0; + + dev_table = (struct sahara_debug_table_entry64 *)(context->rx); + for (i = 0; i < table_nents; ++i) { + /* Do not trust the device, ensure the strings are terminated */ + dev_table[i].description[SAHARA_TABLE_ENTRY_STR_LEN - 1] = 0; + dev_table[i].filename[SAHARA_TABLE_ENTRY_STR_LEN - 1] = 0; + + dump_length = size_add(dump_length, le64_to_cpu(dev_table[i].length)); + if (dump_length == SIZE_MAX) { + /* Discard the dump */ + sahara_send_reset(context); + return; + } + + dev_dbg(&context->mhi_dev->dev, + "Memory dump table entry %lld type: %lld address: %#llx length: %#llx description: \"%s\" filename \"%s\"\n", + i, + le64_to_cpu(dev_table[i].type), + le64_to_cpu(dev_table[i].address), + le64_to_cpu(dev_table[i].length), + dev_table[i].description, + dev_table[i].filename); + } + + dump_length = size_add(dump_length, sizeof(*dump_meta)); + if (dump_length == SIZE_MAX) { + /* Discard the dump */ + sahara_send_reset(context); + return; + } + dump_length = size_add(dump_length, size_mul(sizeof(*image_out_table), table_nents)); + if (dump_length == SIZE_MAX) { + /* Discard the dump */ + sahara_send_reset(context); + return; + } + + context->mem_dump_sz = dump_length; + context->mem_dump = vzalloc(dump_length); + if (!context->mem_dump) { + /* Discard the dump */ + sahara_send_reset(context); + return; + } + + /* Populate the dump metadata and table for userspace */ + dump_meta = context->mem_dump; + dump_meta->magic = SAHARA_DUMP_V1_MAGIC; + dump_meta->version = SAHARA_DUMP_V1_VER; + dump_meta->dump_size = dump_length; + dump_meta->table_size = context->dump_table_length; + + image_out_table = context->mem_dump + sizeof(*dump_meta); + for (i = 0; i < table_nents; ++i) { + image_out_table[i].type = le64_to_cpu(dev_table[i].type); + image_out_table[i].address = le64_to_cpu(dev_table[i].address); + image_out_table[i].length = le64_to_cpu(dev_table[i].length); + strscpy(image_out_table[i].description, dev_table[i].description, + SAHARA_TABLE_ENTRY_STR_LEN); + strscpy(image_out_table[i].filename, + dev_table[i].filename, + SAHARA_TABLE_ENTRY_STR_LEN); + } + + context->mem_dump_freespace = &image_out_table[i]; + + /* Done parsing the table, switch to image dump mode */ + context->dump_table_length = 0; + + /* Request the first chunk of the first image */ + context->dump_image = &image_out_table[0]; + dump_length = min(context->dump_image->length, SAHARA_READ_MAX_SIZE); + /* Avoid requesting EOI sized data so that we can identify errors */ + if (dump_length == SAHARA_END_OF_IMAGE_LENGTH) + dump_length = SAHARA_END_OF_IMAGE_LENGTH / 2; + + context->dump_image_offset = dump_length; + + context->tx[0]->cmd = cpu_to_le32(SAHARA_MEM_READ64_CMD); + context->tx[0]->length = cpu_to_le32(SAHARA_MEM_READ64_LENGTH); + context->tx[0]->memory_read64.memory_address = cpu_to_le64(context->dump_image->address); + context->tx[0]->memory_read64.memory_length = cpu_to_le64(dump_length); + + context->rx_size_requested = dump_length; + + ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0], + SAHARA_MEM_READ64_LENGTH, MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, "Unable to send read for dump content %d\n", ret); +} + +static void sahara_parse_dump_image(struct sahara_context *context) +{ + u64 dump_length; + int ret; + + memcpy(context->mem_dump_freespace, context->rx, context->rx_size); + context->mem_dump_freespace += context->rx_size; + + if (context->dump_image_offset >= context->dump_image->length) { + /* Need to move to next image */ + context->dump_image++; + context->dump_images_left--; + context->dump_image_offset = 0; + + if (!context->dump_images_left) { + /* Dump done */ + dev_coredumpv(context->mhi_dev->mhi_cntrl->cntrl_dev, + context->mem_dump, + context->mem_dump_sz, + GFP_KERNEL); + context->mem_dump = NULL; + sahara_send_reset(context); + return; + } + } + + /* Get next image chunk */ + dump_length = context->dump_image->length - context->dump_image_offset; + dump_length = min(dump_length, SAHARA_READ_MAX_SIZE); + /* Avoid requesting EOI sized data so that we can identify errors */ + if (dump_length == SAHARA_END_OF_IMAGE_LENGTH) + dump_length = SAHARA_END_OF_IMAGE_LENGTH / 2; + + context->tx[0]->cmd = cpu_to_le32(SAHARA_MEM_READ64_CMD); + context->tx[0]->length = cpu_to_le32(SAHARA_MEM_READ64_LENGTH); + context->tx[0]->memory_read64.memory_address = + cpu_to_le64(context->dump_image->address + context->dump_image_offset); + context->tx[0]->memory_read64.memory_length = cpu_to_le64(dump_length); + + context->dump_image_offset += dump_length; + context->rx_size_requested = dump_length; + + ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0], + SAHARA_MEM_READ64_LENGTH, MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, + "Unable to send read for dump content %d\n", ret); +} + +static void sahara_dump_processing(struct work_struct *work) +{ + struct sahara_context *context = container_of(work, struct sahara_context, dump_work); + int ret; + + /* + * We should get the expected raw data, but if the device has an error + * it is supposed to send EOI with an error code. + */ + if (context->rx_size != context->rx_size_requested && + context->rx_size != SAHARA_END_OF_IMAGE_LENGTH) { + dev_err(&context->mhi_dev->dev, + "Unexpected response to read_data. Expected size: %#zx got: %#zx\n", + context->rx_size_requested, + context->rx_size); + goto error; + } + + if (context->rx_size == SAHARA_END_OF_IMAGE_LENGTH && + le32_to_cpu(context->rx->cmd) == SAHARA_END_OF_IMAGE_CMD) { + dev_err(&context->mhi_dev->dev, + "Unexpected EOI response to read_data. Status: %d\n", + le32_to_cpu(context->rx->end_of_image.status)); + goto error; + } + + if (context->rx_size == SAHARA_END_OF_IMAGE_LENGTH && + le32_to_cpu(context->rx->cmd) != SAHARA_END_OF_IMAGE_CMD) { + dev_err(&context->mhi_dev->dev, + "Invalid EOI response to read_data. CMD: %d\n", + le32_to_cpu(context->rx->cmd)); + goto error; + } + + /* + * Need to know if we received the dump table, or part of a dump image. + * Since we get raw data, we cannot tell from the data itself. Instead, + * we use the stored dump_table_length, which we zero after we read and + * process the entire table. + */ + if (context->dump_table_length) + sahara_parse_dump_table(context); + else + sahara_parse_dump_image(context); + + ret = mhi_queue_buf(context->mhi_dev, DMA_FROM_DEVICE, context->rx, + SAHARA_PACKET_MAX_SIZE, MHI_EOT); + if (ret) + dev_err(&context->mhi_dev->dev, "Unable to requeue rx buf %d\n", ret); + + return; + +error: + vfree(context->mem_dump); + context->mem_dump = NULL; + sahara_send_reset(context); +} + static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { struct sahara_context *context; @@ -382,7 +746,8 @@ static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_ } context->mhi_dev = mhi_dev; - INIT_WORK(&context->work, sahara_processing); + INIT_WORK(&context->fw_work, sahara_processing); + INIT_WORK(&context->dump_work, sahara_dump_processing); context->image_table = aic100_image_table; context->table_size = ARRAY_SIZE(aic100_image_table); context->active_image_id = SAHARA_IMAGE_ID_NONE; @@ -405,7 +770,10 @@ static void sahara_mhi_remove(struct mhi_device *mhi_dev) { struct sahara_context *context = dev_get_drvdata(&mhi_dev->dev); - cancel_work_sync(&context->work); + cancel_work_sync(&context->fw_work); + cancel_work_sync(&context->dump_work); + if (context->mem_dump) + vfree(context->mem_dump); sahara_release_image(context); mhi_unprepare_from_transfer(mhi_dev); } @@ -418,8 +786,14 @@ static void sahara_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result { struct sahara_context *context = dev_get_drvdata(&mhi_dev->dev); - if (!mhi_result->transaction_status) - schedule_work(&context->work); + if (!mhi_result->transaction_status) { + context->rx_size = mhi_result->bytes_xferd; + if (context->is_mem_dump_mode) + schedule_work(&context->dump_work); + else + schedule_work(&context->fw_work); + } + } static const struct mhi_device_id sahara_mhi_match_table[] = { -- GitLab From 2eb747a5988e16068471bce8d87fd9843dc5c3b3 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" <linux@treblig.org> Date: Sat, 26 Oct 2024 23:00:10 +0100 Subject: [PATCH 943/970] drm/omap: Clean up deadcode functions dispc_enable_fifomerge() last use was removed by 2012's commit 85099f11bd03 ("Revert "OMAPDSS: APPLY: add fifo merge support funcs"") dispc_has_writeback(), dispc_wb_get_framedone_irq(), dispc_wb_go(), dispc_wb_go_busy() and dispc_wb_setup() were changed from statics to public symbols and unwired from a structure by 2020's commit dac62bcafeaa ("drm/omap: remove dispc_ops") but didn't have any users. dispc_mgr_get_clock_div() got renamed from dispc_get_clock_div() and it's last use was removed in 2011 by commit 42c9dee82129 ("OMAP: DSS2: Remove FB_OMAP_BOOTLOADER_INIT support") Remove them. Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241026220010.93773-1-linux@treblig.org --- drivers/gpu/drm/omapdrm/dss/dispc.c | 146 ---------------------------- drivers/gpu/drm/omapdrm/dss/dss.h | 13 --- 2 files changed, 159 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 993691b3cc7e..9344855c4887 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -691,11 +691,6 @@ u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc, return mgr_desc[channel].sync_lost_irq; } -u32 dispc_wb_get_framedone_irq(struct dispc_device *dispc) -{ - return DISPC_IRQ_FRAMEDONEWB; -} - void dispc_mgr_enable(struct dispc_device *dispc, enum omap_channel channel, bool enable) { @@ -726,30 +721,6 @@ void dispc_mgr_go(struct dispc_device *dispc, enum omap_channel channel) mgr_fld_write(dispc, channel, DISPC_MGR_FLD_GO, 1); } -bool dispc_wb_go_busy(struct dispc_device *dispc) -{ - return REG_GET(dispc, DISPC_CONTROL2, 6, 6) == 1; -} - -void dispc_wb_go(struct dispc_device *dispc) -{ - enum omap_plane_id plane = OMAP_DSS_WB; - bool enable, go; - - enable = REG_GET(dispc, DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1; - - if (!enable) - return; - - go = REG_GET(dispc, DISPC_CONTROL2, 6, 6) == 1; - if (go) { - DSSERR("GO bit not down for WB\n"); - return; - } - - REG_FLD_MOD(dispc, DISPC_CONTROL2, 1, 6, 6); -} - static void dispc_ovl_write_firh_reg(struct dispc_device *dispc, enum omap_plane_id plane, int reg, u32 value) @@ -1498,17 +1469,6 @@ void dispc_ovl_set_fifo_threshold(struct dispc_device *dispc, min(high, 0xfffu)); } -void dispc_enable_fifomerge(struct dispc_device *dispc, bool enable) -{ - if (!dispc_has_feature(dispc, FEAT_FIFO_MERGE)) { - WARN_ON(enable); - return; - } - - DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); - REG_FLD_MOD(dispc, DISPC_CONFIG, enable ? 1 : 0, 14, 14); -} - void dispc_ovl_compute_fifo_thresholds(struct dispc_device *dispc, enum omap_plane_id plane, u32 *fifo_low, u32 *fifo_high, @@ -2814,95 +2774,6 @@ int dispc_ovl_setup(struct dispc_device *dispc, return r; } -int dispc_wb_setup(struct dispc_device *dispc, - const struct omap_dss_writeback_info *wi, - bool mem_to_mem, const struct videomode *vm, - enum dss_writeback_channel channel_in) -{ - int r; - u32 l; - enum omap_plane_id plane = OMAP_DSS_WB; - const int pos_x = 0, pos_y = 0; - const u8 zorder = 0, global_alpha = 0; - const bool replication = true; - bool truncation; - int in_width = vm->hactive; - int in_height = vm->vactive; - enum omap_overlay_caps caps = - OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA; - - if (vm->flags & DISPLAY_FLAGS_INTERLACED) - in_height /= 2; - - DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, " - "rot %d\n", wi->paddr, wi->p_uv_addr, in_width, - in_height, wi->width, wi->height, wi->fourcc, wi->rotation); - - r = dispc_ovl_setup_common(dispc, plane, caps, wi->paddr, wi->p_uv_addr, - wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width, - wi->height, wi->fourcc, wi->rotation, zorder, - wi->pre_mult_alpha, global_alpha, wi->rotation_type, - replication, vm, mem_to_mem, DRM_COLOR_YCBCR_BT601, - DRM_COLOR_YCBCR_LIMITED_RANGE); - if (r) - return r; - - switch (wi->fourcc) { - case DRM_FORMAT_RGB565: - case DRM_FORMAT_RGB888: - case DRM_FORMAT_ARGB4444: - case DRM_FORMAT_RGBA4444: - case DRM_FORMAT_RGBX4444: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XRGB4444: - truncation = true; - break; - default: - truncation = false; - break; - } - - /* setup extra DISPC_WB_ATTRIBUTES */ - l = dispc_read_reg(dispc, DISPC_OVL_ATTRIBUTES(plane)); - l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */ - l = FLD_MOD(l, channel_in, 18, 16); /* CHANNELIN */ - l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */ - if (mem_to_mem) - l = FLD_MOD(l, 1, 26, 24); /* CAPTUREMODE */ - else - l = FLD_MOD(l, 0, 26, 24); /* CAPTUREMODE */ - dispc_write_reg(dispc, DISPC_OVL_ATTRIBUTES(plane), l); - - if (mem_to_mem) { - /* WBDELAYCOUNT */ - REG_FLD_MOD(dispc, DISPC_OVL_ATTRIBUTES2(plane), 0, 7, 0); - } else { - u32 wbdelay; - - if (channel_in == DSS_WB_TV_MGR) - wbdelay = vm->vsync_len + vm->vback_porch; - else - wbdelay = vm->vfront_porch + vm->vsync_len + - vm->vback_porch; - - if (vm->flags & DISPLAY_FLAGS_INTERLACED) - wbdelay /= 2; - - wbdelay = min(wbdelay, 255u); - - /* WBDELAYCOUNT */ - REG_FLD_MOD(dispc, DISPC_OVL_ATTRIBUTES2(plane), wbdelay, 7, 0); - } - - return 0; -} - -bool dispc_has_writeback(struct dispc_device *dispc) -{ - return dispc->feat->has_writeback; -} - int dispc_ovl_enable(struct dispc_device *dispc, enum omap_plane_id plane, bool enable) { @@ -3742,23 +3613,6 @@ void dispc_mgr_set_clock_div(struct dispc_device *dispc, cinfo->pck_div); } -int dispc_mgr_get_clock_div(struct dispc_device *dispc, - enum omap_channel channel, - struct dispc_clock_info *cinfo) -{ - unsigned long fck; - - fck = dispc_fclk_rate(dispc); - - cinfo->lck_div = REG_GET(dispc, DISPC_DIVISORo(channel), 23, 16); - cinfo->pck_div = REG_GET(dispc, DISPC_DIVISORo(channel), 7, 0); - - cinfo->lck = fck / cinfo->lck_div; - cinfo->pck = cinfo->lck / cinfo->pck_div; - - return 0; -} - u32 dispc_read_irqstatus(struct dispc_device *dispc) { return dispc_read_reg(dispc, DISPC_IRQSTATUS); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 4ff02fbc0e71..a8b231ed4f4b 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -416,7 +416,6 @@ u32 dispc_mgr_get_framedone_irq(struct dispc_device *dispc, enum omap_channel channel); u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc, enum omap_channel channel); -u32 dispc_wb_get_framedone_irq(struct dispc_device *dispc); u32 dispc_get_memory_bandwidth_limit(struct dispc_device *dispc); @@ -458,20 +457,11 @@ int dispc_ovl_setup(struct dispc_device *dispc, int dispc_ovl_enable(struct dispc_device *dispc, enum omap_plane_id plane, bool enable); -bool dispc_has_writeback(struct dispc_device *dispc); -int dispc_wb_setup(struct dispc_device *dispc, - const struct omap_dss_writeback_info *wi, - bool mem_to_mem, const struct videomode *vm, - enum dss_writeback_channel channel_in); -bool dispc_wb_go_busy(struct dispc_device *dispc); -void dispc_wb_go(struct dispc_device *dispc); - void dispc_enable_sidle(struct dispc_device *dispc); void dispc_disable_sidle(struct dispc_device *dispc); void dispc_lcd_enable_signal(struct dispc_device *dispc, bool enable); void dispc_pck_free_enable(struct dispc_device *dispc, bool enable); -void dispc_enable_fifomerge(struct dispc_device *dispc, bool enable); typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck, unsigned long pck, void *data); @@ -494,9 +484,6 @@ void dispc_ovl_compute_fifo_thresholds(struct dispc_device *dispc, void dispc_mgr_set_clock_div(struct dispc_device *dispc, enum omap_channel channel, const struct dispc_clock_info *cinfo); -int dispc_mgr_get_clock_div(struct dispc_device *dispc, - enum omap_channel channel, - struct dispc_clock_info *cinfo); void dispc_set_tv_pclk(struct dispc_device *dispc, unsigned long pclk); #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS -- GitLab From b59d1d9d9ab273a8a013ee1d329a74f19110c9ee Mon Sep 17 00:00:00 2001 From: Marek Vasut <marex@denx.de> Date: Sat, 26 Oct 2024 06:10:42 +0200 Subject: [PATCH 944/970] drm/bridge: tc358767: Fix use of unadjusted mode in the driver The driver configures mostly Pixel PLL from the clock cached in local copy of the mode. Make sure the driver uses adjusted mode which contains the updated Pixel PLL settings negotiated in tc_dpi_atomic_check()/tc_edp_atomic_check(). Signed-off-by: Marek Vasut <marex@denx.de> Reviewed-by: Robert Foss <rfoss@kernel.org> Signed-off-by: Robert Foss <rfoss@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20241026041057.247640-1-marex@denx.de --- drivers/gpu/drm/bridge/tc358767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 0c48e747f5b0..d52d55e06be6 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1707,7 +1707,7 @@ static void tc_bridge_mode_set(struct drm_bridge *bridge, { struct tc_data *tc = bridge_to_tc(bridge); - drm_mode_copy(&tc->mode, mode); + drm_mode_copy(&tc->mode, adj); } static const struct drm_edid *tc_edid_read(struct drm_bridge *bridge, -- GitLab From 123aff84f6304a94ac3d6bebb224d4e59da00821 Mon Sep 17 00:00:00 2001 From: Vignesh Raman <vignesh.raman@collabora.com> Date: Tue, 22 Oct 2024 15:15:04 +0530 Subject: [PATCH 945/970] drm/ci: add dedede Add job that executes the IGT test suite for acer-cb317-1h-c3z6-dedede. dedede boards use 64 bit Intel Jasper Lake processors. Signed-off-by: Vignesh Raman <vignesh.raman@collabora.com> Acked-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Helen Koike <helen.koike@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241022094509.85510-2-vignesh.raman@collabora.com --- drivers/gpu/drm/ci/test.yml | 9 ++++ drivers/gpu/drm/ci/xfails/i915-jsl-fails.txt | 51 +++++++++++++++++++ drivers/gpu/drm/ci/xfails/i915-jsl-flakes.txt | 13 +++++ drivers/gpu/drm/ci/xfails/i915-jsl-skips.txt | 20 ++++++++ 4 files changed, 93 insertions(+) create mode 100644 drivers/gpu/drm/ci/xfails/i915-jsl-fails.txt create mode 100644 drivers/gpu/drm/ci/xfails/i915-jsl-flakes.txt create mode 100644 drivers/gpu/drm/ci/xfails/i915-jsl-skips.txt diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml index 09d8447840e9..d0bfe6aab58a 100644 --- a/drivers/gpu/drm/ci/test.yml +++ b/drivers/gpu/drm/ci/test.yml @@ -286,6 +286,15 @@ i915:tgl: GPU_VERSION: tgl RUNNER_TAG: mesa-ci-x86-64-lava-acer-cp514-2h-1130g7-volteer +i915:jsl: + extends: + - .i915 + parallel: 4 + variables: + DEVICE_TYPE: acer-cb317-1h-c3z6-dedede + GPU_VERSION: jsl + RUNNER_TAG: mesa-ci-x86-64-lava-acer-cb317-1h-c3z6-dedede + .amdgpu: extends: - .lava-igt:x86_64 diff --git a/drivers/gpu/drm/ci/xfails/i915-jsl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-jsl-fails.txt new file mode 100644 index 000000000000..ed9f7b576843 --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/i915-jsl-fails.txt @@ -0,0 +1,51 @@ +core_setmaster@master-drop-set-user,Fail +i915_module_load@load,Fail +i915_module_load@reload,Fail +i915_module_load@reload-no-display,Fail +i915_module_load@resize-bar,Fail +i915_pm_rpm@gem-execbuf-stress,Timeout +i915_pm_rpm@module-reload,Fail +kms_flip@plain-flip-fb-recreate,Fail +kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail +kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail +kms_lease@lease-uevent,Fail +kms_pm_rpm@legacy-planes,Timeout +kms_pm_rpm@legacy-planes-dpms,Timeout +kms_pm_rpm@modeset-stress-extra-wait,Timeout +kms_pm_rpm@universal-planes,Timeout +kms_pm_rpm@universal-planes-dpms,Timeout +kms_rotation_crc@multiplane-rotation,Fail +kms_rotation_crc@multiplane-rotation-cropping-bottom,Fail +kms_rotation_crc@multiplane-rotation-cropping-top,Fail +perf@i915-ref-count,Fail +perf_pmu@busy-accuracy-50,Fail +perf_pmu@module-unload,Fail +perf_pmu@most-busy-idle-check-all,Fail +perf_pmu@rc6,Crash +sysfs_heartbeat_interval@long,Timeout +sysfs_heartbeat_interval@off,Timeout +sysfs_preempt_timeout@off,Timeout +sysfs_timeslice_duration@off,Timeout +xe_module_load@force-load,Fail +xe_module_load@load,Fail +xe_module_load@many-reload,Fail +xe_module_load@reload,Fail +xe_module_load@reload-no-display,Fail diff --git a/drivers/gpu/drm/ci/xfails/i915-jsl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-jsl-flakes.txt new file mode 100644 index 000000000000..5c3ef4486b9d --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/i915-jsl-flakes.txt @@ -0,0 +1,13 @@ +# Board Name: acer-cb317-1h-c3z6-dedede +# Bug Report: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12475 +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.12.0-rc1 +kms_flip@flip-vs-panning-interruptible + +# Board Name: acer-cb317-1h-c3z6-dedede +# Bug Report: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12476 +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.12.0-rc1 +kms_universal_plane@cursor-fb-leak diff --git a/drivers/gpu/drm/ci/xfails/i915-jsl-skips.txt b/drivers/gpu/drm/ci/xfails/i915-jsl-skips.txt new file mode 100644 index 000000000000..1a3d87c0ca6e --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/i915-jsl-skips.txt @@ -0,0 +1,20 @@ +# Suspend to RAM seems to be broken on this machine +.*suspend.* + +# Skip driver specific tests +^amdgpu.* +^msm.* +nouveau_.* +^panfrost.* +^v3d.* +^vc4.* +^vmwgfx* + +# GEM tests takes ~1000 hours, so skip it +gem_.* + +# trap_err +i915_pm_rc6_residency.* + +# Hangs the machine and timeout occurs +i915_pm_rpm@system-hibernate* -- GitLab From 973db93de0a007fd1d0d85140c53f70dee6e2c25 Mon Sep 17 00:00:00 2001 From: Vignesh Raman <vignesh.raman@collabora.com> Date: Tue, 22 Oct 2024 15:15:05 +0530 Subject: [PATCH 946/970] drm/ci: add sm8350-hdk Add job that executes the IGT test suite for sm8350-hdk. Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Vignesh Raman <vignesh.raman@collabora.com> Acked-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Helen Koike <helen.koike@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241022094509.85510-3-vignesh.raman@collabora.com --- drivers/gpu/drm/ci/arm64.config | 7 +- drivers/gpu/drm/ci/build.sh | 1 + drivers/gpu/drm/ci/test.yml | 16 ++ .../drm/ci/xfails/msm-sm8350-hdk-fails.txt | 15 ++ .../drm/ci/xfails/msm-sm8350-hdk-flakes.txt | 6 + .../drm/ci/xfails/msm-sm8350-hdk-skips.txt | 211 ++++++++++++++++++ 6 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-fails.txt create mode 100644 drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-flakes.txt create mode 100644 drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-skips.txt diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config index 66e70ced796f..a8fca079921b 100644 --- a/drivers/gpu/drm/ci/arm64.config +++ b/drivers/gpu/drm/ci/arm64.config @@ -90,7 +90,12 @@ CONFIG_QCOM_GPI_DMA=y CONFIG_USB_ONBOARD_DEV=y CONFIG_NVMEM_QCOM_QFPROM=y CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y - +CONFIG_REGULATOR_QCOM_REFGEN=y +CONFIG_TYPEC_MUX_FSA4480=y +CONFIG_QCOM_PMIC_GLINK=y +CONFIG_UCSI_PMIC_GLINK=y +CONFIG_QRTR=y +CONFIG_QRTR_SMD=y # db410c ethernet CONFIG_USB_RTL8152=y diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh index 5a3bdcffae32..139b81db6312 100644 --- a/drivers/gpu/drm/ci/build.sh +++ b/drivers/gpu/drm/ci/build.sh @@ -30,6 +30,7 @@ if [[ "$KERNEL_ARCH" = "arm64" ]]; then DEVICE_TREES+=" arch/arm64/boot/dts/mediatek/mt8192-asurada-spherion-r0.dtb" DEVICE_TREES+=" arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r5.dtb" DEVICE_TREES+=" arch/arm64/boot/dts/qcom/sc7180-trogdor-kingoftown.dtb" + DEVICE_TREES+=" arch/arm64/boot/dts/qcom/sm8350-hdk.dtb" elif [[ "$KERNEL_ARCH" = "arm" ]]; then GCC_ARCH="arm-linux-gnueabihf" DEBIAN_ARCH="armhf" diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml index d0bfe6aab58a..f0ef60c8f56d 100644 --- a/drivers/gpu/drm/ci/test.yml +++ b/drivers/gpu/drm/ci/test.yml @@ -162,6 +162,22 @@ msm:sdm845: script: - ./install/bare-metal/cros-servo.sh +msm:sm8350-hdk: + extends: + - .lava-igt:arm64 + stage: msm + parallel: 4 + variables: + BOOT_METHOD: fastboot + DEVICE_TYPE: sm8350-hdk + DRIVER_NAME: msm + DTB: ${DEVICE_TYPE} + FARM: collabora + GPU_VERSION: ${DEVICE_TYPE} + KERNEL_IMAGE_NAME: "Image.gz" + KERNEL_IMAGE_TYPE: "" + RUNNER_TAG: mesa-ci-x86-64-lava-sm8350-hdk + .rockchip-device: variables: DTB: ${DEVICE_TYPE} diff --git a/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-fails.txt new file mode 100644 index 000000000000..4892c0c70a6d --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-fails.txt @@ -0,0 +1,15 @@ +kms_3d,Fail +kms_cursor_legacy@forked-bo,Fail +kms_cursor_legacy@forked-move,Fail +kms_cursor_legacy@single-bo,Fail +kms_cursor_legacy@single-move,Fail +kms_cursor_legacy@torture-bo,Fail +kms_cursor_legacy@torture-move,Fail +kms_hdmi_inject@inject-4k,Fail +kms_lease@lease-uevent,Fail +kms_plane_alpha_blend@alpha-7efc,Fail +kms_plane_alpha_blend@alpha-basic,Fail +kms_plane_alpha_blend@alpha-opaque-fb,Fail +kms_plane_alpha_blend@alpha-transparent-fb,Fail +kms_plane_alpha_blend@constant-alpha-max,Fail +msm/msm_recovery@gpu-fault-parallel,Fail diff --git a/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-flakes.txt new file mode 100644 index 000000000000..c1859d9b165f --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-flakes.txt @@ -0,0 +1,6 @@ +# Board Name: sm8350-hdk +# Bug Report: https://gitlab.freedesktop.org/drm/msm/-/issues/65 +# Failure Rate: 100 +# IGT Version: 1.28-ga73311079 +# Linux Version: 6.12.0-rc1 +msm/msm_recovery@gpu-fault diff --git a/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-skips.txt new file mode 100644 index 000000000000..329770c520d9 --- /dev/null +++ b/drivers/gpu/drm/ci/xfails/msm-sm8350-hdk-skips.txt @@ -0,0 +1,211 @@ +# Skip driver specific tests +^amdgpu.* +nouveau_.* +^panfrost.* +^v3d.* +^vc4.* +^vmwgfx* + +# Skip intel specific tests +gem_.* +i915_.* +tools_test.* + +# Currently fails and causes coverage loss for other tests +# since core_getversion also fails. +core_hotunplug.* + +# Kernel panic +msm/msm_mapping@ring +# DEBUG - Begin test msm/msm_mapping@ring +# [ 200.874157] [IGT] msm_mapping: executing +# [ 200.880236] [IGT] msm_mapping: starting subtest ring +# [ 200.895243] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=PERMISSION source=CP (0,0,0,1) +# [ 200.906885] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.917625] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.928353] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.939084] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.949815] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.950227] platform 3d6a000.gmu: [drm:a6xx_hfi_send_msg.constprop.0] *ERROR* Message HFI_H2F_MSG_GX_BW_PERF_VOTE id 25 timed out waiting for response +# [ 200.960467] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.960500] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 200.995966] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 201.006702] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 204.213387] platform 3d6a000.gmu: GMU watchdog expired +# [ 205.909103] adreno_fault_handler: 224274 callbacks suppressed +# [ 205.909108] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.925794] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.936529] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.947263] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.957997] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.968731] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.979465] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 205.990199] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 206.000932] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 206.011666] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.925090] adreno_fault_handler: 224511 callbacks suppressed +# [ 210.925096] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.941781] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.952517] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.963250] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.973985] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.984719] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 210.995452] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 211.006186] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 211.016921] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 211.027655] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 215.937100] adreno_fault_handler: 223760 callbacks suppressed +# [ 215.937106] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 215.953824] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 215.964573] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 215.975321] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 215.986067] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 215.996815] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 216.007563] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 216.018310] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 216.029057] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 216.039805] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 220.945182] adreno_fault_handler: 222822 callbacks suppressed +# [ 220.945188] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 220.961897] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 220.972645] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 220.983392] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 220.994140] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 221.004889] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 221.015636] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 221.026383] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 221.037130] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 221.047879] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 225.953179] adreno_fault_handler: 223373 callbacks suppressed +# [ 225.953184] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 225.969883] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 225.980617] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 225.991350] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 226.002084] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 226.012818] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 226.023551] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 226.034285] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 226.045019] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 226.055753] *** gpu fault: ttbr0=00000001160d6000 iova=0001000000001000 dir=WRITE type=UNKNOWN source=CP (0,0,0,1) +# [ 228.001087] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks: +# [ 228.007412] rcu: 0-....: (524 ticks this GP) idle=4ffc/1/0x4000000000000000 softirq=9367/9368 fqs=29 +# [ 228.017097] rcu: (detected by 1, t=6504 jiffies, g=29837, q=6 ncpus=8) +# [ 228.023959] Sending NMI from CPU 1 to CPUs 0: +# [ 228.161164] watchdog: BUG: soft lockup - CPU#0 stuck for 26s! [gpu-worker:150] +# [ 228.173169] Modules linked in: +# [ 228.176361] irq event stamp: 2809595 +# [ 228.180083] hardirqs last enabled at (2809594): [<ffffd3bc52cb91ac>] exit_to_kernel_mode+0x38/0x130 +# [ 228.189547] hardirqs last disabled at (2809595): [<ffffd3bc52cb92c8>] el1_interrupt+0x24/0x64 +# [ 228.198377] softirqs last enabled at (1669060): [<ffffd3bc51936f98>] handle_softirqs+0x4a4/0x4bc +# [ 228.207565] softirqs last disabled at (1669063): [<ffffd3bc518905a4>] __do_softirq+0x14/0x20 +# [ 228.216316] CPU: 0 UID: 0 PID: 150 Comm: gpu-worker Not tainted 6.12.0-rc1-g685d530dc83a #1 +# [ 228.224966] Hardware name: Qualcomm Technologies, Inc. SM8350 HDK (DT) +# [ 228.231730] pstate: 00400005 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +# [ 228.238948] pc : tcp_fastretrans_alert+0x0/0x884 +# [ 228.243751] lr : tcp_ack+0x9d4/0x1238 +# [ 228.247562] sp : ffff8000800036d0 +# [ 228.251011] x29: ffff8000800036d0 x28: 000000000000000c x27: 0000000000000001 +# [ 228.258421] x26: ffff704683cd8000 x25: 0000000000000403 x24: ffff70468b7e7c00 +# [ 228.265829] x23: 0000000000000000 x22: 0000000000000004 x21: 000000000000140f +# [ 228.273237] x20: 00000000f1de79f7 x19: 00000000f1de7a5f x18: 0000000000000001 +# [ 228.280644] x17: 00000000302d6762 x16: 632d6b64682d3035 x15: ffff704683c39000 +# [ 228.288051] x14: 00000000000e2000 x13: ffff704683df6000 x12: 0000000000000000 +# [ 228.295458] x11: 00000000000000a0 x10: 0000000000000000 x9 : ffffd3bc551a9a20 +# [ 228.302865] x8 : ffff800080003640 x7 : 0000000000040faa x6 : 00000000ffff9634 +# [ 228.310271] x5 : 00000000000005a8 x4 : ffff800080003788 x3 : ffff80008000377c +# [ 228.317679] x2 : 0000000000000000 x1 : 00000000f1de79f7 x0 : ffff704683cd8000 +# [ 228.325087] Call trace: +# [ 228.327640] tcp_fastretrans_alert+0x0/0x884 +# [ 228.332082] tcp_rcv_established+0x7c4/0x8bc +# [ 228.336523] tcp_v4_do_rcv+0x244/0x31c +# [ 228.340429] tcp_v4_rcv+0xcc4/0x1084 +# [ 228.344155] ip_protocol_deliver_rcu+0x64/0x218 +# [ 228.348862] ip_local_deliver_finish+0xb8/0x1ac +# [ 228.353566] ip_local_deliver+0x84/0x254 +# [ 228.357651] ip_sublist_rcv_finish+0x84/0xb8 +# [ 228.362092] ip_sublist_rcv+0x11c/0x2f0 +# [ 228.366081] ip_list_rcv+0xfc/0x190 +# [ 228.369711] __netif_receive_skb_list_core+0x174/0x208 +# [ 228.375050] netif_receive_skb_list_internal+0x204/0x3ac +# [ 228.380564] napi_complete_done+0x64/0x1d0 +# [ 228.384826] lan78xx_poll+0x71c/0x9cc +# [ 228.388638] __napi_poll.constprop.0+0x3c/0x254 +# [ 228.393341] net_rx_action+0x164/0x2d4 +# [ 228.397244] handle_softirqs+0x128/0x4bc +# [ 228.401329] __do_softirq+0x14/0x20 +# [ 228.404958] ____do_softirq+0x10/0x1c +# [ 228.408769] call_on_irq_stack+0x24/0x4c +# [ 228.412854] do_softirq_own_stack+0x1c/0x28 +# [ 228.417199] __irq_exit_rcu+0x124/0x164 +# [ 228.421188] irq_exit_rcu+0x10/0x38 +# [ 228.424819] el1_interrupt+0x38/0x64 +# [ 228.428546] el1h_64_irq_handler+0x18/0x24 +# [ 228.432807] el1h_64_irq+0x64/0x68 +# [ 228.436354] lock_acquire+0x214/0x32c +# [ 228.440166] __mutex_lock+0x98/0x3d0 +# [ 228.443893] mutex_lock_nested+0x24/0x30 +# [ 228.447978] fault_worker+0x58/0x184 +# [ 228.451704] kthread_worker_fn+0xf4/0x320 +# [ 228.455873] kthread+0x114/0x118 +# [ 228.459243] ret_from_fork+0x10/0x20 +# [ 228.462970] Kernel panic - not syncing: softlockup: hung tasks +# [ 228.469018] CPU: 0 UID: 0 PID: 150 Comm: gpu-worker Tainted: G L 6.12.0-rc1-g685d530dc83a #1 +# [ 228.479190] Tainted: [L]=SOFTLOCKUP +# [ 228.482815] Hardware name: Qualcomm Technologies, Inc. SM8350 HDK (DT) +# [ 228.489574] Call trace: +# [ 228.492125] dump_backtrace+0x98/0xf0 +# [ 228.495931] show_stack+0x18/0x24 +# [ 228.499380] dump_stack_lvl+0x38/0xd0 +# [ 228.503189] dump_stack+0x18/0x24 +# [ 228.506639] panic+0x3bc/0x41c +# [ 228.509826] watchdog_timer_fn+0x254/0x2e4 +# [ 228.514087] __hrtimer_run_queues+0x3b0/0x40c +# [ 228.518612] hrtimer_interrupt+0xe8/0x248 +# [ 228.522777] arch_timer_handler_virt+0x2c/0x44 +# [ 228.527399] handle_percpu_devid_irq+0xa8/0x2c4 +# [ 228.532103] generic_handle_domain_irq+0x2c/0x44 +# [ 228.536902] gic_handle_irq+0x4c/0x11c +# [ 228.540802] do_interrupt_handler+0x50/0x84 +# [ 228.545146] el1_interrupt+0x34/0x64 +# [ 228.548870] el1h_64_irq_handler+0x18/0x24 +# [ 228.553128] el1h_64_irq+0x64/0x68 +# [ 228.556672] tcp_fastretrans_alert+0x0/0x884 +# [ 228.561110] tcp_rcv_established+0x7c4/0x8bc +# [ 228.565548] tcp_v4_do_rcv+0x244/0x31c +# [ 228.569449] tcp_v4_rcv+0xcc4/0x1084 +# [ 228.573171] ip_protocol_deliver_rcu+0x64/0x218 +# [ 228.577873] ip_local_deliver_finish+0xb8/0x1ac +# [ 228.582574] ip_local_deliver+0x84/0x254 +# [ 228.586655] ip_sublist_rcv_finish+0x84/0xb8 +# [ 228.591092] ip_sublist_rcv+0x11c/0x2f0 +# [ 228.595079] ip_list_rcv+0xfc/0x190 +# [ 228.598706] __netif_receive_skb_list_core+0x174/0x208 +# [ 228.604039] netif_receive_skb_list_internal+0x204/0x3ac +# [ 228.609549] napi_complete_done+0x64/0x1d0 +# [ 228.613808] lan78xx_poll+0x71c/0x9cc +# [ 228.617614] __napi_poll.constprop.0+0x3c/0x254 +# [ 228.622314] net_rx_action+0x164/0x2d4 +# [ 228.626214] handle_softirqs+0x128/0x4bc +# [ 228.630297] __do_softirq+0x14/0x20 +# [ 228.633923] ____do_softirq+0x10/0x1c +# [ 228.637729] call_on_irq_stack+0x24/0x4c +# [ 228.641811] do_softirq_own_stack+0x1c/0x28 +# [ 228.646152] __irq_exit_rcu+0x124/0x164 +# [ 228.650139] irq_exit_rcu+0x10/0x38 +# [ 228.653768] el1_interrupt+0x38/0x64 +# [ 228.657491] el1h_64_irq_handler+0x18/0x24 +# [ 228.661750] el1h_64_irq+0x64/0x68 +# [ 228.665293] lock_acquire+0x214/0x32c +# [ 228.669098] __mutex_lock+0x98/0x3d0 +# [ 228.672821] mutex_lock_nested+0x24/0x30 +# [ 228.676903] fault_worker+0x58/0x184 +# [ 228.680626] kthread_worker_fn+0xf4/0x320 +# [ 228.684790] kthread+0x114/0x118 +# [ 228.688156] ret_from_fork+0x10/0x20 +# [ 228.691882] SMP: stopping secondary CPUs +# [ 229.736843] SMP: failed to stop secondary CPUs 1,4 +# [ 229.741827] Kernel Offset: 0x53bbd1880000 from 0xffff800080000000 +# [ 229.748159] PHYS_OFFSET: 0xfff08fba80000000 +# [ 229.752499] CPU features: 0x18,00000017,00200928,4200720b +# [ 229.758095] Memory Limit: none +# [ 229.761291] ---[ end Kernel panic - not syncing: softlockup: hung tasks ]--- -- GitLab From a2f599046c671d6b46d93aed95b37241ce4504cf Mon Sep 17 00:00:00 2001 From: Li Huafei <lihuafei1@huawei.com> Date: Sun, 27 Oct 2024 01:38:44 +0800 Subject: [PATCH 947/970] drm/nouveau/gr/gf100: Fix missing unlock in gf100_gr_chan_new() When the call to gf100_grctx_generate() fails, unlock gr->fecs.mutex before returning the error. Fixes smatch warning: drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c:480 gf100_gr_chan_new() warn: inconsistent returns '&gr->fecs.mutex'. Fixes: ca081fff6ecc ("drm/nouveau/gr/gf100-: generate golden context during first object alloc") Signed-off-by: Li Huafei <lihuafei1@huawei.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241026173844.2392679-1-lihuafei1@huawei.com --- drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 060c74a80eb1..3ea447f6a45b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -443,6 +443,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, ret = gf100_grctx_generate(gr, chan, fifoch->inst); if (ret) { nvkm_error(&base->engine.subdev, "failed to construct context\n"); + mutex_unlock(&gr->fecs.mutex); return ret; } } -- GitLab From ce68f86c445133117a3474987a1fe29be3d6e8e4 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:07 +0200 Subject: [PATCH 948/970] accel/ivpu: Do not fail when more than 1 tile is fused Allow TILE_FUSE register to disable more than 1 tile. The driver should not prevent such configurations from being functional. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-2-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_hw_btrs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c index 6d5f1cc71143..3212c99f3682 100644 --- a/drivers/accel/ivpu/ivpu_hw_btrs.c +++ b/drivers/accel/ivpu/ivpu_hw_btrs.c @@ -141,16 +141,10 @@ static int read_tile_config_fuse(struct ivpu_device *vdev, u32 *tile_fuse_config } config = REG_GET_FLD(VPU_HW_BTRS_LNL_TILE_FUSE, CONFIG, fuse); - if (!tile_disable_check(config)) { - ivpu_err(vdev, "Fuse: Invalid tile disable config (0x%x)\n", config); - return -EIO; - } + if (!tile_disable_check(config)) + ivpu_warn(vdev, "More than 1 tile disabled, tile fuse config mask: 0x%x\n", config); - if (config) - ivpu_dbg(vdev, MISC, "Fuse: %d tiles enabled. Tile number %d disabled\n", - BTRS_LNL_TILE_MAX_NUM - 1, ffs(config) - 1); - else - ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", BTRS_LNL_TILE_MAX_NUM); + ivpu_dbg(vdev, MISC, "Tile disable config mask: 0x%x\n", config); *tile_fuse_config = config; return 0; -- GitLab From a74f4d991352c95b20f445b8b0c99ffa2ef79f8e Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:08 +0200 Subject: [PATCH 949/970] accel/ivpu: Defer MMU root page table allocation Defer root page table allocation and unify context init/fini functions. Move allocation of the root page table from the file_priv_open function to perform a lazy allocation approach during ivpu_bo_pin(). By doing so, we avoid the overhead of allocating page tables for simple operations like GET_PARAM that do not require them. Additionally, the MMU context descriptor table initialization has been moved to the ivpu_mmu_context_map_page function. This change streamlines the process and ensures that the descriptor table is only initialized when it is actually needed. Refactor init/fini functions to remove redundant code and make the context management more straightforward. Overall, these changes lead to a reduction in the time taken by the file descriptor open operation, as the costly root page table allocation is now avoided for operations that do not require it. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-3-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_drv.c | 12 +-- drivers/accel/ivpu/ivpu_mmu.c | 94 ++++++----------- drivers/accel/ivpu/ivpu_mmu.h | 4 +- drivers/accel/ivpu/ivpu_mmu_context.c | 145 +++++++++++++------------- drivers/accel/ivpu/ivpu_mmu_context.h | 9 +- 5 files changed, 115 insertions(+), 149 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index e7d8967c02f2..34e3e9b1c3f2 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -86,7 +86,7 @@ static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *fi ivpu_cmdq_release_all_locked(file_priv); ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx); - ivpu_mmu_user_context_fini(vdev, &file_priv->ctx); + ivpu_mmu_context_fini(vdev, &file_priv->ctx); file_priv->bound = false; drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id)); } @@ -254,9 +254,7 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) goto err_unlock; } - ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id); - if (ret) - goto err_xa_erase; + ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); @@ -273,8 +271,6 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) return 0; -err_xa_erase: - xa_erase_irq(&vdev->context_xa, ctx_id); err_unlock: mutex_unlock(&vdev->context_list_lock); mutex_destroy(&file_priv->ms_lock); @@ -652,9 +648,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev) if (ret) goto err_shutdown; - ret = ivpu_mmu_global_context_init(vdev); - if (ret) - goto err_shutdown; + ivpu_mmu_global_context_init(vdev); ret = ivpu_mmu_init(vdev); if (ret) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index c078e214b221..4ff0d7a51985 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -696,7 +696,7 @@ int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid) return ret; } -static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) +static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_dma, bool valid) { struct ivpu_mmu_info *mmu = vdev->mmu; struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab; @@ -708,30 +708,29 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) return -EINVAL; entry = cdtab->base + (ssid * IVPU_MMU_CDTAB_ENT_SIZE); - - if (cd_dma != 0) { - cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | - FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | - FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | - IVPU_MMU_CD_0_TCR_EPD1 | - IVPU_MMU_CD_0_AA64 | - IVPU_MMU_CD_0_R | - IVPU_MMU_CD_0_ASET | - IVPU_MMU_CD_0_V; - cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; - cd[2] = 0; - cd[3] = 0x0000000000007444; - - /* For global context generate memory fault on VPU */ - if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) - cd[0] |= IVPU_MMU_CD_0_A; - } else { - memset(cd, 0, sizeof(cd)); - } + drm_WARN_ON(&vdev->drm, (entry[0] & IVPU_MMU_CD_0_V) == valid); + + cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) | + FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) | + FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) | + IVPU_MMU_CD_0_TCR_EPD1 | + IVPU_MMU_CD_0_AA64 | + IVPU_MMU_CD_0_R | + IVPU_MMU_CD_0_ASET; + cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK; + cd[2] = 0; + cd[3] = 0x0000000000007444; + + /* For global context generate memory fault on VPU */ + if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) + cd[0] |= IVPU_MMU_CD_0_A; + + if (valid) + cd[0] |= IVPU_MMU_CD_0_V; WRITE_ONCE(entry[1], cd[1]); WRITE_ONCE(entry[2], cd[2]); @@ -741,8 +740,8 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) if (!ivpu_is_force_snoop_enabled(vdev)) clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE); - ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", - cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); + ivpu_dbg(vdev, MMU, "CDTAB set %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", + valid ? "valid" : "invalid", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]); mutex_lock(&mmu->lock); if (!mmu->on) @@ -758,33 +757,6 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma) return ret; } -static int ivpu_mmu_cd_add_gbl(struct ivpu_device *vdev) -{ - int ret; - - ret = ivpu_mmu_cd_add(vdev, 0, vdev->gctx.pgtable.pgd_dma); - if (ret) - ivpu_err(vdev, "Failed to add global CD entry: %d\n", ret); - - return ret; -} - -static int ivpu_mmu_cd_add_user(struct ivpu_device *vdev, u32 ssid, dma_addr_t cd_dma) -{ - int ret; - - if (ssid == 0) { - ivpu_err(vdev, "Invalid SSID: %u\n", ssid); - return -EINVAL; - } - - ret = ivpu_mmu_cd_add(vdev, ssid, cd_dma); - if (ret) - ivpu_err(vdev, "Failed to add CD entry SSID=%u: %d\n", ssid, ret); - - return ret; -} - int ivpu_mmu_init(struct ivpu_device *vdev) { struct ivpu_mmu_info *mmu = vdev->mmu; @@ -808,12 +780,6 @@ int ivpu_mmu_init(struct ivpu_device *vdev) return ret; } - ret = ivpu_mmu_cd_add_gbl(vdev); - if (ret) { - ivpu_err(vdev, "Failed to initialize strtab: %d\n", ret); - return ret; - } - ret = ivpu_mmu_enable(vdev); if (ret) { ivpu_err(vdev, "Failed to resume MMU: %d\n", ret); @@ -966,12 +932,12 @@ void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev) REGV_WR32(IVPU_MMU_REG_GERRORN, gerror_val); } -int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) +int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable) { - return ivpu_mmu_cd_add_user(vdev, ssid, pgtable->pgd_dma); + return ivpu_mmu_cdtab_entry_set(vdev, ssid, pgtable->pgd_dma, true); } -void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid) +void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid) { - ivpu_mmu_cd_add_user(vdev, ssid, 0); /* 0 will clear CD entry */ + ivpu_mmu_cdtab_entry_set(vdev, ssid, 0, false); } diff --git a/drivers/accel/ivpu/ivpu_mmu.h b/drivers/accel/ivpu/ivpu_mmu.h index 6fa35c240710..7afea9cd8731 100644 --- a/drivers/accel/ivpu/ivpu_mmu.h +++ b/drivers/accel/ivpu/ivpu_mmu.h @@ -40,8 +40,8 @@ struct ivpu_mmu_info { int ivpu_mmu_init(struct ivpu_device *vdev); void ivpu_mmu_disable(struct ivpu_device *vdev); int ivpu_mmu_enable(struct ivpu_device *vdev); -int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); -void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid); +int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable); +void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid); int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid); void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev); diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index bbe652a7019d..8992fe93b679 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -90,19 +90,6 @@ static void ivpu_pgtable_free_page(struct ivpu_device *vdev, u64 *cpu_addr, dma_ } } -static int ivpu_mmu_pgtable_init(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) -{ - dma_addr_t pgd_dma; - - pgtable->pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); - if (!pgtable->pgd_dma_ptr) - return -ENOMEM; - - pgtable->pgd_dma = pgd_dma; - - return 0; -} - static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) { int pgd_idx, pud_idx, pmd_idx; @@ -140,6 +127,27 @@ static void ivpu_mmu_pgtables_free(struct ivpu_device *vdev, struct ivpu_mmu_pgt } ivpu_pgtable_free_page(vdev, pgtable->pgd_dma_ptr, pgtable->pgd_dma); + pgtable->pgd_dma_ptr = NULL; + pgtable->pgd_dma = 0; +} + +static u64* +ivpu_mmu_ensure_pgd(struct ivpu_device *vdev, struct ivpu_mmu_pgtable *pgtable) +{ + u64 *pgd_dma_ptr = pgtable->pgd_dma_ptr; + dma_addr_t pgd_dma; + + if (pgd_dma_ptr) + return pgd_dma_ptr; + + pgd_dma_ptr = ivpu_pgtable_alloc_page(vdev, &pgd_dma); + if (!pgd_dma_ptr) + return NULL; + + pgtable->pgd_dma_ptr = pgd_dma_ptr; + pgtable->pgd_dma = pgd_dma; + + return pgd_dma_ptr; } static u64* @@ -237,6 +245,12 @@ ivpu_mmu_context_map_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr); int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr); + drm_WARN_ON(&vdev->drm, ctx->id == IVPU_RESERVED_CONTEXT_MMU_SSID); + + /* Allocate PGD - first level page table if needed */ + if (!ivpu_mmu_ensure_pgd(vdev, &ctx->pgtable)) + return -ENOMEM; + /* Allocate PUD - second level page table if needed */ if (!ivpu_mmu_ensure_pud(vdev, &ctx->pgtable, pgd_idx)) return -ENOMEM; @@ -448,12 +462,21 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - mutex_unlock(&ctx->lock); - return ret; + goto err_unlock; } vpu_addr += size; } + if (!ctx->is_cd_valid) { + ret = ivpu_mmu_cd_set(vdev, ctx->id, &ctx->pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", + ctx->id, ret); + goto err_unlock; + } + ctx->is_cd_valid = true; + } + /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); @@ -463,6 +486,11 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); return ret; + +err_unlock: + mutex_unlock(&ctx->lock); + return ret; + } void @@ -530,20 +558,12 @@ ivpu_mmu_context_remove_node(struct ivpu_mmu_context *ctx, struct drm_mm_node *n mutex_unlock(&ctx->lock); } -static int -ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) +void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id) { u64 start, end; - int ret; mutex_init(&ctx->lock); - ret = ivpu_mmu_pgtable_init(vdev, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to initialize pgtable for ctx %u: %d\n", context_id, ret); - return ret; - } - if (!context_id) { start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; @@ -554,41 +574,59 @@ ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u3 drm_mm_init(&ctx->mm, start, end - start); ctx->id = context_id; - - return 0; } -static void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) +void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) { - if (drm_WARN_ON(&vdev->drm, !ctx->pgtable.pgd_dma_ptr)) - return; + if (ctx->is_cd_valid) { + ivpu_mmu_cd_clear(vdev, ctx->id); + ctx->is_cd_valid = false; + } mutex_destroy(&ctx->lock); ivpu_mmu_pgtables_free(vdev, &ctx->pgtable); drm_mm_takedown(&ctx->mm); - - ctx->pgtable.pgd_dma_ptr = NULL; - ctx->pgtable.pgd_dma = 0; } -int ivpu_mmu_global_context_init(struct ivpu_device *vdev) +void ivpu_mmu_global_context_init(struct ivpu_device *vdev) { - return ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); + ivpu_mmu_context_init(vdev, &vdev->gctx, IVPU_GLOBAL_CONTEXT_MMU_SSID); } void ivpu_mmu_global_context_fini(struct ivpu_device *vdev) { - return ivpu_mmu_context_fini(vdev, &vdev->gctx); + ivpu_mmu_context_fini(vdev, &vdev->gctx); } int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev) { - return ivpu_mmu_user_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); + int ret; + + ivpu_mmu_context_init(vdev, &vdev->rctx, IVPU_RESERVED_CONTEXT_MMU_SSID); + + mutex_lock(&vdev->rctx.lock); + + if (!ivpu_mmu_ensure_pgd(vdev, &vdev->rctx.pgtable)) { + ivpu_err(vdev, "Failed to allocate root page table for reserved context\n"); + ret = -ENOMEM; + goto unlock; + } + + ret = ivpu_mmu_cd_set(vdev, vdev->rctx.id, &vdev->rctx.pgtable); + if (ret) { + ivpu_err(vdev, "Failed to set context descriptor for reserved context\n"); + goto unlock; + } + +unlock: + mutex_unlock(&vdev->rctx.lock); + return ret; } void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev) { - return ivpu_mmu_user_context_fini(vdev, &vdev->rctx); + ivpu_mmu_cd_clear(vdev, vdev->rctx.id); + ivpu_mmu_context_fini(vdev, &vdev->rctx); } void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) @@ -603,36 +641,3 @@ void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid) xa_unlock(&vdev->context_xa); } - -int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id) -{ - int ret; - - drm_WARN_ON(&vdev->drm, !ctx_id); - - ret = ivpu_mmu_context_init(vdev, ctx, ctx_id); - if (ret) { - ivpu_err(vdev, "Failed to initialize context %u: %d\n", ctx_id, ret); - return ret; - } - - ret = ivpu_mmu_set_pgtable(vdev, ctx_id, &ctx->pgtable); - if (ret) { - ivpu_err(vdev, "Failed to set page table for context %u: %d\n", ctx_id, ret); - goto err_context_fini; - } - - return 0; - -err_context_fini: - ivpu_mmu_context_fini(vdev, ctx); - return ret; -} - -void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx) -{ - drm_WARN_ON(&vdev->drm, !ctx->id); - - ivpu_mmu_clear_pgtable(vdev, ctx->id); - ivpu_mmu_context_fini(vdev, ctx); -} diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/ivpu/ivpu_mmu_context.h index 7f9aaf3d10c2..8042fc067062 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.h +++ b/drivers/accel/ivpu/ivpu_mmu_context.h @@ -23,19 +23,20 @@ struct ivpu_mmu_pgtable { }; struct ivpu_mmu_context { - struct mutex lock; /* Protects: mm, pgtable */ + struct mutex lock; /* Protects: mm, pgtable, is_cd_valid */ struct drm_mm mm; struct ivpu_mmu_pgtable pgtable; + bool is_cd_valid; u32 id; }; -int ivpu_mmu_global_context_init(struct ivpu_device *vdev); +void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 context_id); +void ivpu_mmu_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); +void ivpu_mmu_global_context_init(struct ivpu_device *vdev); void ivpu_mmu_global_context_fini(struct ivpu_device *vdev); int ivpu_mmu_reserved_context_init(struct ivpu_device *vdev); void ivpu_mmu_reserved_context_fini(struct ivpu_device *vdev); -int ivpu_mmu_user_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u32 ctx_id); -void ivpu_mmu_user_context_fini(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); void ivpu_mmu_user_context_mark_invalid(struct ivpu_device *vdev, u32 ssid); int ivpu_mmu_context_insert_node(struct ivpu_mmu_context *ctx, const struct ivpu_addr_range *range, -- GitLab From 94b2a2c0e7cba3f163609dbd94120ee533ad2a07 Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Date: Thu, 17 Oct 2024 16:58:09 +0200 Subject: [PATCH 950/970] accel/ivpu: Remove copy engine support Copy engine was deprecated by the FW and is no longer supported. Compute engine includes all copy engine functionality and should be used instead. This change does not affect user space as the copy engine was never used outside of a couple of tests. Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-4-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_drv.h | 5 +--- drivers/accel/ivpu/ivpu_job.c | 43 +++++++++++-------------------- drivers/accel/ivpu/ivpu_jsm_msg.c | 8 +++--- include/uapi/drm/ivpu_accel.h | 6 +---- 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index f905021ac174..5b4f5104b470 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -49,11 +49,8 @@ #define IVPU_JOB_ID_JOB_MASK GENMASK(7, 0) #define IVPU_JOB_ID_CONTEXT_MASK GENMASK(31, 8) -#define IVPU_NUM_ENGINES 2 #define IVPU_NUM_PRIORITIES 4 -#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES) - -#define IVPU_CMDQ_INDEX(engine, priority) ((engine) * IVPU_NUM_PRIORITIES + (priority)) +#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_PRIORITIES) #define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SIMICS 2 diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 98e0b7b61407..f580959e8778 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -247,8 +247,7 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine, u8 priority) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; int ret; lockdep_assert_held(&file_priv->lock); @@ -257,7 +256,7 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 cmdq = ivpu_cmdq_alloc(file_priv); if (!cmdq) return NULL; - file_priv->cmdq[cmdq_idx] = cmdq; + file_priv->cmdq[priority] = cmdq; } ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority); @@ -267,15 +266,14 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 return cmdq; } -static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engine, u8 priority) +static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priority) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; lockdep_assert_held(&file_priv->lock); if (cmdq) { - file_priv->cmdq[cmdq_idx] = NULL; + file_priv->cmdq[priority] = NULL; ivpu_cmdq_fini(file_priv, cmdq); ivpu_cmdq_free(file_priv, cmdq); } @@ -283,14 +281,12 @@ static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engin void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) { - u16 engine; u8 priority; lockdep_assert_held(&file_priv->lock); - for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) - ivpu_cmdq_release_locked(file_priv, engine, priority); + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) + ivpu_cmdq_release_locked(file_priv, priority); } /* @@ -301,19 +297,15 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) */ static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv) { - u16 engine; u8 priority; mutex_lock(&file_priv->lock); - for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) { - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx]; + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; - if (cmdq) - cmdq->db_registered = false; - } + if (cmdq) + cmdq->db_registered = false; } mutex_unlock(&file_priv->lock); @@ -334,16 +326,11 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv) { - u16 engine; u8 priority; - for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) { - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority); - - if (file_priv->cmdq[cmdq_idx]) - ivpu_cmdq_fini(file_priv, file_priv->cmdq[cmdq_idx]); - } + for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { + if (file_priv->cmdq[priority]) + ivpu_cmdq_fini(file_priv, file_priv->cmdq[priority]); } } @@ -699,7 +686,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) int idx, ret; u8 priority; - if (params->engine > DRM_IVPU_ENGINE_COPY) + if (params->engine != DRM_IVPU_ENGINE_COMPUTE) return -EINVAL; if (params->priority > DRM_IVPU_JOB_PRIORITY_REALTIME) diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 8f5d904ca1ed..30a40be76930 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -132,7 +132,7 @@ int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat) struct vpu_jsm_msg resp; int ret; - if (engine > VPU_ENGINE_COPY) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.query_engine_hb.engine_idx = engine; @@ -155,7 +155,7 @@ int ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine) struct vpu_jsm_msg resp; int ret; - if (engine > VPU_ENGINE_COPY) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.engine_reset.engine_idx = engine; @@ -174,7 +174,7 @@ int ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id struct vpu_jsm_msg resp; int ret; - if (engine > VPU_ENGINE_COPY) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.engine_preempt.engine_idx = engine; @@ -346,7 +346,7 @@ int ivpu_jsm_hws_resume_engine(struct ivpu_device *vdev, u32 engine) struct vpu_jsm_msg resp; int ret; - if (engine >= VPU_ENGINE_NB) + if (engine != VPU_ENGINE_COMPUTE) return -EINVAL; req.payload.hws_resume_engine.engine_idx = engine; diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 234664d35250..a35b97b097bf 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -258,7 +258,7 @@ struct drm_ivpu_bo_info { /* drm_ivpu_submit engines */ #define DRM_IVPU_ENGINE_COMPUTE 0 -#define DRM_IVPU_ENGINE_COPY 1 +#define DRM_IVPU_ENGINE_COPY 1 /* Deprecated */ /** * struct drm_ivpu_submit - Submit commands to the VPU @@ -289,10 +289,6 @@ struct drm_ivpu_submit { * %DRM_IVPU_ENGINE_COMPUTE: * * Performs Deep Learning Neural Compute Inference Operations - * - * %DRM_IVPU_ENGINE_COPY: - * - * Performs memory copy operations to/from system memory allocated for VPU */ __u32 engine; -- GitLab From add38f8211b5dcf447a50bea4da54c391e39336c Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:10 +0200 Subject: [PATCH 951/970] accel/ivpu: Clear CDTAB entry in case of failure Don't leave a context descriptor in case CFGI_ALL flush fails. Mark it as invalid (by clearing valid bit) so nothing is left in partially-initialized state. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-5-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_mmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 4ff0d7a51985..26ef52fbb93e 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -749,10 +749,17 @@ static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_d ret = ivpu_mmu_cmdq_write_cfgi_all(vdev); if (ret) - goto unlock; + goto err_invalidate; ret = ivpu_mmu_cmdq_sync(vdev); + if (ret) + goto err_invalidate; unlock: + mutex_unlock(&mmu->lock); + return 0; + +err_invalidate: + WRITE_ONCE(entry[0], 0); mutex_unlock(&mmu->lock); return ret; } -- GitLab From 1fc65fa96ff4703e8d26dda351d942e8940f322f Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:11 +0200 Subject: [PATCH 952/970] accel/ivpu: Unmap partially mapped BOs in case of errors Ensure that all buffers that were created only partially through allocated scatter-gather table are unmapped from MMU600 in case of errors. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-6-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_mmu_context.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 8992fe93b679..697b57071d54 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -432,6 +432,7 @@ int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr, struct sg_table *sgt, bool llc_coherent) { + size_t start_vpu_addr = vpu_addr; struct scatterlist *sg; int ret; u64 prot; @@ -462,7 +463,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, ret = ivpu_mmu_context_map_pages(vdev, ctx, vpu_addr, dma_addr, size, prot); if (ret) { ivpu_err(vdev, "Failed to map context pages\n"); - goto err_unlock; + goto err_unmap_pages; } vpu_addr += size; } @@ -472,7 +473,7 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, if (ret) { ivpu_err(vdev, "Failed to set context descriptor for context %u: %d\n", ctx->id, ret); - goto err_unlock; + goto err_unmap_pages; } ctx->is_cd_valid = true; } @@ -480,17 +481,19 @@ ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, /* Ensure page table modifications are flushed from wc buffers to memory */ wmb(); - mutex_unlock(&ctx->lock); - ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id); - if (ret) + if (ret) { ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret); - return ret; + goto err_unmap_pages; + } -err_unlock: mutex_unlock(&ctx->lock); - return ret; + return 0; +err_unmap_pages: + ivpu_mmu_context_unmap_pages(ctx, start_vpu_addr, vpu_addr - start_vpu_addr); + mutex_unlock(&ctx->lock); + return ret; } void -- GitLab From ae7af7d8dc2a13a427aa90d003fe4fb2c168342a Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:12 +0200 Subject: [PATCH 953/970] accel/ivpu: Use xa_alloc_cyclic() instead of custom function Remove custom ivpu_id_alloc() wrapper used for ID allocations and replace it with standard xa_alloc_cyclic() API. The idea behind ivpu_id_alloc() was to have monotonic IDs, so the driver is easier to debug because same IDs are not reused all over. The same can be achieved just by using appropriate Linux API. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-7-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_drv.c | 11 ++++------- drivers/accel/ivpu/ivpu_drv.h | 4 ++-- drivers/accel/ivpu/ivpu_job.c | 34 ++++++---------------------------- 3 files changed, 12 insertions(+), 37 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 34e3e9b1c3f2..383e3eb98898 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -256,10 +256,8 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id); - file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, - (file_priv->ctx.id - 1)); - file_priv->default_job_limit.max = file_priv->default_job_limit.min | IVPU_JOB_ID_JOB_MASK; - file_priv->job_limit = file_priv->default_job_limit; + file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); + file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); @@ -618,9 +616,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev) lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); - vdev->default_db_limit.min = IVPU_MIN_DB; - vdev->default_db_limit.max = IVPU_MAX_DB; - vdev->db_limit = vdev->default_db_limit; + vdev->db_limit.min = IVPU_MIN_DB; + vdev->db_limit.max = IVPU_MAX_DB; ret = drmm_mutex_init(&vdev->drm, &vdev->context_list_lock); if (ret) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 5b4f5104b470..677440282170 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -137,7 +137,7 @@ struct ivpu_device { struct xarray db_xa; struct xa_limit db_limit; - struct xa_limit default_db_limit; + u32 db_next; struct mutex bo_list_lock; /* Protects bo_list */ struct list_head bo_list; @@ -174,7 +174,7 @@ struct ivpu_file_priv { struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; struct xa_limit job_limit; - struct xa_limit default_job_limit; + u32 job_id_next; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index f580959e8778..9154c2e14245 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -72,26 +72,6 @@ static void ivpu_preemption_buffers_free(struct ivpu_device *vdev, ivpu_bo_free(cmdq->secondary_preempt_buf); } -static int ivpu_id_alloc(struct xarray *xa, u32 *id, void *entry, struct xa_limit *limit, - const struct xa_limit default_limit) -{ - int ret; - - ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); - if (ret) { - limit->min = default_limit.min; - ret = __xa_alloc(xa, id, entry, *limit, GFP_KERNEL); - if (ret) - return ret; - } - - limit->min = *id + 1; - if (limit->min > limit->max) - limit->min = default_limit.min; - - return ret; -} - static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) { struct ivpu_device *vdev = file_priv->vdev; @@ -102,11 +82,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) if (!cmdq) return NULL; - xa_lock(&vdev->db_xa); /* lock here to protect db_limit */ - ret = ivpu_id_alloc(&vdev->db_xa, &cmdq->db_id, NULL, &vdev->db_limit, - vdev->default_db_limit); - xa_unlock(&vdev->db_xa); - if (ret) { + ret = xa_alloc_cyclic(&vdev->db_xa, &cmdq->db_id, NULL, vdev->db_limit, &vdev->db_next, + GFP_KERNEL); + if (ret < 0) { ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret); goto err_free_cmdq; } @@ -554,9 +532,9 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) xa_lock(&vdev->submitted_jobs_xa); is_first_job = xa_empty(&vdev->submitted_jobs_xa); - ret = ivpu_id_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, &file_priv->job_limit, - file_priv->default_job_limit); - if (ret) { + ret = __xa_alloc_cyclic(&vdev->submitted_jobs_xa, &job->job_id, job, file_priv->job_limit, + &file_priv->job_id_next, GFP_KERNEL); + if (ret < 0) { ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n", file_priv->ctx.id); ret = -EBUSY; -- GitLab From 76ad741ec7349bb1112f3a0ff27adf1ca75cf025 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:13 +0200 Subject: [PATCH 954/970] accel/ivpu: Make command queue ID allocated on XArray Use XArray for dynamic command queue ID allocations instead of fixed ones. This is required by upcoming changes to UAPI that will allow to manage command queues by user space instead of having predefined number of queues in a context. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-8-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_drv.c | 6 +++ drivers/accel/ivpu/ivpu_drv.h | 7 ++- drivers/accel/ivpu/ivpu_job.c | 91 ++++++++++++++++++----------------- drivers/accel/ivpu/ivpu_job.h | 2 + 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 383e3eb98898..f5a8d93fe2a5 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -104,6 +104,8 @@ static void file_priv_release(struct kref *ref) pm_runtime_get_sync(vdev->drm.dev); mutex_lock(&vdev->context_list_lock); file_priv_unbind(vdev, file_priv); + drm_WARN_ON(&vdev->drm, !xa_empty(&file_priv->cmdq_xa)); + xa_destroy(&file_priv->cmdq_xa); mutex_unlock(&vdev->context_list_lock); pm_runtime_put_autosuspend(vdev->drm.dev); @@ -259,6 +261,10 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) file_priv->job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK, (file_priv->ctx.id - 1)); file_priv->job_limit.max = file_priv->job_limit.min | IVPU_JOB_ID_JOB_MASK; + xa_init_flags(&file_priv->cmdq_xa, XA_FLAGS_ALLOC1); + file_priv->cmdq_limit.min = IVPU_CMDQ_MIN_ID; + file_priv->cmdq_limit.max = IVPU_CMDQ_MAX_ID; + mutex_unlock(&vdev->context_list_lock); drm_dev_exit(idx); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 677440282170..8e79d78906bf 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -52,6 +52,9 @@ #define IVPU_NUM_PRIORITIES 4 #define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_PRIORITIES) +#define IVPU_CMDQ_MIN_ID 1 +#define IVPU_CMDQ_MAX_ID 255 + #define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SIMICS 2 #define IVPU_PLATFORM_FPGA 3 @@ -168,13 +171,15 @@ struct ivpu_file_priv { struct kref ref; struct ivpu_device *vdev; struct mutex lock; /* Protects cmdq */ - struct ivpu_cmdq *cmdq[IVPU_NUM_CMDQS_PER_CTX]; + struct xarray cmdq_xa; struct ivpu_mmu_context ctx; struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ struct list_head ms_instance_list; struct ivpu_bo *ms_info_bo; struct xa_limit job_limit; u32 job_id_next; + struct xa_limit cmdq_limit; + u32 cmdq_id_next; bool has_mmu_faults; bool bound; bool aborted; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 9154c2e14245..82a57a30244d 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -89,9 +89,16 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) goto err_free_cmdq; } + ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit, + &file_priv->cmdq_id_next, GFP_KERNEL); + if (ret < 0) { + ivpu_err(vdev, "Failed to allocate command queue id: %d\n", ret); + goto err_erase_db_xa; + } + cmdq->mem = ivpu_bo_create_global(vdev, SZ_4K, DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE); if (!cmdq->mem) - goto err_erase_xa; + goto err_erase_cmdq_xa; ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq); if (ret) @@ -99,7 +106,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) return cmdq; -err_erase_xa: +err_erase_cmdq_xa: + xa_erase(&file_priv->cmdq_xa, cmdq->id); +err_erase_db_xa: xa_erase(&vdev->db_xa, cmdq->db_id); err_free_cmdq: kfree(cmdq); @@ -123,13 +132,13 @@ static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq struct ivpu_device *vdev = file_priv->vdev; int ret; - ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->db_id, + ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->id, task_pid_nr(current), engine, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (ret) return ret; - ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->db_id, + ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->id, priority); if (ret) return ret; @@ -143,20 +152,21 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq * int ret; if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) - ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id, + ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); else ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (!ret) - ivpu_dbg(vdev, JOB, "DB %d registered to ctx %d\n", cmdq->db_id, file_priv->ctx.id); + ivpu_dbg(vdev, JOB, "DB %d registered to cmdq %d ctx %d\n", + cmdq->db_id, cmdq->id, file_priv->ctx.id); return ret; } static int -ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 engine, u8 priority) +ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u8 priority) { struct ivpu_device *vdev = file_priv->vdev; struct vpu_job_queue_header *jobq_header; @@ -172,7 +182,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); jobq_header = &cmdq->jobq->header; - jobq_header->engine_idx = engine; + jobq_header->engine_idx = VPU_ENGINE_COMPUTE; jobq_header->head = 0; jobq_header->tail = 0; if (ivpu_test_mode & IVPU_TEST_MODE_TURBO) { @@ -183,7 +193,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng wmb(); /* Flush WC buffer for jobq->header */ if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority); + ret = ivpu_hws_cmdq_init(file_priv, cmdq, VPU_ENGINE_COMPUTE, priority); if (ret) return ret; } @@ -210,9 +220,9 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm cmdq->db_registered = false; if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { - ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id); + ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id); if (!ret) - ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id); + ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->id); } ret = ivpu_jsm_unregister_db(vdev, cmdq->db_id); @@ -222,51 +232,46 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm return 0; } -static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine, - u8 priority) +static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u8 priority) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; int ret; lockdep_assert_held(&file_priv->lock); + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) + if (cmdq->priority == priority) + break; + if (!cmdq) { cmdq = ivpu_cmdq_alloc(file_priv); if (!cmdq) return NULL; - file_priv->cmdq[priority] = cmdq; + cmdq->priority = priority; } - ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority); + ret = ivpu_cmdq_init(file_priv, cmdq, priority); if (ret) return NULL; return cmdq; } -static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u8 priority) +void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; lockdep_assert_held(&file_priv->lock); - if (cmdq) { - file_priv->cmdq[priority] = NULL; + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) { + xa_erase(&file_priv->cmdq_xa, cmdq_id); ivpu_cmdq_fini(file_priv, cmdq); ivpu_cmdq_free(file_priv, cmdq); } } -void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) -{ - u8 priority; - - lockdep_assert_held(&file_priv->lock); - - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) - ivpu_cmdq_release_locked(file_priv, priority); -} - /* * Mark the doorbell as unregistered * This function needs to be called when the VPU hardware is restarted @@ -275,16 +280,13 @@ void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv) */ static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv) { - u8 priority; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; mutex_lock(&file_priv->lock); - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - struct ivpu_cmdq *cmdq = file_priv->cmdq[priority]; - - if (cmdq) - cmdq->db_registered = false; - } + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) + cmdq->db_registered = false; mutex_unlock(&file_priv->lock); } @@ -304,12 +306,11 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev) static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv) { - u8 priority; + struct ivpu_cmdq *cmdq; + unsigned long cmdq_id; - for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) { - if (file_priv->cmdq[priority]) - ivpu_cmdq_fini(file_priv, file_priv->cmdq[priority]); - } + xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq) + ivpu_cmdq_fini(file_priv, cmdq); } void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv) @@ -334,8 +335,8 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) /* Check if there is space left in job queue */ if (next_entry == header->head) { - ivpu_dbg(vdev, JOB, "Job queue full: ctx %d engine %d db %d head %d tail %d\n", - job->file_priv->ctx.id, job->engine_idx, cmdq->db_id, header->head, tail); + ivpu_dbg(vdev, JOB, "Job queue full: ctx %d cmdq %d db %d head %d tail %d\n", + job->file_priv->ctx.id, cmdq->id, cmdq->db_id, header->head, tail); return -EBUSY; } @@ -522,7 +523,7 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority) mutex_lock(&file_priv->lock); - cmdq = ivpu_cmdq_acquire(file_priv, job->engine_idx, priority); + cmdq = ivpu_cmdq_acquire(file_priv, priority); if (!cmdq) { ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n", file_priv->ctx.id, job->engine_idx, priority); diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h index 6accb94028c7..8b19e3f8b4cf 100644 --- a/drivers/accel/ivpu/ivpu_job.h +++ b/drivers/accel/ivpu/ivpu_job.h @@ -28,8 +28,10 @@ struct ivpu_cmdq { struct ivpu_bo *secondary_preempt_buf; struct ivpu_bo *mem; u32 entry_count; + u32 id; u32 db_id; bool db_registered; + u8 priority; }; /** -- GitLab From 7df06efe1c28b25ad02e49987cd0bc1661615129 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:14 +0200 Subject: [PATCH 955/970] accel/ivpu: Don't allocate preemption buffers when MIP is disabled Do not allocate preemption buffers when Mid Inference Preemption (MIP) is disabled through test mode. Rename IVPU_TEST_MODE_PREEMPTION_DISABLE to IVPU_TEST_MODE_MIP_DISABLE to better describe that this test mode only disables MIP - job level preemption will still occur. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-9-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_drv.h | 2 +- drivers/accel/ivpu/ivpu_job.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 8e79d78906bf..3fdff3f6cffd 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -197,7 +197,7 @@ extern bool ivpu_force_snoop; #define IVPU_TEST_MODE_NULL_SUBMISSION BIT(2) #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) -#define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6) +#define IVPU_TEST_MODE_MIP_DISABLE BIT(6) #define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8) #define IVPU_TEST_MODE_TURBO BIT(9) extern int ivpu_test_mode; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 82a57a30244d..39ba6d3d8b0d 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -35,7 +35,8 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE); u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE); - if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW || + ivpu_test_mode & IVPU_TEST_MODE_MIP_DISABLE) return 0; cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.user, @@ -347,8 +348,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job) if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION)) entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK; - if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW && - (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) { + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) { if (cmdq->primary_preempt_buf) { entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr; entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf); -- GitLab From 5f8600b9d5a20b01b720b4deeade7a88316aa4e3 Mon Sep 17 00:00:00 2001 From: Maciej Falkowski <maciej.falkowski@linux.intel.com> Date: Thu, 17 Oct 2024 16:58:15 +0200 Subject: [PATCH 956/970] accel/ivpu: Add debug Kconfig option Add CONFIG_DRM_ACCEL_IVPU_DEBUG option that: - Adds -DDEBUG that enables printk regardless of the kernel config - Enables unsafe module params (that are now disabled by default) Signed-off-by: Maciej Falkowski <maciej.falkowski@linux.intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-10-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/Kconfig | 9 +++++++++ drivers/accel/ivpu/Makefile | 2 ++ drivers/accel/ivpu/ivpu_drv.c | 2 ++ drivers/accel/ivpu/ivpu_fw.c | 2 ++ drivers/accel/ivpu/ivpu_pm.c | 2 ++ 5 files changed, 17 insertions(+) diff --git a/drivers/accel/ivpu/Kconfig b/drivers/accel/ivpu/Kconfig index e4d418b44626..9e055b5ce03d 100644 --- a/drivers/accel/ivpu/Kconfig +++ b/drivers/accel/ivpu/Kconfig @@ -16,3 +16,12 @@ config DRM_ACCEL_IVPU and Deep Learning applications. If "M" is selected, the module will be called intel_vpu. + +config DRM_ACCEL_IVPU_DEBUG + bool "Intel NPU debug mode" + depends on DRM_ACCEL_IVPU + help + Choose this option to enable additional + debug features for the Intel NPU driver: + - Always print debug messages regardless of dyndbg config, + - Enable unsafe module params. diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index e73937c86d9a..1029e0bab061 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -24,4 +24,6 @@ intel_vpu-$(CONFIG_DEV_COREDUMP) += ivpu_coredump.o obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o +subdir-ccflags-$(CONFIG_DRM_ACCEL_IVPU_DEBUG) += -DDEBUG + CFLAGS_ivpu_trace_points.o = -I$(src) diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index f5a8d93fe2a5..ca2bf47ce248 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -43,8 +43,10 @@ module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644); MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros."); int ivpu_test_mode; +#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(test_mode, ivpu_test_mode, int, 0644); MODULE_PARM_DESC(test_mode, "Test mode mask. See IVPU_TEST_MODE_* macros."); +#endif u8 ivpu_pll_min_ratio; module_param_named(pll_min_ratio, ivpu_pll_min_ratio, byte, 0644); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index be367465e7df..d358cf0b0f97 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -46,8 +46,10 @@ #define IVPU_FOCUS_PRESENT_TIMER_MS 1000 static char *ivpu_firmware; +#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644); MODULE_PARM_DESC(firmware, "NPU firmware binary in /lib/firmware/.."); +#endif static struct { int gen; diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index e567df79a612..dbc0711e28d1 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -24,8 +24,10 @@ #include "vpu_boot_api.h" static bool ivpu_disable_recovery; +#if IS_ENABLED(CONFIG_DRM_ACCEL_IVPU_DEBUG) module_param_named_unsafe(disable_recovery, ivpu_disable_recovery, bool, 0644); MODULE_PARM_DESC(disable_recovery, "Disables recovery when NPU hang is detected"); +#endif static unsigned long ivpu_tdr_timeout_ms; module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, ulong, 0644); -- GitLab From 83b6fa5844b53fe25417229e44c460e4f84da432 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:16 +0200 Subject: [PATCH 957/970] accel/ivpu: Increase DMA address range Increase DMA address range to: * 128 GB on 37xx (due to MMU limitations) * 256 GB on other generations Merge User and DMA ranges on 40xx and above as it is possible to access whole 256 GBs from both FW and DMA. Increase User range on 37xx from 255MB to 511MB to allow loading very large models. Do not set global_alias_pio_base/size on other generations than 37xx as it's only used on 37xx anyway. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-11-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_fw.c | 6 ++++-- drivers/accel/ivpu/ivpu_hw.c | 10 +++++----- drivers/accel/ivpu/ivpu_mmu_context.c | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index d358cf0b0f97..6037ec0b3096 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -584,8 +584,10 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2; boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2; - boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; - boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); + if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { + boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; + boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); + } /* Allow configuration for L2C_PAGE_TABLE with boot param value */ boot_params->autoconfig = 1; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 1c259d717815..09ada8b500b9 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -114,14 +114,14 @@ static void memory_ranges_init(struct ivpu_device *vdev) { if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0xc0000000, 255 * SZ_1M); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x88000000, 511 * SZ_1M); ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_128G); } else { ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M); - ivpu_hw_range_init(&vdev->hw->ranges.user, 0x80000000, SZ_256M); - ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M); - ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G); + ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000, SZ_2G); + ivpu_hw_range_init(&vdev->hw->ranges.user, 0x100000000, SZ_256G); + vdev->hw->ranges.dma = vdev->hw->ranges.user; } } diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c index 697b57071d54..891967a95bc3 100644 --- a/drivers/accel/ivpu/ivpu_mmu_context.c +++ b/drivers/accel/ivpu/ivpu_mmu_context.c @@ -571,8 +571,8 @@ void ivpu_mmu_context_init(struct ivpu_device *vdev, struct ivpu_mmu_context *ct start = vdev->hw->ranges.global.start; end = vdev->hw->ranges.shave.end; } else { - start = vdev->hw->ranges.user.start; - end = vdev->hw->ranges.dma.end; + start = min_t(u64, vdev->hw->ranges.user.start, vdev->hw->ranges.shave.start); + end = max_t(u64, vdev->hw->ranges.user.end, vdev->hw->ranges.dma.end); } drm_mm_init(&ctx->mm, start, end - start); -- GitLab From e91191efe75a94ae10fac4b384962068a8151886 Mon Sep 17 00:00:00 2001 From: Karol Wachowski <karol.wachowski@intel.com> Date: Thu, 17 Oct 2024 16:58:17 +0200 Subject: [PATCH 958/970] accel/ivpu: Move secondary preemption buffer allocation to DMA range Secondary preemption buffer is accessible by NPU's DMA and can be allocated with addresses above 4 GB. Move secondary preemption buffer allocation from SHAVE range which is much smaller (2GB) to DMA range. This allows to allocate more command queues with corresponding preemption buffers without running out of address range. Signed-off-by: Karol Wachowski <karol.wachowski@intel.com> Reviewed-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241017145817.121590-12-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/ivpu_job.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 39ba6d3d8b0d..7149312f16e1 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -46,7 +46,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev, return -ENOMEM; } - cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.shave, + cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &vdev->hw->ranges.dma, secondary_size, DRM_IVPU_BO_WC); if (!cmdq->secondary_preempt_buf) { ivpu_err(vdev, "Failed to create secondary preemption buffer\n"); -- GitLab From 2e07c88914fc5289c21820b1aa94f058feb38197 Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:53 -0400 Subject: [PATCH 959/970] drm: zynqmp_kms: Unplug DRM device before removal Prevent userspace accesses to the DRM device from causing use-after-frees by unplugging the device before we remove it. This causes any further userspace accesses to result in an error without further calls into this driver's internals. Fixes: d76271d22694 ("drm: xlnx: DRM/KMS driver for Xilinx ZynqMP DisplayPort Subsystem") Closes: https://lore.kernel.org/dri-devel/4d8f4c9b-2efb-4774-9a37-2f257f79b2c9@linux.dev/ Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-2-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c index 2452c2f09161..0812dd6bad7c 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c @@ -538,7 +538,7 @@ void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub) { struct drm_device *drm = &dpsub->drm->dev; - drm_dev_unregister(drm); + drm_dev_unplug(drm); drm_atomic_helper_shutdown(drm); drm_encoder_cleanup(&dpsub->drm->encoder); drm_kms_helper_poll_fini(drm); -- GitLab From a7d5eeaa57d7a0d3d6a1da82b350d9661c8559a1 Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:54 -0400 Subject: [PATCH 960/970] drm: zynqmp_dp: Add locking Add some locking to prevent the IRQ/workers/bridge API calls from stepping on each other's toes. This lock protects: - Non-atomic registers configuring the link. That is, everything but the IRQ registers (since these are accessed in an atomic fashion), and the DP AUX registers (since these don't affect the link). We also access AUX while holding this lock, so it would be very tricky to support. - Link configuration. This is effectively everything in zynqmp_dp which isn't read-only after probe time. So from next_bridge onward. This lock is designed to protect configuration changes so we don't have to do anything tricky. Configuration should never be in the hot path, so I'm not worried about performance. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-3-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 129beac4c073..abfccd8bb5a7 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -280,6 +280,7 @@ struct zynqmp_dp_config { * @dpsub: Display subsystem * @iomem: device I/O memory for register access * @reset: reset controller + * @lock: Mutex protecting this struct and register access (but not AUX) * @irq: irq * @bridge: DRM bridge for the DP encoder * @next_bridge: The downstream bridge @@ -294,11 +295,16 @@ struct zynqmp_dp_config { * @link_config: common link configuration between IP core and sink device * @mode: current mode between IP core and sink device * @train_set: set of training data + * + * @lock covers the link configuration in this struct and the device's + * registers. It does not cover @aux. It is not strictly required for any of + * the members which are only modified at probe/remove time (e.g. @dev). */ struct zynqmp_dp { struct drm_dp_aux aux; struct drm_bridge bridge; struct work_struct hpd_work; + struct mutex lock; struct drm_bridge *next_bridge; struct device *dev; @@ -1386,8 +1392,10 @@ zynqmp_dp_bridge_mode_valid(struct drm_bridge *bridge, } /* Check with link rate and lane count */ + mutex_lock(&dp->lock); rate = zynqmp_dp_max_rate(dp->link_config.max_rate, dp->link_config.max_lanes, dp->config.bpp); + mutex_unlock(&dp->lock); if (mode->clock > rate) { dev_dbg(dp->dev, "filtered mode %s for high pixel rate\n", mode->name); @@ -1414,6 +1422,7 @@ static void zynqmp_dp_bridge_atomic_enable(struct drm_bridge *bridge, pm_runtime_get_sync(dp->dev); + mutex_lock(&dp->lock); zynqmp_dp_disp_enable(dp, old_bridge_state); /* @@ -1474,6 +1483,7 @@ static void zynqmp_dp_bridge_atomic_enable(struct drm_bridge *bridge, zynqmp_dp_write(dp, ZYNQMP_DP_SOFTWARE_RESET, ZYNQMP_DP_SOFTWARE_RESET_ALL); zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 1); + mutex_unlock(&dp->lock); } static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge, @@ -1481,6 +1491,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge, { struct zynqmp_dp *dp = bridge_to_dp(bridge); + mutex_lock(&dp->lock); dp->enabled = false; cancel_work(&dp->hpd_work); zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0); @@ -1491,6 +1502,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge, zynqmp_dp_write(dp, ZYNQMP_DP_TX_AUDIO_CONTROL, 0); zynqmp_dp_disp_disable(dp, old_bridge_state); + mutex_unlock(&dp->lock); pm_runtime_put_sync(dp->dev); } @@ -1533,6 +1545,8 @@ static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *brid u32 state, i; int ret; + mutex_lock(&dp->lock); + /* * This is from heuristic. It takes some delay (ex, 100 ~ 500 msec) to * get the HPD signal with some monitors. @@ -1560,11 +1574,13 @@ static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *brid dp->num_lanes); dp->status = connector_status_connected; + mutex_unlock(&dp->lock); return connector_status_connected; } disconnected: dp->status = connector_status_disconnected; + mutex_unlock(&dp->lock); return connector_status_disconnected; } @@ -1725,6 +1741,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) dp->dev = &pdev->dev; dp->dpsub = dpsub; dp->status = connector_status_disconnected; + mutex_init(&dp->lock); INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); @@ -1838,4 +1855,5 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub) zynqmp_dp_phy_exit(dp); zynqmp_dp_reset(dp, true); + mutex_destroy(&dp->lock); } -- GitLab From 851daf0ceca10278714a359dabbe97d360a6949b Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:55 -0400 Subject: [PATCH 961/970] drm: zynqmp_dp: Don't retrain the link in our IRQ Retraining the link can take a while, and might involve waiting for DPCD reads/writes to complete. In preparation for unthreading the IRQ handler, move this into its own work function. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-4-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 45 ++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index abfccd8bb5a7..cec5711c7026 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -289,6 +289,7 @@ struct zynqmp_dp_config { * @phy: PHY handles for DP lanes * @num_lanes: number of enabled phy lanes * @hpd_work: hot plug detection worker + * @hpd_irq_work: hot plug detection IRQ worker * @status: connection status * @enabled: flag to indicate if the device is enabled * @dpcd: DP configuration data from currently connected sink device @@ -304,6 +305,7 @@ struct zynqmp_dp { struct drm_dp_aux aux; struct drm_bridge bridge; struct work_struct hpd_work; + struct work_struct hpd_irq_work; struct mutex lock; struct drm_bridge *next_bridge; @@ -1671,6 +1673,29 @@ static void zynqmp_dp_hpd_work_func(struct work_struct *work) drm_bridge_hpd_notify(&dp->bridge, status); } +static void zynqmp_dp_hpd_irq_work_func(struct work_struct *work) +{ + struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, + hpd_irq_work); + u8 status[DP_LINK_STATUS_SIZE + 2]; + int err; + + mutex_lock(&dp->lock); + err = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, + DP_LINK_STATUS_SIZE + 2); + if (err < 0) { + dev_dbg_ratelimited(dp->dev, + "could not read sink status: %d\n", err); + } else { + if (status[4] & DP_LINK_STATUS_UPDATED || + !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) || + !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) { + zynqmp_dp_train_loop(dp); + } + } + mutex_unlock(&dp->lock); +} + static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data) { struct zynqmp_dp *dp = (struct zynqmp_dp *)data; @@ -1702,23 +1727,9 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data) if (status & ZYNQMP_DP_INT_HPD_EVENT) schedule_work(&dp->hpd_work); - if (status & ZYNQMP_DP_INT_HPD_IRQ) { - int ret; - u8 status[DP_LINK_STATUS_SIZE + 2]; - - ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, - DP_LINK_STATUS_SIZE + 2); - if (ret < 0) - goto handled; - - if (status[4] & DP_LINK_STATUS_UPDATED || - !drm_dp_clock_recovery_ok(&status[2], dp->mode.lane_cnt) || - !drm_dp_channel_eq_ok(&status[2], dp->mode.lane_cnt)) { - zynqmp_dp_train_loop(dp); - } - } + if (status & ZYNQMP_DP_INT_HPD_IRQ) + schedule_work(&dp->hpd_irq_work); -handled: return IRQ_HANDLED; } @@ -1744,6 +1755,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) mutex_init(&dp->lock); INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); + INIT_WORK(&dp->hpd_irq_work, zynqmp_dp_hpd_irq_work_func); /* Acquire all resources (IOMEM, IRQ and PHYs). */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp"); @@ -1848,6 +1860,7 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub) zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL); disable_irq(dp->irq); + cancel_work_sync(&dp->hpd_irq_work); cancel_work_sync(&dp->hpd_work); zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0); -- GitLab From 948a944ea7a6c64cac73c46d06da0548d8f03b65 Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:56 -0400 Subject: [PATCH 962/970] drm: zynqmp_dp: Convert to a hard IRQ Now that all of the sleeping work is done outside of the IRQ, we can convert it to a hard IRQ. Shared IRQs may be triggered even after calling disable_irq, so use free_irq instead which removes our callback altogether. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-5-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index cec5711c7026..532e103713b3 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -1831,9 +1831,8 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) * Now that the hardware is initialized and won't generate spurious * interrupts, request the IRQ. */ - ret = devm_request_threaded_irq(dp->dev, dp->irq, NULL, - zynqmp_dp_irq_handler, IRQF_ONESHOT, - dev_name(dp->dev), dp); + ret = devm_request_irq(dp->dev, dp->irq, zynqmp_dp_irq_handler, + IRQF_SHARED, dev_name(dp->dev), dp); if (ret < 0) goto err_phy_exit; @@ -1858,7 +1857,7 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub) struct zynqmp_dp *dp = dpsub->dp; zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL); - disable_irq(dp->irq); + devm_free_irq(dp->dev, dp->irq, dp); cancel_work_sync(&dp->hpd_irq_work); cancel_work_sync(&dp->hpd_work); -- GitLab From 2425dee876bffc0d34413fccb4d2eae4f251db5c Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:57 -0400 Subject: [PATCH 963/970] drm: zynqmp_dp: Use AUX IRQs instead of polling Instead of polling the status register for the AUX status, just enable the IRQs and signal a completion. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-6-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 35 +++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 532e103713b3..babfa3581014 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -286,6 +286,7 @@ struct zynqmp_dp_config { * @next_bridge: The downstream bridge * @config: IP core configuration from DTS * @aux: aux channel + * @aux_done: Completed when we get an AUX reply or timeout * @phy: PHY handles for DP lanes * @num_lanes: number of enabled phy lanes * @hpd_work: hot plug detection worker @@ -306,6 +307,7 @@ struct zynqmp_dp { struct drm_bridge bridge; struct work_struct hpd_work; struct work_struct hpd_irq_work; + struct completion aux_done; struct mutex lock; struct drm_bridge *next_bridge; @@ -942,12 +944,15 @@ static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr, u8 *buf, u8 bytes, u8 *reply) { bool is_read = (cmd & AUX_READ_BIT) ? true : false; + unsigned long time_left; u32 reg, i; reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REQUEST) return -EBUSY; + reinit_completion(&dp->aux_done); + zynqmp_dp_write(dp, ZYNQMP_DP_AUX_ADDRESS, addr); if (!is_read) for (i = 0; i < bytes; i++) @@ -962,17 +967,14 @@ static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr, zynqmp_dp_write(dp, ZYNQMP_DP_AUX_COMMAND, reg); /* Wait for reply to be delivered upto 2ms */ - for (i = 0; ; i++) { - reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); - if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY) - break; + time_left = wait_for_completion_timeout(&dp->aux_done, + msecs_to_jiffies(2)); + if (!time_left) + return -ETIMEDOUT; - if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT || - i == 2) - return -ETIMEDOUT; - - usleep_range(1000, 1100); - } + reg = zynqmp_dp_read(dp, ZYNQMP_DP_INTERRUPT_SIGNAL_STATE); + if (reg & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT) + return -ETIMEDOUT; reg = zynqmp_dp_read(dp, ZYNQMP_DP_AUX_REPLY_CODE); if (reply) @@ -1056,6 +1058,9 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp) (w << ZYNQMP_DP_AUX_CLK_DIVIDER_AUX_FILTER_SHIFT) | (rate / (1000 * 1000))); + zynqmp_dp_write(dp, ZYNQMP_DP_INT_EN, ZYNQMP_DP_INT_REPLY_RECEIVED | + ZYNQMP_DP_INT_REPLY_TIMEOUT); + dp->aux.name = "ZynqMP DP AUX"; dp->aux.dev = dp->dev; dp->aux.drm_dev = dp->bridge.dev; @@ -1073,6 +1078,9 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp) static void zynqmp_dp_aux_cleanup(struct zynqmp_dp *dp) { drm_dp_aux_unregister(&dp->aux); + + zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_REPLY_RECEIVED | + ZYNQMP_DP_INT_REPLY_TIMEOUT); } /* ----------------------------------------------------------------------------- @@ -1730,6 +1738,12 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data) if (status & ZYNQMP_DP_INT_HPD_IRQ) schedule_work(&dp->hpd_irq_work); + if (status & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY) + complete(&dp->aux_done); + + if (status & ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT) + complete(&dp->aux_done); + return IRQ_HANDLED; } @@ -1753,6 +1767,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub) dp->dpsub = dpsub; dp->status = connector_status_disconnected; mutex_init(&dp->lock); + init_completion(&dp->aux_done); INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func); INIT_WORK(&dp->hpd_irq_work, zynqmp_dp_hpd_irq_work_func); -- GitLab From 17f12a46cffd916fe735213c1b1c3dad1de187f3 Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:58 -0400 Subject: [PATCH 964/970] drm: zynqmp_dp: Split off several helper functions In preparation for supporting compliance testing, split off several helper functions. No functional change intended. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-7-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 48 ++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index babfa3581014..3edefa0f1795 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -636,6 +636,7 @@ static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp, /** * zynqmp_dp_update_vs_emph - Update the training values * @dp: DisplayPort IP core structure + * @train_set: A set of training values * * Update the training values based on the request from sink. The mapped values * are predefined, and values(vs, pe, pc) are from the device manual. @@ -643,12 +644,12 @@ static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp, * Return: 0 if vs and emph are updated successfully, or the error code returned * by drm_dp_dpcd_write(). */ -static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp) +static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp, u8 *train_set) { unsigned int i; int ret; - ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, dp->train_set, + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, train_set, dp->mode.lane_cnt); if (ret < 0) return ret; @@ -656,7 +657,7 @@ static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp) for (i = 0; i < dp->mode.lane_cnt; i++) { u32 reg = ZYNQMP_DP_SUB_TX_PHY_PRECURSOR_LANE_0 + i * 4; union phy_configure_opts opts = { 0 }; - u8 train = dp->train_set[i]; + u8 train = train_set[i]; opts.dp.voltage[0] = (train & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT; @@ -700,7 +701,7 @@ static int zynqmp_dp_link_train_cr(struct zynqmp_dp *dp) * So, This loop should exit before 512 iterations */ for (max_tries = 0; max_tries < 512; max_tries++) { - ret = zynqmp_dp_update_vs_emph(dp); + ret = zynqmp_dp_update_vs_emph(dp, dp->train_set); if (ret) return ret; @@ -765,7 +766,7 @@ static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp) return ret; for (tries = 0; tries < DP_MAX_TRAINING_TRIES; tries++) { - ret = zynqmp_dp_update_vs_emph(dp); + ret = zynqmp_dp_update_vs_emph(dp, dp->train_set); if (ret) return ret; @@ -788,28 +789,29 @@ static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp) } /** - * zynqmp_dp_train - Train the link + * zynqmp_dp_setup() - Set up major link parameters * @dp: DisplayPort IP core structure + * @bw_code: The link bandwidth as a multiple of 270 MHz + * @lane_cnt: The number of lanes to use + * @enhanced: Use enhanced framing + * @downspread: Enable spread-spectrum clocking * - * Return: 0 if all trains are done successfully, or corresponding error code. + * Return: 0 on success, or -errno on failure */ -static int zynqmp_dp_train(struct zynqmp_dp *dp) +static int zynqmp_dp_setup(struct zynqmp_dp *dp, u8 bw_code, u8 lane_cnt, + bool enhanced, bool downspread) { u32 reg; - u8 bw_code = dp->mode.bw_code; - u8 lane_cnt = dp->mode.lane_cnt; u8 aux_lane_cnt = lane_cnt; - bool enhanced; int ret; zynqmp_dp_write(dp, ZYNQMP_DP_LANE_COUNT_SET, lane_cnt); - enhanced = drm_dp_enhanced_frame_cap(dp->dpcd); if (enhanced) { zynqmp_dp_write(dp, ZYNQMP_DP_ENHANCED_FRAME_EN, 1); aux_lane_cnt |= DP_LANE_COUNT_ENHANCED_FRAME_EN; } - if (dp->dpcd[3] & 0x1) { + if (downspread) { zynqmp_dp_write(dp, ZYNQMP_DP_DOWNSPREAD_CTL, 1); drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); @@ -852,8 +854,24 @@ static int zynqmp_dp_train(struct zynqmp_dp *dp) } zynqmp_dp_write(dp, ZYNQMP_DP_PHY_CLOCK_SELECT, reg); - ret = zynqmp_dp_phy_ready(dp); - if (ret < 0) + return zynqmp_dp_phy_ready(dp); +} + +/** + * zynqmp_dp_train - Train the link + * @dp: DisplayPort IP core structure + * + * Return: 0 if all trains are done successfully, or corresponding error code. + */ +static int zynqmp_dp_train(struct zynqmp_dp *dp) +{ + int ret; + + ret = zynqmp_dp_setup(dp, dp->mode.bw_code, dp->mode.lane_cnt, + drm_dp_enhanced_frame_cap(dp->dpcd), + dp->dpcd[DP_MAX_DOWNSPREAD] & + DP_MAX_DOWNSPREAD_0_5); + if (ret) return ret; zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, 1); -- GitLab From 76f2c96d6cea2a84ac8f7c899a4a5ae2bff1ed33 Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:35:59 -0400 Subject: [PATCH 965/970] drm: zynqmp_dp: Take dp->lock in zynqmp_dp_hpd_work_func Add a non-locking version of zynqmp_dp_bridge_detect and use it in zynqmp_dp_hpd_work_func so we can take the lock explicitly. This will make it easier to check for hpd_ignore when we add debugfs support. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-8-sean.anderson@linux.dev --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 3edefa0f1795..49b4b24f499f 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -1566,14 +1566,13 @@ static int zynqmp_dp_bridge_atomic_check(struct drm_bridge *bridge, return 0; } -static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *bridge) +static enum drm_connector_status __zynqmp_dp_bridge_detect(struct zynqmp_dp *dp) { - struct zynqmp_dp *dp = bridge_to_dp(bridge); struct zynqmp_dp_link_config *link_config = &dp->link_config; u32 state, i; int ret; - mutex_lock(&dp->lock); + lockdep_assert_held(&dp->lock); /* * This is from heuristic. It takes some delay (ex, 100 ~ 500 msec) to @@ -1602,16 +1601,26 @@ static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *brid dp->num_lanes); dp->status = connector_status_connected; - mutex_unlock(&dp->lock); return connector_status_connected; } disconnected: dp->status = connector_status_disconnected; - mutex_unlock(&dp->lock); return connector_status_disconnected; } +static enum drm_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *bridge) +{ + struct zynqmp_dp *dp = bridge_to_dp(bridge); + enum drm_connector_status ret; + + mutex_lock(&dp->lock); + ret = __zynqmp_dp_bridge_detect(dp); + mutex_unlock(&dp->lock); + + return ret; +} + static const struct drm_edid *zynqmp_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector) { @@ -1695,7 +1704,10 @@ static void zynqmp_dp_hpd_work_func(struct work_struct *work) struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, hpd_work); enum drm_connector_status status; - status = zynqmp_dp_bridge_detect(&dp->bridge); + mutex_lock(&dp->lock); + status = __zynqmp_dp_bridge_detect(dp); + mutex_unlock(&dp->lock); + drm_bridge_hpd_notify(&dp->bridge, status); } -- GitLab From 28edaacb821c69241f6c0be6bbd29f7145f1b44f Mon Sep 17 00:00:00 2001 From: Sean Anderson <sean.anderson@linux.dev> Date: Fri, 9 Aug 2024 15:36:00 -0400 Subject: [PATCH 966/970] drm: zynqmp_dp: Add debugfs interface for compliance testing Add a debugfs interface for exercising the various test modes supported by the DisplayPort controller. This allows performing compliance testing, or performing signal integrity measurements on a failing link. At the moment, we do not support sink-driven link quality testing, although such support would be fairly easy to add. Additionally, add some debugfs files for ignoring AUX errors and HPD events, as this can allow testing with equipment that cannot emulate a DPRX. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> [Tomi: fixed a few minor formatting issues] Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240809193600.3360015-9-sean.anderson@linux.dev --- Documentation/gpu/drivers.rst | 1 + Documentation/gpu/zynqmp.rst | 149 +++++++ MAINTAINERS | 1 + drivers/gpu/drm/xlnx/zynqmp_dp.c | 680 ++++++++++++++++++++++++++++++- 4 files changed, 828 insertions(+), 3 deletions(-) create mode 100644 Documentation/gpu/zynqmp.rst diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst index b899cbc5c2b4..187201aedbe5 100644 --- a/Documentation/gpu/drivers.rst +++ b/Documentation/gpu/drivers.rst @@ -22,6 +22,7 @@ GPU Driver Documentation afbc komeda-kms panfrost + zynqmp .. only:: subproject and html diff --git a/Documentation/gpu/zynqmp.rst b/Documentation/gpu/zynqmp.rst new file mode 100644 index 000000000000..f57bfa0ad6ec --- /dev/null +++ b/Documentation/gpu/zynqmp.rst @@ -0,0 +1,149 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +=============================================== +Xilinx ZynqMP Ultrascale+ DisplayPort Subsystem +=============================================== + +This subsystem handles DisplayPort video and audio output on the ZynqMP. It +supports in-memory framebuffers with the DisplayPort DMA controller +(xilinx-dpdma), as well as "live" video and audio from the programmable logic +(PL). This subsystem can perform several transformations, including color space +conversion, alpha blending, and audio mixing, although not all features are +currently supported. + +debugfs +------- + +To support debugging and compliance testing, several test modes can be enabled +though debugfs. The following files in /sys/kernel/debug/dri/X/DP-1/test/ +control the DisplayPort test modes: + +active: + Writing a 1 to this file will activate test mode, and writing a 0 will + deactivate test mode. Writing a 1 or 0 when the test mode is already + active/inactive will re-activate/re-deactivate test mode. When test + mode is inactive, changes made to other files will have no (immediate) + effect, although the settings will be saved for when test mode is + activated. When test mode is active, changes made to other files will + apply immediately. + +custom: + Custom test pattern value + +downspread: + Enable/disable clock downspreading (spread-spectrum clocking) by + writing 1/0 + +enhanced: + Enable/disable enhanced framing + +ignore_aux_errors: + Ignore AUX errors when set to 1. Writes to this file take effect + immediately (regardless of whether test mode is active) and affect all + AUX transfers. + +ignore_hpd: + Ignore hotplug events (such as cable removals or monitor link + retraining requests) when set to 1. Writes to this file take effect + immediately (regardless of whether test mode is active). + +laneX_preemphasis: + Preemphasis from 0 (lowest) to 2 (highest) for lane X + +laneX_swing: + Voltage swing from 0 (lowest) to 3 (highest) for lane X + +lanes: + Number of lanes to use (1, 2, or 4) + +pattern: + Test pattern. May be one of: + + video + Use regular video input + + symbol-error + Symbol error measurement pattern + + prbs7 + Output of the PRBS7 (x^7 + x^6 + 1) polynomial + + 80bit-custom + A custom 80-bit pattern + + cp2520 + HBR2 compliance eye pattern + + tps1 + Link training symbol pattern TPS1 (/D10.2/) + + tps2 + Link training symbol pattern TPS2 + + tps3 + Link training symbol pattern TPS3 (for HBR2) + +rate: + Rate in hertz. One of + + * 5400000000 (HBR2) + * 2700000000 (HBR) + * 1620000000 (RBR) + +You can dump the displayport test settings with the following command:: + + for prop in /sys/kernel/debug/dri/1/DP-1/test/*; do + printf '%-17s ' ${prop##*/} + if [ ${prop##*/} = custom ]; then + hexdump -C $prop | head -1 + else + cat $prop + fi + done + +The output could look something like:: + + active 1 + custom 00000000 00 00 00 00 00 00 00 00 00 00 |..........| + downspread 0 + enhanced 1 + ignore_aux_errors 1 + ignore_hpd 1 + lane0_preemphasis 0 + lane0_swing 3 + lane1_preemphasis 0 + lane1_swing 3 + lanes 2 + pattern prbs7 + rate 1620000000 + +The recommended test procedure is to connect the board to a monitor, +configure test mode, activate test mode, and then disconnect the cable +and connect it to your test equipment of choice. For example, one +sequence of commands could be:: + + echo 1 > /sys/kernel/debug/dri/1/DP-1/test/enhanced + echo tps1 > /sys/kernel/debug/dri/1/DP-1/test/pattern + echo 1620000000 > /sys/kernel/debug/dri/1/DP-1/test/rate + echo 1 > /sys/kernel/debug/dri/1/DP-1/test/ignore_aux_errors + echo 1 > /sys/kernel/debug/dri/1/DP-1/test/ignore_hpd + echo 1 > /sys/kernel/debug/dri/1/DP-1/test/active + +at which point the cable could be disconnected from the monitor. + +Internals +--------- + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_disp.h + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dpsub.h + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_kms.h + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_disp.c + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dp.c + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_dpsub.c + +.. kernel-doc:: drivers/gpu/drm/xlnx/zynqmp_kms.c diff --git a/MAINTAINERS b/MAINTAINERS index 8b993d6de0f3..a3c87aab42d9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7838,6 +7838,7 @@ L: dri-devel@lists.freedesktop.org S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/xlnx/ +F: Documentation/gpu/zynqmp.rst F: drivers/gpu/drm/xlnx/ DRM GPU SCHEDULER diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 49b4b24f499f..25c5dc61ee88 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -18,7 +18,9 @@ #include <drm/drm_modes.h> #include <drm/drm_of.h> +#include <linux/bitfield.h> #include <linux/clk.h> +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/io.h> @@ -51,6 +53,7 @@ MODULE_PARM_DESC(power_on_delay_ms, "DP power on delay in msec (default: 4)"); #define ZYNQMP_DP_LANE_COUNT_SET 0x4 #define ZYNQMP_DP_ENHANCED_FRAME_EN 0x8 #define ZYNQMP_DP_TRAINING_PATTERN_SET 0xc +#define ZYNQMP_DP_LINK_QUAL_PATTERN_SET 0x10 #define ZYNQMP_DP_SCRAMBLING_DISABLE 0x14 #define ZYNQMP_DP_DOWNSPREAD_CTL 0x18 #define ZYNQMP_DP_SOFTWARE_RESET 0x1c @@ -64,6 +67,9 @@ MODULE_PARM_DESC(power_on_delay_ms, "DP power on delay in msec (default: 4)"); ZYNQMP_DP_SOFTWARE_RESET_STREAM3 | \ ZYNQMP_DP_SOFTWARE_RESET_STREAM4 | \ ZYNQMP_DP_SOFTWARE_RESET_AUX) +#define ZYNQMP_DP_COMP_PATTERN_80BIT_1 0x20 +#define ZYNQMP_DP_COMP_PATTERN_80BIT_2 0x24 +#define ZYNQMP_DP_COMP_PATTERN_80BIT_3 0x28 /* Core enable registers */ #define ZYNQMP_DP_TRANSMITTER_ENABLE 0x80 @@ -207,6 +213,7 @@ MODULE_PARM_DESC(power_on_delay_ms, "DP power on delay in msec (default: 4)"); #define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_2 BIT(2) #define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_3 BIT(3) #define ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL 0xf +#define ZYNQMP_DP_TRANSMIT_PRBS7 0x230 #define ZYNQMP_DP_PHY_PRECURSOR_LANE_0 0x23c #define ZYNQMP_DP_PHY_PRECURSOR_LANE_1 0x240 #define ZYNQMP_DP_PHY_PRECURSOR_LANE_2 0x244 @@ -274,6 +281,69 @@ struct zynqmp_dp_config { u8 bpp; }; +/** + * enum test_pattern - Test patterns for test testing + * @TEST_VIDEO: Use regular video input + * @TEST_SYMBOL_ERROR: Symbol error measurement pattern + * @TEST_PRBS7: Output of the PRBS7 (x^7 + x^6 + 1) polynomial + * @TEST_80BIT_CUSTOM: A custom 80-bit pattern + * @TEST_CP2520: HBR2 compliance eye pattern + * @TEST_TPS1: Link training symbol pattern TPS1 (/D10.2/) + * @TEST_TPS2: Link training symbol pattern TPS2 + * @TEST_TPS3: Link training symbol pattern TPS3 (for HBR2) + */ +enum test_pattern { + TEST_VIDEO, + TEST_TPS1, + TEST_TPS2, + TEST_TPS3, + TEST_SYMBOL_ERROR, + TEST_PRBS7, + TEST_80BIT_CUSTOM, + TEST_CP2520, +}; + +static const char *const test_pattern_str[] = { + [TEST_VIDEO] = "video", + [TEST_TPS1] = "tps1", + [TEST_TPS2] = "tps2", + [TEST_TPS3] = "tps3", + [TEST_SYMBOL_ERROR] = "symbol-error", + [TEST_PRBS7] = "prbs7", + [TEST_80BIT_CUSTOM] = "80bit-custom", + [TEST_CP2520] = "cp2520", +}; + +/** + * struct zynqmp_dp_test - Configuration for test mode + * @pattern: The test pattern + * @enhanced: Use enhanced framing + * @downspread: Use SSC + * @active: Whether test mode is active + * @custom: Custom pattern for %TEST_80BIT_CUSTOM + * @train_set: Voltage/preemphasis settings + * @bw_code: Bandwidth code for the link + * @link_cnt: Number of lanes + */ +struct zynqmp_dp_test { + enum test_pattern pattern; + bool enhanced, downspread, active; + u8 custom[10]; + u8 train_set[ZYNQMP_DP_MAX_LANES]; + u8 bw_code; + u8 link_cnt; +}; + +/** + * struct zynqmp_dp_train_set_priv - Private data for train_set debugfs files + * @dp: DisplayPort IP core structure + * @lane: The lane for this file + */ +struct zynqmp_dp_train_set_priv { + struct zynqmp_dp *dp; + int lane; +}; + /** * struct zynqmp_dp - Xilinx DisplayPort core * @dev: device structure @@ -284,23 +354,28 @@ struct zynqmp_dp_config { * @irq: irq * @bridge: DRM bridge for the DP encoder * @next_bridge: The downstream bridge + * @test: Configuration for test mode * @config: IP core configuration from DTS * @aux: aux channel * @aux_done: Completed when we get an AUX reply or timeout + * @ignore_aux_errors: If set, AUX errors are suppressed * @phy: PHY handles for DP lanes * @num_lanes: number of enabled phy lanes * @hpd_work: hot plug detection worker * @hpd_irq_work: hot plug detection IRQ worker + * @ignore_hpd: If set, HPD events and IRQs are ignored * @status: connection status * @enabled: flag to indicate if the device is enabled * @dpcd: DP configuration data from currently connected sink device * @link_config: common link configuration between IP core and sink device * @mode: current mode between IP core and sink device * @train_set: set of training data + * @debugfs_train_set: Debugfs private data for @train_set * * @lock covers the link configuration in this struct and the device's - * registers. It does not cover @aux. It is not strictly required for any of - * the members which are only modified at probe/remove time (e.g. @dev). + * registers. It does not cover @aux or @ignore_aux_errors. It is not strictly + * required for any of the members which are only modified at probe/remove time + * (e.g. @dev). */ struct zynqmp_dp { struct drm_dp_aux aux; @@ -320,9 +395,13 @@ struct zynqmp_dp { enum drm_connector_status status; int irq; bool enabled; + bool ignore_aux_errors; + bool ignore_hpd; + struct zynqmp_dp_train_set_priv debugfs_train_set[ZYNQMP_DP_MAX_LANES]; struct zynqmp_dp_mode mode; struct zynqmp_dp_link_config link_config; + struct zynqmp_dp_test test; struct zynqmp_dp_config config; u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 train_set[ZYNQMP_DP_MAX_LANES]; @@ -1034,6 +1113,8 @@ zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) if (dp->status == connector_status_disconnected) { dev_dbg(dp->dev, "no connected aux device\n"); + if (dp->ignore_aux_errors) + goto fake_response; return -ENODEV; } @@ -1042,7 +1123,13 @@ zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) dev_dbg(dp->dev, "failed to do aux transfer (%d)\n", ret); - return ret; + if (!dp->ignore_aux_errors) + return ret; + +fake_response: + msg->reply = DP_AUX_NATIVE_REPLY_ACK; + memset(msg->buffer, 0, msg->size); + return msg->size; } /** @@ -1658,6 +1745,582 @@ zynqmp_dp_bridge_get_input_bus_fmts(struct drm_bridge *bridge, return zynqmp_dp_bridge_default_bus_fmts(num_input_fmts); } +/* ----------------------------------------------------------------------------- + * debugfs + */ + +/** + * zynqmp_dp_set_test_pattern() - Configure the link for a test pattern + * @dp: DisplayPort IP core structure + * @pattern: The test pattern to configure + * @custom: The custom pattern to use if @pattern is %TEST_80BIT_CUSTOM + * + * Return: 0 on success, or negative errno on (DPCD) failure + */ +static int zynqmp_dp_set_test_pattern(struct zynqmp_dp *dp, + enum test_pattern pattern, + u8 *const custom) +{ + bool scramble = false; + u32 train_pattern = 0; + u32 link_pattern = 0; + u8 dpcd_train = 0; + u8 dpcd_link = 0; + int ret; + + switch (pattern) { + case TEST_TPS1: + train_pattern = 1; + break; + case TEST_TPS2: + train_pattern = 2; + break; + case TEST_TPS3: + train_pattern = 3; + break; + case TEST_SYMBOL_ERROR: + scramble = true; + link_pattern = DP_PHY_TEST_PATTERN_ERROR_COUNT; + break; + case TEST_PRBS7: + /* We use a dedicated register to enable PRBS7 */ + dpcd_link = DP_LINK_QUAL_PATTERN_ERROR_RATE; + break; + case TEST_80BIT_CUSTOM: { + const u8 *p = custom; + + link_pattern = DP_LINK_QUAL_PATTERN_80BIT_CUSTOM; + + zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_1, + (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); + zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_2, + (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]); + zynqmp_dp_write(dp, ZYNQMP_DP_COMP_PATTERN_80BIT_3, + (p[9] << 8) | p[8]); + break; + } + case TEST_CP2520: + link_pattern = DP_LINK_QUAL_PATTERN_CP2520_PAT_1; + break; + default: + WARN_ON_ONCE(1); + fallthrough; + case TEST_VIDEO: + scramble = true; + } + + zynqmp_dp_write(dp, ZYNQMP_DP_SCRAMBLING_DISABLE, !scramble); + zynqmp_dp_write(dp, ZYNQMP_DP_TRAINING_PATTERN_SET, train_pattern); + zynqmp_dp_write(dp, ZYNQMP_DP_LINK_QUAL_PATTERN_SET, link_pattern); + zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMIT_PRBS7, pattern == TEST_PRBS7); + + dpcd_link = dpcd_link ?: link_pattern; + dpcd_train = train_pattern; + if (!scramble) + dpcd_train |= DP_LINK_SCRAMBLING_DISABLE; + + if (dp->dpcd[DP_DPCD_REV] < 0x12) { + if (pattern == TEST_CP2520) + dev_warn(dp->dev, + "can't set sink link quality pattern to CP2520 for DPCD < r1.2; error counters will be invalid\n"); + else + dpcd_train |= FIELD_PREP(DP_LINK_QUAL_PATTERN_11_MASK, + dpcd_link); + } else { + u8 dpcd_link_lane[ZYNQMP_DP_MAX_LANES]; + + memset(dpcd_link_lane, dpcd_link, ZYNQMP_DP_MAX_LANES); + ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_QUAL_LANE0_SET, + dpcd_link_lane, ZYNQMP_DP_MAX_LANES); + if (ret < 0) + return ret; + } + + ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, dpcd_train); + return ret < 0 ? ret : 0; +} + +static int zynqmp_dp_test_setup(struct zynqmp_dp *dp) +{ + return zynqmp_dp_setup(dp, dp->test.bw_code, dp->test.link_cnt, + dp->test.enhanced, dp->test.downspread); +} + +static ssize_t zynqmp_dp_pattern_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct dentry *dentry = file->f_path.dentry; + struct zynqmp_dp *dp = file->private_data; + char buf[16]; + ssize_t ret; + + ret = debugfs_file_get(dentry); + if (unlikely(ret)) + return ret; + + mutex_lock(&dp->lock); + ret = snprintf(buf, sizeof(buf), "%s\n", + test_pattern_str[dp->test.pattern]); + mutex_unlock(&dp->lock); + + debugfs_file_put(dentry); + return simple_read_from_buffer(user_buf, count, ppos, buf, ret); +} + +static ssize_t zynqmp_dp_pattern_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct dentry *dentry = file->f_path.dentry; + struct zynqmp_dp *dp = file->private_data; + char buf[16]; + ssize_t ret; + int pattern; + + ret = debugfs_file_get(dentry); + if (unlikely(ret)) + return ret; + + ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, + count); + if (ret < 0) + goto out; + buf[ret] = '\0'; + + pattern = sysfs_match_string(test_pattern_str, buf); + if (pattern < 0) { + ret = -EINVAL; + goto out; + } + + mutex_lock(&dp->lock); + dp->test.pattern = pattern; + if (dp->test.active) + ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, + dp->test.custom) ?: ret; + mutex_unlock(&dp->lock); + +out: + debugfs_file_put(dentry); + return ret; +} + +static const struct file_operations fops_zynqmp_dp_pattern = { + .read = zynqmp_dp_pattern_read, + .write = zynqmp_dp_pattern_write, + .open = simple_open, + .llseek = noop_llseek, +}; + +static int zynqmp_dp_enhanced_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->lock); + *val = dp->test.enhanced; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_enhanced_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + int ret = 0; + + mutex_lock(&dp->lock); + dp->test.enhanced = val; + if (dp->test.active) + ret = zynqmp_dp_test_setup(dp); + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_enhanced, zynqmp_dp_enhanced_get, + zynqmp_dp_enhanced_set, "%llu\n"); + +static int zynqmp_dp_downspread_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->lock); + *val = dp->test.downspread; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_downspread_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + int ret = 0; + + mutex_lock(&dp->lock); + dp->test.downspread = val; + if (dp->test.active) + ret = zynqmp_dp_test_setup(dp); + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_downspread, zynqmp_dp_downspread_get, + zynqmp_dp_downspread_set, "%llu\n"); + +static int zynqmp_dp_active_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->lock); + *val = dp->test.active; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_active_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + int ret = 0; + + mutex_lock(&dp->lock); + if (val) { + if (val < 2) { + ret = zynqmp_dp_test_setup(dp); + if (ret) + goto out; + } + + ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, + dp->test.custom); + if (ret) + goto out; + + ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); + if (ret) + goto out; + + dp->test.active = true; + } else { + int err; + + dp->test.active = false; + err = zynqmp_dp_set_test_pattern(dp, TEST_VIDEO, NULL); + if (err) + dev_warn(dp->dev, "could not clear test pattern: %d\n", + err); + zynqmp_dp_train_loop(dp); + } +out: + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_active, zynqmp_dp_active_get, + zynqmp_dp_active_set, "%llu\n"); + +static ssize_t zynqmp_dp_custom_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct dentry *dentry = file->f_path.dentry; + struct zynqmp_dp *dp = file->private_data; + ssize_t ret; + + ret = debugfs_file_get(dentry); + if (unlikely(ret)) + return ret; + + mutex_lock(&dp->lock); + ret = simple_read_from_buffer(user_buf, count, ppos, &dp->test.custom, + sizeof(dp->test.custom)); + mutex_unlock(&dp->lock); + + debugfs_file_put(dentry); + return ret; +} + +static ssize_t zynqmp_dp_custom_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct dentry *dentry = file->f_path.dentry; + struct zynqmp_dp *dp = file->private_data; + ssize_t ret; + char buf[sizeof(dp->test.custom)]; + + ret = debugfs_file_get(dentry); + if (unlikely(ret)) + return ret; + + ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count); + if (ret < 0) + goto out; + + mutex_lock(&dp->lock); + memcpy(dp->test.custom, buf, ret); + if (dp->test.active) + ret = zynqmp_dp_set_test_pattern(dp, dp->test.pattern, + dp->test.custom) ?: ret; + mutex_unlock(&dp->lock); + +out: + debugfs_file_put(dentry); + return ret; +} + +static const struct file_operations fops_zynqmp_dp_custom = { + .read = zynqmp_dp_custom_read, + .write = zynqmp_dp_custom_write, + .open = simple_open, + .llseek = noop_llseek, +}; + +static int zynqmp_dp_swing_get(void *data, u64 *val) +{ + struct zynqmp_dp_train_set_priv *priv = data; + struct zynqmp_dp *dp = priv->dp; + + mutex_lock(&dp->lock); + *val = dp->test.train_set[priv->lane] & DP_TRAIN_VOLTAGE_SWING_MASK; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_swing_set(void *data, u64 val) +{ + struct zynqmp_dp_train_set_priv *priv = data; + struct zynqmp_dp *dp = priv->dp; + u8 *train_set = &dp->test.train_set[priv->lane]; + int ret = 0; + + if (val > 3) + return -EINVAL; + + mutex_lock(&dp->lock); + *train_set &= ~(DP_TRAIN_MAX_SWING_REACHED | + DP_TRAIN_VOLTAGE_SWING_MASK); + *train_set |= val; + if (val == 3) + *train_set |= DP_TRAIN_MAX_SWING_REACHED; + + if (dp->test.active) + ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_swing, zynqmp_dp_swing_get, + zynqmp_dp_swing_set, "%llu\n"); + +static int zynqmp_dp_preemphasis_get(void *data, u64 *val) +{ + struct zynqmp_dp_train_set_priv *priv = data; + struct zynqmp_dp *dp = priv->dp; + + mutex_lock(&dp->lock); + *val = FIELD_GET(DP_TRAIN_PRE_EMPHASIS_MASK, + dp->test.train_set[priv->lane]); + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_preemphasis_set(void *data, u64 val) +{ + struct zynqmp_dp_train_set_priv *priv = data; + struct zynqmp_dp *dp = priv->dp; + u8 *train_set = &dp->test.train_set[priv->lane]; + int ret = 0; + + if (val > 2) + return -EINVAL; + + mutex_lock(&dp->lock); + *train_set &= ~(DP_TRAIN_MAX_PRE_EMPHASIS_REACHED | + DP_TRAIN_PRE_EMPHASIS_MASK); + *train_set |= val; + if (val == 2) + *train_set |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; + + if (dp->test.active) + ret = zynqmp_dp_update_vs_emph(dp, dp->test.train_set); + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_preemphasis, zynqmp_dp_preemphasis_get, + zynqmp_dp_preemphasis_set, "%llu\n"); + +static int zynqmp_dp_lanes_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->lock); + *val = dp->test.link_cnt; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_lanes_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + int ret = 0; + + if (val > ZYNQMP_DP_MAX_LANES) + return -EINVAL; + + mutex_lock(&dp->lock); + if (val > dp->num_lanes) { + ret = -EINVAL; + } else { + dp->test.link_cnt = val; + if (dp->test.active) + ret = zynqmp_dp_test_setup(dp); + } + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_lanes, zynqmp_dp_lanes_get, + zynqmp_dp_lanes_set, "%llu\n"); + +static int zynqmp_dp_rate_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->lock); + *val = drm_dp_bw_code_to_link_rate(dp->test.bw_code) * 10000; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_rate_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + int link_rate; + int ret = 0; + u8 bw_code; + + if (do_div(val, 10000)) + return -EINVAL; + + bw_code = drm_dp_link_rate_to_bw_code(val); + link_rate = drm_dp_bw_code_to_link_rate(bw_code); + if (val != link_rate) + return -EINVAL; + + if (bw_code != DP_LINK_BW_1_62 && bw_code != DP_LINK_BW_2_7 && + bw_code != DP_LINK_BW_5_4) + return -EINVAL; + + mutex_lock(&dp->lock); + dp->test.bw_code = bw_code; + if (dp->test.active) + ret = zynqmp_dp_test_setup(dp); + mutex_unlock(&dp->lock); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_rate, zynqmp_dp_rate_get, + zynqmp_dp_rate_set, "%llu\n"); + +static int zynqmp_dp_ignore_aux_errors_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->aux.hw_mutex); + *val = dp->ignore_aux_errors; + mutex_unlock(&dp->aux.hw_mutex); + return 0; +} + +static int zynqmp_dp_ignore_aux_errors_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + + if (val != !!val) + return -EINVAL; + + mutex_lock(&dp->aux.hw_mutex); + dp->ignore_aux_errors = val; + mutex_unlock(&dp->aux.hw_mutex); + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_ignore_aux_errors, + zynqmp_dp_ignore_aux_errors_get, + zynqmp_dp_ignore_aux_errors_set, "%llu\n"); + +static int zynqmp_dp_ignore_hpd_get(void *data, u64 *val) +{ + struct zynqmp_dp *dp = data; + + mutex_lock(&dp->lock); + *val = dp->ignore_hpd; + mutex_unlock(&dp->lock); + return 0; +} + +static int zynqmp_dp_ignore_hpd_set(void *data, u64 val) +{ + struct zynqmp_dp *dp = data; + + if (val != !!val) + return -EINVAL; + + mutex_lock(&dp->lock); + dp->ignore_hpd = val; + mutex_lock(&dp->lock); + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_zynqmp_dp_ignore_hpd, zynqmp_dp_ignore_hpd_get, + zynqmp_dp_ignore_hpd_set, "%llu\n"); + +static void zynqmp_dp_bridge_debugfs_init(struct drm_bridge *bridge, + struct dentry *root) +{ + struct zynqmp_dp *dp = bridge_to_dp(bridge); + struct dentry *test; + int i; + + dp->test.bw_code = DP_LINK_BW_5_4; + dp->test.link_cnt = dp->num_lanes; + + test = debugfs_create_dir("test", root); +#define CREATE_FILE(name) \ + debugfs_create_file(#name, 0600, test, dp, &fops_zynqmp_dp_##name) + CREATE_FILE(pattern); + CREATE_FILE(enhanced); + CREATE_FILE(downspread); + CREATE_FILE(active); + CREATE_FILE(custom); + CREATE_FILE(rate); + CREATE_FILE(lanes); + CREATE_FILE(ignore_aux_errors); + CREATE_FILE(ignore_hpd); + + for (i = 0; i < dp->num_lanes; i++) { + static const char fmt[] = "lane%d_preemphasis"; + char name[sizeof(fmt)]; + + dp->debugfs_train_set[i].dp = dp; + dp->debugfs_train_set[i].lane = i; + + snprintf(name, sizeof(name), fmt, i); + debugfs_create_file(name, 0600, test, + &dp->debugfs_train_set[i], + &fops_zynqmp_dp_preemphasis); + + snprintf(name, sizeof(name), "lane%d_swing", i); + debugfs_create_file(name, 0600, test, + &dp->debugfs_train_set[i], + &fops_zynqmp_dp_swing); + } +} + static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = { .attach = zynqmp_dp_bridge_attach, .detach = zynqmp_dp_bridge_detach, @@ -1671,6 +2334,7 @@ static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = { .detect = zynqmp_dp_bridge_detect, .edid_read = zynqmp_dp_bridge_edid_read, .atomic_get_input_bus_fmts = zynqmp_dp_bridge_get_input_bus_fmts, + .debugfs_init = zynqmp_dp_bridge_debugfs_init, }; /* ----------------------------------------------------------------------------- @@ -1705,6 +2369,11 @@ static void zynqmp_dp_hpd_work_func(struct work_struct *work) enum drm_connector_status status; mutex_lock(&dp->lock); + if (dp->ignore_hpd) { + mutex_unlock(&dp->lock); + return; + } + status = __zynqmp_dp_bridge_detect(dp); mutex_unlock(&dp->lock); @@ -1719,6 +2388,11 @@ static void zynqmp_dp_hpd_irq_work_func(struct work_struct *work) int err; mutex_lock(&dp->lock); + if (dp->ignore_hpd) { + mutex_unlock(&dp->lock); + return; + } + err = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, status, DP_LINK_STATUS_SIZE + 2); if (err < 0) { -- GitLab From 223842c7702b52846b1c5aef8aca7474ec1fd29b Mon Sep 17 00:00:00 2001 From: Steffen Dirkwinkel <s.dirkwinkel@beckhoff.com> Date: Mon, 28 Oct 2024 14:39:40 +0100 Subject: [PATCH 967/970] drm: xlnx: zynqmp_disp: layer may be null while releasing layer->info can be null if we have an error on the first layer in zynqmp_disp_create_layers Fixes: 1836fd5ed98d ("drm: xlnx: zynqmp_dpsub: Minimize usage of global flag") Signed-off-by: Steffen Dirkwinkel <s.dirkwinkel@beckhoff.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241028133941.54264-1-lists@steffen.cc --- drivers/gpu/drm/xlnx/zynqmp_disp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 9368acf56eaf..e4e0e299e8a7 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -1200,6 +1200,9 @@ static void zynqmp_disp_layer_release_dma(struct zynqmp_disp *disp, { unsigned int i; + if (!layer->info) + return; + for (i = 0; i < layer->info->num_channels; i++) { struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; -- GitLab From 71ba1c9b1c717831920c3d432404ee5a707e04b4 Mon Sep 17 00:00:00 2001 From: Steffen Dirkwinkel <s.dirkwinkel@beckhoff.com> Date: Mon, 28 Oct 2024 14:42:17 +0100 Subject: [PATCH 968/970] drm: xlnx: zynqmp_dpsub: fix hotplug detection drm_kms_helper_poll_init needs to be called after zynqmp_dpsub_kms_init. zynqmp_dpsub_kms_init creates the connector and without it we don't enable hotplug detection. Fixes: eb2d64bfcc17 ("drm: xlnx: zynqmp_dpsub: Report HPD through the bridge") Cc: stable@vger.kernel.org Signed-off-by: Steffen Dirkwinkel <s.dirkwinkel@beckhoff.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241028134218.54727-1-lists@steffen.cc --- drivers/gpu/drm/xlnx/zynqmp_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c index 0812dd6bad7c..fc81983d9e5e 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c @@ -511,12 +511,12 @@ int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub) if (ret) return ret; - drm_kms_helper_poll_init(drm); - ret = zynqmp_dpsub_kms_init(dpsub); if (ret < 0) goto err_poll_fini; + drm_kms_helper_poll_init(drm); + /* Reset all components and register the DRM device. */ drm_mode_config_reset(drm); -- GitLab From d28292aa48d1917db39fac6bcdaf991ba0ed279f Mon Sep 17 00:00:00 2001 From: Matthias Brugger <matthias.bgg@gmail.com> Date: Tue, 29 Oct 2024 12:24:29 +0100 Subject: [PATCH 969/970] drm/v3d: Drop allocation of object without mountpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function drm_gem_shmem_create_with_mnt() creates an object without using the mountpoint if gemfs is NULL. Drop the else branch calling drm_gem_shmem_create(). Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com> Signed-off-by: MaÃra Canal <mcanal@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241029-v3d-v2-1-c0d3dd328d1b@gmail.com --- drivers/gpu/drm/v3d/v3d_bo.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c index 7055f7c7bcfe..73ab7dd31b17 100644 --- a/drivers/gpu/drm/v3d/v3d_bo.c +++ b/drivers/gpu/drm/v3d/v3d_bo.c @@ -157,13 +157,8 @@ struct v3d_bo *v3d_bo_create(struct drm_device *dev, struct drm_file *file_priv, struct v3d_bo *bo; int ret; - /* Let the user opt out of allocating the BOs with THP */ - if (v3d->gemfs) - shmem_obj = drm_gem_shmem_create_with_mnt(dev, unaligned_size, - v3d->gemfs); - else - shmem_obj = drm_gem_shmem_create(dev, unaligned_size); - + shmem_obj = drm_gem_shmem_create_with_mnt(dev, unaligned_size, + v3d->gemfs); if (IS_ERR(shmem_obj)) return ERR_CAST(shmem_obj); bo = to_v3d_bo(&shmem_obj->base); -- GitLab From 904bc5479896d8da7dcd3e162ce224c32c3dc6c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= <adrian.larumbe@collabora.com> Date: Wed, 9 Oct 2024 22:43:30 +0100 Subject: [PATCH 970/970] Documentation/gpu: Fix Panthor documentation build warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Panthor documentation build errors uncovered by the makedocs target when building with extra warnings enabled. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Fixes: 6a797bdfde77 ("drm/panthor: add sysfs knob for enabling job profiling") Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241009214346.2308917-1-adrian.larumbe@collabora.com --- Documentation/gpu/drivers.rst | 1 + Documentation/gpu/drm-usage-stats.rst | 1 + Documentation/gpu/panthor.rst | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst index 187201aedbe5..1f17ad0790d7 100644 --- a/Documentation/gpu/drivers.rst +++ b/Documentation/gpu/drivers.rst @@ -22,6 +22,7 @@ GPU Driver Documentation afbc komeda-kms panfrost + panthor zynqmp .. only:: subproject and html diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst index 566e122e6e60..cfdd1a05fced 100644 --- a/Documentation/gpu/drm-usage-stats.rst +++ b/Documentation/gpu/drm-usage-stats.rst @@ -191,4 +191,5 @@ Driver specific implementations * :ref:`i915-usage-stats` * :ref:`panfrost-usage-stats` +* :ref:`panthor-usage-stats` * :ref:`xe-usage-stats` diff --git a/Documentation/gpu/panthor.rst b/Documentation/gpu/panthor.rst index cbf5c4429a2d..3f8979fa2b86 100644 --- a/Documentation/gpu/panthor.rst +++ b/Documentation/gpu/panthor.rst @@ -4,7 +4,7 @@ drm/Panthor CSF driver ========================= -.. _panfrost-usage-stats: +.. _panthor-usage-stats: Panthor DRM client usage stats implementation ============================================== -- GitLab