Re: linux-next: Tree for Aug 17 (DRM_TTM KUNIT tests)
Am 17.08.23 um 20:44 schrieb Randy Dunlap: On 8/16/23 21:47, Stephen Rothwell wrote: Hi all, Changes since 20230816: on risc-v 32-bit: when # CONFIG_MMU is not set Patch to fix this is already queued up for the next pull request. Sorry for the noise, Christian. WARNING: unmet direct dependencies detected for DRM_TTM Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && MMU [=n] Selected by [y]: - DRM_TTM_KUNIT_TEST [=y] && HAS_IOMEM [=y] && DRM [=y] && KUNIT [=y] WARNING: unmet direct dependencies detected for DRM_TTM Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && MMU [=n] Selected by [y]: - DRM_TTM_KUNIT_TEST [=y] && HAS_IOMEM [=y] && DRM [=y] && KUNIT [=y] WARNING: unmet direct dependencies detected for DRM_TTM Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && MMU [=n] Selected by [y]: - DRM_TTM_KUNIT_TEST [=y] && HAS_IOMEM [=y] && DRM [=y] && KUNIT [=y] /opt/crosstool/gcc-13.1.0-nolibc/riscv32-linux/bin/riscv32-linux-ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `.L31': ttm_bo_vm.c:(.text+0x42c): undefined reference to `vmf_insert_pfn_prot' /opt/crosstool/gcc-13.1.0-nolibc/riscv32-linux/bin/riscv32-linux-ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `.L104': ttm_bo_vm.c:(.text+0xa70): undefined reference to `vmf_insert_pfn_prot'
Re: [PATCH v2 5/6] drm/vkms: Support enabling ConfigFS devices
On 8/15/23 23:01, Marius Vlad wrote: Hi, See below some minor comments: On Fri, Jun 23, 2023 at 06:23:47PM -0400, Jim Shargo wrote: VKMS now supports creating and using virtual devices! In addition to the enabling logic, this commit also prevents users from adding new objects once a card is registered. Signed-off-by: Jim Shargo --- drivers/gpu/drm/vkms/vkms_configfs.c | 37 +++-- drivers/gpu/drm/vkms/vkms_crtc.c | 4 +- drivers/gpu/drm/vkms/vkms_drv.c | 3 +- drivers/gpu/drm/vkms/vkms_drv.h | 2 +- drivers/gpu/drm/vkms/vkms_output.c | 201 +++ 5 files changed, 202 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c index 544024735d19..f5eed6d23dcd 100644 --- a/drivers/gpu/drm/vkms/vkms_configfs.c +++ b/drivers/gpu/drm/vkms/vkms_configfs.c @@ -504,29 +504,40 @@ static ssize_t device_enabled_store(struct config_item *item, const char *buf, { struct vkms_configfs *configfs = item_to_configfs(item); struct vkms_device *device; - int value, ret; + int enabled, ret; - ret = kstrtoint(buf, 0, ); + ret = kstrtoint(buf, 0, ); if (ret) return ret; - if (value != 1) - return -EINVAL; - - mutex_lock(>lock); - - if (configfs->vkms_device) { + if (enabled == 0) { + mutex_lock(>lock); + if (configfs->vkms_device) { + vkms_remove_device(configfs->vkms_device); + configfs->vkms_device = NULL; + } mutex_unlock(>lock); + return len; } - device = vkms_add_device(configfs); - mutex_unlock(>lock); + if (enabled == 1) { + mutex_lock(>lock); + if (!configfs->vkms_device) { + device = vkms_add_device(configfs); + if (IS_ERR(device)) { + mutex_unlock(>lock); + return -PTR_ERR(device); + } + + configfs->vkms_device = device; + } + mutex_unlock(>lock); - if (IS_ERR(device)) - return -PTR_ERR(device); + return len; + } - return len; + return -EINVAL; } CONFIGFS_ATTR(device_, enabled); diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index d91e49c53adc..5ebb5264f6ef 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -278,7 +278,7 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = { struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev, struct drm_plane *primary, -struct drm_plane *cursor) +struct drm_plane *cursor, const char *name) { struct drm_device *dev = >drm; struct vkms_crtc *vkms_crtc; @@ -290,7 +290,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev, vkms_crtc = >output.crtcs[vkmsdev->output.num_crtcs++]; ret = drmm_crtc_init_with_planes(dev, _crtc->base, primary, cursor, -_crtc_funcs, NULL); +_crtc_funcs, name); if (ret) { DRM_ERROR("Failed to init CRTC\n"); goto out_error; diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 1b5b7143792f..314a04659c5f 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -210,7 +210,7 @@ static int vkms_platform_probe(struct platform_device *pdev) ret = drm_dev_register(_device->drm, 0); if (ret) { DRM_ERROR("Unable to register device with id %d\n", pdev->id); - return ret; + goto out_release_group; } drm_fbdev_generic_setup(_device->drm, 0); @@ -256,6 +256,7 @@ struct vkms_device *vkms_add_device(struct vkms_configfs *configfs) dev, _platform_driver.driver))) { pdev = to_platform_device(dev); max_id = max(max_id, pdev->id); + put_device(dev); } pdev = platform_device_register_data(NULL, DRIVER_NAME, max_id + 1, diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h index 3634eeeb4548..3d592d085f49 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.h +++ b/drivers/gpu/drm/vkms/vkms_drv.h @@ -239,7 +239,7 @@ void vkms_remove_device(struct vkms_device *vkms_device); /* CRTC */ struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev, struct drm_plane *primary, -struct drm_plane *cursor); +struct drm_plane *cursor, const char *name); int vkms_output_init(struct
Re: [git pull] drm fixes for 6.5-rc7
The pull request you sent on Fri, 18 Aug 2023 07:36:16 +1000: > git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2023-08-18-1 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/1ada9c07407d66679967fe5c2cbb7eda2e0addbf Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
[PATCH] drm/display/dp: Fix the DP DSC Receiver cap size
DP DSC Receiver Capabilities are exposed via DPCD 60h-6Fh. Fix the DSC RECEIVER CAP SIZE accordingly. Fixes: ffddc4363c28 ("drm/dp: Add DP DSC DPCD receiver capability size define and missing SHIFT") Cc: Anusha Srivatsa Cc: Manasi Navare Cc: # v5.0+ Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- include/drm/display/drm_dp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 02f2ac4dd2df..e69cece404b3 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -1537,7 +1537,7 @@ enum drm_dp_phy { #define DP_BRANCH_OUI_HEADER_SIZE 0xc #define DP_RECEIVER_CAP_SIZE 0xf -#define DP_DSC_RECEIVER_CAP_SIZE0xf +#define DP_DSC_RECEIVER_CAP_SIZE0x10 /* DSC Capabilities 0x60 through 0x6F */ #define EDP_PSR_RECEIVER_CAP_SIZE 2 #define EDP_DISPLAY_CTL_CAP_SIZE 3 #define DP_LTTPR_COMMON_CAP_SIZE 8 -- 2.40.1
Re: [PATCH v2 4/6] drm/vkms: Add ConfigFS scaffolding to VKMS
From: Maira Canal Hi Jim, On 6/23/23 19:23, Jim Shargo wrote: > This change adds the basic scaffolding for ConfigFS, including setting > up the default directories. It does not allow for the registration of > configfs-backed devices, which is complex and provided in a follow-up > commit. > > This CL includes docs about using ConfigFS with VKMS, but I'll summarize > in brief here as well (assuming ConfigFS is mounted at /config/): > > To create a new device, you can do so via `mkdir > /config/vkms/my-device`. > > This will create a number of directories and files automatically: > > /config >`-- vkms >`-- my-device >|-- connectors >|-- crtcs >|-- encoders >|-- planes >`-- enabled > > You can then configure objects by mkdir'ing in each of the directories. > > When you're satisfied, you can `echo 1 > /config/vkms/my-device/enabled`. > This will create a new device according to your configuration. > > For now, this will fail, but the next change will add support for it. > > Signed-off-by: Jim Shargo > --- > Documentation/gpu/vkms.rst | 17 +- > drivers/gpu/drm/Kconfig | 1 + > drivers/gpu/drm/vkms/Makefile| 1 + > drivers/gpu/drm/vkms/vkms_configfs.c | 646 +++ > drivers/gpu/drm/vkms/vkms_drv.c | 52 ++- > drivers/gpu/drm/vkms/vkms_drv.h | 92 +++- > drivers/gpu/drm/vkms/vkms_output.c | 5 + > 7 files changed, 799 insertions(+), 15 deletions(-) > create mode 100644 drivers/gpu/drm/vkms/vkms_configfs.c > > diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst > index ba04ac7c2167..2c342ef0fb7b 100644 > --- a/Documentation/gpu/vkms.rst > +++ b/Documentation/gpu/vkms.rst > @@ -51,6 +51,12 @@ To disable the driver, use :: > > sudo modprobe -r vkms > > +Configuration With ConfigFS > +=== > + > +.. kernel-doc:: drivers/gpu/drm/vkms/vkms_configfs.c > + :doc: ConfigFS Support for VKMS > + > Testing With IGT > > > @@ -135,22 +141,15 @@ project. > Runtime Configuration > - > > -We want to be able to reconfigure vkms instance without having to reload the > -module. Use/Test-cases: > +We want to vkms instances without having to reload the module. Such I believe that there is a verb missing here. fixed. > +configuration can be added as extensions to vkms's ConfigFS support. Use-cases: > > - Hotplug/hotremove connectors on the fly (to be able to test DP MST handling > of compositors). > > -- Configure planes/crtcs/connectors (we'd need some code to have more than 1 of > - them first). > - > - Change output configuration: Plug/unplug screens, change EDID, allow changing > the refresh rate. > > -The currently proposed solution is to expose vkms configuration through > -configfs. All existing module options should be supported through configfs > -too. > - > Writeback support > - > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index afb3b2f5f425..71eb913b378f 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -262,6 +262,7 @@ config DRM_VKMS >depends on DRM && MMU >select DRM_KMS_HELPER >select DRM_GEM_SHMEM_HELPER > + select CONFIGFS_FS >select CRC32 >default n >help > diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile > index 1b28a6a32948..6b83907ad554 100644 > --- a/drivers/gpu/drm/vkms/Makefile > +++ b/drivers/gpu/drm/vkms/Makefile > @@ -1,5 +1,6 @@ > # SPDX-License-Identifier: GPL-2.0-only > vkms-y := \ > + vkms_configfs.o \ >vkms_drv.o \ >vkms_plane.o \ >vkms_output.o \ > diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c > new file mode 100644 > index ..544024735d19 > --- /dev/null > +++ b/drivers/gpu/drm/vkms/vkms_configfs.c > @@ -0,0 +1,646 @@ > +// SPDX-License-Identifier: GPL-2.0+ > + > +#include > +#include > +#include > + > +#include > +#include > + > +#include "vkms_drv.h" > + > +/** > + * DOC: ConfigFS Support for VKMS > + * > + * VKMS is instrumented with support for configuration via :doc:`ConfigFS > + * <../filesystems/configfs>`. > + * > + * With VKMS installed, you can mount ConfigFS at ``/config/`` like so:: > + * > + * mkdir -p /config/ > + * sudo mount -t configfs none /config > + * > + * This allows you to configure multiple virtual devices in addition to an > + * immutable "default" device created by the driver at initialization time. Note > + * that the default device is immutable because we cannot pre-populate ConfigFS > + * directories with normal files. > + * > + * To set up a new device, create a new directory under the VKMS configfs > + * directory:: > + * > + * mkdir /config/vkms/test > + * > + * With your device created you'll find an new directory ready to be > + * configured:: > + * >
[PATCH] drm/vmwgfx: Fix possible invalid drm gem put calls
From: Zack Rusin vmw_bo_unreference sets the input buffer to null on exit, resulting in null ptr deref's on the subsequent drm gem put calls. This went unnoticed because only very old userspace would be exercising those paths but it wouldn't be hard to hit on old distros with brand new kernels. Introduce a new function that abstracts unrefing of user bo's to make the code cleaner and more explicit. Signed-off-by: Zack Rusin Reported-by: Ian Forbes Fixes: 9ef8d83e8e25 ("drm/vmwgfx: Do not drop the reference to the handle too soon") Cc: # v6.4+ --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 6 ++ drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 8 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 ++ drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 3 +-- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 3 +-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 82094c137855..c43853597776 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -497,10 +497,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp, if (!(flags & drm_vmw_synccpu_allow_cs)) { atomic_dec(_bo->cpu_writers); } - ttm_bo_put(_bo->tbo); + vmw_user_bo_unref(vmw_bo); } - drm_gem_object_put(_bo->tbo.base); return ret; } @@ -540,8 +539,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, return ret; ret = vmw_user_bo_synccpu_grab(vbo, arg->flags); - vmw_bo_unreference(); - drm_gem_object_put(>tbo.base); + vmw_user_bo_unref(vbo); if (unlikely(ret != 0)) { if (ret == -ERESTARTSYS || ret == -EBUSY) return -EBUSY; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h index 50a836e70994..1d433fceed3d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h @@ -195,6 +195,14 @@ static inline struct vmw_bo *vmw_bo_reference(struct vmw_bo *buf) return buf; } +static inline void vmw_user_bo_unref(struct vmw_bo *vbo) +{ + if (vbo) { + ttm_bo_put(>tbo); + drm_gem_object_put(>tbo.base); + } +} + static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj) { return container_of((gobj), struct vmw_bo, tbo.base); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 6b9aa2b4ef54..25b96821df0f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -1164,8 +1164,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, } vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB); ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo); - ttm_bo_put(_bo->tbo); - drm_gem_object_put(_bo->tbo.base); + vmw_user_bo_unref(vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1221,8 +1220,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo); - ttm_bo_put(_bo->tbo); - drm_gem_object_put(_bo->tbo.base); + vmw_user_bo_unref(vmw_bo); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b62207be3363..1489ad73c103 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1665,10 +1665,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, err_out: /* vmw_user_lookup_handle takes one ref so does new_fb */ - if (bo) { - vmw_bo_unreference(); - drm_gem_object_put(>tbo.base); - } + if (bo) + vmw_user_bo_unref(bo); if (surface) vmw_surface_unreference(); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index 7e112319a23c..fb85f244c3d0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -451,8 +451,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data, ret = vmw_overlay_update_stream(dev_priv, buf, arg, true); - vmw_bo_unreference(); - drm_gem_object_put(>tbo.base); + vmw_user_bo_unref(buf); out_unlock: mutex_unlock(>mutex); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index e7226db8b242..1e81ff2422cf 100644 ---
Re: [PATCH v4] PCI/VGA: Make the vga_is_firmware_default() less arch-dependent
Hi, On 2023/8/18 06:08, Bjorn Helgaas wrote: On Wed, Aug 16, 2023 at 06:05:27AM +0800, Sui Jingfeng wrote: Currently, the vga_is_firmware_default() function only works on x86 and ia64, it is a no-op on ARM, ARM64, PPC, RISC-V, etc. This patch completes the implementation for the rest of the architectures. The added code tries to identify the PCI(e) VGA device that owns the firmware framebuffer before PCI resource reallocation happens. As far as I can tell, this is basically identical to the existing vga_is_firmware_default(), except that this patch funs that code as a header fixup, so it happens before any PCI BAR reallocations happen. Yes, what you said is right in overall. But I think I should mention a few tiny points that make a difference. 1) My version is *less arch-dependent* Again, since the global screen_info is arch-dependent. The vga_is_firmware_default() mess up the arch-dependent part and arch-independent part. It's a mess and it's a bit harder to make the cleanup on the top of it. While my version is my version split the arch-dependent part and arch-independent part clearly. Since we decide to make it less arch-dependent, we have to bear the pain. Despite all other arches should always export the screen_info like the X86 and IA64 arch does, or at least a arch should give a Kconfig token (for example, CONFIG_ARCH_HAS_SCREEN_INFO) to demonstrate that an arch has the support for it. While currently, the fact is that the dependence just populated to everywhere. I think this is the hard part, you have to investigate how various arches defines and set up the screen_info. And then process dependency and the linkage problem across arch properly. 2) My version focus on the address in ranges, weaken the size parameter. Which make the code easy to read and follow the canonical convention to express the address range. while the vga_is_firmware_default() is not. 3) A tiny change make a big difference. The original vga_is_firmware_default() only works with the assumption that the PCI resource reallocation won't happens. While I see no clue that why this is true even on X86 and IA64. The original patch[1] not mention this assumption explicitly. [1] 86fd887b7fe3 ('vgaarb: Don't default exclusively to first video device with mem+io') That sounds like a good idea, because this is all based on the framebuffer in screen_info, and screen_info was initialized before PCI enumeration, and it certainly doesn't account for any BAR changes done by the PCI core. Yes. So why would we keep vga_is_firmware_default() at all? If the header fixup has already identified the firmware framebuffer, it seems pointless to look again later. It need another patch to do the cleanup work, while my patch just add code to solve the real problem. It focus on provide a solution for the architectures which have a decent way set up the screen_info. Other things except that is secondary.
Re: [PATCH v2 2/6] drm/vkms: Support multiple DRM objects (crtcs, etc.) per VKMS device
Thanks for taking the time, everyone! Sorry it took so long, we had some internal shuffling etc going on and I was building out what we needed these chagnes for in the first place, this will be the first of a few replies followed by a new version of the series to be sent out. First up is a respons to Maria, Marius to follow. --- Maria, > - if (vkms->output.composer_workq) > - destroy_workqueue(vkms->output.composer_workq); > + for (int i = 0; i < vkms->output.num_crtcs; i++) > + destroy_workqueue(vkms->output.crtcs[i].composer_workq); I don't believe there is any need for a null check. If you look in the crtc_init, it is zero'd before returning any errors and that is the only place it is set. I don't believe that release can be called by an interrupt/async (and if it did it would need a mutex/lock anyway). > > static const struct drm_plane_funcs vkms_plane_funcs = { > - .update_plane = drm_atomic_helper_update_plane, > - .disable_plane = drm_atomic_helper_disable_plane, > - .reset = vkms_plane_reset, Yeah these do seem weirdly formatted on devices that don't treat tabs well. The default formatter on my editor has a few suggestions for this file, but they are all optional. I'll send an extra patch that formats stuff and see what people think, but ill make it seperate after all this is done. For now I reverted this. >> -if (IS_ERR(plane)) >> -return plane; >> +if (output->num_planes >= VKMS_MAX_PLANES) >> +return ERR_PTR(-ENOMEM); >> + >> +plane = >planes[output->num_planes++]; >> +ret = drm_universal_plane_init(dev, >base, 0, _plane_funcs, >> + vkms_formats, ARRAY_SIZE(vkms_formats), >> + NULL, type, NULL); > >Wouldn't be possible to use drmm_universal_plane_alloc? Maybe, but the *_init pattern allows these things to be inline in the struct as they are now, and consistent with the other drm kernel objects in the vkms_output struct. There are also a few other places we could use drmm, surely, but to limit the scope/risk why don't we do that as a followup? --- Marius, Yeah those values could safely be completely removed. Good catch :)
Re: [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread
On Thu, Aug 17, 2023 at 01:13:31PM +0200, Danilo Krummrich wrote: > On 8/17/23 07:33, Christian König wrote: > > Am 16.08.23 um 18:33 schrieb Danilo Krummrich: > > > On 8/16/23 16:59, Christian König wrote: > > > > Am 16.08.23 um 14:30 schrieb Danilo Krummrich: > > > > > On 8/16/23 16:05, Christian König wrote: > > > > > > Am 16.08.23 um 13:30 schrieb Danilo Krummrich: > > > > > > > Hi Matt, > > > > > > > > > > > > > > On 8/11/23 04:31, Matthew Brost wrote: > > > > > > > > In XE, the new Intel GPU driver, a choice has made to have a 1 > > > > > > > > to 1 > > > > > > > > mapping between a drm_gpu_scheduler and > > > > > > > > drm_sched_entity. At first this > > > > > > > > seems a bit odd but let us explain the reasoning below. > > > > > > > > > > > > > > > > 1. In XE the submission order from multiple drm_sched_entity is > > > > > > > > not > > > > > > > > guaranteed to be the same completion even if > > > > > > > > targeting the same hardware > > > > > > > > engine. This is because in XE we have a firmware scheduler, the > > > > > > > > GuC, > > > > > > > > which allowed to reorder, timeslice, and preempt > > > > > > > > submissions. If a using > > > > > > > > shared drm_gpu_scheduler across multiple > > > > > > > > drm_sched_entity, the TDR falls > > > > > > > > apart as the TDR expects submission order == > > > > > > > > completion order. Using a > > > > > > > > dedicated drm_gpu_scheduler per drm_sched_entity solve this > > > > > > > > problem. > > > > > > > > > > > > > > > > 2. In XE submissions are done via programming a > > > > > > > > ring buffer (circular > > > > > > > > buffer), a drm_gpu_scheduler provides a limit on > > > > > > > > number of jobs, if the > > > > > > > > limit of number jobs is set to RING_SIZE / > > > > > > > > MAX_SIZE_PER_JOB we get flow > > > > > > > > control on the ring for free. > > > > > > > > > > > > > > In XE, where does the limitation of MAX_SIZE_PER_JOB come from? > > > > > > > > > > > > > > In Nouveau we currently do have such a limitation as > > > > > > > well, but it is derived from the RING_SIZE, hence > > > > > > > RING_SIZE / MAX_SIZE_PER_JOB would always be 1. > > > > > > > However, I think most jobs won't actually utilize > > > > > > > the whole ring. > > > > > > > > > > > > Well that should probably rather be RING_SIZE / > > > > > > MAX_SIZE_PER_JOB = hw_submission_limit (or even > > > > > > hw_submission_limit - 1 when the hw can't distinct full > > > > > > vs empty ring buffer). > > > > > > > > > > Not sure if I get you right, let me try to clarify what I > > > > > was trying to say: I wanted to say that in Nouveau > > > > > MAX_SIZE_PER_JOB isn't really limited by anything other than > > > > > the RING_SIZE and hence we'd never allow more than 1 active > > > > > job. > > > > > > > > But that lets the hw run dry between submissions. That is > > > > usually a pretty horrible idea for performance. > > > > > > Correct, that's the reason why I said it seems to be more efficient > > > to base ring flow control on the actual size of each incoming job > > > rather than the maximum size of a job. > > > > > > > > > > > > > > > > > However, it seems to be more efficient to base ring flow > > > > > control on the actual size of each incoming job rather than > > > > > the worst case, namely the maximum size of a job. > > > > > > > > That doesn't sounds like a good idea to me. See we don't limit > > > > the number of submitted jobs based on the ring size, but rather > > > > we calculate the ring size based on the number of submitted > > > > jobs. > > > > > > > > > > My point isn't really about whether we derive the ring size from the > > > job limit or the other way around. It's more about the job size (or > > > its maximum size) being arbitrary. > > > > > > As mentioned in my reply to Matt: > > > > > > "In Nouveau, userspace can submit an arbitrary amount of addresses > > > of indirect bufferes containing the ring instructions. The ring on > > > the kernel side takes the addresses of the indirect buffers rather > > > than the instructions themself. Hence, technically there isn't > > > really a limit on the amount of IBs submitted by a job except for > > > the ring size." > > > > > > So, my point is that I don't really want to limit the job size > > > artificially just to be able to fit multiple jobs into the ring even > > > if they're submitted at their "artificial" maximum size, but rather > > > track how much of the ring the submitted job actually occupies. > > > > > > > In other words the hw_submission_limit defines the ring size, > > > > not the other way around. And you usually want the > > > > hw_submission_limit as low as possible for good scheduler > > > > granularity and to avoid extra overhead. > > > > > > I don't think you really mean "as low as possible", do you? > > > > No, I do mean as low as possible or in other words as few as possible. > > > > Ideally the scheduler would submit only the minimum amount of work to > > the
[Bug 217664] Laptop doesnt wake up from suspend mode.
https://bugzilla.kernel.org/show_bug.cgi?id=217664 --- Comment #19 from popus_czy_to_ty (pentelja...@o2.pl) --- now nvidia using some intel driver somehow xD sd@Crawler-E25:~$ lspci -knn | grep VGA -A 5 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA107M [GeForce RTX 3050 Mobile] [10de:25a2] (rev a1) Subsystem: CLEVO/KAPOK Computer GA107M [GeForce RTX 3050 Mobile] [1558:5e00] Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:2291] (rev a1) Subsystem: NVIDIA Corporation Device [10de:] Kernel driver in use: snd_hda_intel -- 05:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Cezanne [Radeon Vega Series / Radeon Vega Mobile Series] [1002:1638] (rev c6) Subsystem: CLEVO/KAPOK Computer Cezanne [Radeon Vega Series / Radeon Vega Mobile Series] [1558:5e00] Kernel driver in use: amdgpu Kernel modules: amdgpu 05:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Renoir Radeon High Definition Audio Controller [1002:1637] Subsystem: CLEVO/KAPOK Computer Renoir Radeon High Definition Audio -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[Bug 217664] Laptop doesnt wake up from suspend mode.
https://bugzilla.kernel.org/show_bug.cgi?id=217664 popus_czy_to_ty (pentelja...@o2.pl) changed: What|Removed |Added Kernel Version||6.2.0-27-generic --- Comment #18 from popus_czy_to_ty (pentelja...@o2.pl) --- banned all in grub ( GRUB_CMDLINE_LINUX_DEFAULT="quiet splash module_blacklist=nvidia,nvidia-current,nvidia_drm,nvidia_uvm,nvidia_modeset,nouveau" ) still doesnt wake up -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [RFC PATCH 1/3] drm/virtio: .release ops for virtgpu fence release
On 8/16/2023 10:05 PM, Dmitry Osipenko wrote: On 8/16/23 21:10, Kim, Dongwon wrote: Hi, On 8/14/2023 9:18 PM, Dmitry Osipenko wrote: On 7/13/23 01:44, Dongwon Kim wrote: virtio_gpu_fence_release is added to free virtio-gpu-fence upon release of dma_fence. Cc: Gerd Hoffmann Cc: Vivek Kasireddy Signed-off-by: Dongwon Kim --- drivers/gpu/drm/virtio/virtgpu_fence.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index f28357dbde35..ba659ac2a51d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -63,12 +63,20 @@ static void virtio_gpu_timeline_value_str(struct dma_fence *f, char *str, (u64)atomic64_read(>drv->last_fence_id)); } +static void virtio_gpu_fence_release(struct dma_fence *f) +{ + struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); + + kfree(fence); +} + static const struct dma_fence_ops virtio_gpu_fence_ops = { .get_driver_name = virtio_gpu_get_driver_name, .get_timeline_name = virtio_gpu_get_timeline_name, .signaled = virtio_gpu_fence_signaled, .fence_value_str = virtio_gpu_fence_value_str, .timeline_value_str = virtio_gpu_timeline_value_str, + .release = virtio_gpu_fence_release, }; struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev, This change doesn't do anything practically useful, AFAICT. The intention of this ".release" is to free virtio_gpu_fence when the last dma_fence_put is done for the associated dma fence. What makes you think that fence won't be freed otherwise? Sounds like haven't tried to check what dma_fence_release() code does, have you? I see it now. For some reason, I assumed virtio_gpu_fence holds the pointer of dma_fence. This release ops is indeed not needed as you mentioned. Thanks
Re: [RFC PATCH 3/3] drm/virtio: drm_gem_plane_helper_prepare_fb for obj synchronization
On 7/13/23 01:44, Dongwon Kim wrote: > This helper is needed for framebuffer synchronization. Old framebuffer data > is often displayed on the guest display without this helper. > > Cc: Gerd Hoffmann > Cc: Vivek Kasireddy > Signed-off-by: Dongwon Kim > --- > drivers/gpu/drm/virtio/virtgpu_plane.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c > b/drivers/gpu/drm/virtio/virtgpu_plane.c > index a063f06ab6c5..e197299489ce 100644 > --- a/drivers/gpu/drm/virtio/virtgpu_plane.c > +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include "virtgpu_drv.h" > > @@ -271,6 +272,9 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane > *plane, > vgfb = to_virtio_gpu_framebuffer(new_state->fb); > vgplane_st = to_virtio_gpu_plane_state(new_state); > bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); > + > + drm_gem_plane_helper_prepare_fb(plane, new_state); The implicit display BO sync should happen on a host side, unless you're rendering with Venus and then displaying with virgl. Doing it on guest side should be a major performance hit. Please provide a complete description of your setup: what VMM you use, config options, what tests you're running. -- Best regards, Dmitry
Re: [RFC PATCH 2/3] drm/virtio: new fence for every plane update
... > +static struct > +drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane) > +{ > + struct virtio_gpu_plane_state *new; > + > + if (WARN_ON(!plane->state)) > + return NULL; When plane->state can be NULL? > + new = kzalloc(sizeof(*new), GFP_KERNEL); > + if (!new) > + return NULL; > + > + __drm_atomic_helper_plane_duplicate_state(plane, >base); > + > + return >base; > +} > + > +static void virtio_gpu_plane_destroy_state(struct drm_plane *plane, > +struct drm_plane_state *state) > +{ > + __drm_atomic_helper_plane_destroy_state(state); > + kfree(to_virtio_gpu_plane_state(state)); > +} > + > static const struct drm_plane_funcs virtio_gpu_plane_funcs = { > .update_plane = drm_atomic_helper_update_plane, > .disable_plane = drm_atomic_helper_disable_plane, > .reset = drm_atomic_helper_plane_reset, > - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, > - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, > + .atomic_duplicate_state = virtio_gpu_plane_duplicate_state, > + .atomic_destroy_state = virtio_gpu_plane_destroy_state, Similar to the other email, please see how container_of() works. There is no need change .atomic_destroy_state ... > @@ -237,41 +262,29 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane > *plane, > struct drm_device *dev = plane->dev; > struct virtio_gpu_device *vgdev = dev->dev_private; > struct virtio_gpu_framebuffer *vgfb; > + struct virtio_gpu_plane_state *vgplane_st; > struct virtio_gpu_object *bo; > > if (!new_state->fb) > return 0; > > vgfb = to_virtio_gpu_framebuffer(new_state->fb); > + vgplane_st = to_virtio_gpu_plane_state(new_state); > bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]); > if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob)) > return 0; > > - if (bo->dumb && (plane->state->fb != new_state->fb)) { > - vgfb->fence = virtio_gpu_fence_alloc(vgdev, > vgdev->fence_drv.context, > + if (bo->dumb) { Why "&& (plane->state->fb != new_state->fb)" disappeared? > + vgplane_st->fence = virtio_gpu_fence_alloc(vgdev, > + vgdev->fence_drv.context, >0); > - if (!vgfb->fence) > + if (!vgplane_st->fence) > return -ENOMEM; > } > > return 0; > } > > -static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, > - struct drm_plane_state *state) > -{ > - struct virtio_gpu_framebuffer *vgfb; > - > - if (!state->fb) > - return; > - > - vgfb = to_virtio_gpu_framebuffer(state->fb); > - if (vgfb->fence) { > - dma_fence_put(>fence->f); > - vgfb->fence = NULL; > - } > -} How come that virtio_gpu_plane_cleanup_fb() isn't needed anymore? You created fence in prepare_fb(), you must release it in cleanup_fb() if fence still presents. -- Best regards, Dmitry
Re: [RFC PATCH 1/3] drm/virtio: .release ops for virtgpu fence release
On 8/17/23 08:25, Kim, Dongwon wrote: ... > Yeah, I know it frees 'struct dma_fence *f' but what about 'struct > virtio_gpu_fence *fence'? This is a device specific fence that contains > struct dma_fence *f. But hold on... so when fence->ops->release is > called then dma_fence_free won't be called here: > > if (fence->ops->release) > fence->ops->release(fence); > else > dma_fence_free(fence); > > In that case, I think virtio_gpu_fence_release should do > "dma_fence_free(f)" before freeing virtio_gpu_fence? Am I right? > Like, > > static void virtio_gpu_fence_release(struct dma_fence *f) > { > struct virtio_gpu_fence *fence = to_virtio_gpu_fence(f); > > dma_fence_free(f); > kfree(fence); > } That is a double free and wrong of course. Both dma_fence *f and virtio_gpu_fence *fence point at the same kmemory object. See to_virtio_gpu_fence() and please research how container_of() works. -- Best regards, Dmitry
linux-next: manual merge of the drm tree with the drm-fixes tree
Hi all, Today's linux-next merge of the drm tree got a conflict in: drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c between commits: 61319b8e3b58 ("drm/amd/pm: disable the SMU13 OD feature support temporarily") b6360a5ec31d ("drm/amd/pm: disallow the fan setting if there is no fan on smu 13.0.0") from the drm-fixes tree and commit: 510d242f498a ("drm/amd/pm: disable the SMU13 OD feature support temporarily") from the drm tree. The git automatic resolution got this wrong by adding an extra "#if 0" above the duplicated "PPTable_t *pptable = smu->smu_table.driver_pptable;" from b6360a5ec31d. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 0fb6be11a0cc,fddcd834bcec.. --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@@ -331,9 -331,8 +331,8 @@@ static int smu_v13_0_0_check_powerplay_ struct smu_13_0_0_powerplay_table *powerplay_table = table_context->power_play_table; struct smu_baco_context *smu_baco = >smu_baco; -#if 0 PPTable_t *pptable = smu->smu_table.driver_pptable; +#if 0 - PPTable_t *pptable = smu->smu_table.driver_pptable; const OverDriveLimits_t * const overdrive_upperlimits = >SkuTable.OverDriveLimitsBasicMax; const OverDriveLimits_t * const overdrive_lowerlimits = pgpGHsF8KJSqw.pgp Description: OpenPGP digital signature
Re: [PATCH v4] PCI/VGA: Make the vga_is_firmware_default() less arch-dependent
Hi, On 2023/8/18 06:08, Bjorn Helgaas wrote: + if (resource_type(res) != IORESOURCE_MEM) + continue; + + if (!res->start || !res->end) + continue; + + if (res->start <= fb_start && fb_end <= res->end) { + pdev_boot_vga = pdev; + + vgaarb_info(>dev, + "BAR %d contains firmware FB\n", i); Print the BAR with %pR and include the framebuffer region from screen_info in the same format. I do remember that you already told me to do this in V3, sorry for not replying to you at V3. Most of the time, what you tell me is right.But here, I think I need to explain. Because doing it that way will make the code line too long,and it will exceed 80 characters in the column if we print too much. I believe that the vgaarb_info() at here is already the most compact and simplest form. Printing the BAR with %pR is not absolute necessary, because we can get the additional information by: $ lspci | grep VGA $ dmesg | grep 05:00.0 $ dmesg | grep :03:00.0 $ dmesg | grep PCI Actually, I only add something that is absolute necessary. Printing BAR with %pR and/or Printing the framebuffer region is consider to only for *debugging* purpose.
[PATCH -next RESEND] backlight: led_bl: Remove redundant of_match_ptr()
The driver depends on CONFIG_OF, it is not necessary to use of_match_ptr() here. Signed-off-by: Ruan Jinjie Reviewed-by: Daniel Thompson --- drivers/video/backlight/led_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c index 3259292fda76..032f8bddf872 100644 --- a/drivers/video/backlight/led_bl.c +++ b/drivers/video/backlight/led_bl.c @@ -243,7 +243,7 @@ MODULE_DEVICE_TABLE(of, led_bl_of_match); static struct platform_driver led_bl_driver = { .driver = { .name = "led-backlight", - .of_match_table = of_match_ptr(led_bl_of_match), + .of_match_table = led_bl_of_match, }, .probe = led_bl_probe, .remove_new = led_bl_remove, -- 2.34.1
Re: [PATCH v5 03/17] drm/imagination/uapi: Add PowerVR driver UAPI
On Wed, Aug 16, 2023 at 3:26 AM Sarah Walker wrote: > Add the UAPI implementation for the PowerVR driver. > > Changes from v4 : > - Remove CREATE_ZEROED flag for BO creation (all buffers are now zeroed) > > Co-developed-by: Frank Binns > Signed-off-by: Frank Binns > Co-developed-by: Boris Brezillon > Signed-off-by: Boris Brezillon > Co-developed-by: Matt Coster > Signed-off-by: Matt Coster > Co-developed-by: Donald Robson > Signed-off-by: Donald Robson > Signed-off-by: Sarah Walker > --- > MAINTAINERS|1 + > include/uapi/drm/pvr_drm.h | 1303 > 2 files changed, 1304 insertions(+) > create mode 100644 include/uapi/drm/pvr_drm.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index f84390bb6cfe..55e17f8aea91 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -10144,6 +10144,7 @@ M: Sarah Walker > M: Donald Robson > S: Supported > F: Documentation/devicetree/bindings/gpu/img,powervr.yaml > +F: include/uapi/drm/pvr_drm.h > > IMON SOUNDGRAPH USB IR RECEIVER > M: Sean Young > diff --git a/include/uapi/drm/pvr_drm.h b/include/uapi/drm/pvr_drm.h > new file mode 100644 > index ..c0aac8b135ca > --- /dev/null > +++ b/include/uapi/drm/pvr_drm.h > @@ -0,0 +1,1303 @@ > +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ > +/* Copyright (c) 2023 Imagination Technologies Ltd. */ > + > +#ifndef PVR_DRM_UAPI_H > +#define PVR_DRM_UAPI_H > + > +#include "drm.h" > + > +#include > +#include > + > +#if defined(__cplusplus) > +extern "C" { > +#endif > + > +/** > + * DOC: PowerVR UAPI > + * > + * The PowerVR IOCTL argument structs have a few limitations in place, in > + * addition to the standard kernel restrictions: > + * > + * - All members must be type-aligned. > + * - The overall struct must be padded to 64-bit alignment. > + * - Explicit padding is almost always required. This takes the form of > + *``_padding_[x]`` members of sufficient size to pad to the next > power-of-two > + *alignment, where [x] is the offset into the struct in hexadecimal. > Arrays > + *are never used for alignment. Padding fields must be zeroed; this is > + *always checked. > + * - Unions may only appear as the last member of a struct. > + * - Individual union members may grow in the future. The space between > the > + *end of a union member and the end of its containing union is > considered > + *"implicit padding" and must be zeroed. This is always checked. > + * > + * In addition to the IOCTL argument structs, the PowerVR UAPI makes use > of > + * DEV_QUERY argument structs. These are used to fetch information about > the > + * device and runtime. These structs are subject to the same rules set out > + * above. > + */ > + > +/** > + * struct drm_pvr_obj_array - Container used to pass arrays of objects > + * > + * It is not unusual to have to extend objects to pass new parameters, > and the DRM > + * ioctl infrastructure is supporting that by padding ioctl arguments > with zeros > + * when the data passed by userspace is smaller than the struct defined > in the > + * drm_ioctl_desc, thus keeping things backward compatible. This type is > just > + * applying the same concepts to indirect objects passed through arrays > referenced > + * from the main ioctl arguments structure: the stride basically defines > the size > + * of the object passed by userspace, which allows the kernel driver to > pad with > + * zeros when it's smaller than the size of the object it expects. > + * > + * Use ``DRM_PVR_OBJ_ARRAY()`` to fill object array fields, unless you > + * have a very good reason not to. > + */ > +struct drm_pvr_obj_array { > + /** @stride: Stride of object struct. Used for versioning. */ > + __u32 stride; > + > + /** @count: Number of objects in the array. */ > + __u32 count; > + > + /** @array: User pointer to an array of objects. */ > + __u64 array; > +}; > + > +/** > + * DRM_PVR_OBJ_ARRAY() - Helper macro for filling > drm_pvr_obj_array. > + * @cnt: Number of elements pointed to py @ptr. > + * @ptr: Pointer to start of a C array. > + * > + * Return: Literal of type drm_pvr_obj_array. > + */ > +#define DRM_PVR_OBJ_ARRAY(cnt, ptr) \ > + { .stride = sizeof((ptr)[0]), .count = (cnt), .array = > (__u64)(uintptr_t)(ptr) } > + > +/** > + * DOC: PowerVR IOCTL interface > + */ > + > +/** > + * PVR_IOCTL() - Build a PowerVR IOCTL number > + * @_ioctl: An incrementing id for this IOCTL. Added to %DRM_COMMAND_BASE. > + * @_mode: Must be one of %DRM_IOR, %DRM_IOW or %DRM_IOWR. > + * @_data: The type of the args struct passed by this IOCTL. > + * > + * The struct referred to by @_data must have a ``drm_pvr_ioctl_`` prefix > and an > + * ``_args suffix``. They are therefore omitted from @_data. > + * > + * This should only be used to build the constants described below; it > should > + * never be used to call an IOCTL directly. > + * > + * Return: An IOCTL
Re: [PATCH v3 1/2] udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap
Hi Vivek, kernel test robot noticed the following build errors: [auto build test ERROR on drm-misc/drm-misc-next] [also build test ERROR on drm-tip/drm-tip linus/master v6.5-rc6 next-20230817] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Vivek-Kasireddy/udmabuf-Use-vmf_insert_pfn-and-VM_PFNMAP-for-handling-mmap/20230817-150922 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20230817064623.3424348-2-vivek.kasireddy%40intel.com patch subject: [PATCH v3 1/2] udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap config: sh-randconfig-r004-20230818 (https://download.01.org/0day-ci/archive/20230818/202308180617.rl3qsrnt-...@intel.com/config) compiler: sh4-linux-gcc (GCC) 12.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230818/202308180617.rl3qsrnt-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202308180617.rl3qsrnt-...@intel.com/ All errors (new ones prefixed by >>): sh4-linux-ld: drivers/dma-buf/udmabuf.o: in function `udmabuf_vm_fault': >> udmabuf.c:(.text+0xd8): undefined reference to `vmf_insert_pfn' -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH v5 14/17] drm/imagination: Implement job submission and scheduling
On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker wrote: > Implement job submission ioctl. Job scheduling is implemented using > drm_sched. [...] > +/** > + * pvr_job_data_fini() - Cleanup all allocs used to set up job submission. > + * @job_data: Job data array. > + * @job_count: Number of members of @job_data. > + */ > +static void > +pvr_job_data_fini(struct pvr_job_data *job_data, u32 job_count) > +{ > + for (u32 i = 0; i < job_count; i++) { > + pvr_job_put(job_data[i].job); > + kvfree(job_data[i].sync_ops); > + } > +} > + > +/** > + * pvr_job_data_init() - Init an array of created jobs, associating them with > + * the appropriate sync_ops args, which will be copied in. > + * @pvr_dev: Target PowerVR device. > + * @pvr_file: Pointer to PowerVR file structure. > + * @job_args: Job args array copied from user. > + * @job_count: Number of members of @job_args. > + * @job_data_out: Job data array. > + */ > +static int pvr_job_data_init(struct pvr_device *pvr_dev, > +struct pvr_file *pvr_file, > +struct drm_pvr_job *job_args, > +u32 *job_count, > +struct pvr_job_data *job_data_out) > +{ > + int err = 0, i = 0; > + > + for (; i < *job_count; i++) { > + job_data_out[i].job = > + create_job(pvr_dev, pvr_file, _args[i]); > + err = PTR_ERR_OR_ZERO(job_data_out[i].job); > + > + if (err) { > + *job_count = i; > + job_data_out[i].job = NULL; > + goto err_cleanup; I think this bailout looks fine... > + } > + > + err = PVR_UOBJ_GET_ARRAY(job_data_out[i].sync_ops, > +_args[i].sync_ops); > + if (err) { > + *job_count = i; > + goto err_cleanup; ... but this bailout looks like it has an off-by-one. We have initialized the job pointers up to (inclusive) index i... > + } > + > + job_data_out[i].sync_op_count = job_args[i].sync_ops.count; > + } > + > + return 0; > + > +err_cleanup: > + pvr_job_data_fini(job_data_out, i); ... but then we pass i to pvr_job_data_fini() as the exclusive limit of job indices to free? I think this will leave a leaked job around. > + > + return err; > +}
Re: [PATCH v5 13/17] drm/imagination: Implement context creation/destruction ioctls
On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker wrote: > > Implement ioctls for the creation and destruction of contexts. Contexts are > used for job submission and each is associated with a particular job type. [...] > +/** > + * pvr_context_create() - Create a context. > + * @pvr_file: File to attach the created context to. > + * @args: Context creation arguments. > + * > + * Return: > + * * 0 on success, or > + * * A negative error code on failure. > + */ > +int pvr_context_create(struct pvr_file *pvr_file, struct > drm_pvr_ioctl_create_context_args *args) > +{ > + struct pvr_device *pvr_dev = pvr_file->pvr_dev; > + struct pvr_context *ctx; > + int ctx_size; > + int err; > + > + /* Context creation flags are currently unused and must be zero. */ > + if (args->flags) > + return -EINVAL; > + > + ctx_size = get_fw_obj_size(args->type); > + if (ctx_size < 0) > + return ctx_size; > + > + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); > + if (!ctx) > + return -ENOMEM; > + > + ctx->data_size = ctx_size; > + ctx->type = args->type; > + ctx->flags = args->flags; > + ctx->pvr_dev = pvr_dev; > + kref_init(>ref_count); > + > + err = remap_priority(pvr_file, args->priority, >priority); > + if (err) > + goto err_free_ctx; > + > + ctx->vm_ctx = pvr_vm_context_lookup(pvr_file, > args->vm_context_handle); > + if (IS_ERR(ctx->vm_ctx)) { > + err = PTR_ERR(ctx->vm_ctx); > + goto err_free_ctx; > + } > + > + ctx->data = kzalloc(ctx_size, GFP_KERNEL); > + if (!ctx->data) { > + err = -ENOMEM; > + goto err_put_vm; > + } > + > + err = init_fw_objs(ctx, args, ctx->data); > + if (err) > + goto err_free_ctx_data; > + > + err = pvr_fw_object_create(pvr_dev, ctx_size, > PVR_BO_FW_FLAGS_DEVICE_UNCACHED, > + ctx_fw_data_init, ctx, >fw_obj); > + if (err) > + goto err_free_ctx_data; > + > + err = xa_alloc(_dev->ctx_ids, >ctx_id, ctx, xa_limit_32b, > GFP_KERNEL); > + if (err) > + goto err_destroy_fw_obj; > + > + err = xa_alloc(_file->ctx_handles, >handle, ctx, > xa_limit_32b, GFP_KERNEL); > + if (err) > + goto err_release_id; This bailout looks a bit dodgy. We have already inserted ctx into _dev->ctx_ids, and now we just take it out again. If someone could concurrently call pvr_context_lookup_id() on the ID we just allocated (I don't understand enough about what's going on here at a high level to be able to tell if that's possible), I think they would be able to elevate the ctx->ref_count from 1 to 2, and then on the bailout path we'll just free the ctx without looking at the refcount. If this can't happen, it might be a good idea to add a comment explaining why. If it can happen, I guess one way to fix it would be to replace this last bailout with a call to pvr_context_put()? > + > + return 0; > + > +err_release_id: > + xa_erase(_dev->ctx_ids, ctx->ctx_id); > + > +err_destroy_fw_obj: > + pvr_fw_object_destroy(ctx->fw_obj); > + > +err_free_ctx_data: > + kfree(ctx->data); > + > +err_put_vm: > + pvr_vm_context_put(ctx->vm_ctx); > + > +err_free_ctx: > + kfree(ctx); > + return err; > +}
Re: [PATCH v5 08/17] drm/imagination: Add GEM and VM related code
Hi! Thanks, I think it's great that Imagination is writing an upstream driver for PowerVR. :) On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker wrote: > Add a GEM implementation based on drm_gem_shmem, and support code for the > PowerVR GPU MMU. The GPU VA manager is used for address space management. [...] > +/** > + * DOC: Flags for DRM_IOCTL_PVR_CREATE_BO (kernel-only) > + * > + * Kernel-only values allowed in _gem_object->flags. The majority of > options > + * for this field are specified in the UAPI header "pvr_drm.h" with a > + * DRM_PVR_BO_ prefix. To distinguish these internal options (which must > exist > + * in ranges marked as "reserved" in the UAPI header), we drop the DRM > prefix. > + * The public options should be used directly, DRM prefix and all. > + * > + * To avoid potentially confusing gaps in the UAPI options, these kernel-only > + * options are specified "in reverse", starting at bit 63. > + * > + * We use "reserved" to refer to bits defined here and not exposed in the > UAPI. > + * Bits not defined anywhere are "undefined". > + * > + * Creation options > + *These use the prefix PVR_BO_CREATE_. > + * > + **There are currently no kernel-only flags in this group.* > + * > + * Device mapping options > + *These use the prefix PVR_BO_DEVICE_. > + * > + **There are currently no kernel-only flags in this group.* > + * > + * CPU mapping options > + *These use the prefix PVR_BO_CPU_. > + * > + *:CACHED: By default, all GEM objects are mapped write-combined on the > + * CPU. Set this flag to override this behaviour and map the object > + * cached. > + */ > +#define PVR_BO_CPU_CACHED BIT_ULL(63) > + > +#define PVR_BO_FW_NO_CLEAR_ON_RESET BIT_ULL(62) > + > +/* Bits 62..3 are undefined. */ > +/* Bits 2..0 are defined in the UAPI. */ > + > +/* Other utilities. */ > +#define PVR_BO_UNDEFINED_MASK GENMASK_ULL(61, 3) > +#define PVR_BO_RESERVED_MASK (PVR_BO_UNDEFINED_MASK | GENMASK_ULL(63, 63)) In commit 1a9c568fb559 ("drm/imagination: Rework firmware object initialisation") in powervr-next, PVR_BO_FW_NO_CLEAR_ON_RESET (bit 62) was added in the kernel-only flags group, but the mask PVR_BO_RESERVED_MASK (which is used in pvr_ioctl_create_bo to detect kernel-only and reserved flags) looks like it wasn't changed to include bit 62. I think that means it becomes possible for userspace to pass this bit in via pvr_ioctl_create_bo()? If my understanding is correct and that was unintentional, it might be a good idea to change these defines: #define PVR_BO_UNDEFINED_MASK GENMASK_ULL(61, 3) #define PVR_BO_RESERVED_MASK (PVR_BO_UNDEFINED_MASK | GENMASK_ULL(63, 63)) into something like this to avoid future mishaps like this: /* first bit that is not used for UAPI BO options */ #define PVR_BO_FIRST_RESERVED_BIT 3 #define PVR_BO_UNDEFINED_MASK GENMASK_ULL(61, PVR_BO_FIRST_RESERVED_BIT) #define PVR_BO_RESERVED_MASK GENMASK_ULL(63, PVR_BO_FIRST_RESERVED_BIT) > + > +/* > + * All firmware-mapped memory uses (mostly) the same flags. Specifically, > + * firmware-mapped memory should be: > + * * Read/write on the device, > + * * Read/write on the CPU, and > + * * Write-combined on the CPU. > + * > + * The only variation is in caching on the device. > + */ > +#define PVR_BO_FW_FLAGS_DEVICE_CACHED (ULL(0)) > +#define PVR_BO_FW_FLAGS_DEVICE_UNCACHED DRM_PVR_BO_DEVICE_BYPASS_CACHE [...] > +/** > + * pvr_page_table_l2_entry_raw_set() - Write a valid entry into a raw level 2 > + * page table. > + * @entry: Target raw level 2 page table entry. > + * @child_table_dma_addr: DMA address of the level 1 page table to be > + *associated with @entry. > + * > + * When calling this function, @child_table_dma_addr must be a valid DMA > + * address and a multiple of %ROGUE_MMUCTRL_PC_DATA_PD_BASE_ALIGNSIZE. > + */ > +static void > +pvr_page_table_l2_entry_raw_set(struct pvr_page_table_l2_entry_raw *entry, > + dma_addr_t child_table_dma_addr) > +{ > + child_table_dma_addr >>= ROGUE_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT; > + > + entry->val = > + PVR_PAGE_TABLE_FIELD_PREP(2, PC, VALID, true) | > + PVR_PAGE_TABLE_FIELD_PREP(2, PC, ENTRY_PENDING, false) | > + PVR_PAGE_TABLE_FIELD_PREP(2, PC, PD_BASE, > child_table_dma_addr); > +} For this function and others that manipulate page table entries, please use some kernel helper that ensures that the store can't tear (at least WRITE_ONCE() - that can still tear on 32-bit, but I see the driver depends on ARM64, so that's not a problem). [...] > +/** > + * pvr_page_table_l2_insert() - Insert an entry referring to a level 1 page > + * table into a level 2 page table. > + * @op_ctx: Target MMU op context pointing at the entry to insert the L1 page > + * table into. > + * @child_table: Target level 1 page table to be referenced by the new entry. > + * > + * It is the caller's responsibility to ensure @op_ctx.curr_page
Re: [RFC PATCH v2 00/11] Device Memory TCP
On Thu, Aug 17, 2023 at 11:04 AM Pavel Begunkov wrote: > > On 8/14/23 02:12, David Ahern wrote: > > On 8/9/23 7:57 PM, Mina Almasry wrote: > >> Changes in RFC v2: > >> -- > ... > >> ** Test Setup > >> > >> Kernel: net-next with this RFC and memory provider API cherry-picked > >> locally. > >> > >> Hardware: Google Cloud A3 VMs. > >> > >> NIC: GVE with header split & RSS & flow steering support. > > > > This set seems to depend on Jakub's memory provider patches and a netdev > > driver change which is not included. For the testing mentioned here, you > > must have a tree + branch with all of the patches. Is it publicly available? > > > > It would be interesting to see how well (easy) this integrates with > > io_uring. Besides avoiding all of the syscalls for receiving the iov and > > releasing the buffers back to the pool, io_uring also brings in the > > ability to seed a page_pool with registered buffers which provides a > > means to get simpler Rx ZC for host memory. > > The patchset sounds pretty interesting. I've been working with David Wei > (CC'ing) on io_uring zc rx (prototype polishing stage) all that is old > similar approaches based on allocating an rx queue. It targets host > memory and device memory as an extra feature, uapi is different, lifetimes > are managed/bound to io_uring. Completions/buffers are returned to user via > a separate queue instead of cmsg, and pushed back granularly to the kernel > via another queue. I'll leave it to David to elaborate > > It sounds like we have space for collaboration here, if not merging then > reusing internals as much as we can, but we'd need to look into the > details deeper. > I'm happy to look at your implementation and collaborate on something that works for both use cases. Feel free to share unpolished prototype so I can start having a general idea if possible. > > Overall I like the intent and possibilities for extensions, but a lot of > > details are missing - perhaps some are answered by seeing an end-to-end > > implementation. > > -- > Pavel Begunkov -- Thanks, Mina
Re: [Patch v2 2/3] drm/mst: Refactor the flow for payload allocation/removement
Two small comments: On Mon, 2023-08-07 at 10:56 +0800, Wayne Lin wrote: > [Why] > Today, the allocation/deallocation steps and status is a bit unclear. > > For instance, payload->vc_start_slot = -1 stands for "the failure of > updating DPCD payload ID table" and can also represent as "payload is not > allocated yet". These two cases should be handled differently and hence > better to distinguish them for better understanding. > > [How] > Define enumeration - ALLOCATION_LOCAL, ALLOCATION_DFP and ALLOCATION_REMOTE > to distinguish different allocation status. Adjust the code to handle > different status accordingly for better understanding the sequence of > payload allocation and payload removement. > > For payload creation, the procedure should look like this: > DRM part 1: > * step 1 - update sw mst mgr variables to add a new payload > * step 2 - add payload at immediate DFP DPCD payload table > > Driver: > * Add new payload in HW and sync up with DFP by sending ACT > > DRM Part 2: > * Send ALLOCATE_PAYLOAD sideband message to allocate bandwidth along the > virtual channel. > > And as for payload removement, the procedure should look like this: > DRM part 1: > * step 1 - Send ALLOCATE_PAYLOAD sideband message to release bandwidth >along the virtual channel > * step 2 - Clear payload allocation at immediate DFP DPCD payload table > > Driver: > * Remove the payload in HW and sync up with DFP by sending ACT > > DRM part 2: > * update sw mst mgr variables to remove the payload > > Note that it's fine to fail when communicate with the branch device > connected at immediate downstrean-facing port, but updating variables of > SW mst mgr and HW configuration should be conducted anyway. That's because > it's under commit_tail and we need to complete the HW programming. > > Changes since v1: > * Remove the set but not use variable 'old_payload' in function > 'nv50_msto_prepare'. Catched by kernel test robot > > Signed-off-by: Wayne Lin > --- > .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 20 ++- > drivers/gpu/drm/display/drm_dp_mst_topology.c | 159 +++--- > drivers/gpu/drm/i915/display/intel_dp_mst.c | 18 +- > drivers/gpu/drm/nouveau/dispnv50/disp.c | 21 +-- > include/drm/display/drm_dp_mst_helper.h | 23 ++- > 5 files changed, 153 insertions(+), 88 deletions(-) > > 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 d9a482908380..9ad509279b0a 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 > @@ -219,7 +219,7 @@ static void dm_helpers_construct_old_payload( > /* Set correct time_slots/PBN of old payload. >* other fields (delete & dsc_enabled) in >* struct drm_dp_mst_atomic_payload are don't care fields > - * while calling drm_dp_remove_payload() > + * while calling drm_dp_remove_payload_part2() >*/ > for (i = 0; i < current_link_table.stream_count; i++) { > dc_alloc = > @@ -262,13 +262,12 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( > > mst_mgr = >mst_root->mst_mgr; > mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state); > - > - /* It's OK for this to fail */ > new_payload = drm_atomic_get_mst_payload_state(mst_state, > aconnector->mst_output_port); > > if (enable) { > target_payload = new_payload; > > + /* It's OK for this to fail */ > drm_dp_add_payload_part1(mst_mgr, mst_state, new_payload); > } else { > /* construct old payload by VCPI*/ > @@ -276,7 +275,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( > new_payload, _payload); > target_payload = _payload; > > - drm_dp_remove_payload(mst_mgr, mst_state, _payload, > new_payload); > + drm_dp_remove_payload_part1(mst_mgr, mst_state, new_payload); > } > > /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or > @@ -342,7 +341,7 @@ bool dm_helpers_dp_mst_send_payload_allocation( > struct amdgpu_dm_connector *aconnector; > struct drm_dp_mst_topology_state *mst_state; > struct drm_dp_mst_topology_mgr *mst_mgr; > - struct drm_dp_mst_atomic_payload *payload; > + struct drm_dp_mst_atomic_payload *new_payload, *old_payload; > enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD; > enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD; > int ret = 0; > @@ -355,15 +354,20 @@ bool dm_helpers_dp_mst_send_payload_allocation( > mst_mgr = >mst_root->mst_mgr; > mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state); > > - payload = drm_atomic_get_mst_payload_state(mst_state, > aconnector->mst_output_port); > + new_payload =
Re: [PATCH v4] PCI/VGA: Make the vga_is_firmware_default() less arch-dependent
On Wed, Aug 16, 2023 at 06:05:27AM +0800, Sui Jingfeng wrote: > Currently, the vga_is_firmware_default() function only works on x86 and > ia64, it is a no-op on ARM, ARM64, PPC, RISC-V, etc. This patch completes > the implementation for the rest of the architectures. The added code tries > to identify the PCI(e) VGA device that owns the firmware framebuffer > before PCI resource reallocation happens. As far as I can tell, this is basically identical to the existing vga_is_firmware_default(), except that this patch funs that code as a header fixup, so it happens before any PCI BAR reallocations happen. That sounds like a good idea, because this is all based on the framebuffer in screen_info, and screen_info was initialized before PCI enumeration, and it certainly doesn't account for any BAR changes done by the PCI core. So why would we keep vga_is_firmware_default() at all? If the header fixup has already identified the firmware framebuffer, it seems pointless to look again later. > This patch makes the vga_is_firmware_default() function works on whatever > arch that has UEFI GOP support. But we make it available only on platforms > where PCI resource relocation happens. if the provided method proves to be > effective and reliable, it can be expanded to other arch easily. > > v2: > * Fix test robot warnnings and fix typos > > v3: > * Fix linkage problems if the global screen_info is not exported > > v4: > * Handle linkage problems by hiding behind of CONFIG_SYSFB, > * Drop side-effects and simplify. The v2, v3, v4 changelog is nice, but we don't need it in the commit log itself, where it will become part of the git history. It should go in a cover letter or after the "---" marker: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?id=v6.0#n678 > Since only one GPU could owns the firmware fb in normal case, things > are almost done once we determine the boot VGA selected by firmware. > By using the DECLARE_PCI_FIXUP_CLASS_HEADER(), we also ensure that we > could identify the primary display (if there do have one) before PCI > resource reallocation happen. > > The method provided in this patch will be effective as long as the target > platform has a way set up the kernel's screen_info. For the machines with > UEFI firmware, the screen_info is typically set up by the UEFI stub with > respect to the UEFI GOP protocol. Since the UEFI stub executes in the > context of the decompressor, and it cannot access the kernel's screen_info > directly. Hence, the efi stub copies the screen_info provided by firmware > to kernel's counterpart. Therefore, we handle linkage problems by using > the CONFIG_EFI guard. Since when CONFIG_EFI is set, the kernel's > screen_info is guaranteed to be static linkable for arm, arm64, riscv. > V4 of this patch handle linkage problems by hiding behind of CONFIG_SYSFB, > since sysfb reference the global screen_info as well. > > This patch is tested on: > > 1) LS3A5000+LS7A1000 platform with three video cards > > $ lspci | grep VGA > > 00:06.1 VGA compatible controller: Loongson Technology LLC DC (Display > Controller) (rev 01) > 03:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] > Caicos XT [Radeon HD 7470/8470 / R5 235/310 OEM] > 07:00.0 VGA compatible controller: S3 Graphics Ltd. Device 9070 (rev 01) > 08:00.0 VGA compatible controller: S3 Graphics Ltd. Device 9070 (rev 01) > > Before apply this patch: > > [0.361748] pci :00:06.1: vgaarb: setting as boot VGA device > [0.361751] pci :00:06.1: vgaarb: bridge control possible > [0.361753] pci :00:06.1: vgaarb: VGA device added: > decodes=io+mem,owns=io+mem,locks=none > [0.361763] pci :03:00.0: vgaarb: bridge control possible > [0.361765] pci :03:00.0: vgaarb: VGA device added: > decodes=io+mem,owns=none,locks=none > [0.361771] pci :07:00.0: vgaarb: bridge control possible > [0.361773] pci :07:00.0: vgaarb: VGA device added: > decodes=io+mem,owns=none,locks=none > [0.361777] pci :08:00.0: vgaarb: bridge control possible > [0.361779] pci :08:00.0: vgaarb: VGA device added: > decodes=io+mem,owns=none,locks=none > [0.361781] vgaarb: loaded > [0.367838] pci :00:06.1: Overriding boot device as 1002:6778 > [0.367841] pci :00:06.1: Overriding boot device as 5333:9070 > [0.367843] pci :00:06.1: Overriding boot device as 5333:9070 > > After apply this patch: > > [0.357780] pci :03:00.0: vgaarb: BAR 0 contains firmware FB > [0.361726] pci :00:06.1: vgaarb: setting as boot VGA device > [0.361729] pci :00:06.1: vgaarb: bridge control possible > [0.361731] pci :00:06.1: vgaarb: VGA device added: > decodes=io+mem,owns=io+mem,locks=none > [0.361741] pci :03:00.0: vgaarb: setting as boot VGA device > (overriding previous) > [0.361743] pci :03:00.0: vgaarb: bridge control
Re: [PATCH 3/3] drm/mst: adjust the function drm_dp_remove_payload_part2()
On Mon, 2023-08-07 at 18:59 +0300, Imre Deak wrote: > On Mon, Aug 07, 2023 at 02:43:02AM +, Lin, Wayne wrote: > > [AMD Official Use Only - General] > > > > > -Original Message- > > > From: Imre Deak > > > Sent: Friday, August 4, 2023 11:32 PM > > > To: Lin, Wayne > > > Cc: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org; > > > ly...@redhat.com; jani.nik...@intel.com; ville.syrj...@linux.intel.com; > > > Wentland, Harry ; Zuo, Jerry > > > > > > Subject: Re: [PATCH 3/3] drm/mst: adjust the function > > > drm_dp_remove_payload_part2() > > > > > > On Fri, Aug 04, 2023 at 02:20:29PM +0800, Wayne Lin wrote: > > > > [...] > > > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > > b/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > > index e04f87ff755a..4270178f95f6 100644 > > > > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c > > > > @@ -3382,8 +3382,7 @@ > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1); > > > > * drm_dp_remove_payload_part2() - Remove an MST payload locally > > > > * @mgr: Manager to use. > > > > * @mst_state: The MST atomic state > > > > - * @old_payload: The payload with its old state > > > > - * @new_payload: The payload with its latest state > > > > + * @payload: The payload with its latest state > > > > * > > > > * Updates the starting time slots of all other payloads which would > > > > have > > > been shifted towards > > > > * the start of the payload ID table as a result of removing a > > > > payload. Driver should call this @@ -3392,25 +3391,36 @@ > > > EXPORT_SYMBOL(drm_dp_remove_payload_part1); > > > > */ > > > > void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr > > > *mgr, > > > > struct drm_dp_mst_topology_state > > > *mst_state, > > > > -const struct drm_dp_mst_atomic_payload > > > *old_payload, > > > > -struct drm_dp_mst_atomic_payload > > > *new_payload) > > > > +struct drm_dp_mst_atomic_payload > > > *payload) > > > > { > > > > struct drm_dp_mst_atomic_payload *pos; > > > > + u8 time_slots_to_remove; > > > > + u8 next_payload_vc_start = mgr->next_start_slot; > > > > + > > > > + /* Find the current allocated time slot number of the payload */ > > > > + list_for_each_entry(pos, _state->payloads, next) { > > > > + if (pos != payload && > > > > + pos->vc_start_slot > payload->vc_start_slot && > > > > + pos->vc_start_slot < next_payload_vc_start) > > > > + next_payload_vc_start = pos->vc_start_slot; > > > > + } > > > > + > > > > + time_slots_to_remove = next_payload_vc_start - > > > > +payload->vc_start_slot; > > > > > > Imo, the intuitive way would be to pass the old payload state to this > > > function - > > > which already contains the required time_slots param - and refactor things > > > instead moving vc_start_slot from the payload state to mgr suggested by > > > Ville > > > earlier. > > > > > > --Imre > > > > Hi Imre, > > Thanks for your feedback! > > > > I understand it's functionally correct. But IMHO, it's still a bit > > conceptually different between the time slot in old state and the time > > slot in current payload table. My thought is the time slot at the > > moment when we are removing the payload would be a better choice. > > Yes, they are different. The old state contains the time slot the > payload was added with in a preceding commit and so the time slot value > which should be used when removing the same payload in the current > commit. > > The new state contains a time slot value with which the payload will be > added in the current commit and can be different than the one in the old > state if the current commit has changed the payload size (meaning that > the same atomic commit will first remove the payload using the time slot > value in the old state and afterwards will add back the same payload > using the time slot value in the new state). > > > And with this, we can also simplify some codes. Especially remove > > workaround in amd driver. In fact, DRM mst code maintains the payload > > table and all the time slot info is in it already. We don't really > > have to pass a new parameter. > > I agree that drm_dp_remove_payload() could be simplified, but this > should be done so that the drivers can pass the old payload state to it > (without having to pass the new state). This would be possible if > vc_start_slot was not tracked in the payload state (which is really not > an atomic state that can be precomputed as all other atomic state), > rather it would be tracked in struct drm_dp_mst_topology_mgr. JFYI too - I think I'm fine with us moving vc_start_slot elsewhere at this point ;) > > It looks like AMD has to reconstruct the old state in > dm_helpers_construct_old_payload(). Could you explain why it couldn't > instead
[PATCH] dma-buf/sw_sync: Avoid recursive lock during fence signal
From: Rob Clark If a signal callback releases the sw_sync fence, that will trigger a deadlock as the timeline_fence_release recurses onto the fence->lock (used both for signaling and the the timeline tree). To avoid that, temporarily hold an extra reference to the signalled fences until after we drop the lock. (This is an alternative implementation of https://patchwork.kernel.org/patch/11664717/ which avoids some potential UAF issues with the original patch.) Reported-by: Bas Nieuwenhuizen Fixes: d3c6dd1fb30d ("dma-buf/sw_sync: Synchronize signal vs syncpt free") Signed-off-by: Rob Clark --- drivers/dma-buf/sw_sync.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 63f0aeb66db6..ceb6a0408624 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -191,6 +191,7 @@ static const struct dma_fence_ops timeline_fence_ops = { */ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) { + LIST_HEAD(signalled); struct sync_pt *pt, *next; trace_sync_timeline(obj); @@ -203,9 +204,13 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) if (!timeline_fence_signaled(>base)) break; + dma_fence_get(>base); + list_del_init(>link); rb_erase(>node, >pt_tree); + list_add_tail(>link, ); + /* * A signal callback may release the last reference to this * fence, causing it to be freed. That operation has to be @@ -218,6 +223,11 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) } spin_unlock_irq(>lock); + + list_for_each_entry_safe(pt, next, , link) { + list_del(>link); + dma_fence_put(>base); + } } /** -- 2.41.0
[git pull] drm fixes for 6.5-rc7
Hi Linus, Regular enough week, mostly the usual amdgpu and i915 fixes. Then qaic, nouveau, qxl and a revert for an EDID patch that had some side effects, along with a couple of panel fixes. Dave. drm-fixes-2023-08-18-1: drm fixes for 6.5-rc7 edid: - revert mode parsing fix that had side effects. i915: - Fix the flow for ignoring GuC SLPC efficient frequency selection - Fix SDVO panel_type initialization - Fix display probe for IVB Q and IVB D GT2 server nouveau: - fix use-after-free in connector code qaic: - integer overflow check fix - fix slicing memory leak panel: - fix JDI LT070ME05000 probing - fix AUO G121EAN01 timings amdgpu: - SMU 13.x fixes - Fix mcbp parameter for gfx9 - SMU 11.x fixes - Temporary fix for large numbers of XCP partitions - S0ix fixes - DCN 2.0 fix qxl: - fix use after free race in dumb object allocation The following changes since commit 2ccdd1b13c591d306f0401d98dedc4bdcd02b421: Linux 6.5-rc6 (2023-08-13 11:29:55 -0700) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2023-08-18-1 for you to fetch changes up to c611589b4259ed63b9b77be6872b1ce07ec0ac16: drm/qxl: fix UAF on handle creation (2023-08-18 06:57:38 +1000) drm fixes for 6.5-rc7 edid: - revert mode parsing fix that had side effects. i915: - Fix the flow for ignoring GuC SLPC efficient frequency selection - Fix SDVO panel_type initialization - Fix display probe for IVB Q and IVB D GT2 server nouveau: - fix use-after-free in connector code qaic: - integer overflow check fix - fix slicing memory leak panel: - fix JDI LT070ME05000 probing - fix AUO G121EAN01 timings amdgpu: - SMU 13.x fixes - Fix mcbp parameter for gfx9 - SMU 11.x fixes - Temporary fix for large numbers of XCP partitions - S0ix fixes - DCN 2.0 fix qxl: - fix use after free race in dumb object allocation Alex Deucher (1): Revert "Revert "drm/amdgpu/display: change pipe policy for DCN 2.0"" Asad Kamal (1): drm/amd/pm: Update pci link width for smu v13.0.6 Dan Carpenter (1): accel/qaic: Clean up integer overflow checking in map_user_pages() Dave Airlie (3): Merge tag 'drm-intel-fixes-2023-08-17' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes Merge tag 'drm-misc-fixes-2023-08-17' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes Merge tag 'amd-drm-fixes-6.5-2023-08-16' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes David Heidelberg (1): drm/panel: JDI LT070ME05000 simplify with dev_err_probe() James Zhu (1): drm/amdgpu: skip xcp drm device allocation when out of drm resource Jani Nikula (3): drm/i915/sdvo: fix panel_type initialization drm/i915: fix display probe for IVB Q and IVB D GT2 server Revert "drm/edid: Fix csync detailed mode parsing" Jiadong Zhu (1): drm/amdgpu: disable mcbp if parameter zero is set Karol Herbst (1): drm/nouveau/disp: fix use-after-free in error handling of nouveau_connector_create Kenneth Feng (1): drm/amd/pm: disallow the fan setting if there is no fan on smu 13.0.0 Lijo Lazar (1): drm/amd/pm: Fix temperature unit of SMU v13.0.6 Luca Ceresoli (1): drm/panel: simple: Fix AUO G121EAN01 panel timings according to the docs Mario Limonciello (1): drm/amd: flush any delayed gfxoff on suspend entry Pranjal Ramajor Asha Kanojiya (1): accel/qaic: Fix slicing memory leak Tim Huang (1): drm/amdgpu: skip fence GFX interrupts disable/enable for S0ix Umio Yasuno (1): drm/amdgpu/pm: fix throttle_status for other than MP1 11.0.7 Vinay Belgaumkar (1): drm/i915/guc/slpc: Restore efficient freq earlier Wander Lairson Costa (1): drm/qxl: fix UAF on handle creation drivers/accel/qaic/qaic_control.c | 26 +- drivers/accel/qaic/qaic_data.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 41 -- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c| 9 + drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c| 13 ++- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 9 - .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c| 14 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 4 +++ .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 19 +++--- drivers/gpu/drm/drm_edid.c | 29 +-- .../gpu/drm/i915/display/intel_display_device.c| 24 +++-- drivers/gpu/drm/i915/display/intel_sdvo.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c| 22 +++- drivers/gpu/drm/nouveau/nouveau_connector.c| 11 +++---
Re: [PATCH v2] drm/i915/guc: Force a reset on internal GuC error
On 8/15/2023 5:39 PM, john.c.harri...@intel.com wrote: From: John Harrison If GuC hits an internal error (and survives long enough to report it to the KMD), it is basically toast and will stop until a GT reset and subsequent GuC reload is performed. Previously, the KMD just printed an error message and then waited for the heartbeat to eventually kick in and trigger a reset (assuming the heartbeat had not been disabled). Instead, force the reset immediately to guarantee that it happens and to eliminate the very long heartbeat delay. The captured error state is also more likely to be useful if captured at the time of the error rather than many seconds later. Note that it is not possible to trigger a reset from with the G2H handler itself. The reset prepare process involves flushing outstanding G2H contents. So a deadlock could result. Instead, the G2H handler queues a worker thread to do the reset asynchronously. v2: Flush the worker on suspend and shutdown. Add rate limiting to prevent spam from a totally dead system (review feedback from Daniele). Signed-off-by: John Harrison Reviewed-by: Daniele Ceraolo Spurio Daniele --- drivers/gpu/drm/i915/gt/uc/intel_guc.c| 38 +++ drivers/gpu/drm/i915/gt/uc/intel_guc.h| 15 + drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 6 +--- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index 569b5fe94c416..12a817b762334 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -159,6 +159,21 @@ static void gen11_disable_guc_interrupts(struct intel_guc *guc) gen11_reset_guc_interrupts(guc); } +static void guc_dead_worker_func(struct work_struct *w) +{ + struct intel_guc *guc = container_of(w, struct intel_guc, dead_guc_worker); + struct intel_gt *gt = guc_to_gt(guc); + unsigned long last = guc->last_dead_guc_jiffies; + unsigned long delta = jiffies_to_msecs(jiffies - last); + + if (delta < 500) { + intel_gt_set_wedged(gt); + } else { + intel_gt_handle_error(gt, ALL_ENGINES, I915_ERROR_CAPTURE, "dead GuC"); + guc->last_dead_guc_jiffies = jiffies; + } +} + void intel_guc_init_early(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); @@ -171,6 +186,8 @@ void intel_guc_init_early(struct intel_guc *guc) intel_guc_slpc_init_early(>slpc); intel_guc_rc_init_early(guc); + INIT_WORK(>dead_guc_worker, guc_dead_worker_func); + mutex_init(>send_mutex); spin_lock_init(>irq_lock); if (GRAPHICS_VER(i915) >= 11) { @@ -461,6 +478,8 @@ void intel_guc_fini(struct intel_guc *guc) if (!intel_uc_fw_is_loadable(>fw)) return; + flush_work(>dead_guc_worker); + if (intel_guc_slpc_is_used(guc)) intel_guc_slpc_fini(>slpc); @@ -585,6 +604,20 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, return ret; } +int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action) +{ + if (action == INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED) + guc_err(guc, "Crash dump notification\n"); + else if (action == INTEL_GUC_ACTION_NOTIFY_EXCEPTION) + guc_err(guc, "Exception notification\n"); + else + guc_err(guc, "Unknown crash notification: 0x%04X\n", action); + + queue_work(system_unbound_wq, >dead_guc_worker); + + return 0; +} + int intel_guc_to_host_process_recv_msg(struct intel_guc *guc, const u32 *payload, u32 len) { @@ -601,6 +634,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc, if (msg & INTEL_GUC_RECV_MSG_EXCEPTION) guc_err(guc, "Received early exception notification!\n"); + if (msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | INTEL_GUC_RECV_MSG_EXCEPTION)) + queue_work(system_unbound_wq, >dead_guc_worker); + return 0; } @@ -640,6 +676,8 @@ int intel_guc_suspend(struct intel_guc *guc) return 0; if (intel_guc_submission_is_used(guc)) { + flush_work(>dead_guc_worker); + /* * This H2G MMIO command tears down the GuC in two steps. First it will * generate a G2H CTB for every active context indicating a reset. In diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 8dc291ff00935..6c392bad29c19 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -266,6 +266,20 @@ struct intel_guc { unsigned long last_stat_jiffies; } timestamp; + /** +* @dead_guc_worker: Asynchronous worker thread for forcing a GuC reset. +* Specifically used when the G2H handler wants to issue
Re: [PATCH v2] drm: bridge: samsung-dsim: Fix init during host transfer
On Thu, Aug 17, 2023 at 1:59 PM Fabio Estevam wrote: > > Hi Tim, > > On Thu, Aug 17, 2023 at 5:53 PM Tim Harvey wrote: > > > Frieder, > > > > Sorry for the delay. Yes this resolves the regression I ran into. I > > tested it on top of v6.5-rc6 on a gw72xx-0x with a DFROBOT DRF0678 7in > > 800x480 (Raspberry Pi) display which has the Toshiba TC358762 > > compatible DSI to DBI bridge. > > > > Let's please get this into v6.5 as soon as possible. > > Care to provide your Tested-by tag? Fabio, Yes, sorry: Tested-by: Tim Harvey # imx8mm-venice-gw72xx-0x with toshiba tc358762 MIPI DSI bridge best regards, Tim
Re: [PATCH v2] drm: bridge: samsung-dsim: Fix init during host transfer
Hi Tim, On Thu, Aug 17, 2023 at 5:53 PM Tim Harvey wrote: > Frieder, > > Sorry for the delay. Yes this resolves the regression I ran into. I > tested it on top of v6.5-rc6 on a gw72xx-0x with a DFROBOT DRF0678 7in > 800x480 (Raspberry Pi) display which has the Toshiba TC358762 > compatible DSI to DBI bridge. > > Let's please get this into v6.5 as soon as possible. Care to provide your Tested-by tag?
Re: [PATCH v2] drm: bridge: samsung-dsim: Fix init during host transfer
On Mon, Jul 24, 2023 at 8:16 AM Frieder Schrempf wrote: > > From: Frieder Schrempf > > In case the downstream bridge or panel uses DSI transfers before the > DSI host was actually initialized through samsung_dsim_atomic_enable() > which clears the stop state (LP11) mode, all transfers will fail. > > This happens with downstream bridges that are controlled by DSI > commands such as the tc358762. > > As documented in [1] DSI hosts are expected to allow transfers > outside the normal bridge enable/disable flow. > > To fix this make sure that stop state is cleared in > samsung_dsim_host_transfer() which restores the previous > behavior. > > We also factor out the common code to enable/disable stop state > to samsung_dsim_set_stop_state(). > > [1] https://docs.kernel.org/gpu/drm-kms-helpers.html#mipi-dsi-bridge-operation > > Fixes: 0c14d3130654 ("drm: bridge: samsung-dsim: Fix i.MX8M enable flow to > meet spec") > Reported-by: Tim Harvey > Signed-off-by: Frieder Schrempf > --- > Changes for v2: > * Fix reversed stop state enable/disable in samsung_dsim_set_stop_state() > > Hi Tim, could you please give this patch a try and report back if > it fixes your problem? Thanks! > --- > drivers/gpu/drm/bridge/samsung-dsim.c | 27 +-- > 1 file changed, 17 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c > b/drivers/gpu/drm/bridge/samsung-dsim.c > index 043b8109e64a..73ec60757dbc 100644 > --- a/drivers/gpu/drm/bridge/samsung-dsim.c > +++ b/drivers/gpu/drm/bridge/samsung-dsim.c > @@ -1386,6 +1386,18 @@ static void samsung_dsim_disable_irq(struct > samsung_dsim *dsi) > disable_irq(dsi->irq); > } > > +static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool > enable) > +{ > + u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); > + > + if (enable) > + reg |= DSIM_FORCE_STOP_STATE; > + else > + reg &= ~DSIM_FORCE_STOP_STATE; > + > + samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); > +} > + > static int samsung_dsim_init(struct samsung_dsim *dsi) > { > const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; > @@ -1445,15 +1457,12 @@ static void samsung_dsim_atomic_enable(struct > drm_bridge *bridge, >struct drm_bridge_state > *old_bridge_state) > { > struct samsung_dsim *dsi = bridge_to_dsi(bridge); > - u32 reg; > > if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) { > samsung_dsim_set_display_mode(dsi); > samsung_dsim_set_display_enable(dsi, true); > } else { > - reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); > - reg &= ~DSIM_FORCE_STOP_STATE; > - samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); > + samsung_dsim_set_stop_state(dsi, false); > } > > dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; > @@ -1463,16 +1472,12 @@ static void samsung_dsim_atomic_disable(struct > drm_bridge *bridge, > struct drm_bridge_state > *old_bridge_state) > { > struct samsung_dsim *dsi = bridge_to_dsi(bridge); > - u32 reg; > > if (!(dsi->state & DSIM_STATE_ENABLED)) > return; > > - if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) { > - reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); > - reg |= DSIM_FORCE_STOP_STATE; > - samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); > - } > + if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) > + samsung_dsim_set_stop_state(dsi, true); > > dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; > } > @@ -1775,6 +1780,8 @@ static ssize_t samsung_dsim_host_transfer(struct > mipi_dsi_host *host, > if (ret) > return ret; > > + samsung_dsim_set_stop_state(dsi, false); > + > ret = mipi_dsi_create_packet(, msg); > if (ret < 0) > return ret; > -- > 2.41.0 > Frieder, Sorry for the delay. Yes this resolves the regression I ran into. I tested it on top of v6.5-rc6 on a gw72xx-0x with a DFROBOT DRF0678 7in 800x480 (Raspberry Pi) display which has the Toshiba TC358762 compatible DSI to DBI bridge. Let's please get this into v6.5 as soon as possible. Best regards, Tim
Re: [PATCH] clk: Annotate struct clk_hw_onecell_data with __counted_by
On 8/17/23 14:30, Kees Cook wrote: Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). As found with Coccinelle[1], add __counted_by for struct clk_hw_onecell_data. Additionally, since the element count member must be set before accessing the annotated flexible array member, move its initialization earlier. [1] https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci Cc: Michael Turquette Cc: Stephen Boyd Cc: Joel Stanley Cc: Andrew Jeffery Cc: Taichi Sugaya Cc: Takao Orito Cc: Qin Jian Cc: Andrew Lunn Cc: Gregory Clement Cc: Sebastian Hesselbarth Cc: Andy Gross Cc: Bjorn Andersson Cc: Konrad Dybcio Cc: Sergio Paracuellos Cc: Matthias Brugger Cc: AngeloGioacchino Del Regno Cc: Maxime Ripard Cc: Chen-Yu Tsai Cc: Jernej Skrabec Cc: David Airlie Cc: Daniel Vetter Cc: Samuel Holland Cc: Vinod Koul Cc: Kishon Vijay Abraham I Cc: linux-...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: linux-asp...@lists.ozlabs.org Cc: linux-arm-...@vger.kernel.org Cc: linux-media...@lists.infradead.org Cc: dri-devel@lists.freedesktop.org Cc: linux-su...@lists.linux.dev Cc: linux-...@lists.infradead.org Signed-off-by: Kees Cook Reviewed-by: Gustavo A. R. Silva Thanks -- Gustavo --- drivers/clk/clk-aspeed.c| 3 +-- drivers/clk/clk-ast2600.c | 2 +- drivers/clk/clk-gemini.c| 2 +- drivers/clk/clk-milbeaut.c | 3 +-- drivers/clk/clk-sp7021.c| 3 +-- drivers/clk/mvebu/cp110-system-controller.c | 2 +- drivers/clk/qcom/clk-cpu-8996.c | 2 +- drivers/clk/ralink/clk-mt7621.c | 3 +-- drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 3 +-- drivers/phy/qualcomm/phy-qcom-edp.c | 2 +- include/linux/clk-provider.h| 2 +- 11 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c index 284710adaef5..ff84191d0fe8 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/clk-aspeed.c @@ -701,6 +701,7 @@ static void __init aspeed_cc_init(struct device_node *np) GFP_KERNEL); if (!aspeed_clk_data) return; + aspeed_clk_data->num = ASPEED_NUM_CLKS; /* * This way all clocks fetched before the platform device probes, @@ -732,8 +733,6 @@ static void __init aspeed_cc_init(struct device_node *np) aspeed_ast2500_cc(map); else pr_err("unknown platform, failed to add clocks\n"); - - aspeed_clk_data->num = ASPEED_NUM_CLKS; ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data); if (ret) pr_err("failed to add DT provider: %d\n", ret); diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index f9e27f95a967..909c3137c428 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -839,6 +839,7 @@ static void __init aspeed_g6_cc_init(struct device_node *np) ASPEED_G6_NUM_CLKS), GFP_KERNEL); if (!aspeed_g6_clk_data) return; + aspeed_g6_clk_data->num = ASPEED_G6_NUM_CLKS; /* * This way all clocks fetched before the platform device probes, @@ -860,7 +861,6 @@ static void __init aspeed_g6_cc_init(struct device_node *np) } aspeed_g6_cc(map); - aspeed_g6_clk_data->num = ASPEED_G6_NUM_CLKS; ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_g6_clk_data); if (ret) pr_err("failed to add DT provider: %d\n", ret); diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index a23fa6d47ef1..2572d15aadd0 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -404,6 +404,7 @@ static void __init gemini_cc_init(struct device_node *np) GFP_KERNEL); if (!gemini_clk_data) return; + gemini_clk_data->num = GEMINI_NUM_CLKS; /* * This way all clock fetched before the platform device probes, @@ -457,7 +458,6 @@ static void __init gemini_cc_init(struct device_node *np) gemini_clk_data->hws[GEMINI_CLK_APB] = hw; /* Register the clocks to be accessed by the device tree */ - gemini_clk_data->num = GEMINI_NUM_CLKS; of_clk_add_hw_provider(np, of_clk_hw_onecell_get, gemini_clk_data); } CLK_OF_DECLARE_DRIVER(gemini_cc, "cortina,gemini-syscon", gemini_cc_init); diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index 050fd4fb588f..18c20aff45f7 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -618,6 +618,7 @@ static void __init
Re: [PATCH v2 2/4] arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver
On 17/08/2023 15:59, Dmitry Baryshkov wrote: Add the nb7vpq904m, onboard USB-C redriver / retimer. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 52 +++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 303d07f9c6e5..a4f7a9f9c22c 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -610,6 +610,46 @@ lt9611_out: endpoint { /* LS-I2C1 */ { status = "okay"; + + typec-mux@1c { + compatible = "onnn,nb7vpq904m"; + reg = <0x1c>; + + vcc-supply = <_s4a_1p8>; + + retimer-switch; + orientation-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + redriver_usb_con_ss: endpoint { + remote-endpoint = <_typec_mux_in>; + }; + }; + + port@1 { + reg = <1>; + + redriver_phy_con_ss: endpoint { + remote-endpoint = <_1_qmpphy_out>; + data-lanes = <0 1 2 3>; + }; + }; + + port@2 { + reg = <2>; + + redriver_usb_con_sbu: endpoint { + remote-endpoint = <_typec_sbu_out>; + }; + }; + }; + }; }; { @@ -1299,7 +1339,7 @@ _1_qmpphy { }; _1_qmpphy_out { - remote-endpoint = <_typec_mux_in>; + remote-endpoint = <_phy_con_ss>; }; _2 { @@ -1388,7 +1428,15 @@ pm8150b_role_switch_in: endpoint { port@1 { reg = <1>; pm8150b_typec_mux_in: endpoint { - remote-endpoint = <_1_qmpphy_out>; + remote-endpoint = <_usb_con_ss>; + }; + }; + + port@2 { + reg = <2>; + + pm8150b_typec_sbu_out: endpoint { + remote-endpoint = <_usb_con_sbu>; }; }; }; LGTM Reviewed-by: Bryan O'Donoghue
[PATCH] clk: Annotate struct clk_hw_onecell_data with __counted_by
Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). As found with Coccinelle[1], add __counted_by for struct clk_hw_onecell_data. Additionally, since the element count member must be set before accessing the annotated flexible array member, move its initialization earlier. [1] https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci Cc: Michael Turquette Cc: Stephen Boyd Cc: Joel Stanley Cc: Andrew Jeffery Cc: Taichi Sugaya Cc: Takao Orito Cc: Qin Jian Cc: Andrew Lunn Cc: Gregory Clement Cc: Sebastian Hesselbarth Cc: Andy Gross Cc: Bjorn Andersson Cc: Konrad Dybcio Cc: Sergio Paracuellos Cc: Matthias Brugger Cc: AngeloGioacchino Del Regno Cc: Maxime Ripard Cc: Chen-Yu Tsai Cc: Jernej Skrabec Cc: David Airlie Cc: Daniel Vetter Cc: Samuel Holland Cc: Vinod Koul Cc: Kishon Vijay Abraham I Cc: linux-...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: linux-asp...@lists.ozlabs.org Cc: linux-arm-...@vger.kernel.org Cc: linux-media...@lists.infradead.org Cc: dri-devel@lists.freedesktop.org Cc: linux-su...@lists.linux.dev Cc: linux-...@lists.infradead.org Signed-off-by: Kees Cook --- drivers/clk/clk-aspeed.c| 3 +-- drivers/clk/clk-ast2600.c | 2 +- drivers/clk/clk-gemini.c| 2 +- drivers/clk/clk-milbeaut.c | 3 +-- drivers/clk/clk-sp7021.c| 3 +-- drivers/clk/mvebu/cp110-system-controller.c | 2 +- drivers/clk/qcom/clk-cpu-8996.c | 2 +- drivers/clk/ralink/clk-mt7621.c | 3 +-- drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 3 +-- drivers/phy/qualcomm/phy-qcom-edp.c | 2 +- include/linux/clk-provider.h| 2 +- 11 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c index 284710adaef5..ff84191d0fe8 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/clk-aspeed.c @@ -701,6 +701,7 @@ static void __init aspeed_cc_init(struct device_node *np) GFP_KERNEL); if (!aspeed_clk_data) return; + aspeed_clk_data->num = ASPEED_NUM_CLKS; /* * This way all clocks fetched before the platform device probes, @@ -732,8 +733,6 @@ static void __init aspeed_cc_init(struct device_node *np) aspeed_ast2500_cc(map); else pr_err("unknown platform, failed to add clocks\n"); - - aspeed_clk_data->num = ASPEED_NUM_CLKS; ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data); if (ret) pr_err("failed to add DT provider: %d\n", ret); diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index f9e27f95a967..909c3137c428 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -839,6 +839,7 @@ static void __init aspeed_g6_cc_init(struct device_node *np) ASPEED_G6_NUM_CLKS), GFP_KERNEL); if (!aspeed_g6_clk_data) return; + aspeed_g6_clk_data->num = ASPEED_G6_NUM_CLKS; /* * This way all clocks fetched before the platform device probes, @@ -860,7 +861,6 @@ static void __init aspeed_g6_cc_init(struct device_node *np) } aspeed_g6_cc(map); - aspeed_g6_clk_data->num = ASPEED_G6_NUM_CLKS; ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_g6_clk_data); if (ret) pr_err("failed to add DT provider: %d\n", ret); diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index a23fa6d47ef1..2572d15aadd0 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -404,6 +404,7 @@ static void __init gemini_cc_init(struct device_node *np) GFP_KERNEL); if (!gemini_clk_data) return; + gemini_clk_data->num = GEMINI_NUM_CLKS; /* * This way all clock fetched before the platform device probes, @@ -457,7 +458,6 @@ static void __init gemini_cc_init(struct device_node *np) gemini_clk_data->hws[GEMINI_CLK_APB] = hw; /* Register the clocks to be accessed by the device tree */ - gemini_clk_data->num = GEMINI_NUM_CLKS; of_clk_add_hw_provider(np, of_clk_hw_onecell_get, gemini_clk_data); } CLK_OF_DECLARE_DRIVER(gemini_cc, "cortina,gemini-syscon", gemini_cc_init); diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index 050fd4fb588f..18c20aff45f7 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -618,6 +618,7 @@ static void __init m10v_cc_init(struct device_node *np) if (!m10v_clk_data) return; +
[BUG] KCSAN: data-race in drm_sched_entity_is_ready [gpu_sched] / drm_sched_entity_push_job [gpu_sched]
Hi, This is your friendly bug reporter. The environment is vanilla torvalds tree kernel on Ubuntu 22.04 LTS and a Ryzen 7950X box. Please find attached the complete dmesg output from the ring buffer and lshw output. NOTE: The kernel reports tainted kernel, but to my knowledge there are no proprietary (G) modules, but this taint is turned on by the previous bugs. dmesg excerpt: [ 8791.864576] == [ 8791.864648] BUG: KCSAN: data-race in drm_sched_entity_is_ready [gpu_sched] / drm_sched_entity_push_job [gpu_sched] [ 8791.864776] write (marked) to 0x9b74491b7c40 of 8 bytes by task 3807 on cpu 18: [ 8791.864788] drm_sched_entity_push_job+0xf4/0x2a0 [gpu_sched] [ 8791.864852] amdgpu_cs_ioctl+0x3888/0x3de0 [amdgpu] [ 8791.868731] drm_ioctl_kernel+0x127/0x210 [drm] [ 8791.869222] drm_ioctl+0x38f/0x6f0 [drm] [ 8791.869711] amdgpu_drm_ioctl+0x7e/0xe0 [amdgpu] [ 8791.873660] __x64_sys_ioctl+0xd2/0x120 [ 8791.873676] do_syscall_64+0x58/0x90 [ 8791.873688] entry_SYSCALL_64_after_hwframe+0x73/0xdd [ 8791.873710] read to 0x9b74491b7c40 of 8 bytes by task 1119 on cpu 27: [ 8791.873722] drm_sched_entity_is_ready+0x16/0x50 [gpu_sched] [ 8791.873786] drm_sched_select_entity+0x1c7/0x220 [gpu_sched] [ 8791.873849] drm_sched_main+0xd2/0x500 [gpu_sched] [ 8791.873912] kthread+0x18b/0x1d0 [ 8791.873924] ret_from_fork+0x43/0x70 [ 8791.873939] ret_from_fork_asm+0x1b/0x30 [ 8791.873955] value changed: 0x -> 0x9b750ebcfc00 [ 8791.873971] Reported by Kernel Concurrency Sanitizer on: [ 8791.873980] CPU: 27 PID: 1119 Comm: gfx_0.0.0 Tainted: G L 6.5.0-rc6-net-cfg-kcsan-00038-g16931859a650 #35 [ 8791.873994] Hardware name: ASRock X670E PG Lightning/X670E PG Lightning, BIOS 1.21 04/26/2023 [ 8791.874002] == Best regards, Mirsad Todorovac dmesg-3.log.xz Description: application/xz lshw.txt.xz Description: application/xz
Re: [PATCH 3/4] drm/uapi: document the USB subconnector type
Simon, Laurent, On 03/08/2023 23:46, Simon Ser wrote: On Thursday, August 3rd, 2023 at 22:44, Laurent Pinchart wrote: On Thu, Aug 03, 2023 at 03:31:16PM +, Simon Ser wrote: On Thursday, August 3rd, 2023 at 17:22, Simon Ser cont...@emersion.fr wrote: The KMS docs describe "subconnector" to be defined as "downstream port" for DP. Can USB-C (or USB) be seen as a DP downstream port? To expand on this a bit: I'm wondering if we're mixing apples and oranges here. The current values of "subconnector" typically describe the lower-level protocol tunneled inside DP. For instance, VGA can be tunneled inside the DP cable when using DP → VGA adapter. Doesn't this contradict the example use case you gave in your previous e-mail, with wlroots stating "DP-3 via DVI-D" ? I understand that as DP carried over a DVI-D physical connector, did I get it wrong ? No, this is DVI carried over DP. DP cannot be carried over VGA/DVI/HDMI, but VGA/DVI/HDMI can be carried over DP. Please excuse me for the long delay, I was on vacation. Several notes on the subconnector topic. For TV and DVI-I we are really identifying a connector (or a part of the connector pins) present on the device. So, we can have e.g. following combinations (type / subtype): DVI-I / DVI-D (digital part of DVI connector) DVI-I / DVI-A (analog part of DVI connector) TV / S-Video (full S-Video connector) TV / Composite (either a separate Composite connector, or shared with S-Video) etc. For DP unfortunately we have mixed everything together. The physical connector present on the device can be DP / miniDP or USB-C (or micro-USB for SlimPort). The physical protocol can be DP or DVI / HDMI (but only for dual-mode DP ports). Over USB-C link the DP can be transferred using DP or USB signal levels. And last, but not least, we have the dongle / display connector type, which can be VGA (for active DP -> VGA converters), HDMI, DVI, DP, etc. If we were designing this from the scratch, I'd say that we should encode physical connector type to DRM connector type and the dongle type to subconnector. However AMD and Intel drivers have already reused DisplayPort connector type for USB-C connections. Subconnector type represents (if known) the type of downstream / dongle port. I'm not going to judge whether this was correct or not. We have to live with this and behave in a similar way. We have been looking for a way to document that the corresponding DP port is represented by the USB connector on the device. Consequently, I believe the best way to document it, would be to use DisplayPort / USB, when there is no dongle connected, switching to DisplayPort / HDMI, DisplayPort / VGA, DisplayPort / DisplayPort, etc. when the actual dongle / display is connected and then switching back to the DisplayPort / USB when it gets disconnected. If this sounds good to all parties, I'll post v2, adding this explanation to the cover letter. -- With best wishes Dmitry
Re: [Freedreno] [PATCH 3/3] drm/msm/dpu: drop dpu_encoder_phys_ops.atomic_mode_set
On 8/17/2023 11:50 AM, Dmitry Baryshkov wrote: On 08/08/2023 02:49, Abhinav Kumar wrote: On 6/4/2023 7:45 AM, Dmitry Baryshkov wrote: The atomic_mode_set() callback only sets the phys_enc's IRQ data. As the INTF and WB are statically allocated to each encoder/phys_enc, drop the atomic_mode_set callback and set the IRQs during encoder init. For the CMD panel usecase some of IRQ indexes depend on the selected resources. Move setting them to the irq_enable() callback. The irq_enable() callback is called from the dpu_encoder_virt_atomic_enable() after the phys layer's enable. Thats late. So lets consider the case where command mode panel's clock is powered from bootloader (quite common). Now, as soon as the tearcheck is configured and interface is ON from the phys's enable(), nothing prevents / should prevent the interrupt from firing. Please note that interrupt callbacks are also registered from the irq_control(). There is no way the interrupt can fire beforehand (and the call chain is dpu_encoder_virt_atomic_enable() -> dpu_encoder_resource_control() -> _dpu_encoder_resource_control_helper() -> _dpu_encoder_irq_control() -> irq_control(). If we ever want to move irq_control() to be called before phys's enable() callbacks, this will be a separate patchset, involving refactoring of dpu_encoder_resource_control(). Ack, I will rebase my patches on top of this and re-test it. Then will give my R-b, tested-by tags by Monday. So I feel / think mode_set is the correct location to assign these. I can ack patches 1 and 2 but I think you did those mainly for this one, so I would like to get some clarity on this part. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 -- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 5 --- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 32 --- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 13 ++-- .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 11 +-- 5 files changed, 17 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index cc61f0cf059d..6b5c80dc5967 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1148,8 +1148,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); phys->cached_mode = crtc_state->adjusted_mode; - if (phys->ops.atomic_mode_set) - phys->ops.atomic_mode_set(phys, crtc_state, conn_state); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index faf033cd086e..24dbc28be4f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -67,8 +67,6 @@ struct dpu_encoder_phys; * @is_master: Whether this phys_enc is the current master * encoder. Can be switched at enable time. Based * on split_role and current mode (CMD/VID). - * @atomic_mode_set: DRM Call. Set a DRM mode. - * This likely caches the mode, for use at enable. * @enable: DRM Call. Enable a DRM mode. * @disable: DRM Call. Disable mode. * @atomic_check: DRM Call. Atomic check new DRM state. @@ -95,9 +93,6 @@ struct dpu_encoder_phys; struct dpu_encoder_phys_ops { void (*prepare_commit)(struct dpu_encoder_phys *encoder); bool (*is_master)(struct dpu_encoder_phys *encoder); - void (*atomic_mode_set)(struct dpu_encoder_phys *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state); void (*enable)(struct dpu_encoder_phys *encoder); void (*disable)(struct dpu_encoder_phys *encoder); int (*atomic_check)(struct dpu_encoder_phys *encoder, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 3422b49f23c2..a0b7d8803e94 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -140,23 +140,6 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx) dpu_encoder_underrun_callback(phys_enc->parent, phys_enc); } -static void dpu_encoder_phys_cmd_atomic_mode_set( - struct dpu_encoder_phys *phys_enc, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start; - - phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done; - - if (phys_enc->has_intf_te) - phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr; - else - phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr; - -
Re: [PATCH 3/3] drm/msm/dpu: drop dpu_encoder_phys_ops.atomic_mode_set
On 08/08/2023 02:49, Abhinav Kumar wrote: On 6/4/2023 7:45 AM, Dmitry Baryshkov wrote: The atomic_mode_set() callback only sets the phys_enc's IRQ data. As the INTF and WB are statically allocated to each encoder/phys_enc, drop the atomic_mode_set callback and set the IRQs during encoder init. For the CMD panel usecase some of IRQ indexes depend on the selected resources. Move setting them to the irq_enable() callback. The irq_enable() callback is called from the dpu_encoder_virt_atomic_enable() after the phys layer's enable. Thats late. So lets consider the case where command mode panel's clock is powered from bootloader (quite common). Now, as soon as the tearcheck is configured and interface is ON from the phys's enable(), nothing prevents / should prevent the interrupt from firing. Please note that interrupt callbacks are also registered from the irq_control(). There is no way the interrupt can fire beforehand (and the call chain is dpu_encoder_virt_atomic_enable() -> dpu_encoder_resource_control() -> _dpu_encoder_resource_control_helper() -> _dpu_encoder_irq_control() -> irq_control(). If we ever want to move irq_control() to be called before phys's enable() callbacks, this will be a separate patchset, involving refactoring of dpu_encoder_resource_control(). So I feel / think mode_set is the correct location to assign these. I can ack patches 1 and 2 but I think you did those mainly for this one, so I would like to get some clarity on this part. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 -- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 5 --- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 32 --- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 13 ++-- .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 11 +-- 5 files changed, 17 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index cc61f0cf059d..6b5c80dc5967 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1148,8 +1148,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); phys->cached_mode = crtc_state->adjusted_mode; - if (phys->ops.atomic_mode_set) - phys->ops.atomic_mode_set(phys, crtc_state, conn_state); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index faf033cd086e..24dbc28be4f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -67,8 +67,6 @@ struct dpu_encoder_phys; * @is_master: Whether this phys_enc is the current master * encoder. Can be switched at enable time. Based * on split_role and current mode (CMD/VID). - * @atomic_mode_set: DRM Call. Set a DRM mode. - * This likely caches the mode, for use at enable. * @enable: DRM Call. Enable a DRM mode. * @disable: DRM Call. Disable mode. * @atomic_check: DRM Call. Atomic check new DRM state. @@ -95,9 +93,6 @@ struct dpu_encoder_phys; struct dpu_encoder_phys_ops { void (*prepare_commit)(struct dpu_encoder_phys *encoder); bool (*is_master)(struct dpu_encoder_phys *encoder); - void (*atomic_mode_set)(struct dpu_encoder_phys *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state); void (*enable)(struct dpu_encoder_phys *encoder); void (*disable)(struct dpu_encoder_phys *encoder); int (*atomic_check)(struct dpu_encoder_phys *encoder, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 3422b49f23c2..a0b7d8803e94 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -140,23 +140,6 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx) dpu_encoder_underrun_callback(phys_enc->parent, phys_enc); } -static void dpu_encoder_phys_cmd_atomic_mode_set( - struct dpu_encoder_phys *phys_enc, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start; - - phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done; - - if (phys_enc->has_intf_te) - phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr; - else - phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr; - - phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun; -} - static int _dpu_encoder_phys_cmd_handle_ppdone_timeout( struct dpu_encoder_phys
Re: linux-next: Tree for Aug 17 (DRM_TTM KUNIT tests)
On 8/16/23 21:47, Stephen Rothwell wrote: > Hi all, > > Changes since 20230816: > on risc-v 32-bit: when # CONFIG_MMU is not set WARNING: unmet direct dependencies detected for DRM_TTM Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && MMU [=n] Selected by [y]: - DRM_TTM_KUNIT_TEST [=y] && HAS_IOMEM [=y] && DRM [=y] && KUNIT [=y] WARNING: unmet direct dependencies detected for DRM_TTM Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && MMU [=n] Selected by [y]: - DRM_TTM_KUNIT_TEST [=y] && HAS_IOMEM [=y] && DRM [=y] && KUNIT [=y] WARNING: unmet direct dependencies detected for DRM_TTM Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && MMU [=n] Selected by [y]: - DRM_TTM_KUNIT_TEST [=y] && HAS_IOMEM [=y] && DRM [=y] && KUNIT [=y] /opt/crosstool/gcc-13.1.0-nolibc/riscv32-linux/bin/riscv32-linux-ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `.L31': ttm_bo_vm.c:(.text+0x42c): undefined reference to `vmf_insert_pfn_prot' /opt/crosstool/gcc-13.1.0-nolibc/riscv32-linux/bin/riscv32-linux-ld: drivers/gpu/drm/ttm/ttm_bo_vm.o: in function `.L104': ttm_bo_vm.c:(.text+0xa70): undefined reference to `vmf_insert_pfn_prot' -- ~Randy
Re: [PATCH] drm/panel: Add prepare_prev_first flag to Visionox VTDR6130
On 16/08/2023 10:51, neil.armstr...@linaro.org wrote: Hi Abhinav, On 14/08/2023 20:02, Abhinav Kumar wrote: Hi Neil On 8/14/2023 1:01 AM, neil.armstr...@linaro.org wrote: Hi Abhinav, On 10/08/2023 18:26, Abhinav Kumar wrote: Hi Neil On 8/3/2023 10:19 AM, Jessica Zhang wrote: On 7/31/2023 6:00 AM, Neil Armstrong wrote: Hi, On 26/07/2023 00:56, Jessica Zhang wrote: Due to a recent introduction of the pre_enable_prev_first bridge flag [1], the panel driver will be probed before the DSI is enabled, causing the DCS commands to fail to send. Ensure that DSI is enabled before panel probe by setting the prepare_prev_first flag for the panel. Well this is specific to MSM DSI driver, it's not related at all to the panel. I dont fully agree this is a MSM DSI driver specific thing. If the panel can send its commands in its enable() callback, then this flag need not be set. When a panel sends its DCS commands in its pre_enable() callback, any DSI controller will need to be ON before that otherwise DCS commands cannot be sent. With this in mind, may I know why is this a MSM change and not a panel change? As per my discussion with Dmitry during the last sync up, we were aligned on this expectation. As of today, only the MSM DSI driver expects panels to have prepare_prev_first because it's the first one calling pre_enable() before the DSI controller to be on, all other DSI drivers I know still enables the DSI controller in mode_set() and thus can send commands in pre_enable() which is a loose way to map the pre-video state for DSI panels... It looks like there are multiple panels already setting this flag so this panel will not be the first unless they were added to make those work with MSM (which seems unlikely) panel-samsung-s6d7aa0.c: ctx->panel.prepare_prev_first = true; panel-samsung-s6e3ha2.c: ctx->panel.prepare_prev_first = true; panel-samsung-s6e63j0x03.c: ctx->panel.prepare_prev_first = true; panel-samsung-s6e8aa0.c: ctx->panel.prepare_prev_first = true; This is where I would like to understand a bit that if the panel sends out the ON commands in enable() instead of pre_enable() then, this flag will not be needed. So its also depends on the panel side and thats why the bridge feeds of the panel's input in devm_drm_panel_bridge_add_typed() bridge->pre_enable_prev_first = panel->prepare_prev_first; A panel driver should not depend on features of a DSI controller, which is the case here with this patch. Today's expectation is to send DSI commands in pre_enable() then when enabled expect to be in video mode when enable() is called. We are not depending on any feature as such. Any DSI controller , not just MSM's would need to be ON for DCS commands to be sent out in the panel's pre_enable() callback. Its not true that MSM is the only driver powering on the DSI controller in pre_enable(). Even MTK seems to be doing that mtk_dsi_bridge_atomic_pre_enable So I assume any panel which sends out commands in pre_enable() will not work with MTK as well. Sending HS commands will always work on any controller, it's all about LP commands. The Samsung panels you listed only send HS commands so they can use prepare_prev_first and work on any controllers. I think there is some misunderstanding there, supported by the description of the flag. If I remember correctly, some hosts (sunxi) can not send DCS commands after enabling video stream and switching to HS mode, see [1]. Thus, as you know, most of the drivers have all DSI panel setup commands in drm_panel_funcs::prepare() / drm_bridge_funcs::pre_enable() callbacks, not paying attention whether these commands are to be sent in LP or in HS mode. Previously DSI source drivers could power on the DSI link either in mode_set() or in pre_enable() callbacks, with mode_set() being the hack to make panel/bridge drivers to be able to send commands from their prepare() / pre_enable() callbacks. With the prev_first flags being introduced, we have established that DSI link should be enabled in DSI host's pre_enable() callback and switched to HS mode (be it command or video) in the enable() callback. So far so good. Unfortunately this change is not fully backwards-compatible. This requires that all DSI panels sending commands from prepare() should have the prepare_prev_first flag. In some sense, all such patches might have Fixes: 5ea6b1702781 ("drm/panel: Add prepare_prev_first flag to drm_panel"). None of the panels using LP commands uses prepare_prev_first: $ grep prepare_prev_first `grep -l LPM drivers/gpu/drm/panel/panel-*` $ Note that there's a smart move for VTDR6130 with the command mode introduced in 20230728011218.14630-1-parel...@quicinc.com, in the way prepare_prev_first could only be set to true if command-mode is selected. I'll accept that since it would be logical, video mode won't work anymore but by default the panel would still work in command
[PATCH v5 5/5] drm/amdgpu: Create version number for coredumps
Even if there's nothing currently parsing amdgpu's coredump files, if we eventually have such tools they will be glad to find a version field to properly read the file. Create a version number to be displayed on top of coredump file, to be incremented when the file format or content get changed. Signed-off-by: André Almeida --- v5: new patch drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c index 579b70a3cdab..e92c81ff27be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c @@ -192,6 +192,7 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, p = drm_coredump_printer(); drm_printf(, " AMDGPU Device Coredump \n"); + drm_printf(, "version: " AMDGPU_COREDUMP_VERSION "\n"); drm_printf(, "kernel: " UTS_RELEASE "\n"); drm_printf(, "module: " KBUILD_MODNAME "\n"); drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h index 01e8183ade4b..ec3a409ec509 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h @@ -88,6 +88,9 @@ struct amdgpu_reset_domain { }; #ifdef CONFIG_DEV_COREDUMP + +#define AMDGPU_COREDUMP_VERSION "1" + struct amdgpu_coredump_info { struct amdgpu_device*adev; struct amdgpu_task_info reset_task_info; -- 2.41.0
[PATCH v5 4/5] drm/amdgpu: Move coredump code to amdgpu_reset file
Giving that we use codedump just for device resets, move it's functions and structs to a more semantic file, the amdgpu_reset.{c, h}. Signed-off-by: André Almeida --- v5: no change --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 9 --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 78 -- drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 76 + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 10 +++ 4 files changed, 86 insertions(+), 87 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 56d78ca6e917..b11187d153ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -781,15 +781,6 @@ struct amdgpu_mqd { #define AMDGPU_PRODUCT_NAME_LEN 64 struct amdgpu_reset_domain; -#ifdef CONFIG_DEV_COREDUMP -struct amdgpu_coredump_info { - struct amdgpu_device*adev; - struct amdgpu_task_info reset_task_info; - struct timespec64 reset_time; - boolreset_vram_lost; -}; -#endif - struct amdgpu_reset_info { /* reset dump register */ u32 *reset_dump_reg_list; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 96975591841d..883953f2ae53 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include @@ -4799,82 +4797,6 @@ static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev) return 0; } -#ifndef CONFIG_DEV_COREDUMP -static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, - struct amdgpu_reset_context *reset_context) -{ -} -#else -static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, - size_t count, void *data, size_t datalen) -{ - struct drm_printer p; - struct amdgpu_coredump_info *coredump = data; - struct drm_print_iterator iter; - int i; - - iter.data = buffer; - iter.offset = 0; - iter.start = offset; - iter.remain = count; - - p = drm_coredump_printer(); - - drm_printf(, " AMDGPU Device Coredump \n"); - drm_printf(, "kernel: " UTS_RELEASE "\n"); - drm_printf(, "module: " KBUILD_MODNAME "\n"); - drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); - if (coredump->reset_task_info.pid) - drm_printf(, "process_name: %s PID: %d\n", - coredump->reset_task_info.process_name, - coredump->reset_task_info.pid); - - if (coredump->reset_vram_lost) - drm_printf(, "VRAM is lost due to GPU reset!\n"); - if (coredump->adev->reset_info.num_regs) { - drm_printf(, "AMDGPU register dumps:\nOffset: Value:\n"); - - for (i = 0; i < coredump->adev->reset_info.num_regs; i++) - drm_printf(, "0x%08x: 0x%08x\n", - coredump->adev->reset_info.reset_dump_reg_list[i], - coredump->adev->reset_info.reset_dump_reg_value[i]); - } - - return count - iter.remain; -} - -static void amdgpu_devcoredump_free(void *data) -{ - kfree(data); -} - -static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, - struct amdgpu_reset_context *reset_context) -{ - struct amdgpu_coredump_info *coredump; - struct drm_device *dev = adev_to_drm(adev); - - coredump = kzalloc(sizeof(*coredump), GFP_NOWAIT); - - if (!coredump) { - DRM_ERROR("%s: failed to allocate memory for coredump\n", __func__); - return; - } - - coredump->reset_vram_lost = vram_lost; - - if (reset_context->job && reset_context->job->vm) - coredump->reset_task_info = reset_context->job->vm->task_info; - - coredump->adev = adev; - - ktime_get_ts64(>reset_time); - - dev_coredumpm(dev->dev, THIS_MODULE, coredump, 0, GFP_NOWAIT, - amdgpu_devcoredump_read, amdgpu_devcoredump_free); -} -#endif - int amdgpu_do_asic_reset(struct list_head *device_list_handle, struct amdgpu_reset_context *reset_context) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c index 5fed06ffcc6b..579b70a3cdab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c @@ -21,6 +21,9 @@ * */ +#include +#include + #include "amdgpu_reset.h" #include "aldebaran.h" #include "sienna_cichlid.h" @@ -167,5 +170,78 @@ void amdgpu_device_unlock_reset_domain(struct amdgpu_reset_domain *reset_domain) up_write(_domain->sem); } +#ifndef CONFIG_DEV_COREDUMP +void amdgpu_coredump(struct amdgpu_device *adev, bool
[PATCH v5 3/5] drm/amdgpu: Encapsulate all device reset info
To better organize struct amdgpu_device, keep all reset information related fields together in a separated struct. Signed-off-by: André Almeida --- v5: new patch, as requested by Shashank Sharma --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 34 + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 10 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 16 +- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 0d560b713948..56d78ca6e917 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -781,6 +781,26 @@ struct amdgpu_mqd { #define AMDGPU_PRODUCT_NAME_LEN 64 struct amdgpu_reset_domain; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device*adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + boolreset_vram_lost; +}; +#endif + +struct amdgpu_reset_info { + /* reset dump register */ + u32 *reset_dump_reg_list; + u32 *reset_dump_reg_value; + int num_regs; + +#ifdef CONFIG_DEV_COREDUMP + struct amdgpu_coredump_info *coredump_info; +#endif +}; + /* * Non-zero (true) if the GPU has VRAM. Zero (false) otherwise. */ @@ -1084,10 +1104,7 @@ struct amdgpu_device { struct mutexbenchmark_mutex; - /* reset dump register */ - uint32_t*reset_dump_reg_list; - uint32_t*reset_dump_reg_value; - int num_regs; + struct amdgpu_reset_inforeset_info; boolscpm_enabled; uint32_tscpm_status; @@ -1100,15 +1117,6 @@ struct amdgpu_device { uint32_taid_mask; }; -#ifdef CONFIG_DEV_COREDUMP -struct amdgpu_coredump_info { - struct amdgpu_device*adev; - struct amdgpu_task_info reset_task_info; - struct timespec64 reset_time; - boolreset_vram_lost; -}; -#endif - static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) { return container_of(ddev, struct amdgpu_device, ddev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index a4faea4fa0b5..3136a0774dd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -2016,8 +2016,8 @@ static ssize_t amdgpu_reset_dump_register_list_read(struct file *f, if (ret) return ret; - for (i = 0; i < adev->num_regs; i++) { - sprintf(reg_offset, "0x%x\n", adev->reset_dump_reg_list[i]); + for (i = 0; i < adev->reset_info.num_regs; i++) { + sprintf(reg_offset, "0x%x\n", adev->reset_info.reset_dump_reg_list[i]); up_read(>reset_domain->sem); if (copy_to_user(buf + len, reg_offset, strlen(reg_offset))) return -EFAULT; @@ -2074,9 +2074,9 @@ static ssize_t amdgpu_reset_dump_register_list_write(struct file *f, if (ret) goto error_free; - swap(adev->reset_dump_reg_list, tmp); - swap(adev->reset_dump_reg_value, new); - adev->num_regs = i; + swap(adev->reset_info.reset_dump_reg_list, tmp); + swap(adev->reset_info.reset_dump_reg_value, new); + adev->reset_info.num_regs = i; up_write(>reset_domain->sem); ret = size; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b5b879bcc5c9..96975591841d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4790,10 +4790,10 @@ static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev) lockdep_assert_held(>reset_domain->sem); - for (i = 0; i < adev->num_regs; i++) { - adev->reset_dump_reg_value[i] = RREG32(adev->reset_dump_reg_list[i]); - trace_amdgpu_reset_reg_dumps(adev->reset_dump_reg_list[i], -adev->reset_dump_reg_value[i]); + for (i = 0; i < adev->reset_info.num_regs; i++) { + adev->reset_info.reset_dump_reg_value[i] = RREG32(adev->reset_info.reset_dump_reg_list[i]); + trace_amdgpu_reset_reg_dumps(adev->reset_info.reset_dump_reg_list[i], + adev->reset_info.reset_dump_reg_value[i]); } return 0; @@ -4831,13 +4831,13 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, if (coredump->reset_vram_lost) drm_printf(, "VRAM is lost due to GPU reset!\n"); - if (coredump->adev->num_regs) { + if (coredump->adev->reset_info.num_regs) { drm_printf(,
[PATCH v5 2/5] drm/amdgpu: Rework coredump to use memory dynamically
Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- v5: no change v4: change kmalloc to kzalloc --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 63 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9c6a332261ab..0d560b713948 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1088,11 +1088,6 @@ struct amdgpu_device { uint32_t*reset_dump_reg_list; uint32_t*reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - boolreset_vram_lost; - struct timespec64 reset_time; -#endif boolscpm_enabled; uint32_tscpm_status; @@ -1105,6 +1100,15 @@ struct amdgpu_device { uint32_taid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device*adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + boolreset_vram_lost; +}; +#endif + static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) { return container_of(ddev, struct amdgpu_device, ddev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bf4781551f88..b5b879bcc5c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4799,12 +4799,17 @@ static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev) return 0; } -#ifdef CONFIG_DEV_COREDUMP +#ifndef CONFIG_DEV_COREDUMP +static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, + struct amdgpu_reset_context *reset_context) +{ +} +#else static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count, void *data, size_t datalen) { struct drm_printer p; - struct amdgpu_device *adev = data; + struct amdgpu_coredump_info *coredump = data; struct drm_print_iterator iter; int i; @@ -4818,21 +4823,21 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, drm_printf(, " AMDGPU Device Coredump \n"); drm_printf(, "kernel: " UTS_RELEASE "\n"); drm_printf(, "module: " KBUILD_MODNAME "\n"); - drm_printf(, "time: %lld.%09ld\n", adev->reset_time.tv_sec, adev->reset_time.tv_nsec); - if (adev->reset_task_info.pid) + drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); + if (coredump->reset_task_info.pid) drm_printf(, "process_name: %s PID: %d\n", - adev->reset_task_info.process_name, - adev->reset_task_info.pid); + coredump->reset_task_info.process_name, + coredump->reset_task_info.pid); - if (adev->reset_vram_lost) + if (coredump->reset_vram_lost) drm_printf(, "VRAM is lost due to GPU reset!\n"); - if (adev->num_regs) { + if (coredump->adev->num_regs) { drm_printf(, "AMDGPU register dumps:\nOffset: Value:\n"); - for (i = 0; i < adev->num_regs; i++) + for (i = 0; i < coredump->adev->num_regs; i++) drm_printf(, "0x%08x: 0x%08x\n", - adev->reset_dump_reg_list[i], - adev->reset_dump_reg_value[i]); + coredump->adev->reset_dump_reg_list[i], + coredump->adev->reset_dump_reg_value[i]); } return count - iter.remain; @@ -4840,14 +4845,32 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, static void amdgpu_devcoredump_free(void *data) { + kfree(data); } -static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev) +static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, + struct amdgpu_reset_context *reset_context) { + struct amdgpu_coredump_info *coredump; struct drm_device *dev = adev_to_drm(adev); - ktime_get_ts64(>reset_time); - dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_NOWAIT, + coredump = kzalloc(sizeof(*coredump), GFP_NOWAIT); + + if (!coredump) { + DRM_ERROR("%s: failed to allocate memory
[PATCH v5 0/5] drm/amdgpu: Rework coredump memory allocation
Hi, The patches of this set are a rework to alloc devcoredump dynamically and to move it to a better source file. Thanks, André Changelog: v4: https://lore.kernel.org/dri-devel/20230815195100.294458-1-andrealm...@igalia.com/ - New patch to encapsulate all reset info in a struct v3: https://lore.kernel.org/dri-devel/20230810192330.198326-1-andrealm...@igalia.com/ - Changed from kmalloc to kzalloc - Dropped "Create a module param to disable soft recovery" for now v2: https://lore.kernel.org/dri-devel/20230713213242.680944-1-andrealm...@igalia.com/ - Drop the IB and ring patch - Drop patch that limited information from kernel threads - Add patch to move coredump to amdgpu_reset v1: https://lore.kernel.org/dri-devel/20230711213501.526237-1-andrealm...@igalia.com/ - Drop "Mark contexts guilty for causing soft recoveries" patch - Use GFP_NOWAIT for devcoredump allocatio André Almeida (5): drm/amdgpu: Allocate coredump memory in a nonblocking way drm/amdgpu: Rework coredump to use memory dynamically drm/amdgpu: Encapsulate all device reset info drm/amdgpu: Move coredump code to amdgpu_reset file drm/amdgpu: Create version number for coredumps drivers/gpu/drm/amd/amdgpu/amdgpu.h | 21 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 10 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 75 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 77 + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 13 5 files changed, 114 insertions(+), 82 deletions(-) -- 2.41.0
[PATCH v5 1/5] drm/amdgpu: Allocate coredump memory in a nonblocking way
During a GPU reset, a normal memory reclaim could block to reclaim memory. Giving that coredump is a best effort mechanism, it shouldn't disturb the reset path. Change its memory allocation flag to a nonblocking one. Signed-off-by: André Almeida Reviewed-by: Christian König --- v5: no change --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index aa171db68639..bf4781551f88 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4847,7 +4847,7 @@ static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev) struct drm_device *dev = adev_to_drm(adev); ktime_get_ts64(>reset_time); - dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_KERNEL, + dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_NOWAIT, amdgpu_devcoredump_read, amdgpu_devcoredump_free); } #endif -- 2.41.0
Re: [PATCH v2 4/9] drm/sched: Split free_job into own work item
On Thu, Aug 17, 2023 at 03:39:40PM +0200, Christian König wrote: > Am 11.08.23 um 04:31 schrieb Matthew Brost: > > Rather than call free_job and run_job in same work item have a dedicated > > work item for each. This aligns with the design and intended use of work > > queues. > > I would rather say we should get completely rid of the free_job callback. > Would we still have work item? e.g. Would we still want to call drm_sched_get_cleanup_job which removes the job from the pending list and adjusts the TDR? Trying to figure out out what this looks like. We probably can't do all of this from an IRQ context. > Essentially the job is just the container which carries the information > which are necessary before you push it to the hw. The real representation of > the submission is actually the scheduler fence. > Most of the free_jobs call plus drm_sched_job_cleanup + a put on job. In Xe this cannot be called from an IRQ context either. I'm just confused what exactly you are suggesting here. Matt > All the lifetime issues we had came from ignoring this fact and I think we > should push for fixing this design up again. > > Regards, > Christian. > > > > > Signed-off-by: Matthew Brost > > --- > > drivers/gpu/drm/scheduler/sched_main.c | 137 ++--- > > include/drm/gpu_scheduler.h| 8 +- > > 2 files changed, 106 insertions(+), 39 deletions(-) > > > > diff --git a/drivers/gpu/drm/scheduler/sched_main.c > > b/drivers/gpu/drm/scheduler/sched_main.c > > index cede47afc800..b67469eac179 100644 > > --- a/drivers/gpu/drm/scheduler/sched_main.c > > +++ b/drivers/gpu/drm/scheduler/sched_main.c > > @@ -213,11 +213,12 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq > > *rq, > >* drm_sched_rq_select_entity_rr - Select an entity which could provide a > > job to run > >* > >* @rq: scheduler run queue to check. > > + * @dequeue: dequeue selected entity > >* > >* Try to find a ready entity, returns NULL if none found. > >*/ > > static struct drm_sched_entity * > > -drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq) > > +drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq, bool dequeue) > > { > > struct drm_sched_entity *entity; > > @@ -227,8 +228,10 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq) > > if (entity) { > > list_for_each_entry_continue(entity, >entities, list) { > > if (drm_sched_entity_is_ready(entity)) { > > - rq->current_entity = entity; > > - reinit_completion(>entity_idle); > > + if (dequeue) { > > + rq->current_entity = entity; > > + reinit_completion(>entity_idle); > > + } > > spin_unlock(>lock); > > return entity; > > } > > @@ -238,8 +241,10 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq) > > list_for_each_entry(entity, >entities, list) { > > if (drm_sched_entity_is_ready(entity)) { > > - rq->current_entity = entity; > > - reinit_completion(>entity_idle); > > + if (dequeue) { > > + rq->current_entity = entity; > > + reinit_completion(>entity_idle); > > + } > > spin_unlock(>lock); > > return entity; > > } > > @@ -257,11 +262,12 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq) > >* drm_sched_rq_select_entity_fifo - Select an entity which provides a > > job to run > >* > >* @rq: scheduler run queue to check. > > + * @dequeue: dequeue selected entity > >* > >* Find oldest waiting ready entity, returns NULL if none found. > >*/ > > static struct drm_sched_entity * > > -drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq) > > +drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq, bool dequeue) > > { > > struct rb_node *rb; > > @@ -271,8 +277,10 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq > > *rq) > > entity = rb_entry(rb, struct drm_sched_entity, rb_tree_node); > > if (drm_sched_entity_is_ready(entity)) { > > - rq->current_entity = entity; > > - reinit_completion(>entity_idle); > > + if (dequeue) { > > + rq->current_entity = entity; > > + reinit_completion(>entity_idle); > > + } > > break; > > } > > } > > @@ -282,13 +290,54 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq > > *rq) > > } > > /** > > - * drm_sched_submit_queue - scheduler queue submission > > + * drm_sched_run_job_queue - queue job submission > >* @sched: scheduler instance > >*/ > > -static void
[linux-next:master] BUILD REGRESSION 47762f08697484cf0c2f2904b8c52375ed26c8cb
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master branch HEAD: 47762f08697484cf0c2f2904b8c52375ed26c8cb Add linux-next specific files for 20230817 Error/Warning reports: https://lore.kernel.org/oe-kbuild-all/202307281049.40t8s0uv-...@intel.com https://lore.kernel.org/oe-kbuild-all/202307301850.i9xfnwt6-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308111853.isf5a6vc-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308112307.tpmybd3l-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308112326.ajavwcoc-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308162234.y7j8jeif-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308170007.ozhdwitj-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308170206.fzg3v1gy-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308170227.ymiflmbt-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308170544.f6zj62al-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308171406.uwe0yyv9-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308171521.dfezznue-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308171555.5msxbst8-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308171620.m4mnacwz-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308171742.ancabig1-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308171801.p2rd8yel-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308172148.ppkmoai8-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308172348.1bthullk-...@intel.com https://lore.kernel.org/oe-kbuild-all/202308180127.vd7yrpga-...@intel.com Error/Warning: (recently discovered and may have been fixed) ../lib/gcc/loongarch64-linux/12.3.0/plugin/include/config/loongarch/loongarch-opts.h:31:10: fatal error: loongarch-def.h: No such file or directory ./drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1: warning: 'product_name' not found ./drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1: warning: 'serial_number' not found Documentation/gpu/rfc/i915_scheduler.rst:138: WARNING: Unknown directive type "c:namespace-push". Documentation/gpu/rfc/i915_scheduler.rst:143: WARNING: Unknown directive type "c:namespace-pop". ERROR: modpost: "bdev_mark_dead" [drivers/s390/block/dasd_mod.ko] undefined! Warning: kernel/Kconfig.kexec references a file that doesn't exist: file:Documentation/s390/zfcpdump.rst arch/csky/include/asm/ptrace.h:100:11: error: expected ';' before 'void' arch/csky/include/asm/ptrace.h:99:11: error: expected ';' before 'int' arch/csky/include/asm/traps.h:43:11: error: expected ';' before 'void' arch/loongarch/kernel/asm-offsets.c:172:6: warning: no previous prototype for 'output_thread_lbt_defines' [-Wmissing-prototypes] drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:516: warning: Function parameter or member 'xcc_id' not described in 'amdgpu_mm_wreg_mmio_rlc' drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:576: warning: Function parameter or member 'xcc_id' not described in 'amdgpu_mm_wreg_mmio_rlc' drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c:123: warning: Excess function parameter 'db_index' description in 'amdgpu_doorbell_index_on_bar' drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c:123: warning: Function parameter or member 'doorbell_index' not described in 'amdgpu_doorbell_index_on_bar' drivers/gpu/drm/drm_gpuva_mgr.c:1079:32: warning: variable 'prev' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/drm_gpuva_mgr.c:1079:39: warning: variable 'prev' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/tests/drm_kunit_helpers.c:172: warning: expecting prototype for drm_kunit_helper_context_alloc(). Prototype was for drm_kunit_helper_acquire_ctx_alloc() instead drivers/infiniband/hw/irdma/verbs.c:584: warning: Function parameter or member 'udata' not described in 'irdma_setup_umode_qp' drivers/infiniband/hw/irdma/verbs.c:586: warning: Function parameter or member 'udata' not described in 'irdma_setup_umode_qp' drivers/media/pci/intel/ivsc/mei_csi.c:342:10: error: call to undeclared function 'v4l2_subdev_get_try_format'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] drivers/media/pci/intel/ivsc/mei_csi.c:342:10: error: incompatible integer to pointer conversion returning 'int' from a function with result type 'struct v4l2_mbus_framefmt *' [-Wint-conversion] drivers/media/pci/intel/ivsc/mei_csi.c:360:14: error: incompatible integer to pointer conversion assigning to 'struct v4l2_mbus_framefmt *' from 'int' [-Wint-conversion] drivers/pinctrl/pinctrl-cy8c95x0.c:168: warning: Function parameter or member 'gpio_reset' not described in 'cy8c95x0_pinctrl' drivers/rpmsg/rpmsg_char.c:75: warning: Function parameter or member 'remote_flow_restricted' not described in 'rpmsg_eptdev' drivers/rpmsg/rpmsg_char.c:75: warning: Function parameter or member 'remote_flow_updated' not described in 'rpmsg_eptdev' drivers/video/backlight/lp855x_bl.c:
Re: [PATCH v2 2/2] drm/edid: Fix "Analog composite sync!" for current eDP display panels
Hey Jani, On 8/17/23 15:05, Jani Nikula wrote: On Thu, 17 Aug 2023, Dirk Lehmann wrote: VESA Enhanced EDID Standard does not clearly describe how display panel vendors should setup the Sync Signal Defintions (bit 4 & 3) in the Detailed Timing Definition (relative offset 17, absolute offset 47h[+18]) for Digital Video Signal Interfaces (bit 7 at offset 14h). In practice many eDP panels which using a Digital Video Signal Interfaces (bit 7 at offset 14h == 1) are leaving the Sync Signal Defintions at offset 47h[+18] blank 0x00, which would mean concerned with the VESA Standard [1] that they are using "Analog Composite Sync". Fix: Just detect Analog Sync Signal if an Analog Video Signal Interface (bit 7 at offset 14h == 0) is in use. Just detect Digital Sync Signal if an Digital Video Signal Interface is in use. Reference: [1] VESA Enhanced EDID Standard, Release A, Rev.2, Page 35 Please don't reply with patches in-reply-to other people's patches. Sorry, I am new with such patch lists :/ ... Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8789 This is now fixed by the revert that I just pushed. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8146 I don't think this patch fixes that one; see below. Signed-off-by: Dirk Lehmann --- drivers/gpu/drm/drm_edid.c | 74 -- include/drm/drm_edid.h | 12 +-- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 1f470968ed14..6afdc34e55ce 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3437,6 +3437,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto const struct drm_display_info *info = >display_info; struct drm_device *dev = connector->dev; struct drm_display_mode *mode; + const struct edid *edid = drm_edid->edid; const struct detailed_pixel_timing *pt = >data.pixel_data; unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; @@ -3456,10 +3457,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto connector->base.id, connector->name); return NULL; } - if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { - drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Composite sync not supported\n", - connector->base.id, connector->name); - } /* it is incorrect if hsync/vsync width is zero */ if (!hsync_pulse_width || !vsync_pulse_width) { @@ -3505,11 +3502,68 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto if (info->quirks & EDID_QUIRK_DETAILED_SYNC_PP) { mode->flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC; + } else if (edid->input & DRM_EDID_INPUT_DIGITAL) { + /* !info->quirks && edid->input == DIGITAL */ + switch (pt->misc & DRM_EDID_PT_SYNC_MASK) { + /* VESA Enhanced EDID Standard, Release A, Rev.2, Page 35 +* +* CASE DRM_EDID_PT_ANALOG_CSYNC: +* +* (pt->misc & DRM_EDID_PT_SYNC_MASK == 0x00) means +* "Analog Composite Sync" as described in VESA +* Standard. But many digital display panels without +* composite sync are also using 0x00 here. +* +* Therefore use DEFAULT: as we are currently on an +* digital video signal interface. +*/ + case DRM_EDID_PT_DIGITAL_CSYNC: + drm_dbg_kms(dev, + "[CONNECTOR:%d:%s] Digital composite sync!\n", + connector->base.id, connector->name); + mode->flags |= DRM_MODE_FLAG_CSYNC; + mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? + DRM_MODE_FLAG_PCSYNC : DRM_MODE_FLAG_NCSYNC; + break; + case DRM_EDID_PT_DIGITAL_SEPARATE_SYNC: + drm_dbg_kms(dev, + "[CONNECTOR:%d:%s] Digital seperate sync!\n", + connector->base.id, connector->name); + goto digital_default; + break; /* Missing BREAK throws a compiler warning */ fallthrough; will do the trick. Cool, that's new for me. FALLTHROUGH really works, great :) + default: +digital_default: + mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? + DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; + mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? +
[Bug 217664] Laptop doesnt wake up from suspend mode.
https://bugzilla.kernel.org/show_bug.cgi?id=217664 --- Comment #17 from Alex Deucher (alexdeuc...@gmail.com) --- *blacklisted -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[Bug 217664] Laptop doesnt wake up from suspend mode.
https://bugzilla.kernel.org/show_bug.cgi?id=217664 --- Comment #16 from Alex Deucher (alexdeuc...@gmail.com) --- Does suspend work with gpu drivers backlisted? -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH v3 2/4] drm/msm/dpu: Enable widebus for DSI INTF
On 08/08/2023 00:40, Jessica Zhang wrote: On 8/2/2023 11:20 AM, Dmitry Baryshkov wrote: On Wed, 2 Aug 2023 at 21:09, Jessica Zhang wrote: diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index df88358e7037..dace6168be2d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, phys_enc->hw_pp->idx); - if (intf_cfg.dsc != 0) + if (intf_cfg.dsc != 0) { cmd_mode_cfg.data_compress = true; + cmd_mode_cfg.wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + } This embeds the knowledge that a wide bus can only be enabled when DSC is in use. Please move the wide_bus_en assignment out of conditional code. Wide bus for DSI will only be enabled if DSC is enabled, so this is technically not wrong, as DP will use the video mode path. if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, _mode_cfg); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 8ec6505d9e78..dc6f3febb574 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -521,6 +521,9 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx, This function is only enabled for DPU >= 7.0, while IIRC wide bus can be enabled even for some of the earlier chipsets. The command mode path is only called for DSI, which only supports wide bus for DPU 7.0+. After second consideration, let's ignore this part, as wide bus will only be enabled for DSI / CMD after 7.0. If we ever have SoC that has CMD + wide_bus earlier than 5.0, we can reconsider this code pice. Can you please add a comment that the register itself is present earlier (5.0), but it doesn't have to be programmed since the flags will not be set anyway. if (cmd_mode_cfg->data_compress) intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; + if (cmd_mode_cfg->wide_bus_en) + intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN; + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); } -- With best wishes Dmitry
[PATCH] drm/bridge: Fix kernel-doc typo in desc of output_bus_cfg in drm_bridge_state
There's an obvious copy-paste error in the description of output_bus_cfg. Fix it. Fixes: f32df58acc68 ("drm/bridge: Add the necessary bits to support bus format negotiation") Signed-off-by: Douglas Anderson --- include/drm/drm_atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 9a022caacf93..cf8e1220a4ac 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1126,7 +1126,7 @@ struct drm_bridge_state { struct drm_bus_cfg input_bus_cfg; /** -* @output_bus_cfg: input bus configuration +* @output_bus_cfg: output bus configuration */ struct drm_bus_cfg output_bus_cfg; }; -- 2.41.0.694.ge786442a9b-goog
[Bug 217664] Laptop doesnt wake up from suspend mode.
https://bugzilla.kernel.org/show_bug.cgi?id=217664 --- Comment #15 from popus_czy_to_ty (pentelja...@o2.pl) --- https://www.youtube.com/watch?v=8ttEvWNcMXM -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread
Am 17.08.23 um 14:48 schrieb Danilo Krummrich: On 8/17/23 15:35, Christian König wrote: Am 17.08.23 um 13:13 schrieb Danilo Krummrich: On 8/17/23 07:33, Christian König wrote: [SNIP] My proposal would be to just keep the hw_submission_limit (maybe rename it to submission_unit_limit) and add a submission_units field to struct drm_sched_job. By default a jobs submission_units field would be 0 and the scheduler would behave the exact same way as it does now. Accordingly, jobs with submission_units > 1 would contribute more than one unit to the submission_unit_limit. What do you think about that? I think you are approaching this from the completely wrong side. First of all, thanks for keeping up the discussion - I appreciate it. Some more comments / questions below. See the UAPI needs to be stable, so you need a maximum job size otherwise it can happen that a combination of large and small submissions work while a different combination doesn't. How is this related to the uAPI being stable? What do you mean by 'stable' in this context? Stable is in you don't get indifferent behavior, not stable is in the sense of backward compatibility. Sorry for the confusing wording :) The Nouveau uAPI allows userspace to pass EXEC jobs by supplying the ring ID (channel), in-/out-syncs and a certain amount of indirect push buffers. The amount of IBs per job is limited by the amount of IBs fitting into the ring. Just to be clear, when I say 'job size' I mean the amount of IBs per job. Well that more or less sounds identical to all other hardware I know of, e.g. AMD, Intel and the different ARM chips seem to all work like this. But on those drivers the job size limit is not the ring size, but rather a fixed value (at least as far as I know). Maybe I should also mention that the rings we are talking about are software rings managed by a firmware scheduler. We can have an arbitrary amount of software rings and even multiple ones per FD. Given a constant ring size I really don't see why I should limit the maximum amount of IBs userspace can push per job just to end up with a hw_submission_limit > 1. For example, let's just assume the ring can take 128 IBs, why would I limit userspace to submit just e.g. 16 IBs at a time, such that the hw_submission_limit becomes 8? Well the question is what happens when you have two submissions back to back which use more than halve of the ring buffer? I only see two possible outcomes: 1. You return -EBUSY (or similar) error code indicating the the hw can't receive more commands. 2. Wait on previously pushed commands to be executed. (3. Your driver crash because you accidentally overwrite stuff in the ring buffer which is still executed. I just assume that's prevented). Resolution #1 with -EBUSY is actually something the UAPI should not do, because your UAPI then depends on the specific timing of submissions which is a really bad idea. Resolution #2 is usually bad because it forces the hw to run dry between submission and so degrade performance. What is the advantage of doing that, rather than letting userspace submit *up to* 128 IBs per job and just letting the scheduler push IBs to the ring as long as there's actually space left on the ring? Predictable behavior I think. Basically you want organize things so that the hw is at least kept busy all the time without depending on actual timing. So what you usually do, and this is driver independent because simply a requirement of the UAPI, is that you say here that's my maximum job size as well as the number of submission which should be pushed to the hw at the same time. And then get the resulting ring size by the product of the two. Given the above, how is that a requirement of the uAPI? The requirement of the UAPI is actually pretty simple: You should get consistent results, independent of the timing (at least as long as you don't do stuff in parallel). Otherwise you can run into issues when on a certain configuration stuff suddenly runs faster or slower than expected. In other words you should not depend on that stuff finishes in a certain amount of time. That the ring in this use case can't be fully utilized is not a draw back, this is completely intentional design which should apply to all drivers independent of the vendor. Why wouldn't we want to fully utilize the ring size? As far as I know everybody restricts the submission size to something fixed which is at least smaller than halve the ring size to avoid the problems mentioned above. Regards, Christian. - Danilo Besides all that, you said that filling up the ring just enough to not let the HW run dry rather than filling it up entirely is desirable. Why do you think so? I tend to think that in most cases it shouldn't make difference. That results in better scheduling behavior. It's mostly beneficial if you don't have a hw scheduler, but as far as I can see
[PATCH 11/17] drm/dp_mst: Add helper to determine if an MST port is downstream of another port
Add drm_dp_mst_port_downstream_of_parent() required by the i915 driver in a follow-up patch to resolve a BW overallocation of MST streams going through a given MST port. Cc: Lyude Paul Cc: dri-devel@lists.freedesktop.org Signed-off-by: Imre Deak --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 52 +++ include/drm/display/drm_dp_mst_helper.h | 3 ++ 2 files changed, 55 insertions(+) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index e26f1b7f5a701..ced9ae36a9177 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -5105,6 +5105,58 @@ static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port, return false; } +static bool +drm_dp_mst_port_downstream_of_parent_locked(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port, + struct drm_dp_mst_port *parent) +{ + if (!mgr->mst_primary) + return false; + + port = drm_dp_mst_topology_get_port_validated_locked(mgr->mst_primary, +port); + if (!port) + return false; + + if (!parent) + return true; + + parent = drm_dp_mst_topology_get_port_validated_locked(mgr->mst_primary, + parent); + if (!parent) + return false; + + if (!parent->mstb) + return false; + + return drm_dp_mst_port_downstream_of_branch(port, parent->mstb); +} + +/** + * drm_dp_mst_port_downstream_of_parent - check if a port is downstream of a parent port + * @mgr: MST topology manager + * @port: the port being looked up + * @parent: the parent port + * + * The function returns %true if @port is downstream of @parent. If @parent is + * %NULL - denoting the root port - the function returns %true if @port is in + * @mgr's topology. + */ +bool +drm_dp_mst_port_downstream_of_parent(struct drm_dp_mst_topology_mgr *mgr, +struct drm_dp_mst_port *port, +struct drm_dp_mst_port *parent) +{ + bool ret; + + mutex_lock(>lock); + ret = drm_dp_mst_port_downstream_of_parent_locked(mgr, port, parent); + mutex_unlock(>lock); + + return ret; +} +EXPORT_SYMBOL(drm_dp_mst_port_downstream_of_parent); + static int drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, struct drm_dp_mst_topology_state *state); diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 0953b7b16a51b..097c4204ffae4 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -879,6 +879,9 @@ drm_atomic_get_new_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_atomic_payload * drm_atomic_get_mst_payload_state(struct drm_dp_mst_topology_state *state, struct drm_dp_mst_port *port); +bool drm_dp_mst_port_downstream_of_parent(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port, + struct drm_dp_mst_port *parent); int __must_check drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, -- 2.37.2
[PATCH 13/17] drm/dp_mst: Swap the order of checking root vs. non-root port BW limitations
drm_dp_mst_atomic_check_mgr() should check for BW limitation starting from sink ports continuing towards the root port, so that drivers can use the @failing_port returned to resolve a BW overallocation in an ideal way. For instance from streams A,B,C in a topology A,B going through @failing_port and C not going through it, a BW overallocation of A,B due to a limit of the port must be resolved first before considering the limits of other ports closer to the root port. This way can avoid reducing the BW of stream C unnecessarily due to a BW limit closer to the root port. Based on the above swap the order of the BW check for the root port and the check for all the ports downstream of it (the latter going through the topology already in the sink->root port direction). Cc: Lyude Paul Cc: dri-devel@lists.freedesktop.org Signed-off-by: Imre Deak --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index a32da72bb05c5..12a13885145d3 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -5449,9 +5449,13 @@ EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc); * %-ENOSPC, if the new state is invalid, because of BW limitation * @failing_port is set to: * - The non-root port where a BW limit check failed + * with all the ports downstream of @failing_port passing + * the BW limit check. * The returned port pointer is valid until at least * one payload downstream of it exists. * - %NULL if the BW limit check failed at the root port + * with all the ports downstream of the root port passing + * the BW limit check. * %-EINVAL, if the new state is invalid, because the root port has too many * payloads. */ @@ -5467,17 +5471,16 @@ int drm_dp_mst_atomic_check_mgr(struct drm_atomic_state *state, if (!mgr->mst_state) return 0; - ret = drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state); - if (ret) - return ret; - mutex_lock(>lock); ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary, mst_state, failing_port); mutex_unlock(>lock); - return ret < 0 ? ret : 0; + if (ret < 0) + return ret; + + return drm_dp_mst_atomic_check_payload_alloc_limits(mgr, mst_state); } EXPORT_SYMBOL(drm_dp_mst_atomic_check_mgr); -- 2.37.2
[PATCH 12/17] drm/dp_mst: Factor out a helper to check the atomic state of a topology manager
Factor out a helper to check the atomic state for one MST topology manager, returning the MST port where the BW limit check has failed. This will be used in a follow-up patch by the i915 driver to improve the BW sharing between MST streams. Cc: Lyude Paul Cc: dri-devel@lists.freedesktop.org Signed-off-by: Imre Deak --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 94 +++ include/drm/display/drm_dp_mst_helper.h | 4 + 2 files changed, 79 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index ced9ae36a9177..a32da72bb05c5 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -5159,11 +5159,13 @@ EXPORT_SYMBOL(drm_dp_mst_port_downstream_of_parent); static int drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, - struct drm_dp_mst_topology_state *state); + struct drm_dp_mst_topology_state *state, + struct drm_dp_mst_port **failing_port); static int drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, - struct drm_dp_mst_topology_state *state) + struct drm_dp_mst_topology_state *state, + struct drm_dp_mst_port **failing_port) { struct drm_dp_mst_atomic_payload *payload; struct drm_dp_mst_port *port; @@ -5192,7 +5194,7 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, drm_dbg_atomic(mstb->mgr->dev, "[MSTB:%p] Checking bandwidth limits\n", mstb); list_for_each_entry(port, >ports, next) { - ret = drm_dp_mst_atomic_check_port_bw_limit(port, state); + ret = drm_dp_mst_atomic_check_port_bw_limit(port, state, failing_port); if (ret < 0) return ret; @@ -5204,7 +5206,8 @@ drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, static int drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, - struct drm_dp_mst_topology_state *state) + struct drm_dp_mst_topology_state *state, + struct drm_dp_mst_port **failing_port) { struct drm_dp_mst_atomic_payload *payload; int pbn_used = 0; @@ -5225,13 +5228,15 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, drm_dbg_atomic(port->mgr->dev, "[MSTB:%p] [MST PORT:%p] no BW available for the port\n", port->parent, port); + *failing_port = port; return -EINVAL; } pbn_used = payload->pbn; } else { pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb, -state); +state, +failing_port); if (pbn_used <= 0) return pbn_used; } @@ -5240,6 +5245,7 @@ drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, drm_dbg_atomic(port->mgr->dev, "[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n", port->parent, port, pbn_used, port->full_pbn); + *failing_port = port; return -ENOSPC; } @@ -5417,20 +5423,80 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_dp_mst_atomic_enable_dsc); +/** + * drm_dp_mst_atomic_check_mgr - Check the atomic state of an MST topology manager + * @state: The global atomic state + * @mgr: Manager to check + * @mst_state: The MST atomic state for @mgr + * @failing_port: Returns the port with a BW limitation + * + * Checks the given MST manager's topology state for an atomic update to ensure + * that it's valid. This includes checking whether there's enough bandwidth to + * support the new timeslot allocations in the atomic update. + * + * Any atomic drivers supporting DP MST must make sure to call this or + * the drm_dp_mst_atomic_check() function after checking the rest of their state + * in their _mode_config_funcs.atomic_check() callback. + * + * See also: + * drm_dp_mst_atomic_check() + * drm_dp_atomic_find_time_slots() + * drm_dp_atomic_release_time_slots() + * + * Returns: + * + * 0 if the new state is valid + * %-ENOSPC, if the new state is invalid, because of BW limitation + * @failing_port is set to: + * - The non-root port where a BW limit check failed + * The
[PATCH 10/17] drm/dp_mst: Add a way to calculate PBN values with FEC overhead
Add a way for drivers to calculate the MST PBN values with FEC overhead. This is required by 8b/10b links both for DSC and non-DSC (the latter needed if there are both DSC and non-DSC streams on the same MST link). Also add kunit test cases for PBN values calculated with FEC overhead. Cc: Lyude Paul Cc: Harry Wentland Cc: Wayne Lin Cc: Alex Deucher Cc: dri-devel@lists.freedesktop.org Signed-off-by: Imre Deak --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 18 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 ++-- drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- .../gpu/drm/tests/drm_dp_mst_helper_test.c| 23 ++- include/drm/display/drm_dp_mst_helper.h | 2 +- 7 files changed, 42 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4d3d6009838c7..c34ee22b2e7b2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6782,7 +6782,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder, max_bpc); bpp = convert_dc_color_depth_into_bpc(color_depth) * 3; clock = adjusted_mode->clock; - dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false); + dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false, false); } dm_new_connector_state->vcpi_slots = 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 57230661132bd..9acfdefc792d6 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 @@ -1636,7 +1636,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( } else { /* check if mode could be supported within full_pbn */ bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; - pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); + pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false, false); if (pbn > aconnector->mst_output_port->full_pbn) return DC_FAIL_BANDWIDTH_VALIDATE; diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index bd0f35a0ea5fb..e26f1b7f5a701 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4693,26 +4693,34 @@ EXPORT_SYMBOL(drm_dp_check_act_status); * @clock: dot clock for the mode * @bpp: bpp for the mode. * @dsc: DSC mode. If true, bpp has units of 1/16 of a bit per pixel + * @fec: FEC overhead. * * This uses the formula in the spec to calculate the PBN value for a mode. */ -int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc) +int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc, bool fec) { /* -* margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 +* Overheads: +* - SSC downspread and ref clock variation margin: +* 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 +* - FEC symbol insertions: +* 2.4% as per spec, factor is 1.024 +* * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on * common multiplier to render an integer PBN for all link rate/lane * counts combinations * calculate -* peak_kbps *= (1006/1000) +* peak_kbps *= (1006/1000) without FEC, or +* peak_kbps *= (1030/1000) with FEC * peak_kbps *= (64/54) -* peak_kbps *= 8convert to bytes +* peak_kbps /= 8convert to bytes * * If the bpp is in units of 1/16, further divide by 16. Put this * factor in the numerator rather than the denominator to avoid * integer overflow */ - u32 bpp_m = (dsc ? 64 / 16 : 64) * 1006 * bpp; + u32 overhead = fec ? 1030 : 1006; + u32 bpp_m = (dsc ? 64 / 16 : 64) * overhead * bpp; return DIV_ROUND_UP_ULL(mul_u32_u32(clock, bpp_m), 8 * 54 * 1000 * 1000); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 0dcb9a203dfe7..b22e0cbdb7d56 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -110,7 +110,8 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock,
[PATCH 09/17] drm/dp_mst: Fix fractional bpp scaling in drm_dp_calc_pbn_mode()
For fractional bpp values passed to the function in a .4 fixed point format, the fractional part is currently ignored due to scaling bpp too early. Fix this by scaling the overhead factor instead and to avoid an overflow multiplying bpp with the overhead factor instead of the clock rate. While at it simplify the formula, and pass the expected fixed point bpp values in the kunit tests. Cc: Lyude Paul Cc: dri-devel@lists.freedesktop.org Signed-off-by: Imre Deak --- drivers/gpu/drm/display/drm_dp_mst_topology.c | 7 ++- drivers/gpu/drm/tests/drm_dp_mst_helper_test.c | 8 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index ed96cfcfa3040..bd0f35a0ea5fb 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4712,12 +4712,9 @@ int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc) * factor in the numerator rather than the denominator to avoid * integer overflow */ + u32 bpp_m = (dsc ? 64 / 16 : 64) * 1006 * bpp; - if (dsc) - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006), - 8 * 54 * 1000 * 1000); - - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006), + return DIV_ROUND_UP_ULL(mul_u32_u32(clock, bpp_m), 8 * 54 * 1000 * 1000); } EXPORT_SYMBOL(drm_dp_calc_pbn_mode); diff --git a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c index 545beea33e8c7..ea2182815ebe8 100644 --- a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c @@ -40,15 +40,15 @@ static const struct drm_dp_mst_calc_pbn_mode_test drm_dp_mst_calc_pbn_mode_cases }, { .clock = 332880, - .bpp = 24, + .bpp = 24 << 4, .dsc = true, - .expected = 50 + .expected = 1191 }, { .clock = 324540, - .bpp = 24, + .bpp = 24 << 4, .dsc = true, - .expected = 49 + .expected = 1161 }, }; -- 2.37.2
Re: [PATCH v4 2/4] drm/amdgpu: Rework coredump to use memory dynamically
On 17/08/2023 17:38, André Almeida wrote: Em 17/08/2023 12:26, Shashank Sharma escreveu: On 17/08/2023 17:17, André Almeida wrote: Em 17/08/2023 12:04, Shashank Sharma escreveu: On 17/08/2023 15:45, André Almeida wrote: Hi Shashank, Em 17/08/2023 03:41, Shashank Sharma escreveu: Hello Andre, On 15/08/2023 21:50, André Almeida wrote: Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- v4: change kmalloc to kzalloc --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 63 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9c6a332261ab..0d560b713948 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1088,11 +1088,6 @@ struct amdgpu_device { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - bool reset_vram_lost; - struct timespec64 reset_time; -#endif bool scpm_enabled; uint32_t scpm_status; @@ -1105,6 +1100,15 @@ struct amdgpu_device { uint32_t aid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device *adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + bool reset_vram_lost; +}; The patch looks good to me in general, but I would recommend slightly different arrangement and segregation of GPU reset information. Please consider a higher level structure adev->gpu_reset_info, and move everything related to reset dump info into that, including this new coredump_info structure, something like this: struct amdgpu_reset_info { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; Right, I can encapsulate there reset_dump members, #ifdef CONFIG_DEV_COREDUMP struct amdgpu_coredump_info *coredump_info;/* keep this dynamic allocation */ but we don't need a pointer for amdgpu_coredump_info inside amdgpu_device or inside of amdgpu_device->gpu_reset_info, right? I think it would be better if we keep all of the GPU reset related data in the same structure, so adev->gpu_reset_info->coredump_info sounds about right to me. But after patch 2/4, we don't need to store a coredump_info pointer inside adev, this is what I meant. What would be the purpose of having this pointer? It's freed by amdgpu_devcoredump_free(), so we don't need to keep track of it. Well, actually we are pulling in some 0parallel efforts on enhancing the GPU reset information, and we were planning to use the coredump info for some additional things. So if I have the coredump_info available (like reset_task_info and vram_lost) across a few functions in the driver with adev, it would make my job easy there :). It seems dangerous to use an object with this limited lifetime to rely to read on. If you want to use it you will need to change amdgpu_devcoredump_free() to drop a reference or you will need to use it statically, which defeats the purpose of this patch. Anyway, I'll add it as you requested. I guess if the coredump_free function can make the adev->reset_info->coredump_info= NULL, after freeing it, that will actually help the case. While consuming it, I can simply check if (adev->reset_info->coredump_info) is available to be read. - Shashank - Shashank - Shashank #endif } This will make sure that all the relevant information is at the same place. - Shashank amdgpu_inc_vram_lost(tmp_adev);
Re: [PATCH v4 2/4] drm/amdgpu: Rework coredump to use memory dynamically
Em 17/08/2023 12:26, Shashank Sharma escreveu: On 17/08/2023 17:17, André Almeida wrote: Em 17/08/2023 12:04, Shashank Sharma escreveu: On 17/08/2023 15:45, André Almeida wrote: Hi Shashank, Em 17/08/2023 03:41, Shashank Sharma escreveu: Hello Andre, On 15/08/2023 21:50, André Almeida wrote: Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- v4: change kmalloc to kzalloc --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 63 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9c6a332261ab..0d560b713948 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1088,11 +1088,6 @@ struct amdgpu_device { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - bool reset_vram_lost; - struct timespec64 reset_time; -#endif bool scpm_enabled; uint32_t scpm_status; @@ -1105,6 +1100,15 @@ struct amdgpu_device { uint32_t aid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device *adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + bool reset_vram_lost; +}; The patch looks good to me in general, but I would recommend slightly different arrangement and segregation of GPU reset information. Please consider a higher level structure adev->gpu_reset_info, and move everything related to reset dump info into that, including this new coredump_info structure, something like this: struct amdgpu_reset_info { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; Right, I can encapsulate there reset_dump members, #ifdef CONFIG_DEV_COREDUMP struct amdgpu_coredump_info *coredump_info;/* keep this dynamic allocation */ but we don't need a pointer for amdgpu_coredump_info inside amdgpu_device or inside of amdgpu_device->gpu_reset_info, right? I think it would be better if we keep all of the GPU reset related data in the same structure, so adev->gpu_reset_info->coredump_info sounds about right to me. But after patch 2/4, we don't need to store a coredump_info pointer inside adev, this is what I meant. What would be the purpose of having this pointer? It's freed by amdgpu_devcoredump_free(), so we don't need to keep track of it. Well, actually we are pulling in some 0parallel efforts on enhancing the GPU reset information, and we were planning to use the coredump info for some additional things. So if I have the coredump_info available (like reset_task_info and vram_lost) across a few functions in the driver with adev, it would make my job easy there :). It seems dangerous to use an object with this limited lifetime to rely to read on. If you want to use it you will need to change amdgpu_devcoredump_free() to drop a reference or you will need to use it statically, which defeats the purpose of this patch. Anyway, I'll add it as you requested. - Shashank - Shashank #endif } This will make sure that all the relevant information is at the same place. - Shashank amdgpu_inc_vram_lost(tmp_adev);
Re: [PATCH v4 2/4] drm/amdgpu: Rework coredump to use memory dynamically
On 17/08/2023 17:17, André Almeida wrote: Em 17/08/2023 12:04, Shashank Sharma escreveu: On 17/08/2023 15:45, André Almeida wrote: Hi Shashank, Em 17/08/2023 03:41, Shashank Sharma escreveu: Hello Andre, On 15/08/2023 21:50, André Almeida wrote: Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- v4: change kmalloc to kzalloc --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 63 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9c6a332261ab..0d560b713948 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1088,11 +1088,6 @@ struct amdgpu_device { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - bool reset_vram_lost; - struct timespec64 reset_time; -#endif bool scpm_enabled; uint32_t scpm_status; @@ -1105,6 +1100,15 @@ struct amdgpu_device { uint32_t aid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device *adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + bool reset_vram_lost; +}; The patch looks good to me in general, but I would recommend slightly different arrangement and segregation of GPU reset information. Please consider a higher level structure adev->gpu_reset_info, and move everything related to reset dump info into that, including this new coredump_info structure, something like this: struct amdgpu_reset_info { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; Right, I can encapsulate there reset_dump members, #ifdef CONFIG_DEV_COREDUMP struct amdgpu_coredump_info *coredump_info;/* keep this dynamic allocation */ but we don't need a pointer for amdgpu_coredump_info inside amdgpu_device or inside of amdgpu_device->gpu_reset_info, right? I think it would be better if we keep all of the GPU reset related data in the same structure, so adev->gpu_reset_info->coredump_info sounds about right to me. But after patch 2/4, we don't need to store a coredump_info pointer inside adev, this is what I meant. What would be the purpose of having this pointer? It's freed by amdgpu_devcoredump_free(), so we don't need to keep track of it. Well, actually we are pulling in some 0parallel efforts on enhancing the GPU reset information, and we were planning to use the coredump info for some additional things. So if I have the coredump_info available (like reset_task_info and vram_lost) across a few functions in the driver with adev, it would make my job easy there :). - Shashank - Shashank #endif } This will make sure that all the relevant information is at the same place. - Shashank amdgpu_inc_vram_lost(tmp_adev);
Re: [PATCH] dt-bindings: mxsfb: Exclude i.MX8MQ from power-domains requirement
Hi, On Sun, Jul 30, 2023 at 09:41:20PM +0300, David Heidelberg wrote: > i.MX8MQ uses as secondary compatible fsl,imx6sx-lcdif, which triggers > requirement of power-domains, thou it's not required. > > Fixes: f62678a77d58 ("dt-bindings: mxsfb: Document i.MX8M/i.MX6SX/i.MX6SL > power-domains property") > > Signed-off-by: David Heidelberg > --- > .../devicetree/bindings/display/fsl,lcdif.yaml| 11 +-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml > b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml > index fc11ab5fc465..2d868276b0f9 100644 > --- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml > +++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml > @@ -129,8 +129,15 @@ allOf: >- fsl,imx8mp-lcdif >- fsl,imx93-lcdif > then: > - required: > -- power-domains > + if: > +properties: > + compatible: > +not: > + contains: > +const: fsl,imx8mq-lcdif > + then: > +required: > + - power-domains > > examples: >- | > -- > 2.40.1 > Thanks a lot to Marek and Liu for confirming! Acked-by: Guido Günther Cheers, -- Guido
Re: [PATCH v3 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver
Hi Manikandan, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on lee-mfd/for-mfd-next lee-leds/for-leds-next lee-mfd/for-mfd-fixes linus/master v6.5-rc6 next-20230817] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Manikandan-Muralidharan/mfd-atmel-hlcdc-Add-compatible-for-sam9x75-XLCD-controller/20230817-172003 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20230817091250.225512-6-manikandan.m%40microchip.com patch subject: [PATCH v3 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver config: arm-randconfig-r046-20230817 (https://download.01.org/0day-ci/archive/20230817/202308172303.aguihgky-...@intel.com/config) compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a) reproduce: (https://download.01.org/0day-ci/archive/20230817/202308172303.aguihgky-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202308172303.aguihgky-...@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c:1013:6: warning: no previous >> prototype for function 'hlcdc_irq_dbg' [-Wmissing-prototypes] 1013 | void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, | ^ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c:1013:1: note: declare 'static' if the function is not intended to be used outside of this translation unit 1013 | void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, | ^ | static >> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c:1029:6: warning: no previous >> prototype for function 'xlcdc_irq_dbg' [-Wmissing-prototypes] 1029 | void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, | ^ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c:1029:1: note: declare 'static' if the function is not intended to be used outside of this translation unit 1029 | void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, | ^ | static 2 warnings generated. vim +/hlcdc_irq_dbg +1013 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 1012 > 1013 void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, 1014 const struct atmel_hlcdc_layer_desc *desc) 1015 { 1016 u32 isr = atmel_hlcdc_layer_read_reg(>layer, ATMEL_HLCDC_LAYER_ISR); 1017 1018 /* 1019 * There's not much we can do in case of overrun except informing 1020 * the user. However, we are in interrupt context here, hence the 1021 * use of dev_dbg(). 1022 */ 1023 if (isr & 1024 (ATMEL_HLCDC_LAYER_OVR_IRQ(0) | ATMEL_HLCDC_LAYER_OVR_IRQ(1) | 1025 ATMEL_HLCDC_LAYER_OVR_IRQ(2))) 1026 pr_warn("%s: overrun on plane %s\n", __func__, desc->name); 1027 } 1028 > 1029 void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, 1030 const struct atmel_hlcdc_layer_desc *desc) 1031 { 1032 u32 isr = atmel_hlcdc_layer_read_reg(>layer, ATMEL_XLCDC_LAYER_ISR); 1033 1034 /* 1035 * There's not much we can do in case of overrun except informing 1036 * the user. However, we are in interrupt context here, hence the 1037 * use of dev_dbg(). 1038 */ 1039 if (isr & 1040 (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) | 1041 ATMEL_XLCDC_LAYER_OVR_IRQ(2))) 1042 pr_warn("%s: overrun on plane %s\n", __func__, desc->name); 1043 } 1044 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH] drm/nouveau/disp: fix use-after-free in error handling of nouveau_connector_create
On Thu, Aug 17, 2023 at 12:24:45PM +0200, Karol Herbst wrote: > simply throw a > > printk(KERN_WARNING "nvkm_uconn_uevent %u\n", outp->info.location); > > inside drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c:104 after that > mentioned comment. diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c index 46b057fe1412..661fd0cf3b3b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c @@ -101,6 +101,7 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_ if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO; if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) { /* TODO: support DP IRQ on ANX9805 and remove this hack. */ + printk(KERN_WARNING "nvkm_uconn_uevent %u\n", outp->info.location); if (!outp->info.location) return -EINVAL; } result: [ 10.566759] ACPI: bus type drm_connector registered [ 10.591171] Console: switching to colour dummy device 80x25 [ 10.598472] nouveau :03:00.0: vgaarb: deactivate vga console [ 10.607121] nouveau :03:00.0: NVIDIA GT218 (0a8c00b1) [ 10.728361] nouveau :03:00.0: bios: version 70.18.83.00.08 [ 10.742137] nouveau :03:00.0: fb: 512 MiB DDR3 [ 11.059848] nouveau :03:00.0: DRM: VRAM: 512 MiB [ 11.064911] nouveau :03:00.0: DRM: GART: 1048576 MiB [ 11.070302] nouveau :03:00.0: DRM: TMDS table version 2.0 [ 11.076126] nouveau :03:00.0: DRM: DCB version 4.0 [ 11.081335] nouveau :03:00.0: DRM: DCB outp 00: 02000360 [ 11.087865] nouveau :03:00.0: DRM: DCB outp 01: 02000362 00020010 [ 11.094395] nouveau :03:00.0: DRM: DCB outp 02: 028003a6 0f220010 [ 11.100912] nouveau :03:00.0: DRM: DCB outp 03: 01011380 [ 11.107422] nouveau :03:00.0: DRM: DCB outp 04: 08011382 00020010 [ 11.113940] nouveau :03:00.0: DRM: DCB outp 05: 088113c6 0f220010 [ 11.120457] nouveau :03:00.0: DRM: DCB conn 00: 00101064 [ 11.126182] nouveau :03:00.0: DRM: DCB conn 01: 00202165 [ 11.138865] nouveau :03:00.0: DRM: MM: using COPY for buffer copies [ 11.151291] nvkm_uconn_uevent 0 [ 11.154643] nvkm_uconn_uevent 0 [ 11.157975] nvkm_uconn_uevent 0 [ 11.161298] nvkm_uconn_uevent 0 [ 11.164616] nvkm_uconn_uevent 0 [ 11.167943] nvkm_uconn_uevent 0 [ 11.176010] [drm] Initialized nouveau 1.3.1 20120801 for :03:00.0 on minor 0 [ 11.184186] nouveau :03:00.0: [drm] Cannot find any crtc or sizes [ 11.260527] megasas: 07.725.01.00-rc1 [ 11.264555] st: Version 20160209, fixed bufsize 32768, s/g segs 256 -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
Re: [PATCH v4 2/4] drm/amdgpu: Rework coredump to use memory dynamically
Em 17/08/2023 12:04, Shashank Sharma escreveu: On 17/08/2023 15:45, André Almeida wrote: Hi Shashank, Em 17/08/2023 03:41, Shashank Sharma escreveu: Hello Andre, On 15/08/2023 21:50, André Almeida wrote: Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- v4: change kmalloc to kzalloc --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 63 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9c6a332261ab..0d560b713948 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1088,11 +1088,6 @@ struct amdgpu_device { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - bool reset_vram_lost; - struct timespec64 reset_time; -#endif bool scpm_enabled; uint32_t scpm_status; @@ -1105,6 +1100,15 @@ struct amdgpu_device { uint32_t aid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device *adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + bool reset_vram_lost; +}; The patch looks good to me in general, but I would recommend slightly different arrangement and segregation of GPU reset information. Please consider a higher level structure adev->gpu_reset_info, and move everything related to reset dump info into that, including this new coredump_info structure, something like this: struct amdgpu_reset_info { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; Right, I can encapsulate there reset_dump members, #ifdef CONFIG_DEV_COREDUMP struct amdgpu_coredump_info *coredump_info;/* keep this dynamic allocation */ but we don't need a pointer for amdgpu_coredump_info inside amdgpu_device or inside of amdgpu_device->gpu_reset_info, right? I think it would be better if we keep all of the GPU reset related data in the same structure, so adev->gpu_reset_info->coredump_info sounds about right to me. But after patch 2/4, we don't need to store a coredump_info pointer inside adev, this is what I meant. What would be the purpose of having this pointer? It's freed by amdgpu_devcoredump_free(), so we don't need to keep track of it. - Shashank #endif } This will make sure that all the relevant information is at the same place. - Shashank amdgpu_inc_vram_lost(tmp_adev);
Re: [PATCH v3 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver
Hi Manikandan, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on lee-mfd/for-mfd-next lee-leds/for-leds-next lee-mfd/for-mfd-fixes linus/master v6.5-rc6 next-20230817] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Manikandan-Muralidharan/mfd-atmel-hlcdc-Add-compatible-for-sam9x75-XLCD-controller/20230817-172003 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20230817091250.225512-6-manikandan.m%40microchip.com patch subject: [PATCH v3 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver config: arm-randconfig-r033-20230817 (https://download.01.org/0day-ci/archive/20230817/202308172209.dz2hgtva-...@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 12.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230817/202308172209.dz2hgtva-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202308172209.dz2hgtva-...@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c:1013:6: warning: no previous >> prototype for 'hlcdc_irq_dbg' [-Wmissing-prototypes] 1013 | void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, | ^ >> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c:1029:6: warning: no previous >> prototype for 'xlcdc_irq_dbg' [-Wmissing-prototypes] 1029 | void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, | ^ vim +/hlcdc_irq_dbg +1013 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 1012 > 1013 void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, 1014 const struct atmel_hlcdc_layer_desc *desc) 1015 { 1016 u32 isr = atmel_hlcdc_layer_read_reg(>layer, ATMEL_HLCDC_LAYER_ISR); 1017 1018 /* 1019 * There's not much we can do in case of overrun except informing 1020 * the user. However, we are in interrupt context here, hence the 1021 * use of dev_dbg(). 1022 */ 1023 if (isr & 1024 (ATMEL_HLCDC_LAYER_OVR_IRQ(0) | ATMEL_HLCDC_LAYER_OVR_IRQ(1) | 1025 ATMEL_HLCDC_LAYER_OVR_IRQ(2))) 1026 pr_warn("%s: overrun on plane %s\n", __func__, desc->name); 1027 } 1028 > 1029 void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, 1030 const struct atmel_hlcdc_layer_desc *desc) 1031 { 1032 u32 isr = atmel_hlcdc_layer_read_reg(>layer, ATMEL_XLCDC_LAYER_ISR); 1033 1034 /* 1035 * There's not much we can do in case of overrun except informing 1036 * the user. However, we are in interrupt context here, hence the 1037 * use of dev_dbg(). 1038 */ 1039 if (isr & 1040 (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) | 1041 ATMEL_XLCDC_LAYER_OVR_IRQ(2))) 1042 pr_warn("%s: overrun on plane %s\n", __func__, desc->name); 1043 } 1044 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
mt8183 (google/krane): Resolution over USB-C adapter limited to 1280x720
Dear Linux folks, Using the ten inch tablet Lenovo IdeaPad Duet Chromebook 2in1 with recent ChromeOS, connecting a Dell DA200 (strange display chip inside) or Dell DA300z the available resolutions are limited to 1280x720 and not the supported 1920x1080. The Dell monitor is connected over HDMI to the adapter. [0.00] Linux version 5.10.180-22631-gc8e37fc5f0ab (chrome-bot@chromeos-release-builder-us-central1-b-x32-66-okmh) (Chromium OS 17.0_pre496208_p20230501-r6 clang version 17.0.0 (/mnt/host/source/src/third_party/llvm-project 98f5a340975bc00197c57e39eb4ca26e2da0e8a2), LLD 17.0.0) #1 SMP PREEMPT Wed Jul 26 19:01:55 PDT 2023 […] [0.00] Machine model: MediaTek krane sku176 board Please find the full output from `dmesg` attached. At 144.607419 the Dell DA200 is connected. At 691.133117 the Dell DA300z. I also reported the issue to the Google bug tracker [1]. Kind regards, Paul [1]: https://issuetracker.google.com/issues/295666708crosh> dmesg [0.00] Booting Linux on physical CPU 0x00 [0x410fd034] [0.00] Linux version 5.10.180-22631-gc8e37fc5f0ab (chrome-bot@chromeos-release-builder-us-central1-b-x32-66-okmh) (Chromium OS 17.0_pre496208_p20230501-r6 clang version 17.0.0 (/mnt/host/source/src/third_party/llvm-project 98f5a340975bc00197c57e39eb4ca26e2da0e8a2), LLD 17.0.0) #1 SMP PREEMPT Wed Jul 26 19:01:55 PDT 2023 [0.00] random: crng init done [0.00] Machine model: MediaTek krane sku176 board [0.00] Malformed early option 'console' [0.00] Reserved memory: created DMA memory pool at 0x5000, size 41 MiB [0.00] OF: reserved mem: initialized node scp_mem_region, compatible id shared-dma-pool [0.00] Zone ranges: [0.00] DMA [mem 0x4000-0x] [0.00] DMA32empty [0.00] Normal [mem 0x0001-0x00013fff] [0.00] Movable zone start for each node [0.00] Early memory node ranges [0.00] node 0: [mem 0x4000-0x4fff] [0.00] node 0: [mem 0x5000-0x528f] [0.00] node 0: [mem 0x5290-0x545f] [0.00] node 0: [mem 0x5470-0xffdf] [0.00] node 0: [mem 0x0001-0x00013fff] [0.00] Initmem setup node 0 [mem 0x4000-0x00013fff] [0.00] On node 0 totalpages: 1047808 [0.00] DMA zone: 12288 pages used for memmap [0.00] DMA zone: 0 pages reserved [0.00] DMA zone: 785664 pages, LIFO batch:63 [0.00] Normal zone: 4096 pages used for memmap [0.00] Normal zone: 262144 pages, LIFO batch:63 [0.00] On node 0, zone DMA: 256 pages in unavailable ranges [0.00] On node 0, zone Normal: 512 pages in unavailable ranges [0.00] psci: probing for conduit method from DT. [0.00] psci: PSCIv1.1 detected in firmware. [0.00] psci: Using standard PSCI v0.2 function IDs [0.00] psci: MIGRATE_INFO_TYPE not supported. [0.00] psci: SMC Calling Convention v1.2 [0.00] percpu: Embedded 32 pages/cpu s93336 r8192 d29544 u131072 [0.00] pcpu-alloc: s93336 r8192 d29544 u131072 alloc=32*4096 [0.00] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7 [0.00] Detected VIPT I-cache on CPU0 [0.00] CPU features: detected: ARM erratum 845719 [0.00] CPU features: detected: GIC system register CPU interface [0.00] CPU features: kernel page table isolation forced ON by KASLR [0.00] CPU features: detected: Kernel page table isolation (KPTI) [0.00] Built 1 zonelists, mobility grouping on. Total pages: 1031424 [0.00] Kernel command line: cros_secure console= loglevel=7 init=/sbin/init cros_secure drm.trace=0x106 root=/dev/dm-0 rootwait ro dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 dm="1 vroot none ro 1,0 6144000 verity payload=PARTUUID=6054c8b5-2c17-4e3e-9f5f-bc2a96bf764b/PARTNROFF=1 hashtree=PARTUUID=6054c8b5-2c17-4e3e-9f5f-bc2a96bf764b/PARTNROFF=1 hashstart=6144000 alg=sha256 root_hexdigest=8e442d4eb6f01e3bd21b5b42ede889cd67a316fd949cf05b380e2142181e440f salt=23867f54c1aa0a406880edb52304b63453d25a71950b6d213fce0b11185a03fb" noinitrd vt.global_cursor_default=0 kern_guid=6054c8b5-2c17-4e3e-9f5f-bc2a96bf764b cpuidle.governor=teo [0.00] Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes, linear) [0.00] Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes, linear) [0.00] mem auto-init: stack:all(zero), heap alloc:on, heap free:off [0.00] software IO TLB: mapped [mem 0xfbe0-0xffe0] (64MB) [0.00] Memory: 3977196K/4191232K available (1K kernel code, 2488K rwdata, 5172K rodata, 1408K init, 1073K bss, 214036K reserved, 0K cma-reserved) [
Re: [PATCH V2 1/2] dt-bindings: display: newvision,nv3051d: Add Anbernic 351V Support
On Fri, Aug 11, 2023 at 09:41:50AM -0500, Chris Morgan wrote: > On Thu, Aug 10, 2023 at 05:24:09PM -0600, Rob Herring wrote: > > On Wed, Aug 09, 2023 at 10:39:40AM -0500, Chris Morgan wrote: > > > From: Chris Morgan > > > > > > Document the Anbernic RG351V panel, which appears to be identical to > > > the panel used in their 353 series except for in inclusion of an > > > additional DSI format flag. > > > > > > Signed-off-by: Chris Morgan > > > --- > > > .../display/panel/newvision,nv3051d.yaml | 18 ++ > > > 1 file changed, 10 insertions(+), 8 deletions(-) > > > > > > diff --git > > > a/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml > > > b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml > > > index 116c1b6030a2..576f3640cb33 100644 > > > --- > > > a/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml > > > +++ > > > b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml > > > @@ -7,9 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# > > > title: NewVision NV3051D based LCD panel > > > > > > description: | > > > - The NewVision NV3051D is a driver chip used to drive DSI panels. For > > > now, > > > - this driver only supports the 640x480 panels found in the Anbernic > > > RG353 > > > - based devices. > > > + The NewVision NV3051D is a driver chip used to drive DSI panels. > > > > > > maintainers: > > >- Chris Morgan > > > @@ -19,11 +17,15 @@ allOf: > > > > > > properties: > > >compatible: > > > -items: > > > - - enum: > > > - - anbernic,rg353p-panel > > > - - anbernic,rg353v-panel > > > - - const: newvision,nv3051d > > > +oneOf: > > > + - items: > > > + - enum: > > > + - anbernic,rg353p-panel > > > + - anbernic,rg353v-panel > > > + - const: newvision,nv3051d > > > + > > > + - items: > > > + - const: anbernic,rg351v-panel > > > > I don't understand. Is this panel not based on newvision,nv3051d? If > > not, then it probably should be a different binding. Lot's of panel > > bindings have similar properties. > > It appears to be the same panel (or extremely similar, honestly I don't > know because there are no external markings on it). However, this > specific implementation seems to require MIPI_DSI_CLOCK_NON_CONTINUOUS, > not using it prevents the panel from working. As for the existing panel > MIPI_DSI_CLOCK_NON_CONTINUOUS stops it from working. The different > binding essentially determines whether or not that flag is present, but > otherwise everything else is identical. > > Chris If this is not correct I could also change it so instead there is a property that toggles the MIPI_DSI_CLOCK_NON_CONTINUOUS flag, something like "newvision,clk_non_continuous". Again aside from this flag the panel itself is identical to the one already supported by this driver. Thank you, Chris > > > > > Rob
Re: [PATCH v4 2/4] drm/amdgpu: Rework coredump to use memory dynamically
On 17/08/2023 15:45, André Almeida wrote: Hi Shashank, Em 17/08/2023 03:41, Shashank Sharma escreveu: Hello Andre, On 15/08/2023 21:50, André Almeida wrote: Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- v4: change kmalloc to kzalloc --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 63 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9c6a332261ab..0d560b713948 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1088,11 +1088,6 @@ struct amdgpu_device { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - bool reset_vram_lost; - struct timespec64 reset_time; -#endif bool scpm_enabled; uint32_t scpm_status; @@ -1105,6 +1100,15 @@ struct amdgpu_device { uint32_t aid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device *adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + bool reset_vram_lost; +}; The patch looks good to me in general, but I would recommend slightly different arrangement and segregation of GPU reset information. Please consider a higher level structure adev->gpu_reset_info, and move everything related to reset dump info into that, including this new coredump_info structure, something like this: struct amdgpu_reset_info { uint32_t *reset_dump_reg_list; uint32_t *reset_dump_reg_value; int num_regs; Right, I can encapsulate there reset_dump members, #ifdef CONFIG_DEV_COREDUMP struct amdgpu_coredump_info *coredump_info;/* keep this dynamic allocation */ but we don't need a pointer for amdgpu_coredump_info inside amdgpu_device or inside of amdgpu_device->gpu_reset_info, right? I think it would be better if we keep all of the GPU reset related data in the same structure, so adev->gpu_reset_info->coredump_info sounds about right to me. - Shashank #endif } This will make sure that all the relevant information is at the same place. - Shashank amdgpu_inc_vram_lost(tmp_adev);
Re: [PATCH v1 0/3] udmabuf: Add support for page migration out of movable zone or CMA
On Wed, Aug 16, 2023 at 11:49:31PM -0700, Vivek Kasireddy wrote: > This patch series adds support for migrating pages associated with > a udmabuf out of the movable zone or CMA to avoid breaking features > such as memory hotunplug. > > The first patch exports check_and_migrate_movable_pages() function > out of GUP so that the udmabuf driver can leverage it for page > migration that is done as part of the second patch. The last patch > adds two new udmabuf selftests to verify data coherency after > page migration. Please don't do this. If you want to do what GUP does then call GUP. udmabuf is not so special that it needs to open code its own weird version of it. Jason
[PATCH v2 4/4] arm64: dts: qcom: qrb5165-rb5: enable DP altmode
Add displayport altmode declaration to the Type-C controller node to enable DP altmode negotiation. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 3bd0c06e7315..c8cd40a462a3 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -1423,6 +1423,13 @@ PDO_FIXED_DUAL_ROLE | PDO_FIXED_USB_COMM | PDO_FIXED_DATA_SWAP)>; + altmodes { + displayport { + svid = <0xff01>; + vdo = <0x1c46>; + }; + }; + ports { #address-cells = <1>; #size-cells = <0>; -- 2.39.2
[PATCH v2 3/4] arm64: dts: qcom: qrb5165-rb5: enable displayport controller
Enable the onboard displayport controller, connect it to QMP PHY. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index a4f7a9f9c22c..3bd0c06e7315 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -656,6 +656,15 @@ { status = "okay"; }; +_dp { + status = "okay"; +}; + +_dp_out { + data-lanes = <0 1>; + remote-endpoint = <_1_qmpphy_dp_in>; +}; + _dsi0 { status = "okay"; vdda-supply = <_l9a_1p2>; @@ -1442,3 +1451,7 @@ pm8150b_typec_sbu_out: endpoint { }; }; }; + +_1_qmpphy_dp_in { + remote-endpoint = <_dp_out>; +}; -- 2.39.2
[PATCH v2 1/4] arm64: dts: qcom: sm8250: Add DisplayPort device node
Declare the displayport controller present on the Qualcomm SM8250 SoC. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/sm8250.dtsi | 89 1 file changed, 89 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index eb00bbd3e1f3..8d705a1713fb 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -3638,6 +3638,8 @@ port@1 { port@2 { reg = <2>; + + usb_1_qmpphy_dp_in: endpoint {}; }; }; }; @@ -4405,6 +4407,14 @@ dpu_intf2_out: endpoint { remote-endpoint = <_dsi1_in>; }; }; + + port@2 { + reg = <2>; + + dpu_intf0_out: endpoint { + remote-endpoint = <_dp_in>; + }; + }; }; mdp_opp_table: opp-table { @@ -4432,6 +4442,85 @@ opp-46000 { }; }; + mdss_dp: displayport-controller@ae9 { + compatible = "qcom,sm8250-dp", "qcom,sm8350-dp"; + reg = <0 0xae9 0 0x200>, + <0 0xae90200 0 0x200>, + <0 0xae90400 0 0x600>, + <0 0xae91000 0 0x400>, + <0 0xae91400 0 0x400>; + interrupt-parent = <>; + interrupts = <12>; + clocks = < DISP_CC_MDSS_AHB_CLK>, +< DISP_CC_MDSS_DP_AUX_CLK>, +< DISP_CC_MDSS_DP_LINK_CLK>, +< DISP_CC_MDSS_DP_LINK_INTF_CLK>, +< DISP_CC_MDSS_DP_PIXEL_CLK>; + clock-names = "core_iface", + "core_aux", + "ctrl_link", + "ctrl_link_iface", + "stream_pixel"; + + assigned-clocks = < DISP_CC_MDSS_DP_LINK_CLK_SRC>, + < DISP_CC_MDSS_DP_PIXEL_CLK_SRC>; + assigned-clock-parents = <_phy 0>, +<_phy 1>; + + phys = <_phy>; + phy-names = "dp"; + + #sound-dai-cells = <0>; + + operating-points-v2 = <_opp_table>; + power-domains = < SM8250_MMCX>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + mdss_dp_in: endpoint { + remote-endpoint = <_intf0_out>; + }; + }; + + port@1 { + reg = <1>; + + mdss_dp_out: endpoint { + }; + }; + }; + + dp_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-16000 { + opp-hz = /bits/ 64 <16000>; + required-opps = <_opp_low_svs>; + }; + + opp-27000 { + opp-hz = /bits/ 64 <27000>; + required-opps = <_opp_svs>; + }; + + opp-54000 { + opp-hz = /bits/ 64
[PATCH v2 2/4] arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver
Add the nb7vpq904m, onboard USB-C redriver / retimer. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 52 +++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 303d07f9c6e5..a4f7a9f9c22c 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -610,6 +610,46 @@ lt9611_out: endpoint { /* LS-I2C1 */ { status = "okay"; + + typec-mux@1c { + compatible = "onnn,nb7vpq904m"; + reg = <0x1c>; + + vcc-supply = <_s4a_1p8>; + + retimer-switch; + orientation-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + redriver_usb_con_ss: endpoint { + remote-endpoint = <_typec_mux_in>; + }; + }; + + port@1 { + reg = <1>; + + redriver_phy_con_ss: endpoint { + remote-endpoint = <_1_qmpphy_out>; + data-lanes = <0 1 2 3>; + }; + }; + + port@2 { + reg = <2>; + + redriver_usb_con_sbu: endpoint { + remote-endpoint = <_typec_sbu_out>; + }; + }; + }; + }; }; { @@ -1299,7 +1339,7 @@ _1_qmpphy { }; _1_qmpphy_out { - remote-endpoint = <_typec_mux_in>; + remote-endpoint = <_phy_con_ss>; }; _2 { @@ -1388,7 +1428,15 @@ pm8150b_role_switch_in: endpoint { port@1 { reg = <1>; pm8150b_typec_mux_in: endpoint { - remote-endpoint = <_1_qmpphy_out>; + remote-endpoint = <_usb_con_ss>; + }; + }; + + port@2 { + reg = <2>; + + pm8150b_typec_sbu_out: endpoint { + remote-endpoint = <_usb_con_sbu>; }; }; }; -- 2.39.2
[PATCH v2 0/4] arm64: dts: qcom: qrb5165-rb5: enable DP support
Implement DisplayPort support for the Qualcomm RB5 platform. Note: while testing this, I had link training issues with several dongles with DP connectors. Other DisplayPort-USB-C dongles (with HDMI or VGA connectors) work perfectly. Dependencies: [1] Soft-dependencies: [2], [3] [1] https://lore.kernel.org/linux-arm-msm/20230816115151.501736-1-bryan.odonog...@linaro.org/ [2] https://lore.kernel.org/linux-arm-msm/20230709034211.4045004-1-dmitry.barysh...@linaro.org/ [3] https://lore.kernel.org/linux-arm-msm/20230817145516.5924-1-dmitry.barysh...@linaro.org/ Changes since v1: - Rebased on v9 of Bryan's patchset - Dropped merged dt-bindings patch Dmitry Baryshkov (4): arm64: dts: qcom: sm8250: Add DisplayPort device node arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver arm64: dts: qcom: qrb5165-rb5: enable displayport controller arm64: dts: qcom: qrb5165-rb5: enable DP altmode arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 72 ++- arch/arm64/boot/dts/qcom/sm8250.dtsi | 89 2 files changed, 159 insertions(+), 2 deletions(-) -- 2.39.2
[PATCH v4 2/3] phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE
Switch to using the new DRM_AUX_BRIDGE helper to create the transparent DRM bridge device instead of handcoding corresponding functionality. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 2 +- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 ++- 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index ced603806375..97f53debe761 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -63,7 +63,7 @@ config PHY_QCOM_QMP_COMBO depends on DRM || DRM=n select GENERIC_PHY select MFD_SYSCON - select DRM_PANEL_BRIDGE if DRM + select DRM_AUX_BRIDGE if DRM_BRIDGE && OF help Enable this to support the QMP Combo PHY transceiver that is used with USB3 and DisplayPort controllers on Qualcomm chips. diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 9c3de41ecedb..367d5e93422c 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include @@ -1419,8 +1419,6 @@ struct qmp_combo { struct clk_hw dp_link_hw; struct clk_hw dp_pixel_hw; - struct drm_bridge bridge; - struct typec_switch_dev *sw; enum typec_orientation orientation; }; @@ -3193,44 +3191,6 @@ static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) } #endif -#if IS_ENABLED(CONFIG_DRM) -static int qmp_combo_bridge_attach(struct drm_bridge *bridge, - enum drm_bridge_attach_flags flags) -{ - struct qmp_combo *qmp = container_of(bridge, struct qmp_combo, bridge); - struct drm_bridge *next_bridge; - - if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) - return -EINVAL; - - next_bridge = devm_drm_of_get_bridge(qmp->dev, qmp->dev->of_node, 0, 0); - if (IS_ERR(next_bridge)) { - dev_err(qmp->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); - return PTR_ERR(next_bridge); - } - - return drm_bridge_attach(bridge->encoder, next_bridge, bridge, -DRM_BRIDGE_ATTACH_NO_CONNECTOR); -} - -static const struct drm_bridge_funcs qmp_combo_bridge_funcs = { - .attach = qmp_combo_bridge_attach, -}; - -static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp) -{ - qmp->bridge.funcs = _combo_bridge_funcs; - qmp->bridge.of_node = qmp->dev->of_node; - - return devm_drm_bridge_add(qmp->dev, >bridge); -} -#else -static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp) -{ - return 0; -} -#endif - static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_node *np) { struct device *dev = qmp->dev; @@ -3436,7 +3396,7 @@ static int qmp_combo_probe(struct platform_device *pdev) if (ret) return ret; - ret = qmp_combo_dp_register_bridge(qmp); + ret = drm_aux_bridge_register(dev); if (ret) return ret; -- 2.39.2
[PATCH v4 3/3] usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE
Switch to using the new DRM_AUX_BRIDGE helper to create the transparent DRM bridge device instead of handcoding corresponding functionality. Reviewed-by: Heikki Krogerus Signed-off-by: Dmitry Baryshkov --- drivers/usb/typec/mux/Kconfig | 2 +- drivers/usb/typec/mux/nb7vpq904m.c | 44 ++ 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index 65da61150ba7..e3fee531548f 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -40,7 +40,7 @@ config TYPEC_MUX_NB7VPQ904M tristate "On Semiconductor NB7VPQ904M Type-C redriver driver" depends on I2C depends on DRM || DRM=n - select DRM_PANEL_BRIDGE if DRM + select DRM_AUX_BRIDGE if DRM && OF select REGMAP_I2C help Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C diff --git a/drivers/usb/typec/mux/nb7vpq904m.c b/drivers/usb/typec/mux/nb7vpq904m.c index cda206cf0c38..b17826713753 100644 --- a/drivers/usb/typec/mux/nb7vpq904m.c +++ b/drivers/usb/typec/mux/nb7vpq904m.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -70,8 +70,6 @@ struct nb7vpq904m { bool swap_data_lanes; struct typec_switch *typec_switch; - struct drm_bridge bridge; - struct mutex lock; /* protect non-concurrent retimer & switch */ enum typec_orientation orientation; @@ -297,44 +295,6 @@ static int nb7vpq904m_retimer_set(struct typec_retimer *retimer, struct typec_re return ret; } -#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) -static int nb7vpq904m_bridge_attach(struct drm_bridge *bridge, - enum drm_bridge_attach_flags flags) -{ - struct nb7vpq904m *nb7 = container_of(bridge, struct nb7vpq904m, bridge); - struct drm_bridge *next_bridge; - - if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) - return -EINVAL; - - next_bridge = devm_drm_of_get_bridge(>client->dev, nb7->client->dev.of_node, 0, 0); - if (IS_ERR(next_bridge)) { - dev_err(>client->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); - return PTR_ERR(next_bridge); - } - - return drm_bridge_attach(bridge->encoder, next_bridge, bridge, -DRM_BRIDGE_ATTACH_NO_CONNECTOR); -} - -static const struct drm_bridge_funcs nb7vpq904m_bridge_funcs = { - .attach = nb7vpq904m_bridge_attach, -}; - -static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7) -{ - nb7->bridge.funcs = _bridge_funcs; - nb7->bridge.of_node = nb7->client->dev.of_node; - - return devm_drm_bridge_add(>client->dev, >bridge); -} -#else -static int nb7vpq904m_register_bridge(struct nb7vpq904m *nb7) -{ - return 0; -} -#endif - static const struct regmap_config nb7_regmap = { .max_register = 0x1f, .reg_bits = 8, @@ -461,7 +421,7 @@ static int nb7vpq904m_probe(struct i2c_client *client) gpiod_set_value(nb7->enable_gpio, 1); - ret = nb7vpq904m_register_bridge(nb7); + ret = drm_aux_bridge_register(dev); if (ret) goto err_disable_gpio; -- 2.39.2
[PATCH v4 1/3] drm/bridge: add transparent bridge helper
Define a helper for creating simple transparent bridges which serve the only purpose of linking devices into the bridge chain up to the last bridge representing the connector. This is especially useful for DP/USB-C bridge chains, which can span across several devices, but do not require any additional functionality from the intermediate bridges. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/bridge/Kconfig | 9 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/aux-bridge.c | 132 include/drm/bridge/aux-bridge.h | 19 4 files changed, 161 insertions(+) create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c create mode 100644 include/drm/bridge/aux-bridge.h diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 44a660a4bdbf..80e5d9f722e4 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -12,6 +12,15 @@ config DRM_PANEL_BRIDGE help DRM bridge wrapper of DRM panels +config DRM_AUX_BRIDGE + tristate + depends on DRM_BRIDGE && OF + select AUXILIARY_BUS + select DRM_PANEL_BRIDGE + help + Simple transparent bridge that is used by several non-DRM drivers to + build bridges chain. + menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 2b892b7ed59e..918e3bfff079 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c new file mode 100644 index ..13fe794592f2 --- /dev/null +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Linaro Ltd. + * + * Author: Dmitry Baryshkov + */ +#include +#include + +#include +#include + +static DEFINE_IDA(aux_bridge_ida); + +static void drm_aux_bridge_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + ida_free(_bridge_ida, adev->id); + + kfree(adev); +} + +static void drm_aux_bridge_unregister_adev(void *_adev) +{ + struct auxiliary_device *adev = _adev; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +int drm_aux_bridge_register(struct device *parent) +{ + struct auxiliary_device *adev; + int ret; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + ret = ida_alloc(_bridge_ida, GFP_KERNEL); + if (ret < 0) { + kfree(adev); + return ret; + } + + adev->id = ret; + adev->name = "aux_bridge"; + adev->dev.parent = parent; +#ifdef CONFIG_OF + adev->dev.of_node = parent->of_node; +#endif + adev->dev.release = drm_aux_bridge_release; + + ret = auxiliary_device_init(adev); + if (ret) { + ida_free(_bridge_ida, adev->id); + kfree(adev); + return ret; + } + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev); +} +EXPORT_SYMBOL_GPL(drm_aux_bridge_register); + +struct drm_aux_bridge_data { + struct drm_bridge bridge; + struct drm_bridge *next_bridge; + struct device *dev; +}; + +static int drm_aux_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct drm_aux_bridge_data *data; + + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) + return -EINVAL; + + data = container_of(bridge, struct drm_aux_bridge_data, bridge); + + return drm_bridge_attach(bridge->encoder, data->next_bridge, bridge, +DRM_BRIDGE_ATTACH_NO_CONNECTOR); +} + +static const struct drm_bridge_funcs drm_aux_bridge_funcs = { + .attach = drm_aux_bridge_attach, +}; + +static int drm_aux_bridge_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *id) +{ + struct drm_aux_bridge_data *data; + + data = devm_kzalloc(>dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = >dev; + data->next_bridge = devm_drm_of_get_bridge(>dev, auxdev->dev.of_node, 0, 0); + if (IS_ERR(data->next_bridge)) + return dev_err_probe(>dev, PTR_ERR(data->next_bridge), +"failed to acquire
[PATCH v4 0/3] drm: simplify support for transparent DRM bridges
Supporting DP/USB-C can result in a chain of several transparent bridges (PHY, redrivers, mux, etc). This results in drivers having similar boilerplate code for such bridges. Next, these drivers are susceptible to -EPROBE_DEFER loops: the next bridge can either be probed from the bridge->attach callback, when it is too late to return -EPROBE_DEFER, or from the probe() callback, when the next bridge might not yet be available, because it depends on the resources provided by the probing device. Last, but not least, this results in the the internal knowledge of DRM subsystem slowly diffusing into other subsystems, like PHY or USB/TYPEC. To solve all these issues, define a separate DRM helper, which creates separate aux device just for the bridge. During probe such aux device doesn't result in the EPROBE_DEFER loops. Instead it allows the device drivers to probe properly, according to the actual resource dependencies. The bridge auxdevs are then probed when the next bridge becomes available, sparing drivers from drm_bridge_attach() returning -EPROBE_DEFER. Proposed merge strategy: immutable branch with the drm commit, which is then merged into PHY and USB subsystems together with the corresponding patch. Changes since v3: - Moved bridge driver to gpu/drm/bridge (Neil Armstrong) - Renamed it to aux-bridge (since there is already a simple_bridge driver) - Made CONFIG_OF mandatory for this driver (Neil Armstrong) - Added missing kfree and ida_free (Dan Carpenter) Changes since v2: - ifdef'ed bridge->of_node access (LKP) Changes since v1: - Added EXPORT_SYMBOL_GPL / MODULE_LICENSE / etc. to drm_simple_bridge Dmitry Baryshkov (3): drm/bridge: add transparent bridge helper phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE drivers/gpu/drm/bridge/Kconfig| 9 ++ drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/aux-bridge.c | 132 ++ drivers/phy/qualcomm/Kconfig | 2 +- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 44 +--- drivers/usb/typec/mux/Kconfig | 2 +- drivers/usb/typec/mux/nb7vpq904m.c| 44 +--- include/drm/bridge/aux-bridge.h | 19 8 files changed, 167 insertions(+), 86 deletions(-) create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c create mode 100644 include/drm/bridge/aux-bridge.h -- 2.39.2
[PULL] drm-intel-fixes
Hi Dave and Daniel, I'm covering for Tvrtko on this week's fixes flow. These 3 patches were queued since last week, but I had hold because I had some doubts about the CI results. I have confirmed those issues were not related to these 3 patches, so, here they are. drm-intel-fixes-2023-08-17: - Fix the flow for ignoring GuC SLPC efficient frequency selection (Vinay) - Fix SDVO panel_type initialization (Jani) - Fix display probe for IVB Q and IVB D GT2 server (Jani) Thanks, Rodrigo. The following changes since commit 0bc057eae2610c275361766a064a23cc2758f3ff: Merge tag 'gvt-fixes-2023-08-02' of https://github.com/intel/gvt-linux into drm-intel-fixes (2023-08-02 08:14:57 +0100) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-intel tags/drm-intel-fixes-2023-08-17 for you to fetch changes up to 423ffe62c06ae241ad460f4629dddb9dcf55e060: drm/i915: fix display probe for IVB Q and IVB D GT2 server (2023-08-14 11:59:30 -0400) - Fix the flow for ignoring GuC SLPC efficient frequency selection (Vinay) - Fix SDVO panel_type initialization (Jani) - Fix display probe for IVB Q and IVB D GT2 server (Jani) Jani Nikula (2): drm/i915/sdvo: fix panel_type initialization drm/i915: fix display probe for IVB Q and IVB D GT2 server Vinay Belgaumkar (1): drm/i915/guc/slpc: Restore efficient freq earlier .../gpu/drm/i915/display/intel_display_device.c| 24 +++--- drivers/gpu/drm/i915/display/intel_sdvo.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c| 22 3 files changed, 36 insertions(+), 12 deletions(-)
Re: [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread
On 8/17/23 15:35, Christian König wrote: Am 17.08.23 um 13:13 schrieb Danilo Krummrich: On 8/17/23 07:33, Christian König wrote: [SNIP] The hardware seems to work mostly the same for all vendors, but you somehow seem to think that filling the ring is somehow beneficial which is really not the case as far as I can see. I think that's a misunderstanding. I'm not trying to say that it is *always* beneficial to fill up the ring as much as possible. But I think it is under certain circumstances, exactly those circumstances I described for Nouveau. As far as I can see this is not correct for Nouveau either. As mentioned, in Nouveau the size of a job is only really limited by the ring size, which means that one job can (but does not necessarily) fill up the whole ring. We both agree that this is inefficient, because it potentially results into the HW run dry due to hw_submission_limit == 1. I recognize you said that one should define hw_submission_limit and adjust the other parts of the equation accordingly, the options I see are: (1) Increase the ring size while keeping the maximum job size. (2) Decrease the maximum job size while keeping the ring size. (3) Let the scheduler track the actual job size rather than the maximum job size. (1) results into potentially wasted ring memory, because we're not always reaching the maximum job size, but the scheduler assumes so. (2) results into more IOCTLs from userspace for the same amount of IBs and more jobs result into more memory allocations and more work being submitted to the workqueue (with Matt's patches). (3) doesn't seem to have any of those draw backs. What would be your take on that? Actually, if none of the other drivers is interested into a more precise way of keeping track of the ring utilization, I'd be totally fine to do it in a driver specific way. However, unfortunately I don't see how this would be possible. My proposal would be to just keep the hw_submission_limit (maybe rename it to submission_unit_limit) and add a submission_units field to struct drm_sched_job. By default a jobs submission_units field would be 0 and the scheduler would behave the exact same way as it does now. Accordingly, jobs with submission_units > 1 would contribute more than one unit to the submission_unit_limit. What do you think about that? I think you are approaching this from the completely wrong side. First of all, thanks for keeping up the discussion - I appreciate it. Some more comments / questions below. See the UAPI needs to be stable, so you need a maximum job size otherwise it can happen that a combination of large and small submissions work while a different combination doesn't. How is this related to the uAPI being stable? What do you mean by 'stable' in this context? The Nouveau uAPI allows userspace to pass EXEC jobs by supplying the ring ID (channel), in-/out-syncs and a certain amount of indirect push buffers. The amount of IBs per job is limited by the amount of IBs fitting into the ring. Just to be clear, when I say 'job size' I mean the amount of IBs per job. Maybe I should also mention that the rings we are talking about are software rings managed by a firmware scheduler. We can have an arbitrary amount of software rings and even multiple ones per FD. Given a constant ring size I really don't see why I should limit the maximum amount of IBs userspace can push per job just to end up with a hw_submission_limit > 1. For example, let's just assume the ring can take 128 IBs, why would I limit userspace to submit just e.g. 16 IBs at a time, such that the hw_submission_limit becomes 8? What is the advantage of doing that, rather than letting userspace submit *up to* 128 IBs per job and just letting the scheduler push IBs to the ring as long as there's actually space left on the ring? So what you usually do, and this is driver independent because simply a requirement of the UAPI, is that you say here that's my maximum job size as well as the number of submission which should be pushed to the hw at the same time. And then get the resulting ring size by the product of the two. Given the above, how is that a requirement of the uAPI? That the ring in this use case can't be fully utilized is not a draw back, this is completely intentional design which should apply to all drivers independent of the vendor. Why wouldn't we want to fully utilize the ring size? - Danilo Besides all that, you said that filling up the ring just enough to not let the HW run dry rather than filling it up entirely is desirable. Why do you think so? I tend to think that in most cases it shouldn't make difference. That results in better scheduling behavior. It's mostly beneficial if you don't have a hw scheduler, but as far as I can see there is no need to pump everything to the hw as fast as possible. Regards, Christian. - Danilo Regards, Christian. Because one really is
[PATCH 16/18] drm/i915/dp: Get optimal link config to have best compressed bpp
Currently, we take the max lane, rate and pipe bpp, to get the maximum compressed bpp possible. We then set the output bpp to this value. This patch provides support to have max bpp, min rate and min lanes, that can support the min compressed bpp. v2: -Avoid ending up with compressed bpp, same as pipe bpp. (Stan) -Fix the checks for limits->max/min_bpp while iterating over list of valid DSC bpcs. (Stan) v3: -Refactor the code to have pipe bpp/compressed bpp computation and slice count calculation separately for different cases. v4: -Separate the pipe_bpp calculation for eDP and DP. v5: -Get rid of magic numbers for max and min bpp, and improve documentation. (Stan). -Use functions for {src_sink}_{min_max}_compressed_bpp (Ville). v6: -Remove lines to set link config to max. v7: -Split the part to separate edp and dp functions for computing DSC BPP into separate patch. v8: -Separate mechanism to get compressed bpp for ICL,TGL and XELPD+. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 294 +--- 1 file changed, 261 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3ccdf765c1f0..b295dd32e076 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1689,6 +1689,231 @@ static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp, return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format); } +static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock, + u32 lane_count, u32 mode_clock, + enum intel_output_format output_format, + int timeslots) +{ + u32 available_bw, required_bw; + + available_bw = (link_clock * lane_count * timeslots) / 8; + required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock)); + + return available_bw > required_bw; +} + +static int dsc_compute_link_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits, + u16 compressed_bpp, + int timeslots) +{ + const struct drm_display_mode *adjusted_mode = _config->hw.adjusted_mode; + int link_rate, lane_count; + int i; + + for (i = 0; i < intel_dp->num_common_rates; i++) { + link_rate = intel_dp_common_rate(intel_dp, i); + if (link_rate < limits->min_rate || link_rate > limits->max_rate) + continue; + + for (lane_count = limits->min_lane_count; +lane_count <= limits->max_lane_count; +lane_count <<= 1) { + if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count, + adjusted_mode->clock, + pipe_config->output_format, +timeslots)) + continue; + + pipe_config->lane_count = lane_count; + pipe_config->port_clock = link_rate; + + return 0; + } + } + + return -EINVAL; +} + +static +u16 intel_dp_dsc_max_sink_compressed_bppx16(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int bpc) +{ + u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd); + + if (max_bppx16) + return max_bppx16; + /* +* If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate +* values as given in spec Table 2-157 DP v2.0 +*/ + switch (pipe_config->output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + case INTEL_OUTPUT_FORMAT_YCBCR444: + return (3 * bpc) << 4; + case INTEL_OUTPUT_FORMAT_YCBCR420: + return (3 * (bpc / 2)) << 4; + default: + MISSING_CASE(pipe_config->output_format); + break; + } + + return 0; +} + +static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config) +{ + /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */ + switch (pipe_config->output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + case INTEL_OUTPUT_FORMAT_YCBCR444: + return 8; + case INTEL_OUTPUT_FORMAT_YCBCR420: + return 6; + default: + MISSING_CASE(pipe_config->output_format); + break; + } + + return 0; +} + +static int
[PATCH 18/18] drm/i915/dp: Check if force_dsc_output_format is possible
Currently for testing an output format with DSC, we just force the output format, without checking if it can be supported. This also creates an issue where there is a PCON which might need to convert from forced output format to the format to sink format. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 30 +++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 764663cd73ea..5b48bfe09d0e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -935,16 +935,42 @@ dfp_can_convert_from_ycbcr444(struct intel_dp *intel_dp, return false; } +static bool +dfp_can_convert(struct intel_dp *intel_dp, + enum intel_output_format output_format, + enum intel_output_format sink_format) +{ + switch (output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + return dfp_can_convert_from_rgb(intel_dp, sink_format); + case INTEL_OUTPUT_FORMAT_YCBCR444: + return dfp_can_convert_from_ycbcr444(intel_dp, sink_format); + default: + MISSING_CASE(output_format); + return false; + } + + return false; +} + static enum intel_output_format intel_dp_output_format(struct intel_connector *connector, enum intel_output_format sink_format) { struct intel_dp *intel_dp = intel_attached_dp(connector); struct drm_i915_private *i915 = dp_to_i915(intel_dp); + enum intel_output_format force_dsc_output_format = + intel_dp->force_dsc_output_format; enum intel_output_format output_format; + if (force_dsc_output_format) { + if (source_can_output(intel_dp, force_dsc_output_format) && + (!drm_dp_is_branch(intel_dp->dpcd) || +sink_format != force_dsc_output_format || +dfp_can_convert(intel_dp, force_dsc_output_format, sink_format))) + return force_dsc_output_format; - if (intel_dp->force_dsc_output_format) - return intel_dp->force_dsc_output_format; + drm_dbg_kms(>drm, "Cannot force DSC output format\n"); + } if (sink_format == INTEL_OUTPUT_FORMAT_RGB || dfp_can_convert_from_rgb(intel_dp, sink_format)) -- 2.40.1
[PATCH 13/18] drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp
Refactor code to separate functions for eDP and DP for computing pipe_bpp/compressed bpp when DSC is involved. This will help to optimize the link configuration for DP later. v2: Fix checkpatch warning. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 191 1 file changed, 126 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index db136349d82d..6dfad64b8379 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1696,6 +1696,115 @@ bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp) return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3; } +static +int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + int forced_bpp; + + if (!intel_dp->force_dsc_bpc) + return 0; + + forced_bpp = intel_dp->force_dsc_bpc * 3; + + if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) { + drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", intel_dp->force_dsc_bpc); + return forced_bpp; + } + + drm_dbg_kms(>drm, "Cannot force DSC BPC:%d, due to DSC BPC limits\n", + intel_dp->force_dsc_bpc); + + return 0; +} + +static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, +struct intel_crtc_state *pipe_config, +struct drm_connector_state *conn_state, +struct link_config_limits *limits, +int timeslots) +{ + const struct drm_display_mode *adjusted_mode = _config->hw.adjusted_mode; + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u16 output_bpp, dsc_max_compressed_bpp = 0; + int forced_bpp, pipe_bpp; + + forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp); + + if (forced_bpp) { + pipe_bpp = forced_bpp; + } else { + pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, conn_state->max_requested_bpc); + + if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) { + drm_dbg_kms(>drm, + "Computed BPC less than min supported by source for DSC\n"); + return -EINVAL; + } + } + /* +* For now enable DSC for max link rate, max lane count. +* Optimize this later for the minimum possible link rate/lane count +* with DSC enabled for the requested mode. +*/ + pipe_config->port_clock = limits->max_rate; + pipe_config->lane_count = limits->max_lane_count; + dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(i915, + pipe_config->port_clock, + pipe_config->lane_count, + adjusted_mode->crtc_clock, + adjusted_mode->crtc_hdisplay, + pipe_config->bigjoiner_pipes, + pipe_config->output_format, +pipe_bpp, +timeslots); + if (!dsc_max_compressed_bpp) { + drm_dbg_kms(>drm, "Compressed BPP not supported\n"); + return -EINVAL; + } + + output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); + + pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_compressed_bpp, output_bpp); + + pipe_config->pipe_bpp = pipe_bpp; + + return 0; +} + +static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state, + struct link_config_limits *limits) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + int pipe_bpp, forced_bpp; + + forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp); + + if (forced_bpp) { + pipe_bpp = forced_bpp; + } else { + /* For eDP use max bpp that can be supported with DSC. */ + pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, + conn_state->max_requested_bpc); + if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) { + drm_dbg_kms(>drm, +
[PATCH 11/18] drm/i915/dp: Avoid left shift of DSC output bpp by 4
To make way for fractional bpp support, avoid left shifting the output_bpp by 4 in helper intel_dp_dsc_get_output_bpp. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 10 +++--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 52c47e1b42a0..60c66cc720be 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -814,11 +814,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp); - /* -* Compressed BPP in U6.4 format so multiply by 16, for Gen 11, -* fractional part is 0 -*/ - return bits_per_pixel << 4; + return bits_per_pixel; } u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, @@ -1208,7 +1204,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, mode->hdisplay, bigjoiner, output_format, - pipe_bpp, 64) >> 4; + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -1811,7 +1807,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->pipe_bpp); pipe_config->dsc.compressed_bpp = min_t(u16, - dsc_max_compressed_bpp >> 4, + dsc_max_compressed_bpp, output_bpp); } pipe_config->dsc.slice_count = dsc_dp_slice_count; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index dff4717edbd0..4895d6242915 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -982,7 +982,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, mode->hdisplay, bigjoiner, INTEL_OUTPUT_FORMAT_RGB, - pipe_bpp, 64) >> 4; + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, -- 2.40.1
[PATCH 14/18] drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with DSC
Currently we check if the pipe_bpp selected is >= the min DSC bpc/bpp requirement. We do not check if it is <= the max DSC bpc/bpp requirement. Add checks for max DSC BPC/BPP constraints while computing the pipe_bpp when DSC is in use. v2: Fix the commit message. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 34 + 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 6dfad64b8379..109d7756ede4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1691,13 +1691,27 @@ u8 intel_dp_dsc_min_src_input_bpc(struct drm_i915_private *i915) } static -bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp) +bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, + struct drm_connector_state *conn_state, + struct link_config_limits *limits, + int pipe_bpp) { - return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3; + u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp; + + dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), conn_state->max_requested_bpc); + dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915); + + dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->max_bpp); + dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->min_bpp); + + return pipe_bpp >= dsc_min_pipe_bpp && + pipe_bpp <= dsc_max_pipe_bpp; } static -int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp) +int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp, + struct drm_connector_state *conn_state, + struct link_config_limits *limits) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int forced_bpp; @@ -1707,7 +1721,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp) forced_bpp = intel_dp->force_dsc_bpc * 3; - if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) { + if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) { drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", intel_dp->force_dsc_bpc); return forced_bpp; } @@ -1729,16 +1743,16 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, u16 output_bpp, dsc_max_compressed_bpp = 0; int forced_bpp, pipe_bpp; - forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp); + forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits); if (forced_bpp) { pipe_bpp = forced_bpp; } else { pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, conn_state->max_requested_bpc); - if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) { + if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, pipe_bpp)) { drm_dbg_kms(>drm, - "Computed BPC less than min supported by source for DSC\n"); + "Computed BPC is not in DSC BPC limits\n"); return -EINVAL; } } @@ -1780,7 +1794,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, struct drm_i915_private *i915 = dp_to_i915(intel_dp); int pipe_bpp, forced_bpp; - forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp); + forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits); if (forced_bpp) { pipe_bpp = forced_bpp; @@ -1788,9 +1802,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, /* For eDP use max bpp that can be supported with DSC. */ pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, conn_state->max_requested_bpc); - if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) { + if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, pipe_bpp)) { drm_dbg_kms(>drm, - "Computed BPC less than min supported by source for DSC\n"); + "Computed BPC is not in DSC BPC limits\n"); return -EINVAL; } } -- 2.40.1
[PATCH 04/18] drm/i915/dp: Use consistent name for link bpp and compressed bpp
Currently there are many places where we use output_bpp for link bpp and compressed bpp. Lets use consistent naming: output_bpp : The intermediate value taking into account the output_format chroma subsampling. compressed_bpp : target bpp for the DSC encoder. link_bpp : final bpp used in the link. For 444 sampling without DSC: link_bpp = output_bpp = pipe_bpp For 420 sampling without DSC: output_bpp = pipe_bpp / 2 link_bpp = output_bpp For 444 sampling with DSC: output_bpp = pipe_bpp link_bpp = compressed_bpp, computed with output_bpp (i.e. pipe_bpp in this case) For 420 sampling with DSC: output_bpp = pipe_bpp/2 link_bpp = compressed_bpp, computed with output_bpp Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_dp.c | 84 ++--- drivers/gpu/drm/i915/display/intel_dp.h | 14 ++-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 22 +++--- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a8b67805f3d4..9775c1cbed2b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -740,13 +740,13 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p return bits_per_pixel; } -u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, - u32 link_clock, u32 lane_count, - u32 mode_clock, u32 mode_hdisplay, - bool bigjoiner, - enum intel_output_format output_format, - u32 pipe_bpp, - u32 timeslots) +u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, + u32 link_clock, u32 lane_count, + u32 mode_clock, u32 mode_hdisplay, + bool bigjoiner, + enum intel_output_format output_format, + u32 pipe_bpp, + u32 timeslots) { u32 bits_per_pixel, max_bpp_small_joiner_ram; @@ -1136,7 +1136,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, int target_clock = mode->clock; int max_rate, mode_rate, max_lanes, max_link_clock; int max_dotclk = dev_priv->max_dotclk_freq; - u16 dsc_max_output_bpp = 0; + u16 dsc_max_compressed_bpp = 0; u8 dsc_slice_count = 0; enum drm_mode_status status; bool dsc = false, bigjoiner = false; @@ -1191,21 +1191,21 @@ intel_dp_mode_valid(struct drm_connector *_connector, * integer value since we support only integer values of bpp. */ if (intel_dp_is_edp(intel_dp)) { - dsc_max_output_bpp = + dsc_max_compressed_bpp = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; dsc_slice_count = drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, true); } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) { - dsc_max_output_bpp = - intel_dp_dsc_get_output_bpp(dev_priv, - max_link_clock, - max_lanes, - target_clock, - mode->hdisplay, - bigjoiner, - output_format, - pipe_bpp, 64) >> 4; + dsc_max_compressed_bpp = + intel_dp_dsc_get_max_compressed_bpp(dev_priv, + max_link_clock, + max_lanes, + target_clock, + mode->hdisplay, + bigjoiner, + output_format, + pipe_bpp, 64) >> 4; dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -1213,7 +1213,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
[PATCH 05/18] drm/i915/dp: Update Bigjoiner interface bits for computing compressed bpp
In Bigjoiner check for DSC, bigjoiner interface bits for DP for DISPLAY > 13 is 36 (Bspec: 49259). v2: Corrected Display ver to 13. v3: Follow convention for conditional statement. (Ville) v4: Fix check for display ver. (Ville) v5: Added note for 2 PPC. (Stan) Signed-off-by: Ankit Nautiyal Reviewed-by: Ville Syrjälä Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9775c1cbed2b..a7c706a2327f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -802,8 +802,11 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram); if (bigjoiner) { + int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24; + /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ + int ppc = 2; u32 max_bpp_bigjoiner = - i915->display.cdclk.max_cdclk_freq * 48 / + i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits / intel_dp_mode_to_fec_clock(mode_clock); bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner); -- 2.40.1
[PATCH 10/18] drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also
For DSC the min BPC is 8 for ICL+ and so the min pipe_bpp is 24. Check this condition for cases where bpc is forced by debugfs flag dsc_force_bpc. If the check fails, then WARN and ignore the debugfs flag. For MST case the pipe_bpp is already computed (hardcoded to be 24), and this check is not required. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 48 - 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index fcf94b22e99d..52c47e1b42a0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1694,6 +1694,12 @@ u8 intel_dp_dsc_min_src_input_bpc(struct drm_i915_private *i915) return HAS_DSC(i915) ? 8 : 0; } +static +bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp) +{ + return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3; +} + int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, @@ -1705,7 +1711,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); const struct drm_display_mode *adjusted_mode = _config->hw.adjusted_mode; - int pipe_bpp; int ret; pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && @@ -1717,28 +1722,37 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format)) return -EINVAL; - if (intel_dp->force_dsc_bpc && compute_pipe_bpp) { - pipe_bpp = intel_dp->force_dsc_bpc * 3; - drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n", - intel_dp->force_dsc_bpc); - } else if (compute_pipe_bpp) { - pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); - } else { - pipe_bpp = pipe_config->pipe_bpp; - } + if (compute_pipe_bpp) { + int pipe_bpp; + int forced_bpp = intel_dp->force_dsc_bpc * 3; - if (pipe_bpp < intel_dp_dsc_min_src_input_bpc(dev_priv) * 3) { - drm_dbg_kms(_priv->drm, - "Computed BPC less than min supported by source for DSC\n"); - return -EINVAL; + if (forced_bpp && is_dsc_pipe_bpp_sufficient(dev_priv, forced_bpp)) { + pipe_bpp = forced_bpp; + drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n", + intel_dp->force_dsc_bpc); + } else { + drm_WARN(_priv->drm, forced_bpp, +"Cannot force DSC BPC:%d, due to DSC BPC limits\n", +intel_dp->force_dsc_bpc); + + pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, + conn_state->max_requested_bpc); + + if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { + drm_dbg_kms(_priv->drm, + "Computed BPC less than min supported by source for DSC\n"); + return -EINVAL; + } + } + + pipe_config->pipe_bpp = pipe_bpp; } /* -* For now enable DSC for max bpp, max link rate, max lane count. +* For now enable DSC for max link rate, max lane count. * Optimize this later for the minimum possible link rate/lane count * with DSC enabled for the requested mode. */ - pipe_config->pipe_bpp = pipe_bpp; pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; @@ -1767,7 +1781,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, adjusted_mode->crtc_hdisplay, pipe_config->bigjoiner_pipes, pipe_config->output_format, - pipe_bpp, + pipe_config->pipe_bpp, timeslots); if (!dsc_max_compressed_bpp) { drm_dbg_kms(_priv->drm, -- 2.40.1
[PATCH 07/18] drm/i915/dp: Remove extra logs for printing DSC info
DSC compressed bpp and slice counts are already getting printed at the end of dsc compute config. Remove extra logs. Signed-off-by: Ankit Nautiyal Reviewed-by: Arun R Murthy --- drivers/gpu/drm/i915/display/intel_dp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a7c706a2327f..0b85af7316f4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1782,9 +1782,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, output_bpp); } pipe_config->dsc.slice_count = dsc_dp_slice_count; - drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count %d\n", - pipe_config->dsc.compressed_bpp, - pipe_config->dsc.slice_count); } /* * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate -- 2.40.1
[PATCH 00/18] DSC misc fixes
This series is an attempt to address multiple issues with DSC, scattered in separate existing series. Patches 1-4 are DSC fixes from series to Handle BPC for HDMI2.1 PCON https://patchwork.freedesktop.org/series/107550/ Patches 5-6 are from series DSC fixes for Bigjoiner: https://patchwork.freedesktop.org/series/115773/ Patches 7-17 are based on series to add DSC fractional BPP support: https://patchwork.freedesktop.org/series/111391/ Rev2: Addressed review comments from Stan, Ville. Rev3: Split larger patches. Separate out common helpers. Rev4: Rebased, fixed checkpatch warnings. Rev5: Addressed review comments from Stan. Added a patch to check if forced dsc format can be used before forcing. Rev6: Addressed review comments from Stan. Rev7: Reordered and rebased. Rev8: Dropped few patches to be taken into separate series. Fixed typo in commit message in Patch#2 and rebased. Ankit Nautiyal (18): drm/i915/dp: Consider output_format while computing dsc bpp drm/i915/dp: Move compressed bpp check with 420 format inside the helper drm/i915/dp_mst: Use output_format to get the final link bpp drm/i915/dp: Use consistent name for link bpp and compressed bpp drm/i915/dp: Update Bigjoiner interface bits for computing compressed bpp drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck drm/i915/dp: Remove extra logs for printing DSC info drm/i915/dp: Avoid forcing DSC BPC for MST case drm/i915/dp: Add functions to get min/max src input bpc with DSC drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also drm/i915/dp: Avoid left shift of DSC output bpp by 4 drm/i915/dp: Rename helper to get DSC max pipe_bpp drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with DSC drm/i915/dp: Separate out function to get compressed bpp with joiner drm/i915/dp: Get optimal link config to have best compressed bpp drm/i915/dp: Check src/sink compressed bpp limit for edp drm/i915/dp: Check if force_dsc_output_format is possible drivers/gpu/drm/i915/display/intel_cdclk.c | 59 +- drivers/gpu/drm/i915/display/intel_dp.c | 651 drivers/gpu/drm/i915/display/intel_dp.h | 16 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 33 +- 4 files changed, 596 insertions(+), 163 deletions(-) -- 2.40.1
[PATCH 06/18] drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck
As per Bsepc:49259, Bigjoiner BW check puts restriction on the compressed bpp for a given CDCLK, pixelclock in cases where Bigjoiner + DSC are used. Currently compressed bpp is computed first, and it is ensured that the bpp will work at least with the max CDCLK freq. Since the CDCLK is computed later, lets account for Bigjoiner BW check while calculating Min CDCLK. v2: Use pixel clock in the bw calculations. (Ville) v3: Use helper to account for FEC overhead. (Stan) Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_cdclk.c | 59 +- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 2fb030b1ff1d..de04a6fe54f3 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -32,6 +32,7 @@ #include "intel_cdclk.h" #include "intel_crtc.h" #include "intel_de.h" +#include "intel_dp.h" #include "intel_display_types.h" #include "intel_mchbar_regs.h" #include "intel_pci_config.h" @@ -2533,6 +2534,48 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state) return min_cdclk; } +static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); + int min_cdclk = 0; + + /* +* When we decide to use only one VDSC engine, since +* each VDSC operates with 1 ppc throughput, pixel clock +* cannot be higher than the VDSC clock (cdclk) +* If there 2 VDSC engines, then pixel clock can't be higher than +* VDSC clock(cdclk) * 2 and so on. +*/ + min_cdclk = max_t(int, min_cdclk, + DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances)); + + if (crtc_state->bigjoiner_pipes) { + int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock); + + /* +* According to Bigjoiner bw check: +* compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / Pixel clock +* +* We have already computed compressed_bpp, so now compute the min CDCLK that +* is required to support this compressed_bpp. +* +* => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner Interface bits) +* +* Since PPC = 2 with bigjoiner +* => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits +*/ + int bigjoiner_interface_bits = DISPLAY_VER(i915) > 13 ? 36 : 24; + int min_cdclk_bj = (crtc_state->dsc.compressed_bpp * pixel_clock) / + (2 * bigjoiner_interface_bits); + + min_cdclk = max(min_cdclk, min_cdclk_bj); + } + + return min_cdclk; +} + int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = @@ -2604,20 +2647,8 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) /* Account for additional needs from the planes */ min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk); - /* -* When we decide to use only one VDSC engine, since -* each VDSC operates with 1 ppc throughput, pixel clock -* cannot be higher than the VDSC clock (cdclk) -* If there 2 VDSC engines, then pixel clock can't be higher than -* VDSC clock(cdclk) * 2 and so on. -*/ - if (crtc_state->dsc.compression_enable) { - int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); - - min_cdclk = max_t(int, min_cdclk, - DIV_ROUND_UP(crtc_state->pixel_rate, - num_vdsc_instances)); - } + if (crtc_state->dsc.compression_enable) + min_cdclk = max(min_cdclk, intel_vdsc_min_cdclk(crtc_state)); /* * HACK. Currently for TGL/DG2 platforms we calculate -- 2.40.1
[PATCH 15/18] drm/i915/dp: Separate out function to get compressed bpp with joiner
Pull the code to get joiner constraints on maximum compressed bpp into separate function. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 54 ++--- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 109d7756ede4..3ccdf765c1f0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -740,6 +740,32 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p return bits_per_pixel; } +static +u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915, + u32 mode_clock, u32 mode_hdisplay, + bool bigjoiner) +{ + u32 max_bpp_small_joiner_ram; + + /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ + max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / mode_hdisplay; + + if (bigjoiner) { + int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24; + /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ + int ppc = 2; + u32 max_bpp_bigjoiner = + i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits / + intel_dp_mode_to_fec_clock(mode_clock); + + max_bpp_small_joiner_ram *= 2; + + return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner); + } + + return max_bpp_small_joiner_ram; +} + u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, u32 link_clock, u32 lane_count, u32 mode_clock, u32 mode_hdisplay, @@ -748,7 +774,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, u32 pipe_bpp, u32 timeslots) { - u32 bits_per_pixel, max_bpp_small_joiner_ram; + u32 bits_per_pixel, joiner_max_bpp; /* * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* @@ -788,29 +814,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, (link_clock * lane_count * 8), intel_dp_mode_to_fec_clock(mode_clock)); - /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ - max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / - mode_hdisplay; - - if (bigjoiner) - max_bpp_small_joiner_ram *= 2; - - /* -* Greatest allowed DSC BPP = MIN (output BPP from available Link BW -* check, output bpp from small joiner RAM check) -*/ - bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram); - - if (bigjoiner) { - int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24; - /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ - int ppc = 2; - u32 max_bpp_bigjoiner = - i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits / - intel_dp_mode_to_fec_clock(mode_clock); - - bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner); - } + joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock, + mode_hdisplay, bigjoiner); + bits_per_pixel = min(bits_per_pixel, joiner_max_bpp); bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp); -- 2.40.1
[PATCH 17/18] drm/i915/dp: Check src/sink compressed bpp limit for edp
Use checks for src and sink limits before computing compressed bpp for eDP. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b295dd32e076..764663cd73ea 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2027,6 +2027,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int pipe_bpp, forced_bpp; + int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; + int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits); @@ -2044,9 +2046,19 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, } pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; - pipe_config->dsc.compressed_bpp = - min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4, - pipe_bpp); + + dsc_src_min_bpp = dsc_src_min_compressed_bpp(); + dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config); + dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); + + dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); + dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3); + dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp; + + /* Compressed BPP should be less than the Input DSC bpp */ + dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); + + pipe_config->dsc.compressed_bpp = max(dsc_min_bpp, dsc_max_bpp); pipe_config->pipe_bpp = pipe_bpp; -- 2.40.1
[PATCH 08/18] drm/i915/dp: Avoid forcing DSC BPC for MST case
For MST the bpc is hardcoded to 8, and pipe bpp to 24. So avoid forcing DSC bpc for MST case. v2: Warn and ignore the debug flag than to bail out. (Jani) v3: Fix dbg message to mention forced bpc instead of bpp. v4: Fix checkpatch longline warning. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 12 ++-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0b85af7316f4..d6fd453ade6b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1697,14 +1697,14 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format)) return -EINVAL; - if (compute_pipe_bpp) + if (intel_dp->force_dsc_bpc && compute_pipe_bpp) { + pipe_bpp = intel_dp->force_dsc_bpc * 3; + drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n", + intel_dp->force_dsc_bpc); + } else if (compute_pipe_bpp) { pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); - else + } else { pipe_bpp = pipe_config->pipe_bpp; - - if (intel_dp->force_dsc_bpc) { - pipe_bpp = intel_dp->force_dsc_bpc * 3; - drm_dbg_kms(_priv->drm, "Input DSC BPP forced to %d", pipe_bpp); } /* Min Input BPC for ICL+ is 8 */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 1f00713fb1ad..dff4717edbd0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -361,6 +361,11 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, /* enable compression if the mode doesn't fit available BW */ drm_dbg_kms(_priv->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en); if (ret || intel_dp->force_dsc_en) { + /* +* FIXME: As bpc is hardcoded to 8, as mentioned above, +* WARN and ignore the debug flag force_dsc_bpc for now. +*/ + drm_WARN(_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force BPC for MST\n"); /* * Try to get at least some timeslots and then see, if * we can fit there with DSC. -- 2.40.1
[PATCH 12/18] drm/i915/dp: Rename helper to get DSC max pipe_bpp
The helper intel_dp_dsc_compute_bpp gives the maximum pipe bpp that is allowed with DSC. Rename the this to reflect that it returns max pipe bpp supported with DSC. Signed-off-by: Ankit Nautiyal Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 8 drivers/gpu/drm/i915/display/intel_dp.h | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 60c66cc720be..db136349d82d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1183,7 +1183,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ - pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX); + pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX); /* * Output bpp is stored in 6.4 format so right shift by 4 to get the @@ -1543,7 +1543,7 @@ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private *i915) return 0; } -int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc) +int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int i, num_bpc; @@ -1731,8 +1731,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, "Cannot force DSC BPC:%d, due to DSC BPC limits\n", intel_dp->force_dsc_bpc); - pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, - conn_state->max_requested_bpc); + pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, + conn_state->max_requested_bpc); if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) { drm_dbg_kms(_priv->drm, diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 6fd423463f5c..788a577ebe16 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -106,7 +106,7 @@ void intel_read_dp_sdp(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, unsigned int type); bool intel_digital_port_connected(struct intel_encoder *encoder); -int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); +int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915, u32 link_clock, u32 lane_count, u32 mode_clock, u32 mode_hdisplay, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 4895d6242915..3eb085fbc7c8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -971,7 +971,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ - int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX); + int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX); if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) { dsc_max_compressed_bpp = -- 2.40.1