Re: [RFC PATCH 3/5] drm/amdgpu: Allow explicit sync for VM ops.
Am 06.06.22 um 13:00 schrieb Bas Nieuwenhuizen: On Mon, Jun 6, 2022 at 12:35 PM Christian König wrote: [SNIP] That part won't work at all and would cause additional synchronization problems. First of all for implicit synced CS we should use READ, not BOOKKEEP. Because BOOKKEEP would incorrectly be ignored by OpenGL importers. I've fixed that this causes memory corruption, but it is still nice to avoid. Yes, what I'm saying is that on implicit sync CS submission should add READ fences to the dma resv and on explicit sync CS submission should add BOOKKEEP fences. No, exactly that is wrong. Implicit CS submissions should add WRITE fences. Explicit CS submissions should add READ fences. Only VM updates should add BOOKKEEP fences. BOOKKEEP can only be used by VM updates themselves. So that they don't interfere with CS. That is the point why we would go BOOKKEEP for explicit sync CS submissions, no? Explicit submission shouldn't interfere with any other CS submissions. That includes being totally ignored by GL importers (if we want to have synchronization there between an explicit submission and GL, userspace is expected to use Jason's dmabuf fence import/export IOCTLs) No, that would break existing DMA-buf rules. Explicit CS submissions are still a dependency for implicit submissions. Then the second problem is that the VM IOCTL has absolutely no idea what the CS IOCTL would be doing. That's why we have added the EXPLICIT sync flag on the BO. It doesn't need to? We just use a different sync_mode for BOOKKEEP fences vs others: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.freedesktop.org%2Fpatch%2F487887%2F%3Fseries%3D104578%26rev%3D2&data=05%7C01%7Cchristian.koenig%40amd.com%7C81db0fea1c854076fc4408da47abafaa%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637901099957139870%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=F72Boaesx83MD2pjGuucA1buawi205XLSsQHg5EH39A%3D&reserved=0 No, exactly that's completely broken. Regards, Christian. (the nice thing about doing it this way is that it is independent of the IOCTL, i.e. also works for the delayed mapping changes we trigger on CS submit) Regards, Christian. That should be doable, but then you don't need any of the other changes. Regards, Christian. #1 Is rather easy to fix, you just need to copy all dma_fences from the page table dma_resv object over to the BOs dma_resv object in the gem close handler. E.g. exactly what you suggested with the dma_resv_copy function. #2 is a nightmare. We can't move the TLB flush at the end of the unmap operation because on async TLB flushes are either a bit complicated (double flushes etc..) or don't even work at all because of hw bugs. So to have a reliable TLB flush we must make sure that nothing else is ongoing and that means CS->VM->CS barrier. We try very hard to circumvent that already on maps by (for example) using a completely new VMID for CS after the VM map operation. But for the unmap operation we would need some kind special dma_fence implementation which would not only wait for all existing dma_fence but also for the one added until the unmap operation is completed. Cause otherwise our operation we do at #1 would simply not catch all dma_fences which have access to the memory. That's certainly doable, but I think just using the drm_exec stuff I already came up with is easier. When we can grab locks for all the BOs involved amdgpu_vm_clear_freed() goes away and we can keep track of the unmap operations in the bo_va structure. With that done you can make the explicit sync you noted in the bo_va structure and implicit sync when the bo_va structure goes away. Then the only reason I can see why we would need a CS->VM dependency is implicit synchronization, and that's what we are trying to avoid here in the first place. Regards, Christian. To get rid of this barrier you must first fix the part where CS submissions wait for the VM operation to complete, e.g. the necessity of the barrier. I'm working on this for a couple of years now and I'm really running out of idea how to explain this restriction. Regards, Christian.
Re: [RFC PATCH 3/5] drm/amdgpu: Allow explicit sync for VM ops.
Hi Bas, sorry I totally missed your reply. Just tried to answer your original questions. Regards, Christian. Am 15.06.22 um 02:40 schrieb Bas Nieuwenhuizen: Hi Christian, Friendly ping on the comments here. Are you okay with me re-spinning the series with a fixed patch 1 or do we need further discussion on the approach here? Thanks, Bas On Mon, Jun 6, 2022 at 1:00 PM Bas Nieuwenhuizen wrote: On Mon, Jun 6, 2022 at 12:35 PM Christian König wrote: Am 06.06.22 um 12:30 schrieb Bas Nieuwenhuizen: On Mon, Jun 6, 2022 at 12:15 PM Christian König wrote: Am 03.06.22 um 21:11 schrieb Bas Nieuwenhuizen: On Fri, Jun 3, 2022 at 8:41 PM Christian König wrote: Am 03.06.22 um 19:50 schrieb Bas Nieuwenhuizen: [SNIP] Yeah, but that's exactly the bubble we try to avoid. Isn't it? For this series, not really. To clarify there are two sides for getting GPU bubbles and no overlap: (1) VM operations implicitly wait for earlier CS submissions (2) CS submissions implicitly wait for earlier VM operations Together, these combine to ensure that you get a (potentially small) bubble any time VM work happens. Your series (and further ideas) tackles (2), and is a worthwhile thing to do. However, while writing the userspace for this I noticed this isn't enough to get rid of all our GPU bubbles. In particular when doing a non-sparse map of a new BO, that tends to need to be waited on for the next CS anyway for API semantics. Due to VM operations happening on a single timeline that means this high priority map can end up being blocked by earlier sparse maps and hence the bubble in that case still exists. So in this series I try to tackle (1) instead. Since GPU work typically lags behind CPU submissions and VM operations aren't that slow, we can typically execute VM operations early enough that any implicit syncs from (2) are less/no issue. Ok, once more since you don't seem to understand what I want to say: It isn't possible to fix #1 before you have fixed #2. The VM unmap operation here is a barrier which divides the CS operations in a before and after. This is intentional design. Why is that barrier needed? The two barriers I got and understood and I think we can deal with: 1) the VM unmap is a barrier between prior CS and later memory free. 2) The TLB flush need to happen between a VM unmap and later CS. But why do we need the VM unmap to be a strict barrier between prior CS and later CS? Exactly because of the two reasons you mentioned. This is the part I'm not seeing. I get that removing #2 is a nightmare, which is why I did something that doesn't violate that constraint. Like if an explicit CS that was running before the VM operation runs till after the VM operation (and hence possibly till after the TLB flush, or otherwise have the TLB flush not apply due to lack of async TLB flush support), that is not an issue. It might see the state from before the unmap, or after the unmap, or some intermediate state and all of those would be okay. We still get the constraint that the TLB flush happens between the VM unmap and later CS and hence the unmap is certainly visible to them. So you basically just want to set the sync mode in amdgpu_vm_update_range() to AMDGPU_SYNC_EXPLICIT even when it is an unmap? Yes, with the caveat that I want to do that only for DMA_RESV_USAGE_BOOKKEEP or higher (i.e. if we submit a CS with implicit sync we get the old implicit behavior, if we submit a CS with explicit sync we get the new explicit behavior). The rest of the series is basically just for enabling explicit sync submissions. That part won't work at all and would cause additional synchronization problems. First of all for implicit synced CS we should use READ, not BOOKKEEP. Because BOOKKEEP would incorrectly be ignored by OpenGL importers. I've fixed that this causes memory corruption, but it is still nice to avoid. Yes, what I'm saying is that on implicit sync CS submission should add READ fences to the dma resv and on explicit sync CS submission should add BOOKKEEP fences. BOOKKEEP can only be used by VM updates themselves. So that they don't interfere with CS. That is the point why we would go BOOKKEEP for explicit sync CS submissions, no? Explicit submission shouldn't interfere with any other CS submissions. That includes being totally ignored by GL importers (if we want to have synchronization there between an explicit submission and GL, userspace is expected to use Jason's dmabuf fence import/export IOCTLs) Then the second problem is that the VM IOCTL has absolutely no idea what the CS IOCTL would be doing. That's why we have added the EXPLICIT sync flag on the BO. It doesn't need to? We just use a different sync_mode for BOOKKEEP fences vs others: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.freedesktop.org%2Fpatch%2F487887%2F%3Fseries%3D104578%26rev%3D2&data=05%7C01%7Cchristian.koenig%40amd.com%7C0c76d5c34db846f2fff208da4e67ad7b%7C3dd8961fe4884e608e11a82d994e183d%7
Re: [Intel-gfx] [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition
On 14/06/2022 17:42, Niranjana Vishwanathapura wrote: On Tue, Jun 14, 2022 at 05:07:37PM +0100, Tvrtko Ursulin wrote: On 14/06/2022 17:02, Tvrtko Ursulin wrote: On 14/06/2022 16:43, Niranjana Vishwanathapura wrote: On Tue, Jun 14, 2022 at 08:16:41AM +0100, Tvrtko Ursulin wrote: On 14/06/2022 00:39, Matthew Brost wrote: On Mon, Jun 13, 2022 at 07:09:06PM +0100, Tvrtko Ursulin wrote: On 13/06/2022 18:49, Niranjana Vishwanathapura wrote: On Mon, Jun 13, 2022 at 05:22:02PM +0100, Tvrtko Ursulin wrote: On 13/06/2022 16:05, Niranjana Vishwanathapura wrote: On Mon, Jun 13, 2022 at 09:24:18AM +0100, Tvrtko Ursulin wrote: On 10/06/2022 17:14, Niranjana Vishwanathapura wrote: On Fri, Jun 10, 2022 at 05:48:39PM +0300, Lionel Landwerlin wrote: On 10/06/2022 13:37, Tvrtko Ursulin wrote: On 10/06/2022 08:07, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 490 +++ 1 file changed, 490 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..9fc854969cfb --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,490 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + * bit[0]: If set, VM_BIND is supported, otherwise not. + * bits[8-15]: VM_BIND implementation version. + * version 0 will not have VM_BIND/UNBIND timeline fence array support. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/** + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING + * + * Flag to declare context as long running. + * See struct drm_i915_gem_context_create_ext flags. + * + * Usage of dma-fence expects that they complete in reasonable amount of time. + * Compute on the other hand can be long running. Hence it is not appropriate + * for compute contexts to export request completion dma-fence to user. + * The dma-fence usage will be limited to in-kernel consumption only. + * Compute contexts need to use user/memory fence. + * + * So, long running contexts do not support output fences. Hence, + * I915_EXEC_FENCE_SIGNAL (See &drm_i915_gem_exec_fence.flags) is expected + * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for + * objects mapped to long running contexts. + */ +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING (1u << 2) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f +#define DRM_I915_GEM_WAIT_USER_FENCE 0x40 + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence) + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @queue_idx specifies the queue to use for binding. Same queue can be + * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind + * operations in a queue are performed in the order of submission. + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. + * Also, on those platforms, it is not allowed to bind an device local-memory + * object and a system memory object in a single 2M sect
Re: [PATCH 02/64] drm/crtc: Introduce drmm_crtc_init_with_planes
Hi Am 14.06.22 um 14:09 schrieb Maxime Ripard: On Tue, Jun 14, 2022 at 01:47:28PM +0200, Thomas Zimmermann wrote: Am 14.06.22 um 11:04 schrieb Maxime Ripard: On Tue, Jun 14, 2022 at 10:29:20AM +0200, Thomas Zimmermann wrote: Am 14.06.22 um 09:37 schrieb Maxime Ripard: Hi Thomas, On Mon, Jun 13, 2022 at 01:23:54PM +0200, Thomas Zimmermann wrote: Am 10.06.22 um 11:28 schrieb Maxime Ripard: The DRM-managed function to register a CRTC is drmm_crtc_alloc_with_planes(), which will allocate the underlying structure and initialisation the CRTC. However, we might want to separate the structure creation and the CRTC initialisation, for example if the structure is shared across multiple DRM entities, for example an encoder and a connector. Let's create an helper to only initialise a CRTC that would be passed as an argument. Before I review all of thes patches, one question. it's yet not clear to me why drm_crtc_init_with_planes() wouldn't work. (I know we discussed this on IRC.) If you're calling drmm_mode_config_init(), it will clean up all the CRTC, encoder connector, etc. data structures for you. For CRTC instances in kmalloced memory, wouldn't it be simpler to put the corresponding kfree into vc4_crtc_destroy()? My intent was to remove as much of the lifetime handling and memory-management from drivers as possible. My feeling is that while the solution you suggest would definitely work, it relies on drivers authors to know about this, and make the effort to convert the drivers themselves. And then we would have to review that, which we will probably miss (collectively), because it's a bit obscure. While with either the drmm_alloc_* functions, or the new functions I introduce there, we can just deprecate the old ones, create a TODO entry and a coccinelle script and trust that it works properly. Thanks for explaining the motivation. I would not want to deprecate any of the existing functions, as they work for many drivers. The drmm_ functions add additional overhead that not everyone is willing to pay. I'm a bit confused. drm_crtc_init_with_planes() at the moment has: * Note: consider using drmm_crtc_alloc_with_planes() instead of * drm_crtc_init_with_planes() to let the DRM managed resource infrastructure * take care of cleanup and deallocation. Just like drm_encoder_init(), drm_simple_encoder_init() and drm_universal_plane_init(), so all the functions we have a drmm_* helper for. And we have a TODO-list item that heavily hints at using them: https://dri.freedesktop.org/docs/drm/gpu/todo.html#object-lifetime-fixes So it looks like we're already well on the deprecation path? AFAIU that TODO item is about replacing devm_kzalloc() with drmm_kzalloc(). It's not about the plain init functions, such as drm_crtc_init_with_planes() or drm_universal_plane_init(). Many simple drivers allocate their modesetting pipeline's components first and then build the pipeline with the drm_ functions. I don't think we can take that away from them. Sure, that's exactly what those first patches are about? It allows to use a DRM managed initialization without disrupting the drivers structure too much? The concern I have is that we're adding lots of helpers for all kind of scenarios and end up with a lot of duplication (and fragmentation among drivers). I can see two: whether you want to allocate / init, or just init? We're not going to have more than that. For example, drmm_crtc_alloc_with_planes() really isn't much used by anything. [1] Not that I disagree here, but it might be that it isn't the most helpful helper? In vc4 case, we just can't use it easily. Our CRTC driver is shared between the "regular" CRTCs in the display path, and another instance dedicated to the writeback connector. The shared stuff is initialized through vc4_crtc_init(): https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/vc4/vc4_crtc.c#L1120 It initializes the structure, set up the planes, etc. Basically everything that our CRTC controller will be doing, and would be shared by both cases. However, since the writeback and regular CRTC structures are different, we can't really make that function allocate the backing structure either. It appears to me that it's a problem with how vc4 organizes its pipeline. That's why I suggested to move some of vc4's init code around to make such allocations more flexible. We could do some compiler magic to pass the total size and the offset to that function, just like what drmm_crtc_alloc_with_planes is doing, but then we would have the same issue with the writeback stuff that needs to initialize the encoder and connector. In vc4_crtc.c it should be possible to use drmm_crtc_alloc_with_planes(). In vc4_txp.c, the code apparently initializes struct vc4_txp, so it would be better to use a managed cleanup of struct vc4_txp. See, helpers should be useful to many drivers. If we add them, we also add a resources and maintenance overhead to our libraries. And right
Re: [PATCH] drm/arm/hdlcd: Take over EFI framebuffer properly
Hi Am 14.06.22 um 23:06 schrieb Robin Murphy: On 2022-06-14 14:48, Thomas Zimmermann wrote: Hi Am 14.06.22 um 15:04 schrieb Robin Murphy: The Arm Juno board EDK2 port has provided an EFI GOP display via HDLCD0 for some time now, which works nicely as an early framebuffer. However, once the HDLCD driver probes and takes over the hardware, it should take over the logical framebuffer as well, otherwise the now-defunct GOP device hangs about and virtual console output inevitably disappears into the wrong place most of the time. Signed-off-by: Robin Murphy --- drivers/gpu/drm/arm/hdlcd_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index af59077a5481..a5d04884658b 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -331,6 +331,8 @@ static int hdlcd_drm_bind(struct device *dev) goto err_vblank; } + drm_fb_helper_remove_conflicting_framebuffers(NULL, "hdlcd", false); + In addition to what Javier said, it appears to be too late to call this function. If anything her etouches hardware, you might accidentally interfere with the EFI-related driver. Rather call it at the top of ldlcd_drm_bind(). OK, thanks for the info. I mostly just copied the pattern from the simplest-looking other users (sun4i, tegra, vc4) who all seemed to call it fairly late, and indeed naively it seemed logical not to do it *too* early when there's more chance we might fail to bind and leave the user with no framebuffer at all. In particular, waiting until we've bound the HDMI encoder seems like a good idea in the case of the Juno board (which is the only real HDLCD user), as the I2C bus often gets stuck if the System Control Processor is having a bad day. I also don't believe there's anything here that would affect efifb more than the fact that once the DRM CRTC is alive we simply stop scanning out from the region of memory that efifb is managing, but if it's considered good practice to do this early then I can certainly make that change too. We've been struggling with this a bit. If it works reliably, you're welcome to leave it where it is. Historically, most drivers call this function very early. But for error recovery it would be better to do it as late as possible. Ideally, drivers would first initialize their DRM software state, then kickout the generic driver, and finally take over hardware. But that would require a careful review of each driver. :/ Best regards Thomas Cheers, Robin. -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/arm/hdlcd: Take over EFI framebuffer properly
On 6/15/22 09:39, Thomas Zimmermann wrote: > Hi > > Am 14.06.22 um 23:06 schrieb Robin Murphy: >> On 2022-06-14 14:48, Thomas Zimmermann wrote: >>> Hi >>> >>> Am 14.06.22 um 15:04 schrieb Robin Murphy: The Arm Juno board EDK2 port has provided an EFI GOP display via HDLCD0 for some time now, which works nicely as an early framebuffer. However, once the HDLCD driver probes and takes over the hardware, it should take over the logical framebuffer as well, otherwise the now-defunct GOP device hangs about and virtual console output inevitably disappears into the wrong place most of the time. Signed-off-by: Robin Murphy --- drivers/gpu/drm/arm/hdlcd_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index af59077a5481..a5d04884658b 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -331,6 +331,8 @@ static int hdlcd_drm_bind(struct device *dev) goto err_vblank; } + drm_fb_helper_remove_conflicting_framebuffers(NULL, "hdlcd", false); + >>> >>> In addition to what Javier said, it appears to be too late to call >>> this function. If anything her etouches hardware, you might >>> accidentally interfere with the EFI-related driver. Rather call it at >>> the top of ldlcd_drm_bind(). >> >> OK, thanks for the info. I mostly just copied the pattern from the >> simplest-looking other users (sun4i, tegra, vc4) who all seemed to call >> it fairly late, and indeed naively it seemed logical not to do it *too* >> early when there's more chance we might fail to bind and leave the user >> with no framebuffer at all. In particular, waiting until we've bound the >> HDMI encoder seems like a good idea in the case of the Juno board (which >> is the only real HDLCD user), as the I2C bus often gets stuck if the >> System Control Processor is having a bad day. I also don't believe >> there's anything here that would affect efifb more than the fact that >> once the DRM CRTC is alive we simply stop scanning out from the region >> of memory that efifb is managing, but if it's considered good practice >> to do this early then I can certainly make that change too. > We've been struggling with this a bit. If it works reliably, you're > welcome to leave it where it is. > > Historically, most drivers call this function very early. But for error > recovery it would be better to do it as late as possible. Ideally, > drivers would first initialize their DRM software state, then kickout > the generic driver, and finally take over hardware. But that would > require a careful review of each driver. :/ > We got bug reports on Fedora about regressions caused by the fact that some programs made the (wrong) assumption that /dev/dri/card0 would be the "main" display and just hard-coded that path. But removing the conflicting framebuffers after calling devm_drm_dev_alloc() breaks this assumption, since the registered device will be /dev/dri/card1. All this is to say that doing it too late, even if nothing is touching the HW yet, could still have unexpected consequences across your graphics stack. -- Best regards, Javier Martinez Canillas Linux Engineering Red Hat
Re: [PATCH] drm/arm/hdlcd: Take over EFI framebuffer properly
Am 15.06.22 um 09:50 schrieb Javier Martinez Canillas: [...] Historically, most drivers call this function very early. But for error recovery it would be better to do it as late as possible. Ideally, drivers would first initialize their DRM software state, then kickout the generic driver, and finally take over hardware. But that would require a careful review of each driver. :/ We got bug reports on Fedora about regressions caused by the fact that some programs made the (wrong) assumption that /dev/dri/card0 would be the "main" display and just hard-coded that path. Shh! Don't tell anyone. But removing the conflicting framebuffers after calling devm_drm_dev_alloc() breaks this assumption, since the registered device will be /dev/dri/card1. All this is to say that doing it too late, even if nothing is touching the HW yet, could still have unexpected consequences across your graphics stack. -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/arm/hdlcd: Take over EFI framebuffer properly
On 6/15/22 09:53, Thomas Zimmermann wrote: > > > Am 15.06.22 um 09:50 schrieb Javier Martinez Canillas: > [...] >>> Historically, most drivers call this function very early. But for error >>> recovery it would be better to do it as late as possible. Ideally, >>> drivers would first initialize their DRM software state, then kickout >>> the generic driver, and finally take over hardware. But that would >>> require a careful review of each driver. :/ >>> >> >> We got bug reports on Fedora about regressions caused by the fact that some >> programs made the (wrong) assumption that /dev/dri/card0 would be the "main" >> display and just hard-coded that path. > > Shh! Don't tell anyone. > :) What I tried to say is that deciding where to kick out the firmware-provided framebuffer isn't trivial and would just land the patch as is. At some point we should probably agree on the best place and audit all the drivers to make sure that are doing it properly. -- Best regards, Javier Martinez Canillas Linux Engineering Red Hat
Re: [PATCH 02/64] drm/crtc: Introduce drmm_crtc_init_with_planes
On Wed, Jun 15, 2022 at 09:22:55AM +0200, Thomas Zimmermann wrote: > Hi > > Am 14.06.22 um 14:09 schrieb Maxime Ripard: > > On Tue, Jun 14, 2022 at 01:47:28PM +0200, Thomas Zimmermann wrote: > > > Am 14.06.22 um 11:04 schrieb Maxime Ripard: > > > > On Tue, Jun 14, 2022 at 10:29:20AM +0200, Thomas Zimmermann wrote: > > > > > Am 14.06.22 um 09:37 schrieb Maxime Ripard: > > > > > > Hi Thomas, > > > > > > > > > > > > On Mon, Jun 13, 2022 at 01:23:54PM +0200, Thomas Zimmermann wrote: > > > > > > > Am 10.06.22 um 11:28 schrieb Maxime Ripard: > > > > > > > > The DRM-managed function to register a CRTC is > > > > > > > > drmm_crtc_alloc_with_planes(), which will allocate the > > > > > > > > underlying > > > > > > > > structure and initialisation the CRTC. > > > > > > > > > > > > > > > > However, we might want to separate the structure creation and > > > > > > > > the CRTC > > > > > > > > initialisation, for example if the structure is shared across > > > > > > > > multiple > > > > > > > > DRM entities, for example an encoder and a connector. > > > > > > > > > > > > > > > > Let's create an helper to only initialise a CRTC that would be > > > > > > > > passed as > > > > > > > > an argument. > > > > > > > > > > > > > > Before I review all of thes patches, one question. it's yet not > > > > > > > clear to me > > > > > > > why drm_crtc_init_with_planes() wouldn't work. (I know we > > > > > > > discussed this on > > > > > > > IRC.) > > > > > > > > > > > > > > If you're calling drmm_mode_config_init(), it will clean up all > > > > > > > the CRTC, > > > > > > > encoder connector, etc. data structures for you. For CRTC > > > > > > > instances in > > > > > > > kmalloced memory, wouldn't it be simpler to put the corresponding > > > > > > > kfree into > > > > > > > vc4_crtc_destroy()? > > > > > > > > > > > > My intent was to remove as much of the lifetime handling and > > > > > > memory-management from drivers as possible. > > > > > > > > > > > > My feeling is that while the solution you suggest would definitely > > > > > > work, > > > > > > it relies on drivers authors to know about this, and make the > > > > > > effort to > > > > > > convert the drivers themselves. And then we would have to review > > > > > > that, > > > > > > which we will probably miss (collectively), because it's a bit > > > > > > obscure. > > > > > > > > > > > > While with either the drmm_alloc_* functions, or the new functions I > > > > > > introduce there, we can just deprecate the old ones, create a TODO > > > > > > entry > > > > > > and a coccinelle script and trust that it works properly. > > > > > > > > > > Thanks for explaining the motivation. > > > > > > > > > > I would not want to deprecate any of the existing functions, as they > > > > > work > > > > > for many drivers. The drmm_ functions add additional overhead that not > > > > > everyone is willing to pay. > > > > > > > > I'm a bit confused. drm_crtc_init_with_planes() at the moment has: > > > > > > > > * Note: consider using drmm_crtc_alloc_with_planes() instead of > > > > * drm_crtc_init_with_planes() to let the DRM managed resource > > > > infrastructure > > > > * take care of cleanup and deallocation. > > > > > > > > Just like drm_encoder_init(), drm_simple_encoder_init() and > > > > drm_universal_plane_init(), so all the functions we have a drmm_* helper > > > > for. > > > > > > > > And we have a TODO-list item that heavily hints at using them: > > > > https://dri.freedesktop.org/docs/drm/gpu/todo.html#object-lifetime-fixes > > > > > > > > So it looks like we're already well on the deprecation path? > > > > > > AFAIU that TODO item is about replacing devm_kzalloc() with > > > drmm_kzalloc(). > > > It's not about the plain init functions, such as > > > drm_crtc_init_with_planes() > > > or drm_universal_plane_init(). Many simple drivers allocate their > > > modesetting pipeline's components first and then build the pipeline with > > > the > > > drm_ functions. I don't think we can take that away from them. > > > > Sure, that's exactly what those first patches are about? It allows to > > use a DRM managed initialization without disrupting the drivers > > structure too much? > > > > > The concern I have is that we're adding lots of helpers for all kind of > > > scenarios and end up with a lot of duplication (and fragmentation among > > > drivers). > > > > I can see two: whether you want to allocate / init, or just init? > > We're not going to have more than that. > > > > > For example, drmm_crtc_alloc_with_planes() really isn't much used > > > by anything. [1] > > > > Not that I disagree here, but it might be that it isn't the most helpful > > helper? > > > > In vc4 case, we just can't use it easily. > > > > Our CRTC driver is shared between the "regular" CRTCs in the display > > path, and another instance dedicated to the writeback connector. > > > > The shared stuff is initialized through vc4_crtc_init(): > > https://elixir.bootlin.com/linux/la
Re: [PATCH v2 6/7] drm/bridge: anx7625: Register Type-C mode switches
Il 14/06/22 18:57, Prashant Malani ha scritto: On Tue, Jun 14, 2022 at 1:18 AM AngeloGioacchino Del Regno wrote: Il 09/06/22 20:09, Prashant Malani ha scritto: When the DT node has "switches" available, register a Type-C mode-switch for each listed "switch". This allows the driver to receive state information about what operating mode a Type-C port and its connected peripherals are in, as well as status information (like VDOs) related to that state. The callback function is currently a stub, but subsequent patches will implement the required functionality. Signed-off-by: Prashant Malani --- Changes since v2: - No changes. drivers/gpu/drm/bridge/analogix/anx7625.c | 73 +++ drivers/gpu/drm/bridge/analogix/anx7625.h | 6 ++ 2 files changed, 79 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 07ed44c6b839..d41a21103bd3 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -2581,9 +2582,59 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static int anx7625_typec_mux_set(struct typec_mux_dev *mux, + struct typec_mux_state *state) +{ + return 0; +} + +static int anx7625_register_mode_switch(struct device *dev, struct device_node *node, + struct anx7625_data *ctx) +{ + struct anx7625_port_data *port_data; + struct typec_mux_desc mux_desc = {}; + char name[32]; + u32 port_num; + int ret; + + ret = of_property_read_u32(node, "reg", &port_num); + if (ret) + return ret; + + if (port_num >= ctx->num_typec_switches) { + dev_err(dev, "Invalid port number specified: %d\n", port_num); + return -EINVAL; + } + + port_data = &ctx->typec_ports[port_num]; + port_data->ctx = ctx; + mux_desc.fwnode = &node->fwnode; + mux_desc.drvdata = port_data; + snprintf(name, sizeof(name), "%s-%u", node->name, port_num); + mux_desc.name = name; + mux_desc.set = anx7625_typec_mux_set; + + port_data->typec_mux = typec_mux_register(dev, &mux_desc); + if (IS_ERR(port_data->typec_mux)) { + ret = PTR_ERR(port_data->typec_mux); + dev_err(dev, "Mode switch register for port %d failed: %d", port_num, ret); + } Please return 0 at the end of this function. if (IS_ERR()) { ..code.. return ret; } return 0; } May I ask why? We're not missing any return paths. I would rather we keep it as is (which has the valid return value). I know that you're not missing any return paths. That's only because the proposed one is a common pattern in the kernel and it's only for consistency. Regards, Angelo
Re: [PATCH v2 1/3] drm/msm/dpu: Move LM CRC code into separate method
On Wed, 15 Jun 2022 at 00:13, Jessica Zhang wrote: > > Move layer mixer-specific section of dpu_crtc_get_crc() into a separate > helper method. This way, we can make it easier to get CRCs from other HW > blocks by adding other get_crc helper methods. > > Changes since V1: > - Moved common bitmasks to dpu_hw_util.h > - Moved common CRC methods to dpu_hw_util.c > - Updated copyrights > - Changed crcs array to a dynamically allocated array and added it as a > member of crtc_state > > Signed-off-by: Jessica Zhang Please split this into separate patches. One for hw_util, one for the rest > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 88 + > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 4 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 42 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 46 ++- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 16 > 5 files changed, 124 insertions(+), 72 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > index b56f777dbd0e..16742a66878e 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > @@ -1,5 +1,6 @@ > // SPDX-License-Identifier: GPL-2.0-only > /* > + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. > * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. > * Copyright (C) 2013 Red Hat > * Author: Rob Clark > @@ -88,6 +89,11 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc > *crtc, > enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); > struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); > > + if (crtc_state->crcs) { > + kfree(crtc_state->crcs); > + crtc_state->crcs = NULL; > + } > + > if (source < 0) { > DRM_DEBUG_DRIVER("Invalid source %s for CRTC%d\n", src_name, > crtc->index); > return -EINVAL; > @@ -96,20 +102,37 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc > *crtc, > if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) > *values_cnt = crtc_state->num_mixers; > > + crtc_state->crcs = kcalloc(*values_cnt, sizeof(crtc_state->crcs), > GFP_KERNEL); > + I do not quite like the idea of constantly allocating and freeing the crcs array. I'd suggest defining sensible MAX_CRC_VALUES, using a static array and verifying that no one over commits the MAX_CRC_VALUES. If at some point we decide that we really need the dynamic array, we can implement it later. We already had dynamic arrays and Rob had to fix it. See 00326bfa4e63 ("drm/msm/dpu: Remove dynamic allocation from atomic context"). > return 0; > } > > +static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) > +{ > + struct dpu_crtc_mixer *m; > + int i; > + > + for (i = 0; i < crtc_state->num_mixers; ++i) { > + m = &crtc_state->mixers[i]; > + > + if (!m->hw_lm || !m->hw_lm->ops.setup_misr) > + continue; > + > + /* Calculate MISR over 1 frame */ > + m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); > + } > +} > + > static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char > *src_name) > { > enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); > enum dpu_crtc_crc_source current_source; > struct dpu_crtc_state *crtc_state; > struct drm_device *drm_dev = crtc->dev; > - struct dpu_crtc_mixer *m; > > bool was_enabled; > bool enable = false; > - int i, ret = 0; > + int ret = 0; > > if (source < 0) { > DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", > src_name, crtc->index); > @@ -137,6 +160,10 @@ static int dpu_crtc_set_crc_source(struct drm_crtc > *crtc, const char *src_name) > goto cleanup; > > } else if (was_enabled && !enable) { > + if (crtc_state->crcs) { > + kfree(crtc_state->crcs); > + crtc_state->crcs = NULL; > + } > drm_crtc_vblank_put(crtc); > } > > @@ -146,16 +173,8 @@ static int dpu_crtc_set_crc_source(struct drm_crtc > *crtc, const char *src_name) > > crtc_state->crc_frame_skip_count = 0; > > - for (i = 0; i < crtc_state->num_mixers; ++i) { > - m = &crtc_state->mixers[i]; > - > - if (!m->hw_lm || !m->hw_lm->ops.setup_misr) > - continue; > - > - /* Calculate MISR over 1 frame */ > - m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); > - } > - > + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) > + dpu_crtc_setup_lm_misr(crtc_state); else ? > > cleanup: > drm_modeset_unlock(&crtc->mutex); > @@ -174,34 +193,21 @@ static u32 dpu
Re: [PATCH v2 2/3] drm/msm/dpu: Add MISR register support for interface
On Wed, 15 Jun 2022 at 00:13, Jessica Zhang wrote: > > Add support for setting MISR registers within the interface > > Changes since V1: > - Replaced dpu_hw_intf collect_misr and setup_misr implementations with > calls to dpu_hw_utils helper methods > > Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 19 ++- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 8 +++- > 2 files changed, 25 insertions(+), 2 deletions(-) > > 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 3f4d2c6e1b45..0157613224fd 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > @@ -1,5 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0-only > -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. > +/* > + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. > + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. > */ > > #include "dpu_hwio.h" > @@ -67,6 +69,9 @@ > #define INTF_CFG2_DATABUS_WIDENBIT(0) > #define INTF_CFG2_DATA_HCTL_EN BIT(4) > > +#define INTF_MISR_CTRL 0x180 > +#define INTF_MISR_SIGNATURE0x184 > + > static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, > const struct dpu_mdss_cfg *m, > void __iomem *addr, > @@ -319,6 +324,16 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf > *intf) > return DPU_REG_READ(c, INTF_LINE_COUNT); > } > > +static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, > u32 frame_count) > +{ > + dpu_hw_setup_misr(&intf->hw, enable, frame_count, INTF_MISR_CTRL); > +} > + > +static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 > *misr_value) > +{ > + return dpu_hw_collect_misr(&intf->hw, misr_value, INTF_MISR_CTRL, > INTF_MISR_SIGNATURE); > +} > + > static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, > unsigned long cap) > { > @@ -329,6 +344,8 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, > ops->get_line_count = dpu_hw_intf_get_line_count; > if (cap & BIT(DPU_INTF_INPUT_CTRL)) > ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; > + ops->setup_misr = dpu_hw_intf_setup_misr; > + ops->collect_misr = dpu_hw_intf_collect_misr; > } > > struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > index 7b2d96ac61e8..8d0e7b509260 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > @@ -1,5 +1,7 @@ > /* SPDX-License-Identifier: GPL-2.0-only */ > -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. > +/* > + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. > + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. > */ > > #ifndef _DPU_HW_INTF_H > @@ -57,6 +59,8 @@ struct intf_status { > * @ get_line_count: reads current vertical line counter > * @bind_pingpong_blk: enable/disable the connection with pingpong which will > * feed pixels to this interface > + * @setup_misr: enable/disable MISR > + * @collect_misr: read MISR signature > */ > struct dpu_hw_intf_ops { > void (*setup_timing_gen)(struct dpu_hw_intf *intf, > @@ -77,6 +81,8 @@ struct dpu_hw_intf_ops { > void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, > bool enable, > const enum dpu_pingpong pp); > + void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 > frame_count); > + int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); > }; > > struct dpu_hw_intf { > -- > 2.35.1 > -- With best wishes Dmitry
[Bug 216092] rn_vbios_smu_send_msg_with_param+0xf9/0x100 - amdgpu
https://bugzilla.kernel.org/show_bug.cgi?id=216092 RockT (tr...@gmx.de) changed: What|Removed |Added CC||tr...@gmx.de --- Comment #1 from RockT (tr...@gmx.de) --- I see exactly the same with Manjaro testing kernel 5.19.0-rc1. [7.843798] amdgpu :06:00.0: amdgpu: RAS: optional ras ta ucode is not available [7.852927] amdgpu :06:00.0: amdgpu: RAP: optional rap ta ucode is not available [7.852928] amdgpu :06:00.0: amdgpu: SECUREDISPLAY: securedisplay ta ucode is not available [7.853513] amdgpu :06:00.0: amdgpu: SMU is initialized successfully! [7.853691] [ cut here ] [7.853692] WARNING: CPU: 0 PID: 432 at drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c:98 rn_vbios_smu_send_msg_with_param+0xf1/0x100 [amdgpu] [7.853897] Modules linked in: amd64_edac(-) pcc_cpufreq(-) fjes(+) snd_usb_audio(+) mhi_wwan_ctrl mhi_wwan_mbim snd_usbmidi_lib snd_rawmidi snd_seq_device bnep squashfs loop btusb btrtl qrtr btbcm uvcvideo btintel btmtk videobuf2_vmalloc videobuf2_memops intel_rapl_msr snd_acp3x_rn snd_soc_dmic bluetooth videobuf2_v4l2 videobuf2_common videodev snd_acp3x_pdm_dma vfat ecdh_generic hid_multitouch iwlmvm snd_sof_amd_renoir think_lmi(+) crc16 mc fat snd_ctl_led snd_hda_codec_realtek firmware_attributes_class snd_sof_amd_acp wmi_bmof intel_rapl_common amdgpu(+) snd_sof_pci mac80211 snd_hda_codec_generic snd_hda_codec_hdmi snd_sof snd_hda_intel snd_intel_dspcfg snd_sof_utils snd_intel_sdw_acpi snd_soc_core libarc4 edac_mce_amd snd_hda_codec snd_compress iwlwifi ac97_bus gpu_sched kvm_amd snd_hda_core snd_pcm_dmaengine drm_buddy snd_acp_pci drm_ttm_helper iwlmei snd_pci_acp6x thinkpad_acpi ttm snd_pci_acp5x snd_hwdep ledtrig_audio r8169 cfg80211 kvm snd_pcm snd_rn_pci_acp3x ucsi_acpi [7.853926] platform_profile snd_timer snd_acp_config realtek drm_display_helper snd typec_ucsi irqbypass rfkill mhi_pci_generic mdio_devres sp5100_tco snd_soc_acpi tpm_crb snd_pci_acp3x cec soundcore rapl psmouse mei libphy typec mhi i2c_piix4 k10temp roles i2c_hid_acpi tpm_tis i2c_hid video wmi tpm_tis_core amd_pmc acpi_cpufreq pinctrl_amd joydev mousedev mac_hid uinput ipmi_devintf ipmi_msghandler fuse crypto_user bpf_preload ip_tables x_tables hid_logitech_hidpp xfs libcrc32c crc32c_generic hid_logitech_dj hid_jabra usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm dm_mod serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul vivaldi_fmap crc32c_intel ghash_clmulni_intel aesni_intel nvme crypto_simd ccp xhci_pci cryptd i8042 nvme_core rng_core xhci_pci_renesas serio [7.853954] CPU: 0 PID: 432 Comm: systemd-udevd Not tainted 5.19.0-1-MANJARO #1 12b6001e0e27e2c5de0e86e6e0c9807155e77ed6 [7.853957] Hardware name: LENOVO 20XF006GGE/20XF006GGE, BIOS R1NET50W (1.20) 04/14/2022 [7.853958] RIP: 0010:rn_vbios_smu_send_msg_with_param+0xf1/0x100 [amdgpu] [7.854144] Code: f8 01 75 1b 48 8b 7d 00 5b be 93 62 01 00 48 c7 c2 a0 9f 6c c1 5d 41 5c 41 5d e9 3a ed f4 ff 3d fe 00 00 00 74 de 0f 0b eb da <0f> 0b e9 58 ff ff ff 0f 1f 84 00 00 00 00 00 66 0f 1f 00 0f 1f 44 [7.854146] RSP: 0018:9ae4030076f0 EFLAGS: 00010202 [7.854148] RAX: 00fe RBX: 00030d41 RCX: c1938118 [7.854149] RDX: RSI: 0001629b RDI: 8be18440 [7.854150] RBP: 8be186cdf800 R08: 8be1a1086800 R09: 0cb1 [7.854151] R10: 001e R11: 0036ee80 R12: 000d [7.854152] R13: 0001 R14: 018f R15: 8be186cdf800 [7.854153] FS: 7f8967b45080() GS:8be84ee0() knlGS: [7.854154] CS: 0010 DS: ES: CR0: 80050033 [7.854154] CR2: 5636d87b17c8 CR3: 000105fde000 CR4: 00750ef0 [7.854155] PKRU: 5554 [7.854156] Call Trace: [7.854158] [7.854160] rn_clk_mgr_construct+0x151/0x620 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.854316] dc_clk_mgr_create+0x42c/0x5d0 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.854464] dc_create+0x23c/0x5b0 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.854620] amdgpu_dm_init.isra.0+0x22d/0x350 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.854775] ? dev_vprintk_emit+0x177/0x19c [7.854781] dm_hw_init+0x12/0x20 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.854927] amdgpu_device_init.cold+0x17b4/0x1d57 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.855089] amdgpu_driver_load_kms+0x19/0x130 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.855214] amdgpu_pci_probe+0x148/0x360 [amdgpu a6a2d017171775457fc880c1e7e3ceb4f3d662e5] [7.855335] local_pci_probe+0x42/0x80 [7.855339] pci_device_probe+0xc1/0x220 [7.855341] ? sysfs_do_create_link_sd+0x6a/0xd
Re: [PATCH v2 3/3] drm/msm/dpu: Add interface support for CRC debugfs
On Wed, 15 Jun 2022 at 00:13, Jessica Zhang wrote: > > Add support for writing CRC values for the interface block to > the debugfs by calling the necessary MISR setup/collect methods. > > Changes since V1: > - Set values_cnt to only include phys with backing hw_intf > - Loop over all drm_encs connected to crtc > > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 49 ++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 3 + > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 64 + > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 +++ > 4 files changed, 134 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > index 16742a66878e..8c9933b2337f 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > @@ -79,6 +79,8 @@ static enum dpu_crtc_crc_source > dpu_crtc_parse_crc_source(const char *src_name) > if (!strcmp(src_name, "auto") || > !strcmp(src_name, "lm")) > return DPU_CRTC_CRC_SOURCE_LAYER_MIXER; > + if (!strcmp(src_name, "intf")) > + return DPU_CRTC_CRC_SOURCE_INTF; What about "encoder" / DPU_CRTC_CRC_SOURCE_ENCODER? You basically offload CRC generation/collection to the dpu_encoder, so I'd ignore the fact that only INTF's support MISR generation and use a more generic word here. > > return DPU_CRTC_CRC_SOURCE_INVALID; > } > @@ -99,8 +101,14 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc > *crtc, > return -EINVAL; > } > > - if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) > + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) { > *values_cnt = crtc_state->num_mixers; > + } else if (source == DPU_CRTC_CRC_SOURCE_INTF) { > + struct drm_encoder *drm_enc; Zero values_cnt here. > + > + drm_for_each_encoder_mask(drm_enc, crtc->dev, > crtc->state->encoder_mask) > + *values_cnt += dpu_encoder_get_num_phys(drm_enc); > + } > > crtc_state->crcs = kcalloc(*values_cnt, sizeof(crtc_state->crcs), > GFP_KERNEL); > > @@ -123,6 +131,14 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state > *crtc_state) > } > } > > +static void dpu_crtc_setup_encoder_misr(struct drm_crtc *crtc) > +{ > + struct drm_encoder *drm_enc; > + > + drm_for_each_encoder_mask(drm_enc, crtc->dev, > crtc->state->encoder_mask) > + dpu_encoder_setup_misr(drm_enc); > +} > + > static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char > *src_name) > { > enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); > @@ -175,6 +191,8 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, > const char *src_name) > > if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) > dpu_crtc_setup_lm_misr(crtc_state); > + else if (source == DPU_CRTC_CRC_SOURCE_INTF) > + dpu_crtc_setup_encoder_misr(crtc); else? > > cleanup: > drm_modeset_unlock(&crtc->mutex); > @@ -220,11 +238,31 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, > struct dpu_crtc_state *crt > drm_crtc_accurate_vblank_count(crtc), > crtc_state->crcs); > } > > -static int dpu_crtc_get_crc(struct drm_crtc *crtc) > +static int dpu_crtc_get_encoder_crc(struct drm_crtc *crtc) > { > - struct dpu_crtc_state *crtc_state; > + struct drm_encoder *drm_enc; > + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); > + int rc, pos = 0; > > - crtc_state = to_dpu_crtc_state(crtc->state); > + drm_for_each_encoder_mask(drm_enc, crtc->dev, > crtc->state->encoder_mask) { > + rc = dpu_encoder_get_crc(drm_enc, crtc_state->crcs, pos); > + if (rc < 0) { > + if (rc != -ENODATA) > + DRM_DEBUG_DRIVER("MISR read failed\n"); > + > + return rc; > + } > + > + pos += rc; > + } > + > + return drm_crtc_add_crc_entry(crtc, true, > + drm_crtc_accurate_vblank_count(crtc), > crtc_state->crcs); > +} > + > +static int dpu_crtc_get_crc(struct drm_crtc *crtc) > +{ > + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); Unnecessary change here. Please move it to the patch 1, which refactors this function. > > /* Skip first 2 frames in case of "uncooked" CRCs */ > if (crtc_state->crc_frame_skip_count < 2) { > @@ -235,6 +273,9 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) > if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) > return dpu_crtc_get_lm_crc(crtc, crtc_state); > > + if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_INTF) > + return dpu_crtc_get_encoder_crc(crtc); > + >
Re: [Intel-gfx] [RFC v3 3/3] drm/doc/rfc: VM_BIND uapi definition
On 08/06/2022 21:45, Niranjana Vishwanathapura wrote: On Wed, Jun 08, 2022 at 09:54:24AM +0100, Tvrtko Ursulin wrote: On 08/06/2022 09:45, Lionel Landwerlin wrote: On 08/06/2022 11:36, Tvrtko Ursulin wrote: On 08/06/2022 07:40, Lionel Landwerlin wrote: On 03/06/2022 09:53, Niranjana Vishwanathapura wrote: On Wed, Jun 01, 2022 at 10:08:35PM -0700, Niranjana Vishwanathapura wrote: On Wed, Jun 01, 2022 at 11:27:17AM +0200, Daniel Vetter wrote: On Wed, 1 Jun 2022 at 11:03, Dave Airlie wrote: On Tue, 24 May 2022 at 05:20, Niranjana Vishwanathapura wrote: On Thu, May 19, 2022 at 04:07:30PM -0700, Zanoni, Paulo R wrote: On Tue, 2022-05-17 at 11:32 -0700, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions v2: Ensure proper kernel-doc formatting with cross references. Also add new uapi and documentation as per review comments from Daniel. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 399 +++ 1 file changed, 399 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..589c0a009107 --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,399 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * A VM in VM_BIND mode will not support the older execbuff mode of binding. + * In VM_BIND mode, execbuff ioctl will not accept any execlist (ie., the + * &drm_i915_gem_execbuffer2.buffer_count must be 0). + * Also, &drm_i915_gem_execbuffer2.batch_start_offset and + * &drm_i915_gem_execbuffer2.batch_len must be 0. + * DRM_I915_GEM_EXECBUFFER_EXT_BATCH_ADDRESSES extension must be provided + * to pass in the batch buffer addresses. + * + * Additionally, I915_EXEC_NO_RELOC, I915_EXEC_HANDLE_LUT and + * I915_EXEC_BATCH_FIRST of &drm_i915_gem_execbuffer2.flags must be 0 + * (not used) in VM_BIND mode. I915_EXEC_USE_EXTENSIONS flag must always be + * set (See struct drm_i915_gem_execbuffer_ext_batch_addresses). + * The buffers_ptr, buffer_count, batch_start_offset and batch_len fields + * of struct drm_i915_gem_execbuffer2 are also not used and must be 0. + */ From that description, it seems we have: struct drm_i915_gem_execbuffer2 { __u64 buffers_ptr; -> must be 0 (new) __u32 buffer_count; -> must be 0 (new) __u32 batch_start_offset; -> must be 0 (new) __u32 batch_len; -> must be 0 (new) __u32 DR1; -> must be 0 (old) __u32 DR4; -> must be 0 (old) __u32 num_cliprects; (fences) -> must be 0 since using extensions __u64 cliprects_ptr; (fences, extensions) -> contains an actual pointer! __u64 flags; -> some flags must be 0 (new) __u64 rsvd1; (context info) -> repurposed field (old) __u64 rsvd2; -> unused }; Based on that, why can't we just get drm_i915_gem_execbuffer3 instead of adding even more complexity to an already abused interface? While the Vulkan-like extension thing is really nice, I don't think what we're doing here is extending the ioctl usage, we're completely changing how the base struct should be interpreted based on how the VM was created (which is an entirely different ioctl). From Rusty Russel's API Design grading, drm_i915_gem_execbuffer2 is already at -6 without these changes. I think after vm_bind we'll need to create a -11 entry just to deal with this ioctl. The only change here is removing the execlist support for VM_BIND mode (other than natual extensions). Adding a new execbuffer3 was considered, but I think we need to be careful with that as that goes beyond the VM_BIND support, including any future requirements (as we don't want an execbuffer4 after VM_BIND). Why not? it's not like adding extensions here is really that different than adding new ioctls. I definitely think this deserves an execbuffer3 without even considering future requirements. Just to burn down the old requirements and pointless fields. Make execbuffer3 be vm bind only, no relocs, no legacy bits, leave the older sw on execbuf2 for ever. I guess another point in favour of execbuf3 would be that it's less midlayer. If we share the entry point then there's quite a few vfuncs needed to cleanly split out the vm_bind paths from the legacy reloc/softping paths. If we invert this and do execbuf3, then there's the existing ioctl
Re: [PATCH] drm/arm/hdlcd: Take over EFI framebuffer properly
On Wed, Jun 15, 2022 at 10:00:52AM +0200, Javier Martinez Canillas wrote: > On 6/15/22 09:53, Thomas Zimmermann wrote: > > > > > > Am 15.06.22 um 09:50 schrieb Javier Martinez Canillas: > > [...] > >>> Historically, most drivers call this function very early. But for error > >>> recovery it would be better to do it as late as possible. Ideally, > >>> drivers would first initialize their DRM software state, then kickout > >>> the generic driver, and finally take over hardware. But that would > >>> require a careful review of each driver. :/ > >>> > >> > >> We got bug reports on Fedora about regressions caused by the fact that some > >> programs made the (wrong) assumption that /dev/dri/card0 would be the > >> "main" > >> display and just hard-coded that path. > > > > Shh! Don't tell anyone. > > > > :) > > What I tried to say is that deciding where to kick out the firmware-provided > framebuffer isn't trivial and would just land the patch as is. At some point > we should probably agree on the best place and audit all the drivers to make > sure that are doing it properly. I agree, we should review v2 with the updated API and land the patch if it is reasonable. Due to my "cleverness" HDLCD and mali-dp are probably the only drivers that also use the component framework that adds extra complications in terms of silently not having all dependencies met (you forgot to compile the I2C driver or you didn't load it as a module), so taking over the efifb framebuffer late is a good idea. Best regards, Liviu > > -- > Best regards, > > Javier Martinez Canillas > Linux Engineering > Red Hat > -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯
Re: [PATCH 2/2] arm64: dts: qcom: sm8250: Enable per-process page tables.
On Wed, 15 Jun 2022 at 02:01, Emma Anholt wrote: > > This is an SMMU for the adreno gpu, and adding this compatible lets > the driver use per-fd page tables, which are required for security > between GPU clients. > > Signed-off-by: Emma Anholt > --- > > Tested with a full deqp-vk run on RB5, which did involve some iommu faults. > > arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi > b/arch/arm64/boot/dts/qcom/sm8250.dtsi > index a92230bec1dd..483c0e0f1d1a 100644 > --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi > +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi > @@ -2513,7 +2513,7 @@ gpucc: clock-controller@3d9 { > }; > > adreno_smmu: iommu@3da { > - compatible = "qcom,sm8250-smmu-500", "arm,mmu-500"; > + compatible = "qcom,sm8250-smmu-500", "arm,mmu-500", > "qcom,adreno-smmu"; I see that other dtsi files use a bit different order for the compatibility strings. They put "qcom,adreno-smmu" before "arm,mmu-500". Can we please follow them? With that fixed: Reviewed-by: Dmitry Baryshkov > reg = <0 0x03da 0 0x1>; > #iommu-cells = <2>; > #global-interrupts = <2>; > -- > 2.36.1 > -- With best wishes Dmitry
Re: [PATCH 02/64] drm/crtc: Introduce drmm_crtc_init_with_planes
Hi Am 15.06.22 um 10:32 schrieb Maxime Ripard: [...] See, helpers should be useful to many drivers. If we add them, we also add a resources and maintenance overhead to our libraries. And right now, these new functions appear to work around the design of the vc4 driver's data structures. If you want to keep them, maybe let's first merge them into vc4 (something like vc4_crtc_init_with_planes(), etc). If another driver with a use case comes along, we can still move them out easily. Not that I disagree, but there's also the fact that people will start using helpers because they are available. You mentioned drmm_crtc_alloc_with_planes(). It was introduced in 5.12 with a single user (ipuv3-crtc.c). And then, because it was available, in 5.17 was merged the Unisoc driver that was the second user of that function. OTOH, it actually took 5 releases to find another user. Maybe we need to look harder for possible reuse of helpers, but I wouldn't count 5 releases as a good track record. drmm_simple_encoder_alloc() and drmm_universal_plane_alloc() are in the same situation and we wouldn't have had that discussion if it was kept in the imx driver. The helper being there allows driver authors to discover them easily, pointing out an issue that possibly wasn't obvious to the author, and we can also point during review that the helpers are there to be used. None of that would be possible if we were to keep them in a driver, because no one but the author would know about it. My feeling is that the rule you mention works great when you know that some deviation is going to happen. But we're replacing an init function that has been proved good enough here, so it's not rocket science really. drmm_mutex_init() is a great example of that actually. You merged it recently with two users. We could have used the exact same argument that it belonged in those drivers because it wasn't generic enough or something. But it's trivial, so it was a good decision to merge it as a helper. And because you did so, I later found out that mutex_destroy() was supposed to be called in the first place, I converted vc4 to drmm_mutex_init(), and now that bug is fixed. But when I added it, there actually were two users. I would not have added drmm_mutex_init() if it was only useful for a single driver. In other cases, we tend to push single-user helpers into the drivers. That happened several times with TTM. Code was moved into vmwgfx, because there where no other users. Anyway, as you insist on using this helper, go for it. But please, at least reimplement drm_crtc_alloc_with_planes() on top of a shared internal implementation. AFAICT drm_crtc_alloc_with_planes() is drmm_kzalloc + drmm_crtc_init_with_planes(). Same for other related helpers in the other patches, if there are any. Best regards Thomas It wouldn't have been the case if you kept it inside the drivers. Maxime -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH 1/2] iommu: arm-smmu-impl: Add 8250 display compatible to the client list.
On Wed, 15 Jun 2022 at 02:01, Emma Anholt wrote: > > Required for turning on per-process page tables for the GPU. > > Signed-off-by: Emma Anholt Reviewed-by: Dmitry Baryshkov > --- > > drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > index d8e1ef83c01b..bb9220937068 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > @@ -233,6 +233,7 @@ static const struct of_device_id > qcom_smmu_client_of_match[] __maybe_unused = { > { .compatible = "qcom,sc7280-mdss" }, > { .compatible = "qcom,sc7280-mss-pil" }, > { .compatible = "qcom,sc8180x-mdss" }, > + { .compatible = "qcom,sm8250-mdss" }, > { .compatible = "qcom,sdm845-mdss" }, > { .compatible = "qcom,sdm845-mss-pil" }, > { } > -- > 2.36.1 > -- With best wishes Dmitry
Re: [PATCH] drivers: tty: serial: Add missing of_node_put() in serial-tegra.c
On Wed, Jun 15, 2022 at 06:48:33PM +0800, heliang wrote: > In tegra_uart_init(), of_find_matching_node() will return a node > pointer with refcount incremented. We should use of_node_put() > when it is not used anymore. > > Signed-off-by: heliang We need a real name please, one you sign documents with. thanks, greg k-h
Re: [PATCH v4 3/4] drm/panel: atna33xc20: Take advantage of wait_hpd_asserted() in struct drm_dp_aux
On Wed, 15 Jun 2022 at 00:54, Douglas Anderson wrote: > > Let's add support for being able to read the HPD pin even if it's > hooked directly to the controller. This will let us take away the > waiting in the AUX transfer functions of the eDP controller drivers. > > Signed-off-by: Douglas Anderson Reviewed-by: Dmitry Baryshkov > --- > > Changes in v4: > - Reorganized logic as per Dmitry's suggestion. > > Changes in v3: > - Don't check "hpd_asserted" boolean when unset. > - Handle errors from gpiod_get_value_cansleep() properly. > > Changes in v2: > - Change is_hpd_asserted() to wait_hpd_asserted() > > .../gpu/drm/panel/panel-samsung-atna33xc20.c | 51 ++- > 1 file changed, 38 insertions(+), 13 deletions(-) > -- With best wishes Dmitry
Re: [PATCH v2 3/4] drm/msm/disp/dpu1: use atomic enable/disable callbacks for encoder functions
On 21/02/2022 17:51, Vinod Polimera wrote: Use atomic variants for encoder callback functions such that certain states like self-refresh can be accessed as part of enable/disable sequence. Signed-off-by: Kalyan Thota Signed-off-by: Vinod Polimera Changes in v2: - As per review suggestion by Dmitry. --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1e648db..6eac417 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1138,7 +1138,8 @@ void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc) mutex_unlock(&dpu_enc->enc_lock); } -static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) +static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc, + struct drm_atomic_state *state) { struct dpu_encoder_virt *dpu_enc = NULL; int ret = 0; @@ -1176,7 +1177,8 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) mutex_unlock(&dpu_enc->enc_lock); } -static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) +static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc, + struct drm_atomic_state *state) { struct dpu_encoder_virt *dpu_enc = NULL; struct msm_drm_private *priv; @@ -2094,8 +2096,8 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { .mode_set = dpu_encoder_virt_mode_set, - .disable = dpu_encoder_virt_disable, - .enable = dpu_encoder_virt_enable, + .atomic_disable = dpu_encoder_virt_disable, + .atomic_enable = dpu_encoder_virt_enable, A small nit before you post the next iteration of PSR: Please rename these functions to follow atomic_enable/atomic_disable names. .atomic_check = dpu_encoder_virt_atomic_check, }; -- With best wishes Dmitry
[PATCH] drm/msm/dp: make dp_bridge_mode_valid() more precise
Make dp_connector_mode_valid() return precise MODE_CLOCK_HIGH rather than generic MODE_BAD in case the mode clock is higher than DP_MAX_PIXEL_CLK_KHZ (675 MHz). Reviewed-by: Kuogee Hsieh Reviewed-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index bce77935394f..6ecdd81d0555 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -989,7 +989,7 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; if (mode->clock > DP_MAX_PIXEL_CLK_KHZ) - return MODE_BAD; + return MODE_CLOCK_HIGH; dp_display = container_of(dp, struct dp_display_private, dp_display); link_info = &dp_display->panel->link_info; -- 2.35.1
Re: [PATCH 1/3] drm/mipi-dsi: pass DSC data through the struct mipi_dsi_device
On 01/05/2022 18:12, Dmitry Baryshkov wrote: The commit 0f40ba48de3b ("drm/msm/dsi: Pass DSC params to drm_panel") added a pointer to the DSC data to the struct drm_panel. However DSC support is not limited to the DSI panels. MIPI DSI bridges can also consume DSC command streams. Thus add struct drm_dsc_config pointer to the struct mipi_dsi_device. Signed-off-by: Dmitry Baryshkov Gracious ping for the review from the drm core --- include/drm/drm_mipi_dsi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 147e51b6d241..8b1c9be9b2a7 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -177,6 +177,7 @@ struct mipi_dsi_device_info { * @lp_rate: maximum lane frequency for low power mode in hertz, this should * be set to the real limits of the hardware, zero is only accepted for * legacy drivers + * @dsc: panel/bridge DSC pps payload to be sent */ struct mipi_dsi_device { struct mipi_dsi_host *host; @@ -189,6 +190,7 @@ struct mipi_dsi_device { unsigned long mode_flags; unsigned long hs_rate; unsigned long lp_rate; + struct drm_dsc_config *dsc; }; #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:" -- With best wishes Dmitry
Re: [v2] drm/msm: add null checks for drm device to avoid crash during probe defer
On 03/06/2022 12:42, Vinod Polimera wrote: During probe defer, drm device is not initialized and an external trigger to shutdown is trying to clean up drm device leading to crash. Add checks to avoid drm device cleanup in such cases. BUG: unable to handle kernel NULL pointer dereference at virtual address 00b8 Call trace: drm_atomic_helper_shutdown+0x44/0x144 msm_pdev_shutdown+0x2c/0x38 platform_shutdown+0x2c/0x38 device_shutdown+0x158/0x210 kernel_restart_prepare+0x40/0x4c kernel_restart+0x20/0x6c __arm64_sys_reboot+0x194/0x23c invoke_syscall+0x50/0x13c el0_svc_common+0xa0/0x17c do_el0_svc_compat+0x28/0x34 el0_svc_compat+0x20/0x70 el0t_32_sync_handler+0xa8/0xcc el0t_32_sync+0x1a8/0x1ac Changes in v2: - Add fixes tag. Fixes: 623f279c778 ("drm/msm: fix shutdown hook in case GPU components failed to bind") Signed-off-by: Vinod Polimera Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_drv.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 4448536..d62ac66 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -142,6 +142,9 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; + if (!irq_has_action(kms->irq)) + return; + kms->funcs->irq_uninstall(kms); if (kms->irq_requested) free_irq(kms->irq, dev); @@ -259,6 +262,7 @@ static int msm_drm_uninit(struct device *dev) ddev->dev_private = NULL; drm_dev_put(ddev); + priv->dev = NULL; destroy_workqueue(priv->wq); @@ -1167,7 +1171,7 @@ void msm_drv_shutdown(struct platform_device *pdev) struct msm_drm_private *priv = platform_get_drvdata(pdev); struct drm_device *drm = priv ? priv->dev : NULL; - if (!priv || !priv->kms) + if (!priv || !priv->kms || !drm) return; drm_atomic_helper_shutdown(drm); -- With best wishes Dmitry
Re: [v2] drm/msm: add null checks for drm device to avoid crash during probe defer
On 03/06/2022 12:42, Vinod Polimera wrote: During probe defer, drm device is not initialized and an external trigger to shutdown is trying to clean up drm device leading to crash. Add checks to avoid drm device cleanup in such cases. BUG: unable to handle kernel NULL pointer dereference at virtual address 00b8 Call trace: drm_atomic_helper_shutdown+0x44/0x144 msm_pdev_shutdown+0x2c/0x38 platform_shutdown+0x2c/0x38 device_shutdown+0x158/0x210 kernel_restart_prepare+0x40/0x4c kernel_restart+0x20/0x6c __arm64_sys_reboot+0x194/0x23c invoke_syscall+0x50/0x13c el0_svc_common+0xa0/0x17c do_el0_svc_compat+0x28/0x34 el0_svc_compat+0x20/0x70 el0t_32_sync_handler+0xa8/0xcc el0t_32_sync+0x1a8/0x1ac Changes in v2: - Add fixes tag. Fixes: 623f279c778 ("drm/msm: fix shutdown hook in case GPU components failed to bind") Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/msm_drv.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 4448536..d62ac66 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -142,6 +142,9 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; + if (!irq_has_action(kms->irq)) + return; As a second thought I'd still prefer a variable here. irq_has_action would check that there is _any_ IRQ handler for this IRQ. While we do not have anybody sharing this IRQ, I'd prefer to be clear here, that we do not want to uninstall our IRQ handler rather than any IRQ handler. + kms->funcs->irq_uninstall(kms); if (kms->irq_requested) free_irq(kms->irq, dev); @@ -259,6 +262,7 @@ static int msm_drm_uninit(struct device *dev) ddev->dev_private = NULL; drm_dev_put(ddev); + priv->dev = NULL; destroy_workqueue(priv->wq); @@ -1167,7 +1171,7 @@ void msm_drv_shutdown(struct platform_device *pdev) struct msm_drm_private *priv = platform_get_drvdata(pdev); struct drm_device *drm = priv ? priv->dev : NULL; - if (!priv || !priv->kms) + if (!priv || !priv->kms || !drm) return; drm_atomic_helper_shutdown(drm); -- With best wishes Dmitry
Re: [PATCH] dt-bindings: msm: update maintainers list with proper id
On 03/06/2022 23:09, Kuogee Hsieh wrote: Use quic id instead of codeaurora id in maintainers list for display devicetree bindings. Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov We can pick it through the msm/ tree, if no one objects. --- Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index cd05cfd..c950710 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: MSM Display Port Controller maintainers: - - Kuogee Hsieh + - Kuogee Hsieh description: | Device tree bindings for DisplayPort host controller for MSM targets -- With best wishes Dmitry
Re: [PATCH] drm/msm/dsi: Use single function for reset
On 11/06/2022 01:02, Luca Weiss wrote: From: Vladimir Lypak There is currently two function for performing reset: dsi_sw_reset and dsi_sw_reset_restore. Only difference betwean those is that latter one assumes that DSI controller is enabled. In contrary former one assumes that controller is disabled and executed during power-on. However this assumtion is not true mobile devices which have boot splash set up by boot-loader. This patch removes dsi_sw_reset_restore and makes dsi_sw_reset disable DSI controller during reset sequence if it's enabled. Signed-off-by: Vladimir Lypak Signed-off-by: Luca Weiss Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 48 +- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index a95d5df52653..bab2634ebd11 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1080,12 +1080,32 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) static void dsi_sw_reset(struct msm_dsi_host *msm_host) { + u32 ctrl; + + ctrl = dsi_read(msm_host, REG_DSI_CTRL); + + if (ctrl & DSI_CTRL_ENABLE) { + dsi_write(msm_host, REG_DSI_CTRL, ctrl & ~DSI_CTRL_ENABLE); + /* +* dsi controller need to be disabled before +* clocks turned on +*/ + wmb(); + } + dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS); wmb(); /* clocks need to be enabled before reset */ + /* dsi controller can only be reset while clocks are running */ dsi_write(msm_host, REG_DSI_RESET, 1); msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); + wmb(); /* controller out of reset */ + + if (ctrl & DSI_CTRL_ENABLE) { + dsi_write(msm_host, REG_DSI_CTRL, ctrl); + wmb(); /* make sure dsi controller enabled again */ + } } static void dsi_op_mode_config(struct msm_dsi_host *msm_host, @@ -1478,32 +1498,6 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host, return len; } -static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) -{ - u32 data0, data1; - - data0 = dsi_read(msm_host, REG_DSI_CTRL); - data1 = data0; - data1 &= ~DSI_CTRL_ENABLE; - dsi_write(msm_host, REG_DSI_CTRL, data1); - /* -* dsi controller need to be disabled before -* clocks turned on -*/ - wmb(); - - dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS); - wmb(); /* make sure clocks enabled */ - - /* dsi controller can only be reset while clocks are running */ - dsi_write(msm_host, REG_DSI_RESET, 1); - msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ - dsi_write(msm_host, REG_DSI_RESET, 0); - wmb(); /* controller out of reset */ - dsi_write(msm_host, REG_DSI_CTRL, data0); - wmb(); /* make sure dsi controller enabled again */ -} - static void dsi_hpd_worker(struct work_struct *work) { struct msm_dsi_host *msm_host = @@ -1520,7 +1514,7 @@ static void dsi_err_worker(struct work_struct *work) pr_err_ratelimited("%s: status=%x\n", __func__, status); if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW) - dsi_sw_reset_restore(msm_host); + dsi_sw_reset(msm_host); /* It is safe to clear here because error irq is disabled. */ msm_host->err_work_state = 0; -- With best wishes Dmitry
[PATCH] drm/radeon: Replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi
Replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi for more efficiency Tested on "Oland [Radeon HD 8570 / R7 240/340 OEM]" & "Caicos [R5 230]" Signed-off-by: hongao --- drivers/gpu/drm/radeon/atombios_encoders.c | 6 +++--- drivers/gpu/drm/radeon/radeon_connectors.c | 12 ++-- drivers/gpu/drm/radeon/radeon_display.c| 2 +- drivers/gpu/drm/radeon/radeon_encoders.c | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 70bd84b7ef2b..393d471ba396 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -714,7 +714,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) if (radeon_connector->use_digital && (radeon_connector->audio == RADEON_AUDIO_ENABLE)) return ATOM_ENCODER_MODE_HDMI; - else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && + else if (connector->display_info.is_hdmi && (radeon_connector->audio == RADEON_AUDIO_AUTO)) return ATOM_ENCODER_MODE_HDMI; else if (radeon_connector->use_digital) @@ -733,7 +733,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) if (radeon_audio != 0) { if (radeon_connector->audio == RADEON_AUDIO_ENABLE) return ATOM_ENCODER_MODE_HDMI; - else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && + else if (connector->display_info.is_hdmi && (radeon_connector->audio == RADEON_AUDIO_AUTO)) return ATOM_ENCODER_MODE_HDMI; else @@ -757,7 +757,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) } else if (radeon_audio != 0) { if (radeon_connector->audio == RADEON_AUDIO_ENABLE) return ATOM_ENCODER_MODE_HDMI; - else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && + else if (connector->display_info.is_hdmi && (radeon_connector->audio == RADEON_AUDIO_AUTO)) return ATOM_ENCODER_MODE_HDMI; else diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 58db79921cd3..2fbec7bdd56b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -130,7 +130,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_HDMIB: if (radeon_connector->use_digital) { - if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { + if (connector->display_info.is_hdmi) { if (connector->display_info.bpc) bpc = connector->display_info.bpc; } @@ -138,7 +138,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) break; case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_HDMIA: - if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { + if (connector->display_info.is_hdmi) { if (connector->display_info.bpc) bpc = connector->display_info.bpc; } @@ -147,7 +147,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) dig_connector = radeon_connector->con_priv; if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || - drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { + connector->display_info.is_hdmi) { if (connector->display_info.bpc) bpc = connector->display_info.bpc; } @@ -171,7 +171,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) break; } - if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { + if (connector->display_info.is_hdmi) { /* hdmi deep color only implemented on DCE4+ */ if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) { DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 8 bpc.\n", @@ -1500,7 +1500,7 @@ static enum drm_mode_status radeon_dvi_mode_valid(struct drm_connector *connecto (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_D
Re: [PATCH 1/3] drm/msm/dpu: move intf and wb assignment to dpu_encoder_setup_display()
On 14/06/2022 22:32, Abhinav Kumar wrote: intf and wb resources are not dependent on the rm global state so need not be allocated during dpu_encoder_virt_atomic_mode_set(). Move the allocation of intf and wb resources to dpu_encoder_setup_display() so that we can utilize the hw caps even during atomic_check() phase. Since dpu_encoder_setup_display() already has protection against setting invalid intf_idx and wb_idx, these checks can now be dropped as well. Fixes: e02a559a720f ("make changes to dpu_encoder to support virtual encoder") Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..e991d4ba8a40 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1048,24 +1048,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "no intf or wb block assigned at idx: %d\n", i); - return; - } - - if (phys->hw_intf && phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "invalid phys both intf and wb block at idx: %d\n", i); - return; - } Please retain these checks in dpu_encoder_setup_display(). It checks that we really have got the intf or wb. For example one might have specified the INTF that leads to INTF_NONE interface. Or non-existing/not supported WB. - phys->cached_mode = crtc_state->adjusted_mode; if (phys->ops.atomic_mode_set) phys->ops.atomic_mode_set(phys, crtc_state, conn_state); @@ -2293,7 +2275,14 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; atomic_set(&phys->vsync_cnt, 0); atomic_set(&phys->underrun_cnt, 0); + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); + + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); } + mutex_unlock(&dpu_enc->enc_lock); return ret; -- With best wishes Dmitry
Re: [PATCH 2/3] drm/msm/dpu: fix maxlinewidth for writeback block
On 14/06/2022 22:32, Abhinav Kumar wrote: Writeback block for sm8250 was using the default maxlinewidth of 2048. But this is not right as it supports upto 4096. This should have no effect on most resolutions as we are still limiting upto maxlinewidth of SSPP for adding the modes. Fix the maxlinewidth for writeback block on sm8250. Fixes: 53324b99bd7b ("add writeback blocks to the sm8250 DPU catalog") Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 400ebceb56bb..dd7537e32f88 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1285,7 +1285,7 @@ static const struct dpu_intf_cfg qcm2290_intf[] = { * Writeback blocks config */ #define WB_BLK(_name, _id, _base, _features, _clk_ctrl, \ - __xin_id, vbif_id, _reg, _wb_done_bit) \ + __xin_id, vbif_id, _reg, _max_linewidth, _wb_done_bit) \ { \ .name = _name, .id = _id, \ .base = _base, .len = 0x2c8, \ @@ -1295,13 +1295,13 @@ static const struct dpu_intf_cfg qcm2290_intf[] = { .clk_ctrl = _clk_ctrl, \ .xin_id = __xin_id, \ .vbif_idx = vbif_id, \ - .maxlinewidth = DEFAULT_DPU_LINE_WIDTH, \ + .maxlinewidth = _max_linewidth, \ .intr_wb_done = DPU_IRQ_IDX(_reg, _wb_done_bit) \ } static const struct dpu_wb_cfg sm8250_wb[] = { WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, - VBIF_RT, MDP_SSPP_TOP0_INTR, 4), + VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), }; /* -- With best wishes Dmitry
Re: [PATCH 3/3] drm/msm/dpu: remove hard-coded linewidth limit for writeback
On 14/06/2022 22:32, Abhinav Kumar wrote: Remove the hard-coded limit for writeback and lets start using the one from catalog instead. Fixes: d7d0e73f7de3 ("introduce the dpu_encoder_phys_* for writeback") Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 59da348ff339..fc1d4fda69b5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -20,8 +20,6 @@ #include "dpu_crtc.h" #include "disp/msm_disp_snapshot.h" -#define DEFAULT_MAX_WRITEBACK_WIDTH 2048 - #define to_dpu_encoder_phys_wb(x) \ container_of(x, struct dpu_encoder_phys_wb, base) @@ -278,9 +276,9 @@ static int dpu_encoder_phys_wb_atomic_check( DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, mode->vdisplay); return -EINVAL; - } else if (fb->width > DEFAULT_MAX_WRITEBACK_WIDTH) { + } else if (fb->width > phys_enc->hw_wb->caps->maxlinewidth) { DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n", - fb->width, DEFAULT_MAX_WRITEBACK_WIDTH); + fb->width, phys_enc->hw_wb->caps->maxlinewidth); return -EINVAL; } -- With best wishes Dmitry
Re: [PATCH 1/3] drm/msm/dpu: move intf and wb assignment to dpu_encoder_setup_display()
On 14/06/2022 22:32, Abhinav Kumar wrote: intf and wb resources are not dependent on the rm global state so need not be allocated during dpu_encoder_virt_atomic_mode_set(). Move the allocation of intf and wb resources to dpu_encoder_setup_display() so that we can utilize the hw caps even during atomic_check() phase. Since dpu_encoder_setup_display() already has protection against setting invalid intf_idx and wb_idx, these checks can now be dropped as well. I'm going to pick up the last two patches, so you'd have to resend just the first one. Fixes: e02a559a720f ("make changes to dpu_encoder to support virtual encoder") Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..e991d4ba8a40 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1048,24 +1048,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "no intf or wb block assigned at idx: %d\n", i); - return; - } - - if (phys->hw_intf && phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "invalid phys both intf and wb block at idx: %d\n", i); - return; - } - phys->cached_mode = crtc_state->adjusted_mode; if (phys->ops.atomic_mode_set) phys->ops.atomic_mode_set(phys, crtc_state, conn_state); @@ -2293,7 +2275,14 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; atomic_set(&phys->vsync_cnt, 0); atomic_set(&phys->underrun_cnt, 0); + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); + + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); } + mutex_unlock(&dpu_enc->enc_lock); return ret; -- With best wishes Dmitry
Re: [PATCH v3 2/2] drm/msm: Expose client engine utilization via fdinfo
On 09/06/2022 20:42, Rob Clark wrote: From: Rob Clark Similar to AMD commit 874442541133 ("drm/amdgpu: Add show_fdinfo() interface"), using the infrastructure added in previous patches, we add basic client info and GPU engine utilisation for msm. Example output: # cat /proc/`pgrep glmark2`/fdinfo/6 pos:0 flags: 0242 mnt_id: 21 ino:162 drm-driver: msm drm-client-id: 7 drm-engine-gpu: 1734371319 ns drm-cycles-gpu: 1153645024 drm-maxfreq-gpu:8 Hz See also: https://patchwork.freedesktop.org/patch/468505/ v2: Add dev-maxfreq-$engine and update drm-usage-stats.rst v3: spelling and compiler warning Signed-off-by: Rob Clark Reviewed-by: Dmitry Baryshkov --- Documentation/gpu/drm-usage-stats.rst | 21 + drivers/gpu/drm/msm/msm_drv.c | 19 ++- drivers/gpu/drm/msm/msm_gpu.c | 21 +++-- drivers/gpu/drm/msm/msm_gpu.h | 19 +++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst index 6c9f166a8d6f..92c5117368d7 100644 --- a/Documentation/gpu/drm-usage-stats.rst +++ b/Documentation/gpu/drm-usage-stats.rst @@ -105,6 +105,27 @@ object belong to this client, in the respective memory region. Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB' indicating kibi- or mebi-bytes. +- drm-cycles- + +Engine identifier string must be the same as the one specified in the +drm-engine- tag and shall contain the number of busy cycles for the given +engine. + +Values are not required to be constantly monotonic if it makes the driver +implementation easier, but are required to catch up with the previously reported +larger value within a reasonable period. Upon observing a value lower than what +was previously read, userspace is expected to stay with that larger previous +value until a monotonic update is seen. + +- drm-maxfreq- [Hz|MHz|KHz] + +Engine identifier string must be the same as the one specified in the +drm-engine- tag and shall contain the maximum frequency for the given +engine. Taken together with drm-cycles-, this can be used to calculate +percentage utilization of the engine, whereas drm-engine- only reflects +time active without considering what frequency the engine is operating as a +percentage of it's maximum frequency. + === Driver specific implementations === diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 14ab9a627d8b..57a66093e671 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -948,7 +948,24 @@ static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_RENDER_ALLOW), }; -DEFINE_DRM_GEM_FOPS(fops); +static void msm_fop_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct drm_file *file = f->private_data; + struct drm_device *dev = file->minor->dev; + struct msm_drm_private *priv = dev->dev_private; + struct drm_printer p = drm_seq_file_printer(m); + + if (!priv->gpu) + return; + + msm_gpu_show_fdinfo(priv->gpu, file->driver_priv, &p); +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + DRM_GEM_FOPS, + .show_fdinfo = msm_fop_show_fdinfo, +}; static const struct drm_driver msm_driver = { .driver_features= DRIVER_GEM | diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 244511f85044..f99292eaf529 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -4,6 +4,8 @@ * Author: Rob Clark */ +#include "drm/drm_drv.h" + #include "msm_gpu.h" #include "msm_gem.h" #include "msm_mmu.h" @@ -146,6 +148,16 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) return 0; } +void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx, +struct drm_printer *p) +{ + drm_printf(p, "drm-driver:\t%s\n", gpu->dev->driver->name); + drm_printf(p, "drm-client-id:\t%u\n", ctx->seqno); + drm_printf(p, "drm-engine-gpu:\t%llu ns\n", ctx->elapsed_ns); + drm_printf(p, "drm-cycles-gpu:\t%llu\n", ctx->cycles); + drm_printf(p, "drm-maxfreq-gpu:\t%u Hz\n", gpu->fast_rate); +} + int msm_gpu_hw_init(struct msm_gpu *gpu) { int ret; @@ -652,7 +664,7 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, { int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; volatile struct msm_gpu_submit_stats *stats; - u64 elapsed, clock = 0; + u64 elapsed, clock = 0, cycles; unsigned long flags; stats = &ring->memptrs->stats[index]; @@ -660,12 +672,17 @@ static void retire_sub
Re: [PATCH v3 1/2] drm: Add DRM_GEM_FOPS
On 09/06/2022 20:42, Rob Clark wrote: From: Rob Clark The DEFINE_DRM_GEM_FOPS() helper is a bit limiting if a driver wants to provide additional file ops, like show_fdinfo(). v2: Split out DRM_GEM_FOPS instead of making DEFINE_DRM_GEM_FOPS varardic v3: nits Signed-off-by: Rob Clark Acked-by: Thomas Zimmermann I suspect that with Tomas's ack we can pick this through the drm/msm. Is this correct? (I'll then pick it for the msm-lumag). --- include/drm/drm_gem.h | 26 ++ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 9d7c61a122dc..87cffc9efa85 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -314,6 +314,23 @@ struct drm_gem_object { const struct drm_gem_object_funcs *funcs; }; +/** + * DRM_GEM_FOPS - Default drm GEM file operations + * + * This macro provides a shorthand for setting the GEM file ops in the + * &file_operations structure. If all you need are the default ops, use + * DEFINE_DRM_GEM_FOPS instead. + */ +#define DRM_GEM_FOPS \ + .open = drm_open,\ + .release= drm_release,\ + .unlocked_ioctl = drm_ioctl,\ + .compat_ioctl = drm_compat_ioctl,\ + .poll = drm_poll,\ + .read = drm_read,\ + .llseek = noop_llseek,\ + .mmap = drm_gem_mmap + /** * DEFINE_DRM_GEM_FOPS() - macro to generate file operations for GEM drivers * @name: name for the generated structure @@ -330,14 +347,7 @@ struct drm_gem_object { #define DEFINE_DRM_GEM_FOPS(name) \ static const struct file_operations name = {\ .owner = THIS_MODULE,\ - .open = drm_open,\ - .release= drm_release,\ - .unlocked_ioctl = drm_ioctl,\ - .compat_ioctl = drm_compat_ioctl,\ - .poll = drm_poll,\ - .read = drm_read,\ - .llseek = noop_llseek,\ - .mmap = drm_gem_mmap,\ + DRM_GEM_FOPS,\ } void drm_gem_object_release(struct drm_gem_object *obj); -- With best wishes Dmitry
Re: [PATCH] drm/msm: Use div64_ul instead of do_div
On 26/04/2022 16:21, Wan Jiabing wrote: Fix following coccicheck warning: drivers/gpu/drm/msm/msm_gpu_devfreq.c:72:1-7: WARNING: do_div() does a 64-by-32 division, please consider using div64_ul instead. Use div64_ul instead of do_div to avoid a possible truncation. Signed-off-by: Wan Jiabing Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index d2539ca78c29..c2ea978c8921 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -69,7 +69,7 @@ static void get_raw_dev_status(struct msm_gpu *gpu, df->time = time; busy_time *= USEC_PER_SEC; - do_div(busy_time, sample_rate); + busy_time = div64_ul(busy_time, sample_rate); if (WARN_ON(busy_time > ~0LU)) busy_time = ~0LU; -- With best wishes Dmitry
Re: [PATCH v3 2/2] drm/msm: Expose client engine utilization via fdinfo
On 09/06/2022 18:42, Rob Clark wrote: From: Rob Clark Similar to AMD commit 874442541133 ("drm/amdgpu: Add show_fdinfo() interface"), using the infrastructure added in previous patches, we add basic client info and GPU engine utilisation for msm. Example output: # cat /proc/`pgrep glmark2`/fdinfo/6 pos:0 flags: 0242 mnt_id: 21 ino:162 drm-driver: msm drm-client-id: 7 drm-engine-gpu: 1734371319 ns drm-cycles-gpu: 1153645024 drm-maxfreq-gpu:8 Hz See also: https://patchwork.freedesktop.org/patch/468505/ v2: Add dev-maxfreq-$engine and update drm-usage-stats.rst v3: spelling and compiler warning Signed-off-by: Rob Clark --- Documentation/gpu/drm-usage-stats.rst | 21 + drivers/gpu/drm/msm/msm_drv.c | 19 ++- drivers/gpu/drm/msm/msm_gpu.c | 21 +++-- drivers/gpu/drm/msm/msm_gpu.h | 19 +++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/Documentation/gpu/drm-usage-stats.rst b/Documentation/gpu/drm-usage-stats.rst index 6c9f166a8d6f..92c5117368d7 100644 --- a/Documentation/gpu/drm-usage-stats.rst +++ b/Documentation/gpu/drm-usage-stats.rst @@ -105,6 +105,27 @@ object belong to this client, in the respective memory region. Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB' indicating kibi- or mebi-bytes. +- drm-cycles- + +Engine identifier string must be the same as the one specified in the +drm-engine- tag and shall contain the number of busy cycles for the given +engine. + +Values are not required to be constantly monotonic if it makes the driver +implementation easier, but are required to catch up with the previously reported +larger value within a reasonable period. Upon observing a value lower than what +was previously read, userspace is expected to stay with that larger previous +value until a monotonic update is seen. + +- drm-maxfreq- [Hz|MHz|KHz] Kilo should be lowercase, I *think*. Simplify and only document Hz? + +Engine identifier string must be the same as the one specified in the +drm-engine- tag and shall contain the maximum frequency for the given +engine. Taken together with drm-cycles-, this can be used to calculate +percentage utilization of the engine, whereas drm-engine- only reflects +time active without considering what frequency the engine is operating as a +percentage of it's maximum frequency. Slipped my mind to reply to v3.. Acked-by: Tvrtko Ursulin Regards, Tvrtko + === Driver specific implementations === diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 14ab9a627d8b..57a66093e671 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -948,7 +948,24 @@ static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_RENDER_ALLOW), }; -DEFINE_DRM_GEM_FOPS(fops); +static void msm_fop_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct drm_file *file = f->private_data; + struct drm_device *dev = file->minor->dev; + struct msm_drm_private *priv = dev->dev_private; + struct drm_printer p = drm_seq_file_printer(m); + + if (!priv->gpu) + return; + + msm_gpu_show_fdinfo(priv->gpu, file->driver_priv, &p); +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + DRM_GEM_FOPS, + .show_fdinfo = msm_fop_show_fdinfo, +}; static const struct drm_driver msm_driver = { .driver_features= DRIVER_GEM | diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 244511f85044..f99292eaf529 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -4,6 +4,8 @@ * Author: Rob Clark */ +#include "drm/drm_drv.h" + #include "msm_gpu.h" #include "msm_gem.h" #include "msm_mmu.h" @@ -146,6 +148,16 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) return 0; } +void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx, +struct drm_printer *p) +{ + drm_printf(p, "drm-driver:\t%s\n", gpu->dev->driver->name); + drm_printf(p, "drm-client-id:\t%u\n", ctx->seqno); + drm_printf(p, "drm-engine-gpu:\t%llu ns\n", ctx->elapsed_ns); + drm_printf(p, "drm-cycles-gpu:\t%llu\n", ctx->cycles); + drm_printf(p, "drm-maxfreq-gpu:\t%u Hz\n", gpu->fast_rate); +} + int msm_gpu_hw_init(struct msm_gpu *gpu) { int ret; @@ -652,7 +664,7 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, { int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; volatile struct msm_gpu_submit_stats *stats; - u64 elapsed, clock = 0; + u64 elapsed, clock = 0, cycle
Re: [Freedreno] [PATCH v5 00/10] drm/hdcp: Pull HDCP auth/exchange/check into helpers
On 11/04/2022 23:47, Sean Paul wrote: From: Sean Paul Rebased set from November. Fixed a nit from Stephen in the msm patch and moved hdcp registers into the trogdor dtsi file to avoid differences with sc7180-based windows devices. The set is 4 patches lighter since some of the changes were accepted into msm. I'm still waiting for Intel review of the first 7 patches. Rodrigo/Jani, would you please provide your input so we can move forward with this set? Thanks, Sean Link: https://patchwork.freedesktop.org/series/94623/ #v1 Link: https://patchwork.freedesktop.org/series/94713/ #v2 Link: https://patchwork.freedesktop.org/series/94712/ #v3 Link: https://patchwork.freedesktop.org/series/94712/ #v4 With most of the patches getting necessary acks and r-b, what would be the plan to merge the series? We can take patches 1-4 (core) + 8, 10 (msm) through the msm tree, leaving i915 for the next cycle. Does that sound good? Sean Paul (10): drm/hdcp: Add drm_hdcp_atomic_check() drm/hdcp: Avoid changing crtc state in hdcp atomic check drm/hdcp: Update property value on content type and user changes drm/hdcp: Expand HDCP helper library for enable/disable/check drm/i915/hdcp: Consolidate HDCP setup/state cache drm/i915/hdcp: Retain hdcp_capable return codes drm/i915/hdcp: Use HDCP helpers for i915 dt-bindings: msm/dp: Add bindings for HDCP registers arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller drm/msm: Implement HDCP 1.x using the new drm HDCP helpers .../bindings/display/msm/dp-controller.yaml |7 +- arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi |8 + arch/arm64/boot/dts/qcom/sc7180.dtsi |6 +- drivers/gpu/drm/drm_hdcp.c| 1197 - drivers/gpu/drm/i915/display/intel_atomic.c |7 +- drivers/gpu/drm/i915/display/intel_ddi.c | 29 +- .../drm/i915/display/intel_display_debugfs.c | 11 +- .../drm/i915/display/intel_display_types.h| 58 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 345 ++--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++--- drivers/gpu/drm/i915/display/intel_hdcp.h | 36 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 256 ++-- drivers/gpu/drm/msm/Makefile |1 + drivers/gpu/drm/msm/dp/dp_debug.c | 46 +- drivers/gpu/drm/msm/dp/dp_debug.h |6 +- drivers/gpu/drm/msm/dp/dp_display.c | 46 +- drivers/gpu/drm/msm/dp/dp_display.h |5 + drivers/gpu/drm/msm/dp/dp_drm.c | 68 +- drivers/gpu/drm/msm/dp/dp_drm.h |5 + drivers/gpu/drm/msm/dp/dp_hdcp.c | 453 +++ drivers/gpu/drm/msm/dp/dp_hdcp.h | 27 + drivers/gpu/drm/msm/dp/dp_parser.c| 20 +- drivers/gpu/drm/msm/dp/dp_parser.h|4 + drivers/gpu/drm/msm/dp/dp_reg.h | 32 +- drivers/gpu/drm/msm/msm_atomic.c | 15 + include/drm/drm_hdcp.h| 194 +++ 27 files changed, 2582 insertions(+), 1328 deletions(-) create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h -- With best wishes Dmitry
[PATCH v3 2/3] drm/msm/dpu: fix error handling around dpu_hw_vbif_init
Using IS_ERR_OR_NULL() together with PTR_ERR() is a typical mistake. If the value is NULL, then the function will return 0 instead of a proper return code. Moreover dpu_hw_vbif_init() function can not return NULL. So, replace corresponding IS_ERR_OR_NULL() call with IS_ERR(). Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 1255d00c92cf..922725c92898 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1135,10 +1135,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx, dpu_kms->vbif[vbif_idx], dpu_kms->catalog); - if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) { + if (IS_ERR(dpu_kms->hw_vbif[vbif_idx])) { rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]); - if (!dpu_kms->hw_vbif[vbif_idx]) - rc = -EINVAL; DPU_ERROR("failed to init vbif %d: %d\n", vbif_idx, rc); dpu_kms->hw_vbif[vbif_idx] = NULL; goto power_error; -- 2.35.1
[PATCH v3 3/3] drm/msm/dpu: drop VBIF indices
We do not expect to have other VBIFs. Drop VBIF_n indices and always use VBIF_RT and VBIF_NRT. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 4 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 6 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 36 --- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 400ebceb56bb..f854889ea7fb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1330,7 +1330,7 @@ static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = { static const struct dpu_vbif_cfg msm8998_vbif[] = { { - .name = "vbif_0", .id = VBIF_0, + .name = "vbif_rt", .id = VBIF_RT, .base = 0, .len = 0x1040, .default_ot_rd_limit = 32, .default_ot_wr_limit = 32, @@ -1359,7 +1359,7 @@ static const struct dpu_vbif_cfg msm8998_vbif[] = { static const struct dpu_vbif_cfg sdm845_vbif[] = { { - .name = "vbif_0", .id = VBIF_0, + .name = "vbif_rt", .id = VBIF_RT, .base = 0, .len = 0x1040, .features = BIT(DPU_VBIF_QOS_REMAP), .xin_halt_timeout = 0x4000, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 9f402be55fbf..d3b0ed0a9c6c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -273,11 +273,9 @@ enum dpu_wd_timer { }; enum dpu_vbif { - VBIF_0, - VBIF_1, + VBIF_RT, + VBIF_NRT, VBIF_MAX, - VBIF_RT = VBIF_0, - VBIF_NRT = VBIF_1 }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c index a18fb649301c..1305e250b71e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -19,6 +19,18 @@ static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif v return NULL; } +static const char *dpu_vbif_name(enum dpu_vbif idx) +{ + switch (idx) { + case VBIF_RT: + return "VBIF_RT"; + case VBIF_NRT: + return "VBIF_NRT"; + default: + return "??"; + } +} + /** * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt * @vbif: Pointer to hardware vbif driver @@ -50,12 +62,12 @@ static int _dpu_vbif_wait_for_xin_halt(struct dpu_hw_vbif *vbif, u32 xin_id) if (!status) { rc = -ETIMEDOUT; - DPU_ERROR("VBIF %d client %d not halting. TIMEDOUT.\n", - vbif->idx - VBIF_0, xin_id); + DPU_ERROR("%s client %d not halting. TIMEDOUT.\n", + dpu_vbif_name(vbif->idx), xin_id); } else { rc = 0; - DRM_DEBUG_ATOMIC("VBIF %d client %d is halted\n", - vbif->idx - VBIF_0, xin_id); + DRM_DEBUG_ATOMIC("%s client %d is halted\n", + dpu_vbif_name(vbif->idx), xin_id); } return rc; @@ -95,8 +107,8 @@ static void _dpu_vbif_apply_dynamic_ot_limit(struct dpu_hw_vbif *vbif, } } - DRM_DEBUG_ATOMIC("vbif:%d xin:%d w:%d h:%d fps:%d pps:%llu ot:%u\n", - vbif->idx - VBIF_0, params->xin_id, + DRM_DEBUG_ATOMIC("%s xin:%d w:%d h:%d fps:%d pps:%llu ot:%u\n", + dpu_vbif_name(vbif->idx), params->xin_id, params->width, params->height, params->frame_rate, pps, *ot_lim); } @@ -141,8 +153,8 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif, } exit: - DRM_DEBUG_ATOMIC("vbif:%d xin:%d ot_lim:%d\n", - vbif->idx - VBIF_0, params->xin_id, ot_lim); + DRM_DEBUG_ATOMIC("%s xin:%d ot_lim:%d\n", + dpu_vbif_name(vbif->idx), params->xin_id, ot_lim); return ot_lim; } @@ -242,8 +254,8 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); for (i = 0; i < qos_tbl->npriority_lvl; i++) { - DRM_DEBUG_ATOMIC("vbif:%d xin:%d lvl:%d/%d\n", - params->vbif_idx, params->xin_id, i, + DRM_DEBUG_ATOMIC("%s xin:%d lvl:%d/%d\n", + dpu_vbif_name(params->vbif_idx), params->xin_id, i, qos_tbl->priority_lvl[i]); vbif->ops.set_qos_remap(vbif, params->xin_id, i, qos_tbl->priority_lvl[i]); @@ -263,8 +275,8 @@ void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms) if (vbif && vbif->ops.clear_errors) { vbif->ops.clear_errors(vbif
[PATCH v3 1/3] drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx
Remove loops over hw_vbif. Instead always VBIF's idx as an index in the array. This fixes an error in dpu_kms_hw_init(), where we fill dpu_kms->hw_vbif[i], but check for an error pointer at dpu_kms->hw_vbif[vbif_idx]. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 -- drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 29 +++- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 2b9d931474e0..1255d00c92cf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -830,12 +830,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) _dpu_kms_mmu_destroy(dpu_kms); if (dpu_kms->catalog) { - for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { - u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - - if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) { - dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]); - dpu_kms->hw_vbif[vbif_idx] = NULL; + for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { + if (dpu_kms->hw_vbif[i]) { + dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]); + dpu_kms->hw_vbif[i] = NULL; } } } @@ -1135,7 +1133,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx, + dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx, dpu_kms->vbif[vbif_idx], dpu_kms->catalog); if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) { rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c index 21d20373eb8b..a18fb649301c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -11,6 +11,14 @@ #include "dpu_hw_vbif.h" #include "dpu_trace.h" +static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx) +{ + if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif)) + return dpu_kms->hw_vbif[vbif_idx]; + + return NULL; +} + /** * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt * @vbif: Pointer to hardware vbif driver @@ -148,20 +156,15 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif, void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, struct dpu_vbif_set_ot_params *params) { - struct dpu_hw_vbif *vbif = NULL; + struct dpu_hw_vbif *vbif; struct dpu_hw_mdp *mdp; bool forced_on = false; u32 ot_lim; - int ret, i; + int ret; mdp = dpu_kms->hw_mdp; - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) - vbif = dpu_kms->hw_vbif[i]; - } - + vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); if (!vbif || !mdp) { DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n", vbif != NULL, mdp != NULL); @@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, struct dpu_vbif_set_qos_params *params) { - struct dpu_hw_vbif *vbif = NULL; + struct dpu_hw_vbif *vbif; struct dpu_hw_mdp *mdp; bool forced_on = false; const struct dpu_vbif_qos_tbl *qos_tbl; @@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, } mdp = dpu_kms->hw_mdp; - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) { - vbif = dpu_kms->hw_vbif[i]; - break; - } - } + vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); if (!vbif || !vbif->cap) { DPU_ERROR("invalid vbif %d\n", params->vbif_idx); -- 2.35.1
Re: [PATCH v7 0/8] Add a panel API to set orientation properly
Hi, On Tue, Jun 14, 2022 at 10:50 PM Hsin-Yi Wang wrote: > > On Thu, Jun 9, 2022 at 3:27 PM Hsin-Yi Wang wrote: > > > > Panels usually call drm_connector_set_panel_orientation(), which is > > later than drm/kms driver calling drm_dev_register(). This leads to a > > WARN()[1]. > > > > The orientation property is known earlier. For example, some panels > > parse the property through device tree during probe. > > > > The series add a panel API drm_connector_set_orientation_from_panel() > > for drm/kms drivers. The drivers can call the API to set panel's > > orientation before drm_dev_register(). > > > > Panel needs to implement .get_orientation callback to return the property. > > > > [1] > > https://patchwork.kernel.org/project/linux-mediatek/patch/20220530081910.3947168-2-hsi...@chromium.org/ > > > > Hsin-Yi Wang (8): > > drm/panel: Add an API to allow drm to set orientation from panel > > drm/panel: boe-tv101wum-nl6: Implement .get_orientation callback > > drm/panel: panel-edp: Implement .get_orientation callback > > drm/panel: lvds: Implement .get_orientation callback > > drm/panel: panel-simple: Implement .get_orientation callback > > drm/panel: ili9881c: Implement .get_orientation callback > > drm/panel: elida-kd35t133: Implement .get_orientation callback > > drm: Config orientation property if panel provides it > > > hi Maintainers, > > All the patches are reviewed. If there's no other comments, will this > series be picked? Thanks. Unless someone beat me to it or yells, my plan was to land them to drm-misc-next next week. Since it touches core code I wanted to give a little extra time. Also at the moment patch #8 is all Chromium (all author and reviewers are chromium.org) at the moment so that's another reason to make sure it has sufficient time on the lists. -Doug
[Bug 216092] rn_vbios_smu_send_msg_with_param+0xf9/0x100 - amdgpu
https://bugzilla.kernel.org/show_bug.cgi?id=216092 Alex Deucher (alexdeuc...@gmail.com) changed: What|Removed |Added CC||alexdeuc...@gmail.com --- Comment #2 from Alex Deucher (alexdeuc...@gmail.com) --- Can you bisect? -- 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 216092] rn_vbios_smu_send_msg_with_param+0xf9/0x100 - amdgpu
https://bugzilla.kernel.org/show_bug.cgi?id=216092 --- Comment #3 from Alex Deucher (alexdeuc...@gmail.com) --- Does reverting c1b972a18d05d007f0ddff31db2ff50790576e92 fix the issue? -- 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 1/2] drm: Add DRM_GEM_FOPS
Am 15.06.22 um 14:45 schrieb Dmitry Baryshkov: On 09/06/2022 20:42, Rob Clark wrote: From: Rob Clark The DEFINE_DRM_GEM_FOPS() helper is a bit limiting if a driver wants to provide additional file ops, like show_fdinfo(). v2: Split out DRM_GEM_FOPS instead of making DEFINE_DRM_GEM_FOPS varardic v3: nits Signed-off-by: Rob Clark Acked-by: Thomas Zimmermann I suspect that with Tomas's ack we can pick this through the drm/msm. Is this correct? (I'll then pick it for the msm-lumag). Sure, go ahead. --- include/drm/drm_gem.h | 26 ++ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index 9d7c61a122dc..87cffc9efa85 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -314,6 +314,23 @@ struct drm_gem_object { const struct drm_gem_object_funcs *funcs; }; +/** + * DRM_GEM_FOPS - Default drm GEM file operations + * + * This macro provides a shorthand for setting the GEM file ops in the + * &file_operations structure. If all you need are the default ops, use + * DEFINE_DRM_GEM_FOPS instead. + */ +#define DRM_GEM_FOPS \ + .open = drm_open,\ + .release = drm_release,\ + .unlocked_ioctl = drm_ioctl,\ + .compat_ioctl = drm_compat_ioctl,\ + .poll = drm_poll,\ + .read = drm_read,\ + .llseek = noop_llseek,\ + .mmap = drm_gem_mmap + /** * DEFINE_DRM_GEM_FOPS() - macro to generate file operations for GEM drivers * @name: name for the generated structure @@ -330,14 +347,7 @@ struct drm_gem_object { #define DEFINE_DRM_GEM_FOPS(name) \ static const struct file_operations name = {\ .owner = THIS_MODULE,\ - .open = drm_open,\ - .release = drm_release,\ - .unlocked_ioctl = drm_ioctl,\ - .compat_ioctl = drm_compat_ioctl,\ - .poll = drm_poll,\ - .read = drm_read,\ - .llseek = noop_llseek,\ - .mmap = drm_gem_mmap,\ + DRM_GEM_FOPS,\ } void drm_gem_object_release(struct drm_gem_object *obj); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
[Bug 216092] rn_vbios_smu_send_msg_with_param+0xf9/0x100 - amdgpu
https://bugzilla.kernel.org/show_bug.cgi?id=216092 --- Comment #4 from RockT (tr...@gmx.de) --- (In reply to Alex Deucher from comment #3) > Does reverting c1b972a18d05d007f0ddff31db2ff50790576e92 fix the issue? I never rebuild an Arch/Manjaro Kernel. Will try but cannot promise. -- 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 7/7] drm/bridge: anx7625: Add typec_mux_set callback function
Il 14/06/22 18:58, Prashant Malani ha scritto: On Tue, Jun 14, 2022 at 2:08 AM Pin-yen Lin wrote: Hi AngeloGioacchino, On Tue, Jun 14, 2022 at 4:15 PM AngeloGioacchino Del Regno wrote: Il 09/06/22 20:09, Prashant Malani ha scritto: From: Pin-Yen Lin Add the callback function when the driver receives state changes of the Type-C port. The callback function configures the crosspoint switch of the anx7625 bridge chip, which can change the output pins of the signals according to the port state. Signed-off-by: Pin-Yen Lin Signed-off-by: Prashant Malani --- Changes since v2: - No changes. drivers/gpu/drm/bridge/analogix/anx7625.c | 58 +++ drivers/gpu/drm/bridge/analogix/anx7625.h | 13 + 2 files changed, 71 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index d41a21103bd3..2c308d12fab2 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -2582,9 +2583,66 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static void anx7625_set_crosspoint_switch(struct anx7625_data *ctx, + enum typec_orientation orientation) +{ + if (orientation == TYPEC_ORIENTATION_NORMAL) { + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0, + SW_SEL1_SSRX_RX1 | SW_SEL1_DPTX0_RX2); + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1, + SW_SEL2_SSTX_TX1 | SW_SEL2_DPTX1_TX2); + } else if (orientation == TYPEC_ORIENTATION_REVERSE) { + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0, + SW_SEL1_SSRX_RX2 | SW_SEL1_DPTX0_RX1); + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1, + SW_SEL2_SSTX_TX2 | SW_SEL2_DPTX1_TX1); + } +} + +static void anx7625_typec_two_ports_update(struct anx7625_data *ctx) +{ + if (ctx->typec_ports[0].dp_connected && ctx->typec_ports[1].dp_connected) + /* Both ports available, do nothing to retain the current one. */ + return; + else if (ctx->typec_ports[0].dp_connected) + anx7625_set_crosspoint_switch(ctx, TYPEC_ORIENTATION_NORMAL); + else if (ctx->typec_ports[1].dp_connected) + anx7625_set_crosspoint_switch(ctx, TYPEC_ORIENTATION_REVERSE); +} + static int anx7625_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) { + struct anx7625_port_data *data = typec_mux_get_drvdata(mux); + struct anx7625_data *ctx = data->ctx; + struct device *dev = &ctx->client->dev; + + bool old_dp_connected = (ctx->typec_ports[0].dp_connected || + ctx->typec_ports[1].dp_connected); So the old connection state is "either port0 or port1 are currently connected"... + bool new_dp_connected; + + if (ctx->num_typec_switches == 1) + return 0; + + dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n", + ctx->typec_ports[0].dp_connected, ctx->typec_ports[1].dp_connected); + + data->dp_connected = (state->alt && state->alt->svid == USB_TYPEC_DP_SID && + state->alt->mode == USB_TYPEC_DP_MODE); + > + new_dp_connected = (ctx->typec_ports[0].dp_connected || + ctx->typec_ports[1].dp_connected); ...and the new connection state is the same as the old one, because I don't see anything that could ever modify it in this function's flow, until reaching this assignment. The typec mux driver data (`struct anx7625_port_data *data = typec_mux_get_drvdata(mux)`) is set to one of the `ctx->typec_ports[*]` in `anx7625_register_mode_switch` (see patch 6 of this series). So, the `data->dp_connected = ...` assignment may change the new connection state. Angelo, I think your interpretation of this logic is not accurate.. |old_dp_connected| represents *whether* port1 or port0 has a DP partner connected, not that *either* of them has it. So, this logic looks OK to me. Hello Prashant, You're completely right: I've finally seen where this is happening, so yes we don't know, nor care at that moment, whether data->dp_connected is port0 or port1, we assign and check 'em both again, which is actually smart. I'm sorry for the misunderstandment - and thank you for your reply. Feel free to add my Reviewed-by: AngeloGioacchino Del Regno Regards, Angelo
[PATCH 00/10] drm: selftest: Convert to KUnit
KUnit unifies the test structure and provides helper tools that simplify the development of tests. The basic use case allows running tests as regular processes, which makes it easier to run unit tests on a development machine and to integrate the tests into a CI system. That said, the conversion of selftests for DRM to KUnit tests is beneficial as it unifies the testing API by using the KUnit API. KUnit is beneficial for developers as it eases the process to run unit tests. It is possible to run the tests by using the kunit-tool on userspace with the following command: ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/tests --arch=x86_64 For CI system, it is possible to execute during the build. But, we also think about IGT: we are developing a patch to introduce KUnit to IGT. These patches were developed during a KUnit hackathon [0] last October. Now, we believe that both the IGT side and the Kernel side are in good shape for submission. If you are willing to check the output, here is the Pastebin with the output and execution times [1]. [0] https://groups.google.com/g/kunit-dev/c/YqFR1q2uZvk/m/IbvItSfHBAAJ [1] https://pastebin.com/FJjLPKsC - Arthur Grillo, Isabella Basso, and Maíra Canal Arthur Grillo (2): drm: selftest: refactor drm_cmdline_parser drm: selftest: convert drm_mm selftest to KUnit Maíra Canal (8): drm: selftest: convert drm_damage_helper selftest to KUnit drm: selftest: convert drm_cmdline_parser selftest to KUnit drm: selftest: convert drm_rect selftest to KUnit drm: selftest: convert drm_format selftest to KUnit drm: selftest: convert drm_plane_helper selftest to KUnit drm: selftest: convert drm_dp_mst_helper selftest to KUnit drm: selftest: convert drm_framebuffer selftest to KUnit drm: selftest: convert drm_buddy selftest to KUnit drivers/gpu/drm/Kconfig | 20 +- drivers/gpu/drm/Makefile |2 +- drivers/gpu/drm/selftests/Makefile|8 - .../gpu/drm/selftests/drm_buddy_selftests.h | 15 - .../gpu/drm/selftests/drm_cmdline_selftests.h | 68 - drivers/gpu/drm/selftests/drm_mm_selftests.h | 28 - .../gpu/drm/selftests/drm_modeset_selftests.h | 40 - drivers/gpu/drm/selftests/drm_selftest.c | 109 -- drivers/gpu/drm/selftests/drm_selftest.h | 41 - drivers/gpu/drm/selftests/test-drm_buddy.c| 994 -- .../drm/selftests/test-drm_cmdline_parser.c | 1141 - .../drm/selftests/test-drm_damage_helper.c| 667 -- drivers/gpu/drm/selftests/test-drm_format.c | 280 .../drm/selftests/test-drm_modeset_common.c | 32 - .../drm/selftests/test-drm_modeset_common.h | 52 - drivers/gpu/drm/tests/.kunitconfig|3 + drivers/gpu/drm/tests/Kconfig | 130 ++ drivers/gpu/drm/tests/Makefile| 10 + drivers/gpu/drm/tests/test-drm_buddy.c| 748 +++ .../gpu/drm/tests/test-drm_cmdline_parser.c | 799 .../gpu/drm/tests/test-drm_damage_helper.c| 633 + .../test-drm_dp_mst_helper.c | 82 +- drivers/gpu/drm/tests/test-drm_format.c | 284 .../test-drm_framebuffer.c| 25 +- .../drm/{selftests => tests}/test-drm_mm.c| 1135 +++- .../test-drm_plane_helper.c | 101 +- .../drm/{selftests => tests}/test-drm_rect.c | 124 +- 27 files changed, 3240 insertions(+), 4331 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/Makefile delete mode 100644 drivers/gpu/drm/selftests/drm_buddy_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_cmdline_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_mm_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_modeset_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.c delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_buddy.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_cmdline_parser.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_damage_helper.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_format.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.h create mode 100644 drivers/gpu/drm/tests/.kunitconfig create mode 100644 drivers/gpu/drm/tests/Kconfig create mode 100644 drivers/gpu/drm/tests/Makefile create mode 100644 drivers/gpu/drm/tests/test-drm_buddy.c create mode 100644 drivers/gpu/drm/tests/test-drm_cmdline_parser.c create mode 100644 drivers/gpu/drm/tests/test-drm_damage_helper.c rename drivers/gpu/drm/{selftests => tests}/test-drm_dp_mst_helper.c (73%) create mode 100644 drivers/gpu/drm/tests/test-drm_format.c rename drivers/gpu/drm/{selftests => tests}/test-drm_framebuffer.c (96%) rename drivers/gpu/drm/{selftests => tests}/test-drm_mm.c (58%) rename drivers/
[PATCH 01/10] drm: selftest: convert drm_damage_helper selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM damage helper selftest to the KUnit API. Co-developed-by: Arthur Grillo Signed-off-by: Arthur Grillo Signed-off-by: Maíra Canal --- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/selftests/Makefile| 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 21 - .../drm/selftests/test-drm_damage_helper.c| 667 -- .../drm/selftests/test-drm_modeset_common.h | 21 - drivers/gpu/drm/tests/Kconfig | 28 + drivers/gpu/drm/tests/Makefile| 2 + .../gpu/drm/tests/test-drm_damage_helper.c| 633 + 9 files changed, 667 insertions(+), 711 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/test-drm_damage_helper.c create mode 100644 drivers/gpu/drm/tests/Kconfig create mode 100644 drivers/gpu/drm/tests/Makefile create mode 100644 drivers/gpu/drm/tests/test-drm_damage_helper.c diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index e88c497fa010..bd1b5d82c9cf 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -70,6 +70,8 @@ config DRM_DEBUG_SELFTEST If in doubt, say "N". +source "drivers/gpu/drm/tests/Kconfig" + config DRM_KMS_HELPER tristate depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 15fe3163f822..0f24aa542be0 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o # obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ +obj-y += tests/ obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 5ba5f9138c95..7a1a732e0a1b 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,8 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ - test-drm_damage_helper.o test-drm_dp_mst_helper.o \ - test-drm_rect.o + test-drm_dp_mst_helper.o test-drm_rect.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 782e285ca383..4787b3b70709 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -15,26 +15,5 @@ selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) -selftest(damage_iter_no_damage, igt_damage_iter_no_damage) -selftest(damage_iter_no_damage_fractional_src, igt_damage_iter_no_damage_fractional_src) -selftest(damage_iter_no_damage_src_moved, igt_damage_iter_no_damage_src_moved) -selftest(damage_iter_no_damage_fractional_src_moved, igt_damage_iter_no_damage_fractional_src_moved) -selftest(damage_iter_no_damage_not_visible, igt_damage_iter_no_damage_not_visible) -selftest(damage_iter_no_damage_no_crtc, igt_damage_iter_no_damage_no_crtc) -selftest(damage_iter_no_damage_no_fb, igt_damage_iter_no_damage_no_fb) -selftest(damage_iter_simple_damage, igt_damage_iter_simple_damage) -selftest(damage_iter_single_damage, igt_damage_iter_single_damage) -selftest(damage_iter_single_damage_intersect_src, igt_damage_iter_single_damage_intersect_src) -selftest(damage_iter_single_damage_outside_src, igt_damage_iter_single_damage_outside_src) -selftest(damage_iter_single_damage_fractional_src, igt_damage_iter_single_damage_fractional_src) -selftest(damage_iter_single_damage_intersect_fractional_src, igt_damage_iter_single_damage_intersect_fractional_src) -selftest(damage_iter_single_damage_outside_fractional_src, igt_damage_iter_single_damage_outside_fractional_src) -selftest(damage_iter_single_damage_src_moved, igt_damage_iter_single_damage_src_moved) -selftest(damage_iter_single_damage_fractional_src_moved, igt_damage_iter_single_damage_fractional_src_moved) -selftest(damage_iter_damage, igt_damage_iter_damage) -selftest(damage_iter_damage_one_intersect, igt_damage_iter_damage_one_intersect) -selftest(damage_iter_damage_one_outside, igt_damage_iter_damage_one_outside) -selftest(damage_iter_damage_src_moved, igt_damage_iter_damage_src_moved) -selftest(damage_iter_damage_not_visible, igt_damage_iter_damage_not_visible) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_s
[PATCH 02/10] drm: selftest: refactor drm_cmdline_parser
From: Arthur Grillo Refactor the tests by modularizing the functions to avoid code repetition. Co-developed-by: Maíra Canal Signed-off-by: Arthur Grillo Signed-off-by: Maíra Canal --- .../drm/selftests/test-drm_cmdline_parser.c | 579 +- 1 file changed, 156 insertions(+), 423 deletions(-) diff --git a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c index d96cd890def6..57a229c5fc35 100644 --- a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c +++ b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2019 Bootlin + * Copyright (c) 2021 Ma�ra Canal , + * Copyright (c) 2021 Arthur Grillo */ #define pr_fmt(fmt) "drm_cmdline: " fmt @@ -17,13 +19,25 @@ static const struct drm_connector no_connector = {}; -static int drm_cmdline_test_force_e_only(void *ignored) +static int drm_cmdline_test_properties(void *ignored, + struct drm_cmdline_mode *mode, enum drm_connector_force force) +{ + FAIL_ON(mode->rb); + FAIL_ON(mode->cvt); + FAIL_ON(mode->interlace); + FAIL_ON(mode->margins); + FAIL_ON(mode->force != force); + + return 0; +} + +static int drm_cmdline_test_force_only(void *ignored, char *cmdline, + const struct drm_connector *connector, enum drm_connector_force force) { struct drm_cmdline_mode mode = { }; - FAIL_ON(!drm_mode_parse_command_line_for_connector("e", - &no_connector, - &mode)); + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + connector, &mode)); FAIL_ON(mode.specified); FAIL_ON(mode.refresh_specified); FAIL_ON(mode.bpp_specified); @@ -32,95 +46,101 @@ static int drm_cmdline_test_force_e_only(void *ignored) FAIL_ON(mode.cvt); FAIL_ON(mode.interlace); FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); + FAIL_ON(mode.force != force); return 0; } -static int drm_cmdline_test_force_D_only_not_digital(void *ignored) +static int drm_cmdline_test_freestanding(void *ignored, + struct drm_cmdline_mode *mode, char *cmdline, + const struct drm_connector *connector) { - struct drm_cmdline_mode mode = { }; + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + connector, mode)); + FAIL_ON(mode->specified); + FAIL_ON(mode->refresh_specified); + FAIL_ON(mode->bpp_specified); - FAIL_ON(!drm_mode_parse_command_line_for_connector("D", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); + FAIL_ON(mode->tv_margins.right != 14); + FAIL_ON(mode->tv_margins.left != 24); + FAIL_ON(mode->tv_margins.bottom != 36); + FAIL_ON(mode->tv_margins.top != 42); - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); + return 0; +} + +static int drm_cmdline_test_res_init(void *ignored, + struct drm_cmdline_mode *mode, char *cmdline) +{ + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + &no_connector, mode)); + FAIL_ON(!mode->specified); + FAIL_ON(mode->xres != 720); + FAIL_ON(mode->yres != 480); + + return 0; +} + +static int drm_cmdline_test_res_bpp_init(void *ignored, + struct drm_cmdline_mode *mode, char *cmdline) +{ + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + &no_connector, mode)); + FAIL_ON(!mode->specified); + FAIL_ON(mode->xres != 720); + FAIL_ON(mode->yres != 480); + + FAIL_ON(!mode->refresh_specified); + FAIL_ON(mode->refresh != 60); + FAIL_ON(!mode->bpp_specified); + FAIL_ON(mode->bpp != 24); + + return 0; +} + +static int drm_cmdline_test_force_e_only(void *ignored) +{ + drm_cmdline_test_force_only(ignored, "e", &no_connector, DRM_FORCE_ON); + + return 0; +} + +static int drm_cmdline_test_force_D_only_not_digital(void *ignored) +{ + drm_cmdline_test_force_only(ignored, "D", &no_connector, DRM_FORCE_ON); return 0; } static const struct drm_connector connector_hdmi = { .connector_type = DRM_MODE_CONNECTOR_HDMIB, + }; static int drm_cmdline_test_force_D_only_hdmi(void *ignored) { - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_
[PATCH 03/10] drm: selftest: convert drm_cmdline_parser selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM cmdline parser selftest to the KUnit API. Co-developed-by: Arthur Grillo Signed-off-by: Arthur Grillo Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 2 +- .../gpu/drm/selftests/drm_cmdline_selftests.h | 68 -- .../drm/selftests/test-drm_cmdline_parser.c | 874 -- drivers/gpu/drm/tests/.kunitconfig| 3 + drivers/gpu/drm/tests/Kconfig | 12 + drivers/gpu/drm/tests/Makefile| 1 + .../gpu/drm/tests/test-drm_cmdline_parser.c | 799 7 files changed, 816 insertions(+), 943 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/drm_cmdline_selftests.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_cmdline_parser.c create mode 100644 drivers/gpu/drm/tests/.kunitconfig create mode 100644 drivers/gpu/drm/tests/test-drm_cmdline_parser.c diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 7a1a732e0a1b..8633bb9ea717 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -3,5 +3,5 @@ test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ test-drm_dp_mst_helper.o test-drm_rect.o -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o \ +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h deleted file mode 100644 index 29e367db6118.. --- a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_mm - */ - -#define cmdline_test(test) selftest(test, test) - -cmdline_test(drm_cmdline_test_force_d_only) -cmdline_test(drm_cmdline_test_force_D_only_dvi) -cmdline_test(drm_cmdline_test_force_D_only_hdmi) -cmdline_test(drm_cmdline_test_force_D_only_not_digital) -cmdline_test(drm_cmdline_test_force_e_only) -cmdline_test(drm_cmdline_test_margin_only) -cmdline_test(drm_cmdline_test_interlace_only) -cmdline_test(drm_cmdline_test_res) -cmdline_test(drm_cmdline_test_res_missing_x) -cmdline_test(drm_cmdline_test_res_missing_y) -cmdline_test(drm_cmdline_test_res_bad_y) -cmdline_test(drm_cmdline_test_res_missing_y_bpp) -cmdline_test(drm_cmdline_test_res_vesa) -cmdline_test(drm_cmdline_test_res_vesa_rblank) -cmdline_test(drm_cmdline_test_res_rblank) -cmdline_test(drm_cmdline_test_res_bpp) -cmdline_test(drm_cmdline_test_res_bad_bpp) -cmdline_test(drm_cmdline_test_res_refresh) -cmdline_test(drm_cmdline_test_res_bad_refresh) -cmdline_test(drm_cmdline_test_res_bpp_refresh) -cmdline_test(drm_cmdline_test_res_bpp_refresh_interlaced) -cmdline_test(drm_cmdline_test_res_bpp_refresh_margins) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_off) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_off) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_analog) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_digital) -cmdline_test(drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on) -cmdline_test(drm_cmdline_test_res_margins_force_on) -cmdline_test(drm_cmdline_test_res_vesa_margins) -cmdline_test(drm_cmdline_test_res_invalid_mode) -cmdline_test(drm_cmdline_test_res_bpp_wrong_place_mode) -cmdline_test(drm_cmdline_test_name) -cmdline_test(drm_cmdline_test_name_bpp) -cmdline_test(drm_cmdline_test_name_refresh) -cmdline_test(drm_cmdline_test_name_bpp_refresh) -cmdline_test(drm_cmdline_test_name_refresh_wrong_mode) -cmdline_test(drm_cmdline_test_name_refresh_invalid_mode) -cmdline_test(drm_cmdline_test_name_option) -cmdline_test(drm_cmdline_test_name_bpp_option) -cmdline_test(drm_cmdline_test_rotate_0) -cmdline_test(drm_cmdline_test_rotate_90) -cmdline_test(drm_cmdline_test_rotate_180) -cmdline_test(drm_cmdline_test_rotate_270) -cmdline_test(drm_cmdline_test_rotate_multiple) -cmdline_test(drm_cmdline_test_rotate_invalid_val) -cmdline_test(drm_cmdline_test_rotate_truncated) -cmdline_test(drm_cmdline_test_hmirror) -cmdline_test(drm_cmdline_test_vmirror) -cmdline_test(drm_cmdline_test_margin_options) -cmdline_test(drm_cmdline_test_multiple_options) -cmdline_test(drm_cmdline_test_invalid_option) -cmdline_test(drm_cmdline_test_bpp_extra_and_option) -cmdline_test(drm_cmdline_test_extra_and_option) -cmdline_test(drm_cmdline_test_freestanding_options) -cmdline_test(drm_cmdline_test_freestanding_force_e_and_options) -cmdline_test(drm_cmdline_test_pa
[PATCH 04/10] drm: selftest: convert drm_rect selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM rect selftest to the KUnit API. Co-developed-by: Carlos Veras Signed-off-by: Carlos Veras Co-developed-by: Matheus Vieira Signed-off-by: Matheus Vieira Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 2 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 4 - .../drm/selftests/test-drm_modeset_common.h | 4 - drivers/gpu/drm/tests/Kconfig | 12 ++ drivers/gpu/drm/tests/Makefile| 1 + .../drm/{selftests => tests}/test-drm_rect.c | 124 +- 6 files changed, 79 insertions(+), 68 deletions(-) rename drivers/gpu/drm/{selftests => tests}/test-drm_rect.c (53%) diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 8633bb9ea717..8a794914e328 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ - test-drm_dp_mst_helper.o test-drm_rect.o + test-drm_dp_mst_helper.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 4787b3b70709..a3ca90307364 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -6,10 +6,6 @@ * * Tests are executed in order by igt/drm_selftests_helper */ -selftest(drm_rect_clip_scaled_div_by_zero, igt_drm_rect_clip_scaled_div_by_zero) -selftest(drm_rect_clip_scaled_not_clipped, igt_drm_rect_clip_scaled_not_clipped) -selftest(drm_rect_clip_scaled_clipped, igt_drm_rect_clip_scaled_clipped) -selftest(drm_rect_clip_scaled_signed_vs_unsigned, igt_drm_rect_clip_scaled_signed_vs_unsigned) selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index c29354e59cec..42a10d7da51c 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -16,10 +16,6 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") -int igt_drm_rect_clip_scaled_div_by_zero(void *ignored); -int igt_drm_rect_clip_scaled_not_clipped(void *ignored); -int igt_drm_rect_clip_scaled_clipped(void *ignored); -int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored); int igt_check_plane_state(void *ignored); int igt_check_drm_format_block_width(void *ignored); int igt_check_drm_format_block_height(void *ignored); diff --git a/drivers/gpu/drm/tests/Kconfig b/drivers/gpu/drm/tests/Kconfig index 14ee077cca54..bab6bf363363 100644 --- a/drivers/gpu/drm/tests/Kconfig +++ b/drivers/gpu/drm/tests/Kconfig @@ -37,4 +37,16 @@ config DRM_CMDLINE_PARSER_KUNIT_TEST If in doubt, say "N". +config DRM_RECT_KUNIT_TEST + tristate "KUnit tests for DRM rect" if !DRM_KUNIT_TEST + select DRM_KMS_HELPER + default y if DRM_KUNIT_TEST + help + This option provides a KUnit module that can be used to run + an unit test on the DRM rect API. This option is not + useful for distributions or general kernels, but only for kernel + developers working on DRM and associated drivers. + + If in doubt, say "N". + endmenu diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 3ded14858e8c..d03e28724d47 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_DRM_DAMAGE_HELPER_KUNIT_TEST) += test-drm_damage_helper.o obj-$(CONFIG_DRM_CMDLINE_PARSER_KUNIT_TEST) += test-drm_cmdline_parser.o +obj-$(CONFIG_DRM_RECT_KUNIT_TEST) += test-drm_rect.o diff --git a/drivers/gpu/drm/selftests/test-drm_rect.c b/drivers/gpu/drm/tests/test-drm_rect.c similarity index 53% rename from drivers/gpu/drm/selftests/test-drm_rect.c rename to drivers/gpu/drm/tests/test-drm_rect.c index 3a5ff38321f4..94336412d32d 100644 --- a/drivers/gpu/drm/selftests/test-drm_rect.c +++ b/drivers/gpu/drm/tests/test-drm_rect.c @@ -3,15 +3,10 @@ * Test cases for the drm_rect functions */ -#define pr_fmt(fmt) "drm_rect: " fmt - -#include - +#include #include -#include "test-drm_modeset_common.h" - -int igt_drm_rect_clip_scaled_div_by_zero(void *ignored) +static void igt_drm_rect_clip_scaled_div_by_zero(struct kunit *test) { struct drm_rect src, dst, clip; bool visible; @@ -
[PATCH 1/5] drm/msm: less magic numbers in msm_mdss_enable
Replace magic register writes in msm_mdss_enable() with version that contains less magic and more variable names that can be traced back to the dpu_hw_catalog or the downstream dtsi files. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_mdss.c | 80 ++ 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index 0454a571adf7..b41848bfff91 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -21,6 +21,7 @@ #define HW_REV 0x0 #define HW_INTR_STATUS 0x0010 +#define UBWC_DEC_HW_VERSION0x58 #define UBWC_STATIC0x144 #define UBWC_CTRL_20x150 #define UBWC_PREDICTION_MODE 0x154 @@ -132,9 +133,63 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss) return 0; } +#define UBWC_1_0 0x1000 +#define UBWC_2_0 0x2000 +#define UBWC_3_0 0x3000 +#define UBWC_4_0 0x4000 + +static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss, + u32 ubwc_static) +{ + writel_relaxed(ubwc_static, msm_mdss->mmio + UBWC_STATIC); +} + +static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss, + unsigned int ubwc_version, + u32 ubwc_swizzle, + u32 highest_bank_bit, + u32 macrotile_mode) +{ + u32 value = (ubwc_swizzle & 0x1) | + (highest_bank_bit & 0x3) << 4 | + (macrotile_mode & 0x1) << 12; + + if (ubwc_version == UBWC_3_0) + value |= BIT(10); + + if (ubwc_version == UBWC_1_0) + value |= BIT(8); + + writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC); +} + +static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss, + unsigned int ubwc_version, + u32 ubwc_swizzle, + u32 ubwc_static, + u32 highest_bank_bit, + u32 macrotile_mode) +{ + u32 value = (ubwc_swizzle & 0x7) | + (ubwc_static & 0x1) << 3 | + (highest_bank_bit & 0x7) << 4 | + (macrotile_mode & 0x1) << 12; + + writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC); + + if (ubwc_version == UBWC_3_0) { + writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2); + writel_relaxed(0, msm_mdss->mmio + UBWC_PREDICTION_MODE); + } else { + writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2); + writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE); + } +} + static int msm_mdss_enable(struct msm_mdss *msm_mdss) { int ret; + u32 hw_rev; ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks); if (ret) { @@ -149,26 +204,35 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) if (msm_mdss->is_mdp5) return 0; + hw_rev = readl_relaxed(msm_mdss->mmio + HW_REV); + dev_dbg(msm_mdss->dev, "HW_REV: 0x%x\n", hw_rev); + dev_dbg(msm_mdss->dev, "UBWC_DEC_HW_VERSION: 0x%x\n", + readl_relaxed(msm_mdss->mmio + UBWC_DEC_HW_VERSION)); + /* * ubwc config is part of the "mdss" region which is not accessible * from the rest of the driver. hardcode known configurations here +* +* Decoder version can be read from the UBWC_DEC_HW_VERSION reg, +* UBWC_n and the rest of params comes from hw_catalog. +* Unforunately this driver can not access hw catalog, so we have to +* hardcode them here. */ - switch (readl_relaxed(msm_mdss->mmio + HW_REV)) { + switch (hw_rev) { case DPU_HW_VER_500: case DPU_HW_VER_501: - writel_relaxed(0x420, msm_mdss->mmio + UBWC_STATIC); + msm_mdss_setup_ubwc_dec_30(msm_mdss, UBWC_3_0, 0, 2, 0); break; case DPU_HW_VER_600: - /* TODO: 0x102e for LP_DDR4 */ - writel_relaxed(0x103e, msm_mdss->mmio + UBWC_STATIC); - writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2); - writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE); + /* TODO: highest_bank_bit = 2 for LP_DDR4 */ + msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 3, 1); break; case DPU_HW_VER_620: - writel_relaxed(0x1e, msm_mdss->mmio + UBWC_STATIC); + /* UBWC_2_0 */ + msm_mdss_setup_ubwc_dec_20(msm_mdss, 0x1e); break; case DPU_HW_VER_720: - writel_relaxed(0x101e, msm_mdss->mmio + UBWC_S
[PATCH 2/5] drm/msm/mdss: enable optional core clock for MDP5 MDSS
Enable (optional) core (MDP_CLK) clock that allows accessing HW_REV registers during the platform init. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_mdss.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index b41848bfff91..f7b4628986b8 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -288,7 +288,7 @@ static int msm_mdss_reset(struct device *dev) /* * MDP5 MDSS uses at most three specified clocks. */ -#define MDP5_MDSS_NUM_CLOCKS 3 +#define MDP5_MDSS_NUM_CLOCKS 4 static int mdp5_mdss_parse_clock(struct platform_device *pdev, struct clk_bulk_data **clocks) { struct clk_bulk_data *bulk; @@ -305,6 +305,7 @@ static int mdp5_mdss_parse_clock(struct platform_device *pdev, struct clk_bulk_d bulk[num_clocks++].id = "iface"; bulk[num_clocks++].id = "bus"; bulk[num_clocks++].id = "vsync"; + bulk[num_clocks++].id = "core"; /* for hw_rev access */ ret = devm_clk_bulk_get_optional(&pdev->dev, num_clocks, bulk); if (ret) -- 2.35.1
[PATCH 05/10] drm: selftest: convert drm_format selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM format selftest to the KUnit API. Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 3 - drivers/gpu/drm/selftests/test-drm_format.c | 280 - .../drm/selftests/test-drm_modeset_common.h | 3 - drivers/gpu/drm/tests/Kconfig | 12 + drivers/gpu/drm/tests/Makefile| 1 + drivers/gpu/drm/tests/test-drm_format.c | 284 ++ 7 files changed, 298 insertions(+), 288 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/test-drm_format.c create mode 100644 drivers/gpu/drm/tests/test-drm_format.c diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 8a794914e328..b7f252d886d0 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ - test-drm_format.o test-drm_framebuffer.o \ - test-drm_dp_mst_helper.o + test-drm_framebuffer.o test-drm_dp_mst_helper.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index a3ca90307364..63061ef55eff 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -7,9 +7,6 @@ * Tests are executed in order by igt/drm_selftests_helper */ selftest(check_plane_state, igt_check_plane_state) -selftest(check_drm_format_block_width, igt_check_drm_format_block_width) -selftest(check_drm_format_block_height, igt_check_drm_format_block_height) -selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c deleted file mode 100644 index c5e212afa27a.. --- a/drivers/gpu/drm/selftests/test-drm_format.c +++ /dev/null @@ -1,280 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Test cases for the drm_format functions - */ - -#define pr_fmt(fmt) "drm_format: " fmt - -#include -#include - -#include - -#include "test-drm_modeset_common.h" - -int igt_check_drm_format_block_width(void *ignored) -{ - const struct drm_format_info *info = NULL; - - /* Test invalid arguments */ - FAIL_ON(drm_format_info_block_width(info, 0) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - FAIL_ON(drm_format_info_block_width(info, 1) != 0); - - /* Test 1 plane format */ - info = drm_format_info(DRM_FORMAT_XRGB); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 1); - FAIL_ON(drm_format_info_block_width(info, 1) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - /* Test 2 planes format */ - info = drm_format_info(DRM_FORMAT_NV12); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 1); - FAIL_ON(drm_format_info_block_width(info, 1) != 1); - FAIL_ON(drm_format_info_block_width(info, 2) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - /* Test 3 planes format */ - info = drm_format_info(DRM_FORMAT_YUV422); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 1); - FAIL_ON(drm_format_info_block_width(info, 1) != 1); - FAIL_ON(drm_format_info_block_width(info, 2) != 1); - FAIL_ON(drm_format_info_block_width(info, 3) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - /* Test a tiled format */ - info = drm_format_info(DRM_FORMAT_X0L0); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 2); - FAIL_ON(drm_format_info_block_width(info, 1) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - return 0; -} - -int igt_check_drm_format_block_height(void *ignored) -{ - const struct drm_format_info *info = NULL; - - /* Test invalid arguments */ - FAIL_ON(drm_format_info_block_height(info, 0) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) != 0); - FAIL_ON(drm_format_info_block_height(info, 1) != 0); - - /* Test 1 plane format */ - info = drm_format_info(DRM_FORMAT_XRGB); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_height(info, 0) != 1); - FAIL_ON(drm_format_info_block_height(info, 1) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) !=
[PATCH 06/10] drm: selftest: convert drm_plane_helper selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM plane helper selftest to the KUnit API. Co-developed-by: Djakson C. G. Filho Signed-off-by: Djakson C. G. Filho Co-developed-by: Anderson Fraga Signed-off-by: Anderson Fraga Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 4 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 1 - .../drm/selftests/test-drm_modeset_common.h | 1 - drivers/gpu/drm/tests/Kconfig | 12 +++ drivers/gpu/drm/tests/Makefile| 1 + .../test-drm_plane_helper.c | 101 ++ 6 files changed, 70 insertions(+), 50 deletions(-) rename drivers/gpu/drm/{selftests => tests}/test-drm_plane_helper.c (62%) diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index b7f252d886d0..9e0ccb482841 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ - test-drm_framebuffer.o test-drm_dp_mst_helper.o +test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o \ + test-drm_dp_mst_helper.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 63061ef55eff..22e467f6465a 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -6,7 +6,6 @@ * * Tests are executed in order by igt/drm_selftests_helper */ -selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 5709d967a5c4..790f3cf31f0d 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -16,7 +16,6 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") -int igt_check_plane_state(void *ignored); int igt_check_drm_framebuffer_create(void *ignored); int igt_dp_mst_calc_pbn_mode(void *ignored); int igt_dp_mst_sideband_msg_req_decode(void *ignored); diff --git a/drivers/gpu/drm/tests/Kconfig b/drivers/gpu/drm/tests/Kconfig index 7c4f76560152..5aa8ac2dd28e 100644 --- a/drivers/gpu/drm/tests/Kconfig +++ b/drivers/gpu/drm/tests/Kconfig @@ -61,4 +61,16 @@ config DRM_FORMAT_KUNIT_TEST If in doubt, say "N". +config DRM_PLANE_HELPER_KUNIT_TEST + tristate "KUnit tests for DRM plane helper" if !DRM_KUNIT_TEST + select DRM_KMS_HELPER + default y if DRM_KUNIT_TEST + help + This option provides KUnit modules that can be used to run + various selftests on parts of the DRM plane helper API. This + option is not useful for distributions or general kernels, but only + for kernel developers working on DRM and associated drivers. + + If in doubt, say "N". + endmenu diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 95d1f67f609d..6e3a10806cd8 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_DRM_DAMAGE_HELPER_KUNIT_TEST) += test-drm_damage_helper.o obj-$(CONFIG_DRM_CMDLINE_PARSER_KUNIT_TEST) += test-drm_cmdline_parser.o obj-$(CONFIG_DRM_RECT_KUNIT_TEST) += test-drm_rect.o obj-$(CONFIG_DRM_FORMAT_KUNIT_TEST) += test-drm_format.o +obj-$(CONFIG_DRM_PLANE_HELPER_KUNIT_TEST) += test-drm_plane_helper.o diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/tests/test-drm_plane_helper.c similarity index 62% rename from drivers/gpu/drm/selftests/test-drm_plane_helper.c rename to drivers/gpu/drm/tests/test-drm_plane_helper.c index b61273e9c403..354c2c8d9f1c 100644 --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c +++ b/drivers/gpu/drm/tests/test-drm_plane_helper.c @@ -3,14 +3,11 @@ * Test cases for the drm_plane_helper functions */ -#define pr_fmt(fmt) "drm_plane_helper: " fmt - +#include #include #include #include -#include "test-drm_modeset_common.h" - static void set_src(struct drm_plane_state *plane_state, unsigned src_x, unsigned src_y, unsigned src_w, unsigned src_h) @@ -73,7 +70,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state, return true; } -int igt_check_plane_state(void *ignored) +static void igt_check_plane_state(struct kunit *test) { int ret; @@ -108,10 +105,10
[PATCH 3/5] drm/msm/mdss: check for core clk before accessing HW_REV
Rather than checking whether the platform is an mdp5 or dpu platform, check if the MDP_CLK is provided or not before trying to access HW_REV (and skip reading the registers if the clock is not provided by the DT). Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_mdss.c | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index f7b4628986b8..d81d8fe3584e 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -32,7 +32,6 @@ struct msm_mdss { void __iomem *mmio; struct clk_bulk_data *clocks; size_t num_clocks; - bool is_mdp5; struct { unsigned long enabled_mask; struct irq_domain *domain; @@ -186,6 +185,19 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss, } } +static bool msm_mdss_has_clock(struct msm_mdss *msm_mdss, const char *name) +{ + unsigned int i; + + for (i = 0; i < msm_mdss->num_clocks; i++) { + if (!strcmp(msm_mdss->clocks[i].id, name) && + msm_mdss->clocks[i].clk) + return true; + } + + return false; +} + static int msm_mdss_enable(struct msm_mdss *msm_mdss) { int ret; @@ -198,10 +210,11 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) } /* -* HW_REV requires MDSS_MDP_CLK, which is not enabled by the mdss on -* mdp5 hardware. Skip reading it for now. +* HW_REV requires MDSS_MDP_CLK, which is not used for MDSS device in +* older device trees. Skip accessing registers if the clock is not +* present. */ - if (msm_mdss->is_mdp5) + if (!msm_mdss_has_clock(msm_mdss, "core")) return 0; hw_rev = readl_relaxed(msm_mdss->mmio + HW_REV); @@ -345,7 +358,6 @@ static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5 return ERR_PTR(ret); } msm_mdss->num_clocks = ret; - msm_mdss->is_mdp5 = is_mdp5; msm_mdss->dev = &pdev->dev; -- 2.35.1
[PATCH 5/5] arm64: dts: qcom: add mdp_clk clock to the MDSS device
Add MDP_CLK ("core") clock to the mdss device to allow MDSS driver to access HW_REV/etc registers. Signed-off-by: Dmitry Baryshkov --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index f0f81c23c16f..3d8ecfe56fb3 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -773,8 +773,9 @@ mdss: mdss@90 { interrupt-controller; #interrupt-cells = <1>; - clocks = <&mmcc MDSS_AHB_CLK>; - clock-names = "iface"; + clocks = <&mmcc MDSS_AHB_CLK>, +<&mmcc MDSS_MDP_CLK>; + clock-names = "iface", "core"; #address-cells = <1>; #size-cells = <1>; -- 2.35.1
[PATCH 4/5] drm/msm/mdss: move is_mdp5 condition to msm_mdss_init
Move is_mdp5 check to a more logical place, to the msm_mdss_init(), rather than getting it in the mdss_probe() and passing it then as an argument. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_mdss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index d81d8fe3584e..ce8ff5bfe55a 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -329,8 +329,9 @@ static int mdp5_mdss_parse_clock(struct platform_device *pdev, struct clk_bulk_d return num_clocks; } -static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5) +static struct msm_mdss *msm_mdss_init(struct platform_device *pdev) { + bool is_mdp5 = of_device_is_compatible(pdev->dev.of_node, "qcom,mdss"); struct msm_mdss *msm_mdss; int ret; int irq; @@ -420,11 +421,10 @@ static const struct dev_pm_ops mdss_pm_ops = { static int mdss_probe(struct platform_device *pdev) { struct msm_mdss *mdss; - bool is_mdp5 = of_device_is_compatible(pdev->dev.of_node, "qcom,mdss"); struct device *dev = &pdev->dev; int ret; - mdss = msm_mdss_init(pdev, is_mdp5); + mdss = msm_mdss_init(pdev); if (IS_ERR(mdss)) return PTR_ERR(mdss); -- 2.35.1
[PATCH 07/10] drm: selftest: convert drm_dp_mst_helper selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM DP MST helper selftest to the KUnit API. Co-developed-by: Rubens Gomes Neto Signed-off-by: Rubens Gomes Neto Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 2 - .../drm/selftests/test-drm_modeset_common.h | 2 - drivers/gpu/drm/tests/Kconfig | 13 +++ drivers/gpu/drm/tests/Makefile| 1 + .../test-drm_dp_mst_helper.c | 82 ++- 6 files changed, 59 insertions(+), 44 deletions(-) rename drivers/gpu/drm/{selftests => tests}/test-drm_dp_mst_helper.c (73%) diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 9e0ccb482841..1539f55db9a7 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o \ - test-drm_dp_mst_helper.o +test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 22e467f6465a..40a29b8cf386 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -7,5 +7,3 @@ * Tests are executed in order by igt/drm_selftests_helper */ selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) -selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) -selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 790f3cf31f0d..3feb2fea1a6b 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -17,7 +17,5 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") int igt_check_drm_framebuffer_create(void *ignored); -int igt_dp_mst_calc_pbn_mode(void *ignored); -int igt_dp_mst_sideband_msg_req_decode(void *ignored); #endif diff --git a/drivers/gpu/drm/tests/Kconfig b/drivers/gpu/drm/tests/Kconfig index 5aa8ac2dd28e..eea0783f981d 100644 --- a/drivers/gpu/drm/tests/Kconfig +++ b/drivers/gpu/drm/tests/Kconfig @@ -73,4 +73,17 @@ config DRM_PLANE_HELPER_KUNIT_TEST If in doubt, say "N". +config DRM_DP_MST_HELPER_KUNIT_TEST + tristate "KUnit tests for DRM DP MST helper" if !DRM_KUNIT_TEST + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_DP_HELPER + default y if DRM_KUNIT_TEST + help + This option provides a kunit module that can be used to run + an unit test on the DRM DP MST helper API. This option is not + useful for distributions or general kernels, but only for kernel + developers working on DRM and associated drivers. + + If in doubt, say "N". + endmenu diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 6e3a10806cd8..735ca8e4c446 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_CMDLINE_PARSER_KUNIT_TEST) += test-drm_cmdline_parser.o obj-$(CONFIG_DRM_RECT_KUNIT_TEST) += test-drm_rect.o obj-$(CONFIG_DRM_FORMAT_KUNIT_TEST) += test-drm_format.o obj-$(CONFIG_DRM_PLANE_HELPER_KUNIT_TEST) += test-drm_plane_helper.o +obj-$(CONFIG_DRM_DP_MST_HELPER_KUNIT_TEST) += test-drm_dp_mst_helper.o diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/tests/test-drm_dp_mst_helper.c similarity index 73% rename from drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c rename to drivers/gpu/drm/tests/test-drm_dp_mst_helper.c index 967c52150b67..88120e878a15 100644 --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c +++ b/drivers/gpu/drm/tests/test-drm_dp_mst_helper.c @@ -5,15 +5,15 @@ #define PREFIX_STR "[drm_dp_mst_helper]" +#include #include #include #include #include "../display/drm_dp_mst_topology_internal.h" -#include "test-drm_modeset_common.h" -int igt_dp_mst_calc_pbn_mode(void *ignored) +static void igt_dp_mst_calc_pbn_mode(struct kunit *test) { int pbn, i; const struct { @@ -33,13 +33,11 @@ int igt_dp_mst_calc_pbn_mode(void *ignored) pbn = drm_dp_calc_pbn_mode(test_params[i].rate, test_params[i].bpp, test_params[i].dsc); - FAIL(pbn != test_params[i].expected, + KUNIT_EXPECT_EQ_MSG(test, pbn, test_params[i].expected, "Expected PBN %d for clock %d bpp %d, got %d\n",
[PATCH 08/10] drm: selftest: convert drm_framebuffer selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM framebuffer selftest to the KUnit API. Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 5 +-- .../gpu/drm/selftests/drm_modeset_selftests.h | 9 -- .../drm/selftests/test-drm_modeset_common.c | 32 --- .../drm/selftests/test-drm_modeset_common.h | 21 drivers/gpu/drm/tests/Kconfig | 12 +++ drivers/gpu/drm/tests/Makefile| 1 + .../test-drm_framebuffer.c| 25 ++- 7 files changed, 31 insertions(+), 74 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/drm_modeset_selftests.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.h rename drivers/gpu/drm/{selftests => tests}/test-drm_framebuffer.c (96%) diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 1539f55db9a7..f7db628b60cb 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,5 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o - -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ - test-drm_buddy.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h deleted file mode 100644 index 40a29b8cf386.. --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_selftests_helper - */ -selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c b/drivers/gpu/drm/selftests/test-drm_modeset_common.c deleted file mode 100644 index 2a7f93774006.. --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Common file for modeset selftests. - */ - -#include - -#include "test-drm_modeset_common.h" - -#define TESTS "drm_modeset_selftests.h" -#include "drm_selftest.h" - -#include "drm_selftest.c" - -static int __init test_drm_modeset_init(void) -{ - int err; - - err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); - - return err > 0 ? 0 : err; -} - -static void __exit test_drm_modeset_exit(void) -{ -} - -module_init(test_drm_modeset_init); -module_exit(test_drm_modeset_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h deleted file mode 100644 index 3feb2fea1a6b.. --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __TEST_DRM_MODESET_COMMON_H__ -#define __TEST_DRM_MODESET_COMMON_H__ - -#include -#include - -#define FAIL(test, msg, ...) \ - do { \ - if (test) { \ - pr_err("%s/%u: " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return -EINVAL; \ - } \ - } while (0) - -#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") - -int igt_check_drm_framebuffer_create(void *ignored); - -#endif diff --git a/drivers/gpu/drm/tests/Kconfig b/drivers/gpu/drm/tests/Kconfig index eea0783f981d..de44385f217e 100644 --- a/drivers/gpu/drm/tests/Kconfig +++ b/drivers/gpu/drm/tests/Kconfig @@ -86,4 +86,16 @@ config DRM_DP_MST_HELPER_KUNIT_TEST If in doubt, say "N". +config DRM_FRAMEBUFFER_KUNIT_TEST + tristate "KUnit tests for DRM framebuffer" if !DRM_KUNIT_TEST + select DRM_KMS_HELPER + default y if DRM_KUNIT_TEST + help + This option provides KUnit modules that can be used to run + various selftests on parts of the DRM framebuffer API. This + option is not useful for distributions or general kernels, but only + for kernel developers working on DRM and associated drivers. + + If in doubt, say "N". + endmenu diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 735ca8e4c446..d802ca0f1544 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_RECT_KUNIT_TEST) += test-drm_rect.o obj-$(CONFIG_DRM_FORMAT_KUNIT_TEST) += test-drm_format.o obj-$(CONFIG_DRM_PLANE_HELPER_KUNIT_TEST) += test-drm_plane_helper.o obj-$
[PATCH 09/10] drm: selftest: convert drm_buddy selftest to KUnit
Considering the current adoption of the KUnit framework, convert the DRM buddy selftest to the KUnit API. Signed-off-by: Maíra Canal --- drivers/gpu/drm/selftests/Makefile| 2 +- .../gpu/drm/selftests/drm_buddy_selftests.h | 15 - drivers/gpu/drm/selftests/test-drm_buddy.c| 994 -- drivers/gpu/drm/tests/Kconfig | 15 + drivers/gpu/drm/tests/Makefile| 1 + drivers/gpu/drm/tests/test-drm_buddy.c| 748 + 6 files changed, 765 insertions(+), 1010 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/drm_buddy_selftests.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_buddy.c create mode 100644 drivers/gpu/drm/tests/test-drm_buddy.c diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index f7db628b60cb..a4ebecb8146b 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_buddy.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o diff --git a/drivers/gpu/drm/selftests/drm_buddy_selftests.h b/drivers/gpu/drm/selftests/drm_buddy_selftests.h deleted file mode 100644 index 455b756c4ae5.. --- a/drivers/gpu/drm/selftests/drm_buddy_selftests.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_buddy - */ -selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */ -selftest(buddy_alloc_limit, igt_buddy_alloc_limit) -selftest(buddy_alloc_range, igt_buddy_alloc_range) -selftest(buddy_alloc_optimistic, igt_buddy_alloc_optimistic) -selftest(buddy_alloc_pessimistic, igt_buddy_alloc_pessimistic) -selftest(buddy_alloc_smoke, igt_buddy_alloc_smoke) -selftest(buddy_alloc_pathological, igt_buddy_alloc_pathological) diff --git a/drivers/gpu/drm/selftests/test-drm_buddy.c b/drivers/gpu/drm/selftests/test-drm_buddy.c deleted file mode 100644 index aca0c491040f.. --- a/drivers/gpu/drm/selftests/test-drm_buddy.c +++ /dev/null @@ -1,994 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2019 Intel Corporation - */ - -#define pr_fmt(fmt) "drm_buddy: " fmt - -#include -#include -#include - -#include - -#include "../lib/drm_random.h" - -#define TESTS "drm_buddy_selftests.h" -#include "drm_selftest.h" - -#define IGT_TIMEOUT(name__) \ - unsigned long name__ = jiffies + MAX_SCHEDULE_TIMEOUT - -static unsigned int random_seed; - -static inline u64 get_size(int order, u64 chunk_size) -{ - return (1 << order) * chunk_size; -} - -__printf(2, 3) -static bool __igt_timeout(unsigned long timeout, const char *fmt, ...) -{ - va_list va; - - if (!signal_pending(current)) { - cond_resched(); - if (time_before(jiffies, timeout)) - return false; - } - - if (fmt) { - va_start(va, fmt); - vprintk(fmt, va); - va_end(va); - } - - return true; -} - -static inline const char *yesno(bool v) -{ - return v ? "yes" : "no"; -} - -static void __igt_dump_block(struct drm_buddy *mm, -struct drm_buddy_block *block, -bool buddy) -{ - pr_err("block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%s buddy=%s\n", - block->header, - drm_buddy_block_state(block), - drm_buddy_block_order(block), - drm_buddy_block_offset(block), - drm_buddy_block_size(mm, block), - yesno(!block->parent), - yesno(buddy)); -} - -static void igt_dump_block(struct drm_buddy *mm, - struct drm_buddy_block *block) -{ - struct drm_buddy_block *buddy; - - __igt_dump_block(mm, block, false); - - buddy = drm_get_buddy(block); - if (buddy) - __igt_dump_block(mm, buddy, true); -} - -static int igt_check_block(struct drm_buddy *mm, - struct drm_buddy_block *block) -{ - struct drm_buddy_block *buddy; - unsigned int block_state; - u64 block_size; - u64 offset; - int err = 0; - - block_state = drm_buddy_block_state(block); - - if (block_state != DRM_BUDDY_ALLOCATED && - block_state != DRM_BUDDY_FREE && - block_state != DRM_BUDDY_SPLIT) { - pr_err("block state mismatch\n"); - err = -EINVAL; - } - - block_size = drm_buddy_block_size(mm, block); - offset = drm_buddy_block_offset(block); - - if (block_size < mm->chunk_size) { - pr_err("block size smaller than min size\n"); -
[PATCH 02/10] drm: selftest: refactor drm_cmdline_parser
From: Arthur Grillo Refactor the tests by modularizing the functions to avoid code repetition. Co-developed-by: Maíra Canal Signed-off-by: Arthur Grillo Signed-off-by: Maíra Canal --- .../drm/selftests/test-drm_cmdline_parser.c | 579 +- 1 file changed, 156 insertions(+), 423 deletions(-) diff --git a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c index d96cd890def6..57a229c5fc35 100644 --- a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c +++ b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2019 Bootlin + * Copyright (c) 2021 Ma�ra Canal , + * Copyright (c) 2021 Arthur Grillo */ #define pr_fmt(fmt) "drm_cmdline: " fmt @@ -17,13 +19,25 @@ static const struct drm_connector no_connector = {}; -static int drm_cmdline_test_force_e_only(void *ignored) +static int drm_cmdline_test_properties(void *ignored, + struct drm_cmdline_mode *mode, enum drm_connector_force force) +{ + FAIL_ON(mode->rb); + FAIL_ON(mode->cvt); + FAIL_ON(mode->interlace); + FAIL_ON(mode->margins); + FAIL_ON(mode->force != force); + + return 0; +} + +static int drm_cmdline_test_force_only(void *ignored, char *cmdline, + const struct drm_connector *connector, enum drm_connector_force force) { struct drm_cmdline_mode mode = { }; - FAIL_ON(!drm_mode_parse_command_line_for_connector("e", - &no_connector, - &mode)); + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + connector, &mode)); FAIL_ON(mode.specified); FAIL_ON(mode.refresh_specified); FAIL_ON(mode.bpp_specified); @@ -32,95 +46,101 @@ static int drm_cmdline_test_force_e_only(void *ignored) FAIL_ON(mode.cvt); FAIL_ON(mode.interlace); FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); + FAIL_ON(mode.force != force); return 0; } -static int drm_cmdline_test_force_D_only_not_digital(void *ignored) +static int drm_cmdline_test_freestanding(void *ignored, + struct drm_cmdline_mode *mode, char *cmdline, + const struct drm_connector *connector) { - struct drm_cmdline_mode mode = { }; + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + connector, mode)); + FAIL_ON(mode->specified); + FAIL_ON(mode->refresh_specified); + FAIL_ON(mode->bpp_specified); - FAIL_ON(!drm_mode_parse_command_line_for_connector("D", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); + FAIL_ON(mode->tv_margins.right != 14); + FAIL_ON(mode->tv_margins.left != 24); + FAIL_ON(mode->tv_margins.bottom != 36); + FAIL_ON(mode->tv_margins.top != 42); - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); + return 0; +} + +static int drm_cmdline_test_res_init(void *ignored, + struct drm_cmdline_mode *mode, char *cmdline) +{ + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + &no_connector, mode)); + FAIL_ON(!mode->specified); + FAIL_ON(mode->xres != 720); + FAIL_ON(mode->yres != 480); + + return 0; +} + +static int drm_cmdline_test_res_bpp_init(void *ignored, + struct drm_cmdline_mode *mode, char *cmdline) +{ + FAIL_ON(!drm_mode_parse_command_line_for_connector(cmdline, + &no_connector, mode)); + FAIL_ON(!mode->specified); + FAIL_ON(mode->xres != 720); + FAIL_ON(mode->yres != 480); + + FAIL_ON(!mode->refresh_specified); + FAIL_ON(mode->refresh != 60); + FAIL_ON(!mode->bpp_specified); + FAIL_ON(mode->bpp != 24); + + return 0; +} + +static int drm_cmdline_test_force_e_only(void *ignored) +{ + drm_cmdline_test_force_only(ignored, "e", &no_connector, DRM_FORCE_ON); + + return 0; +} + +static int drm_cmdline_test_force_D_only_not_digital(void *ignored) +{ + drm_cmdline_test_force_only(ignored, "D", &no_connector, DRM_FORCE_ON); return 0; } static const struct drm_connector connector_hdmi = { .connector_type = DRM_MODE_CONNECTOR_HDMIB, + }; static int drm_cmdline_test_force_D_only_hdmi(void *ignored) { - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_
Please add another drm/msm tree to the linux-next
Hi Stephen, I would appreciate if you could add https://gitlab.freedesktop.org/lumag/msm.git msm-next-lumag to the linux-next tree. This tree is a part of drm/msm maintenance structure. As a co-maintainer I collect and test display patches, while Rob concenctrates on GPU part of the driver. Later during the release cycle these patchesare pulled by Rob Clark directly into msm-next. During last cycle Rob suggested adding this tree to the linux-next effort, so that the patches receive better integration testing during the Linux development cycle. Thanks! -- With best wishes Dmitry
[PATCH 10/10] drm: selftest: convert drm_mm selftest to KUnit
From: Arthur Grillo Considering the current adoption of the KUnit framework, convert the DRM mm selftest to the KUnit API. Signed-off-by: Arthur Grillo Signed-off-by: Maíra Canal --- drivers/gpu/drm/Kconfig | 20 - drivers/gpu/drm/Makefile |1 - drivers/gpu/drm/selftests/Makefile|2 - drivers/gpu/drm/selftests/drm_mm_selftests.h | 28 - drivers/gpu/drm/selftests/drm_selftest.c | 109 -- drivers/gpu/drm/selftests/drm_selftest.h | 41 - drivers/gpu/drm/tests/Kconfig | 14 + drivers/gpu/drm/tests/Makefile|1 + .../drm/{selftests => tests}/test-drm_mm.c| 1135 +++-- 9 files changed, 465 insertions(+), 886 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/Makefile delete mode 100644 drivers/gpu/drm/selftests/drm_mm_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.c delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.h rename drivers/gpu/drm/{selftests => tests}/test-drm_mm.c (58%) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index bd1b5d82c9cf..f1330d091a6e 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -50,26 +50,6 @@ config DRM_DEBUG_MM If in doubt, say "N". -config DRM_DEBUG_SELFTEST - tristate "kselftests for DRM" - depends on DRM - depends on DEBUG_KERNEL - select PRIME_NUMBERS - select DRM_DISPLAY_DP_HELPER - select DRM_DISPLAY_HELPER - select DRM_LIB_RANDOM - select DRM_KMS_HELPER - select DRM_BUDDY - select DRM_EXPORT_FOR_TESTS if m - default n - help - This option provides kernel modules that can be used to run - various selftests on parts of the DRM api. This option is not - useful for distributions or general kernels, but only for kernel - developers working on DRM and associated drivers. - - If in doubt, say "N". - source "drivers/gpu/drm/tests/Kconfig" config DRM_KMS_HELPER diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0f24aa542be0..8322a740146f 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -75,7 +75,6 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o # Drivers and the rest # -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ obj-y += tests/ obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile deleted file mode 100644 index a4ebecb8146b.. --- a/drivers/gpu/drm/selftests/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h b/drivers/gpu/drm/selftests/drm_mm_selftests.h deleted file mode 100644 index 8c87c964176b.. --- a/drivers/gpu/drm/selftests/drm_mm_selftests.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_mm - */ -selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */ -selftest(init, igt_init) -selftest(debug, igt_debug) -selftest(reserve, igt_reserve) -selftest(insert, igt_insert) -selftest(replace, igt_replace) -selftest(insert_range, igt_insert_range) -selftest(align, igt_align) -selftest(frag, igt_frag) -selftest(align32, igt_align32) -selftest(align64, igt_align64) -selftest(evict, igt_evict) -selftest(evict_range, igt_evict_range) -selftest(bottomup, igt_bottomup) -selftest(lowest, igt_lowest) -selftest(topdown, igt_topdown) -selftest(highest, igt_highest) -selftest(color, igt_color) -selftest(color_evict, igt_color_evict) -selftest(color_evict_range, igt_color_evict_range) diff --git a/drivers/gpu/drm/selftests/drm_selftest.c b/drivers/gpu/drm/selftests/drm_selftest.c deleted file mode 100644 index e29ed9faef5b.. --- a/drivers/gpu/drm/selftests/drm_selftest.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright © 2016 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED,
Re: [PATCH] drm/i915/pvc: Add recommended MMIO setting
On Mon, 2022-06-13 at 09:53 -0700, Matt Roper wrote: > As with past platforms, the bspec's performance tuning guide provides > recommended MMIO settings. Although not technically "workarounds" we > apply these through the workaround framework to ensure that they're > re-applied at the proper times (e.g., on engine resets) and that any > conflicts with real workarounds are flagged. Reviewed-by: José Roberto de Souza > > Bspec: 72161 > Signed-off-by: Matt Roper > --- > drivers/gpu/drm/i915/gt/intel_gt_regs.h | 5 + > drivers/gpu/drm/i915/gt/intel_workarounds.c | 9 + > 2 files changed, 14 insertions(+) > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h > b/drivers/gpu/drm/i915/gt/intel_gt_regs.h > index 226557018037..07ef111947b8 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h > @@ -981,6 +981,11 @@ > #define XEHP_L3SCQREG7 _MMIO(0xb188) > #define BLEND_FILL_CACHING_OPT_DIS REG_BIT(3) > > +#define XEHPC_L3SCRUB_MMIO(0xb18c) > +#define SCRUB_CL_DWNGRADE_SHARED REG_BIT(12) > +#define SCRUB_RATE_PER_BANK_MASK REG_GENMASK(2, 0) > +#define SCRUB_RATE_4B_PER_CLK > REG_FIELD_PREP(SCRUB_RATE_PER_BANK_MASK, 0x6) > + > #define L3SQCREG1_CCS0 _MMIO(0xb200) > #define FLUSHALLNONCOH REG_BIT(5) > > diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c > b/drivers/gpu/drm/i915/gt/intel_workarounds.c > index 1e982ac931dc..c4af51144216 100644 > --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c > +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c > @@ -2679,6 +2679,15 @@ general_render_compute_wa_init(struct intel_engine_cs > *engine, struct i915_wa_li > { > struct drm_i915_private *i915 = engine->i915; > > + if (IS_PONTEVECCHIO(i915)) { > + /* > + * The following is not actually a "workaround" but rather > + * a recommended tuning setting documented in the bspec's > + * performance guide section. > + */ > + wa_write(wal, XEHPC_L3SCRUB, SCRUB_CL_DWNGRADE_SHARED | > SCRUB_RATE_4B_PER_CLK); > + } > + > if (IS_XEHPSDV(i915)) { > /* Wa_1409954639 */ > wa_masked_en(wal,
Re: [PATCH] drm/msm/gem: Drop early returns in close/purge vma
On Sat, Jun 11, 2022 at 11:16 AM Steev Klimaszewski wrote: > > Hi Rob, > > On 6/10/22 12:20 PM, Rob Clark wrote: > > From: Rob Clark > > > > Keep the warn, but drop the early return. If we do manage to hit this > > sort of issue, skipping the cleanup just makes things worse (dangling > > drm_mm_nodes when the msm_gem_vma is freed, etc). Whereas the worst > > that happens if we tear down a mapping the GPU is accessing is that we > > get GPU iova faults, but otherwise the world keeps spinning. > > forgot this initially: Reported-by: Steev Klimaszewski > > Signed-off-by: Rob Clark > > --- > > drivers/gpu/drm/msm/msm_gem_vma.c | 6 ++ > > 1 file changed, 2 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c > > b/drivers/gpu/drm/msm/msm_gem_vma.c > > index 3c1dc9241831..c471aebcdbab 100644 > > --- a/drivers/gpu/drm/msm/msm_gem_vma.c > > +++ b/drivers/gpu/drm/msm/msm_gem_vma.c > > @@ -62,8 +62,7 @@ void msm_gem_purge_vma(struct msm_gem_address_space > > *aspace, > > unsigned size = vma->node.size; > > > > /* Print a message if we try to purge a vma in use */ > > - if (GEM_WARN_ON(msm_gem_vma_inuse(vma))) > > - return; > > + GEM_WARN_ON(msm_gem_vma_inuse(vma)); > > > > /* Don't do anything if the memory isn't mapped */ > > if (!vma->mapped) > > @@ -128,8 +127,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, > > void msm_gem_close_vma(struct msm_gem_address_space *aspace, > > struct msm_gem_vma *vma) > > { > > - if (GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped)) > > - return; > > + GEM_WARN_ON(msm_gem_vma_inuse(vma) || vma->mapped); > > > > spin_lock(&aspace->lock); > > if (vma->iova) > > I've seen the splat on the Lenovo Yoga C630 here, and have tested this > patch, and as described, the splat still happens, but the system is > still able to be used. > > Tested-by: Steev Klimaszewski >
[PATCH 1/2] drm/msm: Drop update_fences()
From: Rob Clark I noticed while looking at some traces, that we could miss calls to msm_update_fence(), as the irq could have raced with retire_submits() which could have already popped the last submit on a ring out of the queue of in-flight submits. But walking the list of submits in the irq handler isn't really needed, as dma_fence_is_signaled() will dtrt. So lets just drop it entirely. Reported-by: Steev Klimaszewski Fixes: 95d1deb02a9c ("drm/msm/gem: Add fenced vma unpin") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 22 ++ 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index e59a757578df..b61078f0cd0f 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -176,24 +176,6 @@ int msm_gpu_hw_init(struct msm_gpu *gpu) return ret; } -static void update_fences(struct msm_gpu *gpu, struct msm_ringbuffer *ring, - uint32_t fence) -{ - struct msm_gem_submit *submit; - unsigned long flags; - - spin_lock_irqsave(&ring->submit_lock, flags); - list_for_each_entry(submit, &ring->submits, node) { - if (fence_after(submit->seqno, fence)) - break; - - msm_update_fence(submit->ring->fctx, - submit->hw_fence->seqno); - dma_fence_signal(submit->hw_fence); - } - spin_unlock_irqrestore(&ring->submit_lock, flags); -} - #ifdef CONFIG_DEV_COREDUMP static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset, size_t count, void *data, size_t datalen) @@ -450,7 +432,7 @@ static void recover_worker(struct kthread_work *work) if (ring == cur_ring) fence++; - update_fences(gpu, ring, fence); + msm_update_fence(ring->fctx, fence); } if (msm_gpu_active(gpu)) { @@ -753,7 +735,7 @@ void msm_gpu_retire(struct msm_gpu *gpu) int i; for (i = 0; i < gpu->nr_rings; i++) - update_fences(gpu, gpu->rb[i], gpu->rb[i]->memptrs->fence); + msm_update_fence(gpu->rb[i]->fctx, gpu->rb[i]->memptrs->fence); kthread_queue_work(gpu->worker, &gpu->retire_work); update_sw_cntrs(gpu); -- 2.36.1
[PATCH 2/2] drm/msm: Don't overwrite hw fence in hw_init
From: Rob Clark Prior to the last commit, this could result in setting the GPU written fence value back to an older value, if we had missed updating completed_fence prior to suspend. This was mostly harmless as the GPU would eventually overwrite it again with the correct value. But we should just not do this. Instead just leave a sanity check that the fence looks plausible (in case the GPU scribbled on memory). Reported-by: Steev Klimaszewski Fixes: 95d1deb02a9c ("drm/msm/gem: Add fenced vma unpin") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 11 --- drivers/gpu/drm/msm/msm_gpu.c | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index e1aef4875e2f..dd044d557c7c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -498,10 +498,15 @@ int adreno_hw_init(struct msm_gpu *gpu) ring->cur = ring->start; ring->next = ring->start; - - /* reset completed fence seqno: */ - ring->memptrs->fence = ring->fctx->completed_fence; ring->memptrs->rptr = 0; + + /* Detect and clean up an impossible fence, ie. if GPU managed +* to scribble something invalid, we don't want that to confuse +* us into mistakingly believing that submits have completed. +*/ + if (fence_before(ring->fctx->last_fence, ring->memptrs->fence)) { + ring->memptrs->fence = ring->fctx->last_fence; + } } return 0; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index b61078f0cd0f..8c00f9187c03 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -430,7 +430,7 @@ static void recover_worker(struct kthread_work *work) * one more to clear the faulting submit */ if (ring == cur_ring) - fence++; + ring->memptrs->fence = ++fence; msm_update_fence(ring->fctx, fence); } -- 2.36.1
DRM FB interface does not sanitize len when mmap'ed
I am crashing the kernel by doing something I believe I am allowed to do. Using mmap to write to /dev/fb0 as the compatibility layer for Tiny DRM vot,v220hf01a-t (ili9225). First it happens that because of the display resolution of 220*176 the buffer is (16 bit) 77440 bytes, which is not a multiple of the page size (4096), unlike most regular resolution displays. When I touch the mmap'ed virtual address above base+73728 (4096*18) up to 77439: auto file = open("/dev/fb0", O_RDWR); if (!file) throw; auto fbp = (char *)mmap(0, 220 * 176 * 2, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); if ((size_t)fbp <= 0) throw; fbp[220 * 176 * 2 - 2] = 0; I get a crash: [ 14.150463] Unable to handle kernel paging request at virtual address ffc00827c000 [ 14.158640] Mem abort info: [ 14.161626] ESR = 0x9607 [ 14.164969] EC = 0x25: DABT (current EL), IL = 32 bits [ 14.170470] SET = 0, FnV = 0 [ 14.173735] EA = 0, S1PTW = 0 [ 14.177047] FSC = 0x07: level 3 translation fault [ 14.182095] Data abort info: [ 14.185083] ISV = 0, ISS = 0x0007 [ 14.189035] CM = 0, WnR = 0 [ 14.192107] swapper pgtable: 4k pages, 39-bit VAs, pgdp=00d54000 [ 14.198997] [ffc00827c000] pgd=11501003, p4d=11501003, pud=11501003, pmd=11d5c003, pte= [ 14.211992] Internal error: Oops: 9607 [#1] PREEMPT SMP [ 14.217659] CPU: 0 PID: 50 Comm: kworker/0:2 Not tainted 5.18.3 #18 [ 14.224027] Hardware name: Raspberry Pi Compute Module 3 Plus Rev 1.0 (DT) [ 14.231005] Workqueue: events drm_fb_helper_damage_work [ 14.236333] pstate: 2005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 14.243405] pc : __memcpy+0x15c/0x230 [ 14.247131] lr : drm_fb_helper_damage_work+0x25c/0x310 [ 14.252352] sp : ffc00822bd30 [ 14.255712] x29: ffc00822bd30 x28: 01b8 x27: ff80017e1d10 [ 14.262970] x26: ffc008267e80 x25: 00b0 x24: ff8002416800 [ 14.270228] x23: ff8001fd8080 x22: ff80017e1c00 x21: ff80017e1ccc [ 14.277487] x20: ffc00827be80 x19: ff80017e1cd0 x18: ffe5d80bac08 [ 14.284745] x17: 0013 x16: 00fe72080e00 x15: [ 14.292003] x14: x13: x12: [ 14.299259] x11: x10: x9 : [ 14.306517] x8 : x7 : x6 : [ 14.313772] x5 : ffc008268038 x4 : ffc00827c038 x3 : ffc008267fc0 [ 14.321029] x2 : 0028 x1 : ffc00827bfc0 x0 : ffc008267e80 [ 14.328288] Call trace: [ 14.330766] __memcpy+0x15c/0x230 [ 14.334135] process_one_work+0x1dc/0x450 [ 14.338214] worker_thread+0x300/0x450 [ 14.342025] kthread+0x100/0x110 [ 14.345305] ret_from_fork+0x10/0x20 [ 14.348947] Code: a9422428 a9032c6a a9432c2a a984346c (a9c4342c) [ 14.355132] ---[ end trace ]--- By constraining the input with this small patch it works fine: --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -684,11 +684,13 @@ static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, size_t len, struct drm_rect *clip) { + struct drm_fb_helper *fb_helper = info->par; + off_t end = off + len; u32 x1 = 0; u32 y1 = off / info->fix.line_length; u32 x2 = info->var.xres; - u32 y2 = DIV_ROUND_UP(end, info->fix.line_length); + u32 y2 = min_t(u32, DIV_ROUND_UP(end, info->fix.line_length), fb_helper->fb->height); if ((y2 - y1) == 1) { /* I am sure this patch is not how it should be fixed, but I have no knowledge of the subsystem to fix it "at the right place". Thanks, Nuno
Re: [RFC 1/3] drm/amd/display: Introduce KUnit to DML
Hi Daniel Thank you for your feedback! We are working on the comments you pointed out. On 6/7/22 23:36, Daniel Latypov wrote: > On Tue, Jun 7, 2022 at 6:09 PM Maíra Canal wrote: >> diff --git >> a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/display_mode_lib_test.c >> b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/display_mode_lib_test.c >> new file mode 100644 >> index ..3ea0e7fb13e3 >> --- /dev/null >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/display_mode_lib_test.c >> @@ -0,0 +1,83 @@ >> +// SPDX-License-Identifier: MIT >> +/* >> + * KUnit tests for dml/display_mode_lib.h >> + * >> + * Copyright (C) 2022, Maíra Canal >> + */ >> + >> +#include >> +#include "../../dc/dml/display_mode_lib.h" >> +#include "../../dc/dml/display_mode_enums.h" >> +#include "dml_test.h" >> + >> +/** >> + * DOC: Unit tests for AMDGPU DML display_mode_lib.h >> + * >> + * The display_mode_lib.h holds the functions responsible for the >> instantiation >> + * and logging of the Display Mode Library (DML). >> + * >> + * These KUnit tests were implemented with the intention of assuring the >> proper >> + * logging of the DML. >> + * >> + */ >> + >> +static void dml_get_status_message_test(struct kunit *test) >> +{ > > I think this is a case where an exhaustive test might not be warranted. > The function under test is entirely just a switch statement with > return statements, so the chances of things going wrong is minimal. > But that's just my personal preference. Maybe we left out some explanation on this unit test. This RFC was more of an introduction to our project. We wanted to show you the test structure we plan to develop the unit tests during this summer. Initially, we were thinking of using the typical kunit_test_suites structure, but we end up checking out that it wasn't possible, due to the need to insert the tests inside the AMDGPU stack. We also agree with you that this test is trivial and it will probably be removed from the final version. We plan to have more functional tests that explore the inner workings of the DML and especially the corner cases as you said. We apologize if we didn't make it clear in the Cover Letter that this RFC is more of an introduction to the project we pretend to develop in the summer. If you have suggestions on how we can improve the use of KUnit, it is welcome. >> >> +int display_mode_lib_test_init(void) >> +{ >> + pr_info("===> Running display_mode_lib KUnit Tests"); >> + >> pr_info("**"); >> + pr_info("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE >> **"); >> + pr_info("** >> **"); >> + pr_info("** display_mode_lib KUnit Tests are being run. This >> **"); >> + pr_info("** means that this is a TEST kernel and should not be >> **"); >> + pr_info("** used for production. >> **"); >> + pr_info("** >> **"); >> + pr_info("** If you see this message and you are not debugging >> **"); >> + pr_info("** the kernel, report this immediately to your vendor! >> **"); >> + pr_info("** >> **"); >> + >> pr_info("**"); > > David Gow proposed tainting the kernel if we ever try to run a KUnit > test suite here: > https://lore.kernel.org/linux-kselftest/20220513083212.3537869-2-david...@google.com/ > > If that goes in, then this logging might not be as necessary. > I'm not sure what the status of that change is, but we're at least > waiting on a v4, I think. This is going to be great! We will keep an eye on this proposal. - Maíra Canal
Re: [Intel-gfx] [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition
On Wed, Jun 15, 2022 at 08:22:23AM +0100, Tvrtko Ursulin wrote: On 14/06/2022 17:42, Niranjana Vishwanathapura wrote: On Tue, Jun 14, 2022 at 05:07:37PM +0100, Tvrtko Ursulin wrote: On 14/06/2022 17:02, Tvrtko Ursulin wrote: On 14/06/2022 16:43, Niranjana Vishwanathapura wrote: On Tue, Jun 14, 2022 at 08:16:41AM +0100, Tvrtko Ursulin wrote: On 14/06/2022 00:39, Matthew Brost wrote: On Mon, Jun 13, 2022 at 07:09:06PM +0100, Tvrtko Ursulin wrote: On 13/06/2022 18:49, Niranjana Vishwanathapura wrote: On Mon, Jun 13, 2022 at 05:22:02PM +0100, Tvrtko Ursulin wrote: On 13/06/2022 16:05, Niranjana Vishwanathapura wrote: On Mon, Jun 13, 2022 at 09:24:18AM +0100, Tvrtko Ursulin wrote: On 10/06/2022 17:14, Niranjana Vishwanathapura wrote: On Fri, Jun 10, 2022 at 05:48:39PM +0300, Lionel Landwerlin wrote: On 10/06/2022 13:37, Tvrtko Ursulin wrote: On 10/06/2022 08:07, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 490 +++ 1 file changed, 490 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..9fc854969cfb --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,490 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + * bit[0]: If set, VM_BIND is supported, otherwise not. + * bits[8-15]: VM_BIND implementation version. + * version 0 will not have VM_BIND/UNBIND timeline fence array support. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/** + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING + * + * Flag to declare context as long running. + * See struct drm_i915_gem_context_create_ext flags. + * + * Usage of dma-fence expects that they complete in reasonable amount of time. + * Compute on the other hand can be long running. Hence it is not appropriate + * for compute contexts to export request completion dma-fence to user. + * The dma-fence usage will be limited to in-kernel consumption only. + * Compute contexts need to use user/memory fence. + * + * So, long running contexts do not support output fences. Hence, + * I915_EXEC_FENCE_SIGNAL (See &drm_i915_gem_exec_fence.flags) is expected + * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for + * objects mapped to long running contexts. + */ +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING (1u << 2) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f +#define DRM_I915_GEM_WAIT_USER_FENCE 0x40 + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence) + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @queue_idx specifies the queue to use for binding. Same queue can be + * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind + * operations in a queue are performed in the order of submission. + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. + * Also, on those platforms, it is not allowed to bind an device local-
[PATCH 5/6] drm/i915/gt: Serialize GRDOM access between multiple engine resets
From: Chris Wilson Don't allow two engines to be reset in parallel, as they would both try to select a reset bit (and send requests to common registers) and wait on that register, at the same time. Serialize control of the reset requests/acks using the uncore->lock, which will also ensure that no other GT state changes at the same time as the actual reset. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Reported-by: Mika Kuoppala Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Andi Shyti Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/gt/intel_reset.c | 37 --- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index a5338c3fde7a..c68d36fb5bbd 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -300,9 +300,9 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask) return err; } -static int gen6_reset_engines(struct intel_gt *gt, - intel_engine_mask_t engine_mask, - unsigned int retry) +static int __gen6_reset_engines(struct intel_gt *gt, + intel_engine_mask_t engine_mask, + unsigned int retry) { struct intel_engine_cs *engine; u32 hw_mask; @@ -321,6 +321,20 @@ static int gen6_reset_engines(struct intel_gt *gt, return gen6_hw_domain_reset(gt, hw_mask); } +static int gen6_reset_engines(struct intel_gt *gt, + intel_engine_mask_t engine_mask, + unsigned int retry) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(>->uncore->lock, flags); + ret = __gen6_reset_engines(gt, engine_mask, retry); + spin_unlock_irqrestore(>->uncore->lock, flags); + + return ret; +} + static struct intel_engine_cs *find_sfc_paired_vecs_engine(struct intel_engine_cs *engine) { int vecs_id; @@ -487,9 +501,9 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine) rmw_clear_fw(uncore, sfc_lock.lock_reg, sfc_lock.lock_bit); } -static int gen11_reset_engines(struct intel_gt *gt, - intel_engine_mask_t engine_mask, - unsigned int retry) +static int __gen11_reset_engines(struct intel_gt *gt, +intel_engine_mask_t engine_mask, +unsigned int retry) { struct intel_engine_cs *engine; intel_engine_mask_t tmp; @@ -583,8 +597,11 @@ static int gen8_reset_engines(struct intel_gt *gt, struct intel_engine_cs *engine; const bool reset_non_ready = retry >= 1; intel_engine_mask_t tmp; + unsigned long flags; int ret; + spin_lock_irqsave(>->uncore->lock, flags); + for_each_engine_masked(engine, gt, engine_mask, tmp) { ret = gen8_engine_reset_prepare(engine); if (ret && !reset_non_ready) @@ -612,17 +629,19 @@ static int gen8_reset_engines(struct intel_gt *gt, * This is best effort, so ignore any error from the initial reset. */ if (IS_DG2(gt->i915) && engine_mask == ALL_ENGINES) - gen11_reset_engines(gt, gt->info.engine_mask, 0); + __gen11_reset_engines(gt, gt->info.engine_mask, 0); if (GRAPHICS_VER(gt->i915) >= 11) - ret = gen11_reset_engines(gt, engine_mask, retry); + ret = __gen11_reset_engines(gt, engine_mask, retry); else - ret = gen6_reset_engines(gt, engine_mask, retry); + ret = __gen6_reset_engines(gt, engine_mask, retry); skip_reset: for_each_engine_masked(engine, gt, engine_mask, tmp) gen8_engine_reset_cancel(engine); + spin_unlock_irqrestore(>->uncore->lock, flags); + return ret; } -- 2.36.1
[PATCH 6/6] drm/i915/gt: Serialize TLB invalidates with GT resets
From: Chris Wilson Avoid trying to invalidate the TLB in the middle of performing an engine reset, as this may result in the reset timing out. Currently, the TLB invalidate is only serialised by its own mutex, forgoing the uncore lock, but we can take the uncore->lock as well to serialise the mmio access, thereby serialising with the GDRST. Tested on a NUC5i7RYB, BIOS RYBDWi35.86A.0380.2019.0517.1530 with i915 selftest/hangcheck. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Reported-by: Mauro Carvalho Chehab Tested-by: Mauro Carvalho Chehab Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/gt/intel_gt.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index fb4fd5273ca4..33eb93586858 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -1248,6 +1248,8 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) mutex_lock(>->tlb_invalidate_lock); intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); + spin_lock_irq(&uncore->lock); /* seralise invalidate with GT reset */ + awake = 0; for_each_engine(engine, gt, id) { struct reg_and_bit rb; @@ -1272,6 +1274,8 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) IS_ALDERLAKE_P(i915))) intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1); + spin_unlock_irq(&uncore->lock); + for_each_engine_masked(engine, gt, awake, tmp) { struct reg_and_bit rb; -- 2.36.1
[PATCH 4/6] drm/i915/gt: Only invalidate TLBs exposed to user manipulation
From: Chris Wilson Don't flush TLBs when the buffer is only used in the GGTT under full control of the kernel, as there's no risk of of concurrent access and stale access from prefetch. We only need to invalidate the TLB if they are accessible by the user. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Signed-off-by: Chris Wilson Cc: Fei Yang Cc: Andi Shyti Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/i915_vma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 0bffb70b3c5f..7989986161e8 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -537,7 +537,8 @@ int i915_vma_bind(struct i915_vma *vma, bind_flags); } - set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); + if (bind_flags & I915_VMA_LOCAL_BIND) + set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); atomic_or(bind_flags, &vma->flags); return 0; -- 2.36.1
[PATCH 0/6] Fix TLB invalidate issues with Broadwell
i915 selftest hangcheck is causing the i915 driver timeouts, as reported by Intel CI bot: http://gfx-ci.fi.intel.com/cibuglog-ng/issuefilterassoc/24297?query_key=42a999f48fa6ecce068bc8126c069be7c31153b4 When such test runs, the only output is: [ 68.811639] i915: Performing live selftests with st_random_seed=0xe138eac7 st_timeout=500 [ 68.811792] i915: Running hangcheck [ 68.811859] i915: Running intel_hangcheck_live_selftests/igt_hang_sanitycheck [ 68.816910] i915 :00:02.0: [drm] Cannot find any crtc or sizes [ 68.841597] i915: Running intel_hangcheck_live_selftests/igt_reset_nop [ 69.346347] igt_reset_nop: 80 resets [ 69.362695] i915: Running intel_hangcheck_live_selftests/igt_reset_nop_engine [ 69.863559] igt_reset_nop_engine(rcs0): 709 resets [ 70.364924] igt_reset_nop_engine(bcs0): 903 resets [ 70.866005] igt_reset_nop_engine(vcs0): 659 resets [ 71.367934] igt_reset_nop_engine(vcs1): 549 resets [ 71.869259] igt_reset_nop_engine(vecs0): 553 resets [ 71.882592] i915: Running intel_hangcheck_live_selftests/igt_reset_idle_engine [ 72.383554] rcs0: Completed 16605 idle resets [ 72.884599] bcs0: Completed 18641 idle resets [ 73.385592] vcs0: Completed 17517 idle resets [ 73.886658] vcs1: Completed 15474 idle resets [ 74.387600] vecs0: Completed 17983 idle resets [ 74.387667] i915: Running intel_hangcheck_live_selftests/igt_reset_active_engine [ 74.889017] rcs0: Completed 747 active resets [ 75.174240] intel_engine_reset(bcs0) failed, err:-110 [ 75.174301] bcs0: Completed 525 active resets After that, the machine just silently hangs. Bisecting the issue, the patch that introduced the regression is: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Reverting it fix the issues, but introduce other problems, as TLB won't be invalidated anymore. So, instead, let's fix the root cause. It turns that the TLB flush logic ends conflicting with i915 reset, which is called during selftest hangcheck. So, the TLB cache should be serialized, but other TLB fix patches are required for this one to work. Tested on an Intel NUC5i7RYB with an i7-5557U Broadwell CPU. Chris Wilson (6): drm/i915/gt: Ignore TLB invalidations on idle engines drm/i915/gt: Invalidate TLB of the OA unit at TLB invalidations drm/i915/gt: Skip TLB invalidations once wedged drm/i915/gt: Only invalidate TLBs exposed to user manipulation drm/i915/gt: Serialize GRDOM access between multiple engine resets drm/i915/gt: Serialize TLB invalidates with GT resets drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 +++--- drivers/gpu/drm/i915/gt/intel_gt.c| 43 +++ drivers/gpu/drm/i915/gt/intel_gt_pm.h | 3 ++ drivers/gpu/drm/i915/gt/intel_reset.c | 37 ++- drivers/gpu/drm/i915/i915_vma.c | 3 +- 5 files changed, 75 insertions(+), 21 deletions(-) -- 2.36.1
[PATCH 3/6] drm/i915/gt: Skip TLB invalidations once wedged
From: Chris Wilson Skip all further TLB invalidations once the device is wedged and had been reset, as, on such cases, it can no longer process instructions on the GPU and the user no longer has access to the TLB's in each engine. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Signed-off-by: Chris Wilson Cc: Fei Yang Cc: Andi Shyti Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/gt/intel_gt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index 61b7ec5118f9..fb4fd5273ca4 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -1226,6 +1226,9 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) return; + if (intel_gt_is_wedged(gt)) + return; + if (GRAPHICS_VER(i915) == 12) { regs = gen12_regs; num = ARRAY_SIZE(gen12_regs); -- 2.36.1
[PATCH 1/6] drm/i915/gt: Ignore TLB invalidations on idle engines
From: Chris Wilson As an extension of the current skip TLB invalidations, check if the device is powered down prior to any engine activity, as, on such cases, all the TLBs were already invalidated, so an explicit TLB invalidation is not needed. This becomes more significant with GuC, as it can only do so when the connection to the GuC is awake. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Signed-off-by: Chris Wilson Cc: Fei Yang Cc: Andi Shyti Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/gem/i915_gem_pages.c | 10 + drivers/gpu/drm/i915/gt/intel_gt.c| 26 +-- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 3 +++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 97c820eee115..6835279943df 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -6,14 +6,15 @@ #include +#include "gt/intel_gt.h" +#include "gt/intel_gt_pm.h" + #include "i915_drv.h" #include "i915_gem_object.h" #include "i915_scatterlist.h" #include "i915_gem_lmem.h" #include "i915_gem_mman.h" -#include "gt/intel_gt.h" - void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, unsigned int sg_page_sizes) @@ -217,10 +218,11 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { struct drm_i915_private *i915 = to_i915(obj->base.dev); + struct intel_gt *gt = to_gt(i915); intel_wakeref_t wakeref; - with_intel_runtime_pm_if_active(&i915->runtime_pm, wakeref) - intel_gt_invalidate_tlbs(to_gt(i915)); + with_intel_gt_pm_if_awake(gt, wakeref) + intel_gt_invalidate_tlbs(gt); } return pages; diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index f33290358c51..d5ed6a6ac67c 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -11,6 +11,7 @@ #include "i915_drv.h" #include "intel_context.h" +#include "intel_engine_pm.h" #include "intel_engine_regs.h" #include "intel_gt.h" #include "intel_gt_buffer_pool.h" @@ -1216,6 +1217,7 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) struct drm_i915_private *i915 = gt->i915; struct intel_uncore *uncore = gt->uncore; struct intel_engine_cs *engine; + intel_engine_mask_t awake, tmp; enum intel_engine_id id; const i915_reg_t *regs; unsigned int num = 0; @@ -1239,12 +1241,27 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) GEM_TRACE("\n"); - assert_rpm_wakelock_held(&i915->runtime_pm); - mutex_lock(>->tlb_invalidate_lock); intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); + awake = 0; for_each_engine(engine, gt, id) { + struct reg_and_bit rb; + + if (!intel_engine_pm_is_awake(engine)) + continue; + + rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); + if (!i915_mmio_reg_offset(rb.reg)) + continue; + + intel_uncore_write_fw(uncore, rb.reg, rb.bit); + awake |= engine->mask; + } + + for_each_engine_masked(engine, gt, awake, tmp) { + struct reg_and_bit rb; + /* * HW architecture suggest typical invalidation time at 40us, * with pessimistic cases up to 100us and a recommendation to @@ -1252,13 +1269,8 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) */ const unsigned int timeout_us = 100; const unsigned int timeout_ms = 4; - struct reg_and_bit rb; rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); - if (!i915_mmio_reg_offset(rb.reg)) - continue; - - intel_uncore_write_fw(uncore, rb.reg, rb.bit); if (__intel_wait_for_register_fw(uncore, rb.reg, rb.bit, 0, timeout_us, timeout_ms, diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h index bc898df7a48c..a334787a4939 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h @@ -55,6 +55,9 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt) for (tmp = 1, intel_gt_pm_get(gt); tmp; \ intel_gt_pm_put(gt)
[PATCH 2/6] drm/i915/gt: Invalidate TLB of the OA unit at TLB invalidations
From: Chris Wilson On gen12 HW, ensure that the TLB of the OA unit is also invalidated as just invalidating the TLB of an engine is not enough. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Signed-off-by: Chris Wilson Cc: Fei Yang Cc: Andi Shyti Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/gt/intel_gt.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index d5ed6a6ac67c..61b7ec5118f9 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -10,6 +10,7 @@ #include "pxp/intel_pxp.h" #include "i915_drv.h" +#include "i915_perf_oa_regs.h" #include "intel_context.h" #include "intel_engine_pm.h" #include "intel_engine_regs.h" @@ -1259,6 +1260,15 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) awake |= engine->mask; } + /* Wa_2207587034:tgl,dg1,rkl,adl-s,adl-p */ + if (awake && + (IS_TIGERLAKE(i915) || +IS_DG1(i915) || +IS_ROCKETLAKE(i915) || +IS_ALDERLAKE_S(i915) || +IS_ALDERLAKE_P(i915))) + intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1); + for_each_engine_masked(engine, gt, awake, tmp) { struct reg_and_bit rb; -- 2.36.1
[PATCH] drm/rockchip: Detach from ARM DMA domain in attach_device
Since commit 1ea2a07a532b ("iommu: Add DMA ownership management interfaces") the Rockchip display driver on the Firefly RK3288 fails to initialise properly. This is because ARM DMA domain is still attached. Let's follow the lead of exynos and tegra and add code to explicitly remove the ARM domain before attaching a new one. Suggested-by: Robin Murphy Signed-off-by: Steven Price --- See also the thread[1] where I reported the regression. [1] https://lore.kernel.org/linux-kernel/da9cca0a-ec5b-2e73-9de0-a930f7d947b2%40arm.com --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 67d38f53d3e5..13ed33e74457 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -23,6 +23,14 @@ #include #include +#if defined(CONFIG_ARM_DMA_USE_IOMMU) +#include +#else +#define arm_iommu_detach_device(...) ({ }) +#define arm_iommu_release_mapping(...) ({ }) +#define to_dma_iommu_mapping(dev) NULL +#endif + #include "rockchip_drm_drv.h" #include "rockchip_drm_fb.h" #include "rockchip_drm_gem.h" @@ -49,6 +57,15 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, if (!private->domain) return 0; + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + + if (mapping) { + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(mapping); + } + } + ret = iommu_attach_device(private->domain, dev); if (ret) { DRM_DEV_ERROR(dev, "Failed to attach iommu device\n"); -- 2.25.1
Re: [PATCH] drm/sun4i: Fix crash during suspend after component bind failure
Dne sreda, 15. junij 2022 ob 07:42:53 CEST je Samuel Holland napisal(a): > If the component driver fails to bind, or is unbound, the driver data > for the top-level platform device points to a freed drm_device. If the > system is then suspended, the driver passes this dangling pointer to > drm_mode_config_helper_suspend(), which crashes. > > Fix this by only setting the driver data while the platform driver holds > a reference to the drm_device. > > Fixes: 624b4b48d9d8 ("drm: sun4i: Add support for suspending the display driver") > Signed-off-by: Samuel Holland Reviewed-by: Jernej Skrabec Best regards, Jernej
[PATCH v7] drm/msm/dp: force link training for display resolution change
Display resolution change is implemented through drm modeset. Older modeset (resolution) has to be disabled first before newer modeset (resolution) can be enabled. Display disable will turn off both pixel clock and main link clock so that main link have to be re-trained during display enable to have new video stream flow again. At current implementation, display enable function manually kicks up irq_hpd_handle which will read panel link status and start link training if link status is not in sync state. However, there is rare case that a particular panel links status keep staying in sync for some period of time after main link had been shut down previously at display disabled. In this case, main link retraining will not be executed by irq_hdp_handle(). Hence video stream of newer display resolution will fail to be transmitted to panel due to main link is not in sync between host and panel. This patch will bypass irq_hpd_handle() in favor of directly call dp_ctrl_on_stream() to always perform link training in regardless of main link status. So that no unexpected exception resolution change failure cases will happen. Also this implementation are more efficient than manual kicking off irq_hpd_handle function. Changes in v2: -- set force_link_train flag on DP only (is_edp == false) Changes in v3: -- revise commit text -- add Fixes tag Changes in v4: -- revise commit text Changes in v5: -- fix spelling at commit text Changes in v6: -- split dp_ctrl_on_stream() for phy test case -- revise commit text for modeset Changes in v7: -- drop 0 assignment at local variable (ret = 0) Fixes: 62671d2ef24b ("drm/msm/dp: fixes wrong connection state caused by failure of link train") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_ctrl.c| 31 +++ drivers/gpu/drm/msm/dp/dp_ctrl.h| 3 ++- drivers/gpu/drm/msm/dp/dp_display.c | 13 ++--- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index af7a80c..01028b5 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1551,7 +1551,7 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) ret = dp_ctrl_on_link(&ctrl->dp_ctrl); if (!ret) - ret = dp_ctrl_on_stream(&ctrl->dp_ctrl); + ret = dp_ctrl_on_stream_phy_test_report(&ctrl->dp_ctrl); else DRM_ERROR("failed to enable DP link controller\n"); @@ -1807,7 +1807,27 @@ static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl) return dp_ctrl_setup_main_link(ctrl, &training_step); } -int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) +int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) +{ + int ret; + struct dp_ctrl_private *ctrl; + + ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); + + ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; + + ret = dp_ctrl_enable_stream_clocks(ctrl); + if (ret) { + DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); + return ret; + } + + dp_ctrl_send_phy_test_pattern(ctrl); + + return 0; +} + +int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train) { int ret = 0; bool mainlink_ready = false; @@ -1843,12 +1863,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) goto end; } - if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { - dp_ctrl_send_phy_test_pattern(ctrl); - return 0; - } - - if (!dp_ctrl_channel_eq_ok(ctrl)) + if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl)) dp_ctrl_link_retrain(ctrl); /* stop txing train pattern to end link training */ diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h index 0745fde..9a39b00 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h @@ -21,7 +21,8 @@ struct dp_ctrl { }; int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); -int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl); +int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train); +int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl); int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl); int dp_ctrl_off(struct dp_ctrl *dp_ctrl); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index c388323..b6d25ab 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -872,7 +872,7 @@ static int dp_display_enable(struct dp_display_private *dp, u32 data) return 0; } - rc = dp_ctrl_on_stream(dp->ctrl); + rc = dp_ctrl_on_stream(dp->ctrl, data); if (!rc) dp_display->power_on = true; @@ -1654,6 +1654,7 @@ void dp_brid
Re: [PATCH] drm/bridge: anx7625: Zero error variable when panel bridge not present
On Tue, 14 Jun 2022 at 09:52, AngeloGioacchino Del Regno wrote: > > Il 13/06/22 18:37, Nícolas F. R. A. Prado ha scritto: > > While parsing the DT, the anx7625 driver checks for the presence of a > > panel bridge on endpoint 1. If it is missing, pdata->panel_bridge stores > > the error pointer and the function returns successfully without first > > cleaning that variable. This is an issue since other functions later > > check for the presence of a panel bridge by testing the trueness of that > > variable. > > > > In order to ensure proper behavior, zero out pdata->panel_bridge before > > returning when no panel bridge is found. > > > > Fixes: 9e82ea0fb1df ("drm/bridge: anx7625: switch to > > devm_drm_of_get_bridge") > > Signed-off-by: Nícolas F. R. A. Prado > > > > I would've preferred s/zero out/cleanup/g but it's also fine as you wrote it. > Besides, good catch! > > Reviewed-by: AngeloGioacchino Del Regno > > Applied to drm-misc-next
[PATCH v2] drm/arm/hdlcd: Take over EFI framebuffer properly
The Arm Juno board EDK2 port has provided an EFI GOP display via HDLCD0 for some time now, which works nicely as an early framebuffer. However, once the HDLCD driver probes and takes over the hardware, it should take over the logical framebuffer as well, otherwise the now-defunct GOP device hangs about and virtual console output inevitably disappears into the wrong place most of the time. We'll do this after binding the HDMI encoder, since that's the most likely thing to fail, and the EFI console is still better than nothing when that happens. However, the two HDLCD controllers on Juno are independent, and many users will still be using older firmware without any display support, so we'll only bother if we find that the HDLCD we're probing is already enabled. And if it is, then we'll also stop it, since otherwise the display can end up shifted if it's still scanning out while the rest of the registers are subsequently reconfigured. Signed-off-by: Robin Murphy --- Since I ended up adding (relatively) a lot here, I didn't want to second-guess Javier's opinion so left off the R-b tag from v1. drivers/gpu/drm/arm/hdlcd_drv.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index e89ae0ec60eb..1f1171f2f16a 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -314,6 +315,12 @@ static int hdlcd_drm_bind(struct device *dev) goto err_vblank; } + /* If EFI left us running, take over from efifb/sysfb */ + if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) { + hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); + drm_aperture_remove_framebuffers(false, &hdlcd_driver); + } + drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); -- 2.36.1.dirty
[PATCH] drm/arm/hdlcd: Simplify IRQ install/uninstall
Since we no longer need to conform to the structure of the various DRM IRQ callbacks, we can streamline the code by consolidating the piecemeal functions and passing around our private data structure directly. We're also a platform device so should never see IRQ_NOTCONNECTED either. Furthermore we can also get rid of all the unnecesary read-modify-write operations, since on install we know we cleared the whole interrupt mask before enabling the debug IRQs, and thus on uninstall we're always clearing everything as well. Signed-off-by: Robin Murphy --- drivers/gpu/drm/arm/hdlcd_drv.c | 62 + 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 1f1171f2f16a..7d6aa9b3b577 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -41,8 +41,7 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) { - struct drm_device *drm = arg; - struct hdlcd_drm_private *hdlcd = drm->dev_private; + struct hdlcd_drm_private *hdlcd = arg; unsigned long irq_status; irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS); @@ -70,61 +69,32 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) return IRQ_HANDLED; } -static void hdlcd_irq_preinstall(struct drm_device *drm) -{ - struct hdlcd_drm_private *hdlcd = drm->dev_private; - /* Ensure interrupts are disabled */ - hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0); - hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0); -} - -static void hdlcd_irq_postinstall(struct drm_device *drm) -{ -#ifdef CONFIG_DEBUG_FS - struct hdlcd_drm_private *hdlcd = drm->dev_private; - unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK); - - /* enable debug interrupts */ - irq_mask |= HDLCD_DEBUG_INT_MASK; - - hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask); -#endif -} - -static int hdlcd_irq_install(struct drm_device *drm, int irq) +static int hdlcd_irq_install(struct hdlcd_drm_private *hdlcd) { int ret; - if (irq == IRQ_NOTCONNECTED) - return -ENOTCONN; + /* Ensure interrupts are disabled */ + hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0); + hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0); - hdlcd_irq_preinstall(drm); - - ret = request_irq(irq, hdlcd_irq, 0, drm->driver->name, drm); + ret = request_irq(hdlcd->irq, hdlcd_irq, 0, "hdlcd", hdlcd); if (ret) return ret; - hdlcd_irq_postinstall(drm); +#ifdef CONFIG_DEBUG_FS + /* enable debug interrupts */ + hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, HDLCD_DEBUG_INT_MASK); +#endif return 0; } -static void hdlcd_irq_uninstall(struct drm_device *drm) +static void hdlcd_irq_uninstall(struct hdlcd_drm_private *hdlcd) { - struct hdlcd_drm_private *hdlcd = drm->dev_private; /* disable all the interrupts that we might have enabled */ - unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK); + hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0); -#ifdef CONFIG_DEBUG_FS - /* disable debug interrupts */ - irq_mask &= ~HDLCD_DEBUG_INT_MASK; -#endif - - /* disable vsync interrupts */ - irq_mask &= ~HDLCD_INTERRUPT_VSYNC; - hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask); - - free_irq(hdlcd->irq, drm); + free_irq(hdlcd->irq, hdlcd); } static int hdlcd_load(struct drm_device *drm, unsigned long flags) @@ -184,7 +154,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) goto irq_fail; hdlcd->irq = ret; - ret = hdlcd_irq_install(drm, hdlcd->irq); + ret = hdlcd_irq_install(hdlcd); if (ret < 0) { DRM_ERROR("failed to install IRQ handler\n"); goto irq_fail; @@ -342,7 +312,7 @@ static int hdlcd_drm_bind(struct device *dev) err_unload: of_node_put(hdlcd->crtc.port); hdlcd->crtc.port = NULL; - hdlcd_irq_uninstall(drm); + hdlcd_irq_uninstall(hdlcd); of_reserved_mem_device_release(drm->dev); err_free: drm_mode_config_cleanup(drm); @@ -364,7 +334,7 @@ static void hdlcd_drm_unbind(struct device *dev) hdlcd->crtc.port = NULL; pm_runtime_get_sync(dev); drm_atomic_helper_shutdown(drm); - hdlcd_irq_uninstall(drm); + hdlcd_irq_uninstall(hdlcd); pm_runtime_put(dev); if (pm_runtime_enabled(dev)) pm_runtime_disable(dev); -- 2.36.1.dirty
Re: [PATCH v2 1/3] drm/msm/dpu: Move LM CRC code into separate method
On 6/15/2022 2:35 AM, Dmitry Baryshkov wrote: On Wed, 15 Jun 2022 at 00:13, Jessica Zhang wrote: Move layer mixer-specific section of dpu_crtc_get_crc() into a separate helper method. This way, we can make it easier to get CRCs from other HW blocks by adding other get_crc helper methods. Changes since V1: - Moved common bitmasks to dpu_hw_util.h - Moved common CRC methods to dpu_hw_util.c - Updated copyrights - Changed crcs array to a dynamically allocated array and added it as a member of crtc_state Signed-off-by: Jessica Zhang Please split this into separate patches. One for hw_util, one for the rest Sure --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 88 + drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 42 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 46 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 16 5 files changed, 124 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b56f777dbd0e..16742a66878e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -88,6 +89,11 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); + if (crtc_state->crcs) { + kfree(crtc_state->crcs); + crtc_state->crcs = NULL; + } + if (source < 0) { DRM_DEBUG_DRIVER("Invalid source %s for CRTC%d\n", src_name, crtc->index); return -EINVAL; @@ -96,20 +102,37 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) *values_cnt = crtc_state->num_mixers; + crtc_state->crcs = kcalloc(*values_cnt, sizeof(crtc_state->crcs), GFP_KERNEL); + I do not quite like the idea of constantly allocating and freeing the crcs array. I'd suggest defining sensible MAX_CRC_VALUES, using a static array and verifying that no one over commits the MAX_CRC_VALUES. If at some point we decide that we really need the dynamic array, we can implement it later. We already had dynamic arrays and Rob had to fix it. See 00326bfa4e63 ("drm/msm/dpu: Remove dynamic allocation from atomic context"). Ah, got it... the reason I used a dynamic array here was because AFAIK we don't have a defined upper limit for how many drm_encoders can be connected to a CRTC simultaneously. Do you have a suggestion on what value we can set for MAX_CRC_VALUES? return 0; } +static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) +{ + struct dpu_crtc_mixer *m; + int i; + + for (i = 0; i < crtc_state->num_mixers; ++i) { + m = &crtc_state->mixers[i]; + + if (!m->hw_lm || !m->hw_lm->ops.setup_misr) + continue; + + /* Calculate MISR over 1 frame */ + m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); + } +} + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) { enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); enum dpu_crtc_crc_source current_source; struct dpu_crtc_state *crtc_state; struct drm_device *drm_dev = crtc->dev; - struct dpu_crtc_mixer *m; bool was_enabled; bool enable = false; - int i, ret = 0; + int ret = 0; if (source < 0) { DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", src_name, crtc->index); @@ -137,6 +160,10 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) goto cleanup; } else if (was_enabled && !enable) { + if (crtc_state->crcs) { + kfree(crtc_state->crcs); + crtc_state->crcs = NULL; + } drm_crtc_vblank_put(crtc); } @@ -146,16 +173,8 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) crtc_state->crc_frame_skip_count = 0; - for (i = 0; i < crtc_state->num_mixers; ++i) { - m = &crtc_state->mixers[i]; - - if (!m->hw_lm || !m->hw_lm->ops.setup_misr) - continue; - - /* Calculate MISR over 1 frame */ - m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); - } - + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + dpu_crtc_setup
Re: [PATCH v2 3/3] drm/msm/dpu: Add interface support for CRC debugfs
On 6/15/2022 2:44 AM, Dmitry Baryshkov wrote: On Wed, 15 Jun 2022 at 00:13, Jessica Zhang wrote: Add support for writing CRC values for the interface block to the debugfs by calling the necessary MISR setup/collect methods. Changes since V1: - Set values_cnt to only include phys with backing hw_intf - Loop over all drm_encs connected to crtc Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 49 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 64 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 +++ 4 files changed, 134 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 16742a66878e..8c9933b2337f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -79,6 +79,8 @@ static enum dpu_crtc_crc_source dpu_crtc_parse_crc_source(const char *src_name) if (!strcmp(src_name, "auto") || !strcmp(src_name, "lm")) return DPU_CRTC_CRC_SOURCE_LAYER_MIXER; + if (!strcmp(src_name, "intf")) + return DPU_CRTC_CRC_SOURCE_INTF; What about "encoder" / DPU_CRTC_CRC_SOURCE_ENCODER? You basically offload CRC generation/collection to the dpu_encoder, so I'd ignore the fact that only INTF's support MISR generation and use a more generic word here. return DPU_CRTC_CRC_SOURCE_INVALID; } @@ -99,8 +101,14 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, return -EINVAL; } - if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) { *values_cnt = crtc_state->num_mixers; + } else if (source == DPU_CRTC_CRC_SOURCE_INTF) { + struct drm_encoder *drm_enc; Zero values_cnt here. Noted. + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + *values_cnt += dpu_encoder_get_num_phys(drm_enc); + } crtc_state->crcs = kcalloc(*values_cnt, sizeof(crtc_state->crcs), GFP_KERNEL); @@ -123,6 +131,14 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) } } +static void dpu_crtc_setup_encoder_misr(struct drm_crtc *crtc) +{ + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + dpu_encoder_setup_misr(drm_enc); +} + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) { enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); @@ -175,6 +191,8 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) dpu_crtc_setup_lm_misr(crtc_state); + else if (source == DPU_CRTC_CRC_SOURCE_INTF) + dpu_crtc_setup_encoder_misr(crtc); else? > cleanup: drm_modeset_unlock(&crtc->mutex); @@ -220,11 +238,31 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, struct dpu_crtc_state *crt drm_crtc_accurate_vblank_count(crtc), crtc_state->crcs); } -static int dpu_crtc_get_crc(struct drm_crtc *crtc) +static int dpu_crtc_get_encoder_crc(struct drm_crtc *crtc) { - struct dpu_crtc_state *crtc_state; + struct drm_encoder *drm_enc; + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); + int rc, pos = 0; - crtc_state = to_dpu_crtc_state(crtc->state); + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) { + rc = dpu_encoder_get_crc(drm_enc, crtc_state->crcs, pos); + if (rc < 0) { + if (rc != -ENODATA) + DRM_DEBUG_DRIVER("MISR read failed\n"); + + return rc; + } + + pos += rc; + } + + return drm_crtc_add_crc_entry(crtc, true, + drm_crtc_accurate_vblank_count(crtc), crtc_state->crcs); +} + +static int dpu_crtc_get_crc(struct drm_crtc *crtc) +{ + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); Unnecessary change here. Please move it to the patch 1, which refactors this function. Noted. /* Skip first 2 frames in case of "uncooked" CRCs */ if (crtc_state->crc_frame_skip_count < 2) { @@ -235,6 +273,9 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) return dpu_crtc_get_lm_crc(crtc, crtc_state); + if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_INTF) + return dpu_crtc_get_encoder_crc(crtc); + return 0; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h in
Re: [PATCH v2 1/3] drm/msm/dpu: Move LM CRC code into separate method
On 15/06/2022 19:11, Jessica Zhang wrote: On 6/15/2022 2:35 AM, Dmitry Baryshkov wrote: On Wed, 15 Jun 2022 at 00:13, Jessica Zhang wrote: Move layer mixer-specific section of dpu_crtc_get_crc() into a separate helper method. This way, we can make it easier to get CRCs from other HW blocks by adding other get_crc helper methods. Changes since V1: - Moved common bitmasks to dpu_hw_util.h - Moved common CRC methods to dpu_hw_util.c - Updated copyrights - Changed crcs array to a dynamically allocated array and added it as a member of crtc_state Signed-off-by: Jessica Zhang Please split this into separate patches. One for hw_util, one for the rest Sure --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 88 + drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 42 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 46 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 16 5 files changed, 124 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b56f777dbd0e..16742a66878e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -88,6 +89,11 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); + if (crtc_state->crcs) { + kfree(crtc_state->crcs); + crtc_state->crcs = NULL; + } + if (source < 0) { DRM_DEBUG_DRIVER("Invalid source %s for CRTC%d\n", src_name, crtc->index); return -EINVAL; @@ -96,20 +102,37 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) *values_cnt = crtc_state->num_mixers; + crtc_state->crcs = kcalloc(*values_cnt, sizeof(crtc_state->crcs), GFP_KERNEL); + I do not quite like the idea of constantly allocating and freeing the crcs array. I'd suggest defining sensible MAX_CRC_VALUES, using a static array and verifying that no one over commits the MAX_CRC_VALUES. If at some point we decide that we really need the dynamic array, we can implement it later. We already had dynamic arrays and Rob had to fix it. See 00326bfa4e63 ("drm/msm/dpu: Remove dynamic allocation from atomic context"). Ah, got it... the reason I used a dynamic array here was because AFAIK we don't have a defined upper limit for how many drm_encoders can be connected to a CRTC simultaneously. Do you have a suggestion on what value we can set for MAX_CRC_VALUES? Three? Two for two hw_intfs? -- With best wishes Dmitry
[PATCH] drm/msm: Fix fence rollover issue
From: Rob Clark And while we are at it, let's start the fence counter close to the rollover point so that if issues slip in, they are more obvious. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_fence.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index 3df255402a33..a35a6746c7cd 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -28,6 +28,14 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, fctx->fenceptr = fenceptr; spin_lock_init(&fctx->spinlock); + /* +* Start out close to the 32b fence rollover point, so we can +* catch bugs with fence comparisons. +*/ + fctx->last_fence = 0xff00; + fctx->completed_fence = fctx->last_fence; + *fctx->fenceptr = fctx->last_fence; + return fctx; } @@ -46,11 +54,12 @@ bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence) (int32_t)(*fctx->fenceptr - fence) >= 0; } -/* called from workqueue */ +/* called from irq handler */ void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence) { spin_lock(&fctx->spinlock); - fctx->completed_fence = max(fence, fctx->completed_fence); + if (fence_after(fence, fctx->completed_fence)) + fctx->completed_fence = fence; spin_unlock(&fctx->spinlock); } -- 2.36.1
Re: [PATCH -next] drm/bridge: it6505: Add missing CRYPTO_HASH dependency
On Mon, 13 Jun 2022 at 16:54, Zheng Bin wrote: > > The driver uses crypto hash functions so it needs to select CRYPTO_HASH. > This fixes build errors: > > drivers/gpu/drm/bridge/ite-it6505.o: in function `it6505_hdcp_wait_ksv_list': > ite-it6505.c:(.text+0x4c26): undefined reference to `crypto_alloc_shash' > ite-it6505.c:(.text+0x4c6d): undefined reference to `crypto_shash_digest' > ite-it6505.c:(.text+0x4c7d): undefined reference to `crypto_destroy_tfm' > ite-it6505.c:(.text+0x4d69): undefined reference to `crypto_destroy_tfm' > > Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") > Signed-off-by: Zheng Bin > --- > drivers/gpu/drm/bridge/Kconfig | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig > index 8ffd601e68f9..1afe99dac0ff 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -94,6 +94,8 @@ config DRM_ITE_IT6505 > select DRM_KMS_HELPER > select DRM_DP_HELPER > select EXTCON > +select CRYPTO > +select CRYPTO_HASH > help >ITE IT6505 DisplayPort bridge chip driver. > > -- > 2.31.1 > Reviewed-by: Robert Foss Applied to drm-misc-next
[PATCH] drm/msm: Fix %d vs %u
From: Rob Clark In debugging fence rollover, I noticed that GPU state capture and devcore dumps were showing me negative fence numbers. Let's fix that and some related signed vs unsigned confusion. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index dd044d557c7c..ce3b508b7c2b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -790,11 +790,11 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, for (i = 0; i < gpu->nr_rings; i++) { drm_printf(p, " - id: %d\n", i); drm_printf(p, "iova: 0x%016llx\n", state->ring[i].iova); - drm_printf(p, "last-fence: %d\n", state->ring[i].seqno); - drm_printf(p, "retired-fence: %d\n", state->ring[i].fence); - drm_printf(p, "rptr: %d\n", state->ring[i].rptr); - drm_printf(p, "wptr: %d\n", state->ring[i].wptr); - drm_printf(p, "size: %d\n", MSM_GPU_RINGBUFFER_SZ); + drm_printf(p, "last-fence: %u\n", state->ring[i].seqno); + drm_printf(p, "retired-fence: %u\n", state->ring[i].fence); + drm_printf(p, "rptr: %u\n", state->ring[i].rptr); + drm_printf(p, "wptr: %u\n", state->ring[i].wptr); + drm_printf(p, "size: %u\n", MSM_GPU_RINGBUFFER_SZ); adreno_show_object(p, &state->ring[i].data, state->ring[i].data_size, &state->ring[i].encoded); -- 2.36.1
Re: [PATCH 1/3] drm/msm/dpu: move intf and wb assignment to dpu_encoder_setup_display()
On 6/15/2022 5:36 AM, Dmitry Baryshkov wrote: On 14/06/2022 22:32, Abhinav Kumar wrote: intf and wb resources are not dependent on the rm global state so need not be allocated during dpu_encoder_virt_atomic_mode_set(). Move the allocation of intf and wb resources to dpu_encoder_setup_display() so that we can utilize the hw caps even during atomic_check() phase. Since dpu_encoder_setup_display() already has protection against setting invalid intf_idx and wb_idx, these checks can now be dropped as well. Fixes: e02a559a720f ("make changes to dpu_encoder to support virtual encoder") Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..e991d4ba8a40 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1048,24 +1048,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "no intf or wb block assigned at idx: %d\n", i); - return; - } - - if (phys->hw_intf && phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "invalid phys both intf and wb block at idx: %d\n", i); - return; - } Please retain these checks in dpu_encoder_setup_display(). It checks that we really have got the intf or wb. For example one might have specified the INTF that leads to INTF_NONE interface. Or non-existing/not supported WB. Right, so the reason I omitted that was dpu_encoder_setup_display() already has these checks: https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c#L2273 Please check lines 2273-2284. Only if all those checks succeeded we call dpu_encoder_virt_add_phys_encs which increments num_phys_encs. Thats why I dropped those. Let me know if you have more questions. - phys->cached_mode = crtc_state->adjusted_mode; if (phys->ops.atomic_mode_set) phys->ops.atomic_mode_set(phys, crtc_state, conn_state); @@ -2293,7 +2275,14 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; atomic_set(&phys->vsync_cnt, 0); atomic_set(&phys->underrun_cnt, 0); + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); + + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); } + mutex_unlock(&dpu_enc->enc_lock); return ret;
Re: [PATCH] drm/radeon: Replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi
On Wed, Jun 15, 2022 at 8:33 AM hongao wrote: > > Replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi for more > efficiency > > Tested on "Oland [Radeon HD 8570 / R7 240/340 OEM]" & "Caicos [R5 230]" Can you verify that drm_display_info.is_hdmi has been populated when all of these functions are called? Alex > > Signed-off-by: hongao > --- > drivers/gpu/drm/radeon/atombios_encoders.c | 6 +++--- > drivers/gpu/drm/radeon/radeon_connectors.c | 12 ++-- > drivers/gpu/drm/radeon/radeon_display.c| 2 +- > drivers/gpu/drm/radeon/radeon_encoders.c | 4 ++-- > 4 files changed, 12 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c > b/drivers/gpu/drm/radeon/atombios_encoders.c > index 70bd84b7ef2b..393d471ba396 100644 > --- a/drivers/gpu/drm/radeon/atombios_encoders.c > +++ b/drivers/gpu/drm/radeon/atombios_encoders.c > @@ -714,7 +714,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) > if (radeon_connector->use_digital && > (radeon_connector->audio == RADEON_AUDIO_ENABLE)) > return ATOM_ENCODER_MODE_HDMI; > - else if > (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && > + else if (connector->display_info.is_hdmi && > (radeon_connector->audio == > RADEON_AUDIO_AUTO)) > return ATOM_ENCODER_MODE_HDMI; > else if (radeon_connector->use_digital) > @@ -733,7 +733,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) > if (radeon_audio != 0) { > if (radeon_connector->audio == RADEON_AUDIO_ENABLE) > return ATOM_ENCODER_MODE_HDMI; > - else if > (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && > + else if (connector->display_info.is_hdmi && > (radeon_connector->audio == > RADEON_AUDIO_AUTO)) > return ATOM_ENCODER_MODE_HDMI; > else > @@ -757,7 +757,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) > } else if (radeon_audio != 0) { > if (radeon_connector->audio == RADEON_AUDIO_ENABLE) > return ATOM_ENCODER_MODE_HDMI; > - else if > (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) && > + else if (connector->display_info.is_hdmi && > (radeon_connector->audio == > RADEON_AUDIO_AUTO)) > return ATOM_ENCODER_MODE_HDMI; > else > diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c > b/drivers/gpu/drm/radeon/radeon_connectors.c > index 58db79921cd3..2fbec7bdd56b 100644 > --- a/drivers/gpu/drm/radeon/radeon_connectors.c > +++ b/drivers/gpu/drm/radeon/radeon_connectors.c > @@ -130,7 +130,7 @@ int radeon_get_monitor_bpc(struct drm_connector > *connector) > case DRM_MODE_CONNECTOR_DVII: > case DRM_MODE_CONNECTOR_HDMIB: > if (radeon_connector->use_digital) { > - if > (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { > + if (connector->display_info.is_hdmi) { > if (connector->display_info.bpc) > bpc = connector->display_info.bpc; > } > @@ -138,7 +138,7 @@ int radeon_get_monitor_bpc(struct drm_connector > *connector) > break; > case DRM_MODE_CONNECTOR_DVID: > case DRM_MODE_CONNECTOR_HDMIA: > - if > (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { > + if (connector->display_info.is_hdmi) { > if (connector->display_info.bpc) > bpc = connector->display_info.bpc; > } > @@ -147,7 +147,7 @@ int radeon_get_monitor_bpc(struct drm_connector > *connector) > dig_connector = radeon_connector->con_priv; > if ((dig_connector->dp_sink_type == > CONNECTOR_OBJECT_ID_DISPLAYPORT) || > (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) > || > - > drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { > + connector->display_info.is_hdmi) { > if (connector->display_info.bpc) > bpc = connector->display_info.bpc; > } > @@ -171,7 +171,7 @@ int radeon_get_monitor_bpc(struct drm_connector > *connector) > break; > } > > - if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { > + if (connector->display_info.is_hdmi) { > /* hdmi deep color only impleme
Re: [PATCH v2 6/7] drm/bridge: anx7625: Register Type-C mode switches
On Wed, Jun 15, 2022 at 1:45 AM AngeloGioacchino Del Regno wrote: > > Il 14/06/22 18:57, Prashant Malani ha scritto: > > On Tue, Jun 14, 2022 at 1:18 AM AngeloGioacchino Del Regno > > wrote: > >> > >> Il 09/06/22 20:09, Prashant Malani ha scritto: > >>> When the DT node has "switches" available, register a Type-C mode-switch > >>> for each listed "switch". This allows the driver to receive state > >>> information about what operating mode a Type-C port and its connected > >>> peripherals are in, as well as status information (like VDOs) related to > >>> that state. > >>> > >>> The callback function is currently a stub, but subsequent patches will > >>> implement the required functionality. > >>> > >>> Signed-off-by: Prashant Malani > >>> --- > >>> > >>> Changes since v2: > >>> - No changes. > >>> > >>>drivers/gpu/drm/bridge/analogix/anx7625.c | 73 +++ > >>>drivers/gpu/drm/bridge/analogix/anx7625.h | 6 ++ > >>>2 files changed, 79 insertions(+) > >>> > >>> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c > >>> b/drivers/gpu/drm/bridge/analogix/anx7625.c > >>> index 07ed44c6b839..d41a21103bd3 100644 > >>> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c > >>> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c > >>> @@ -15,6 +15,7 @@ > >>>#include > >>>#include > >>>#include > >>> +#include > >>>#include > >>> > >>>#include > >>> @@ -2581,9 +2582,59 @@ static void anx7625_runtime_disable(void *data) > >>>pm_runtime_disable(data); > >>>} > >>> > >>> +static int anx7625_typec_mux_set(struct typec_mux_dev *mux, > >>> + struct typec_mux_state *state) > >>> +{ > >>> + return 0; > >>> +} > >>> + > >>> +static int anx7625_register_mode_switch(struct device *dev, struct > >>> device_node *node, > >>> + struct anx7625_data *ctx) > >>> +{ > >>> + struct anx7625_port_data *port_data; > >>> + struct typec_mux_desc mux_desc = {}; > >>> + char name[32]; > >>> + u32 port_num; > >>> + int ret; > >>> + > >>> + ret = of_property_read_u32(node, "reg", &port_num); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + if (port_num >= ctx->num_typec_switches) { > >>> + dev_err(dev, "Invalid port number specified: %d\n", > >>> port_num); > >>> + return -EINVAL; > >>> + } > >>> + > >>> + port_data = &ctx->typec_ports[port_num]; > >>> + port_data->ctx = ctx; > >>> + mux_desc.fwnode = &node->fwnode; > >>> + mux_desc.drvdata = port_data; > >>> + snprintf(name, sizeof(name), "%s-%u", node->name, port_num); > >>> + mux_desc.name = name; > >>> + mux_desc.set = anx7625_typec_mux_set; > >>> + > >>> + port_data->typec_mux = typec_mux_register(dev, &mux_desc); > >>> + if (IS_ERR(port_data->typec_mux)) { > >>> + ret = PTR_ERR(port_data->typec_mux); > >>> + dev_err(dev, "Mode switch register for port %d failed: %d", > >>> port_num, ret); > >>> + } > >> > >> Please return 0 at the end of this function. > >> > >> if (IS_ERR()) { > >> ..code.. > >> return ret; > >> } > >> > >> return 0; > >> } > > > > May I ask why? We're not missing any return paths. I would rather we > > keep it as is (which has the valid return value). > > > > I know that you're not missing any return paths. > > That's only because the proposed one is a common pattern in the kernel > and it's only for consistency. Thanks for the additional details. Since this isn't addressing any specific bug, and I notice varied usages of "return ret" in this file itself [1][2], I'd prefer keeping it as is. [1]: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/bridge/analogix/anx7625.c#L296 [2]: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/bridge/analogix/anx7625.c#L436 > > Regards, > Angelo >
Re: [PATCH 1/3] drm/msm/dpu: move intf and wb assignment to dpu_encoder_setup_display()
On 15/06/2022 19:40, Abhinav Kumar wrote: On 6/15/2022 5:36 AM, Dmitry Baryshkov wrote: On 14/06/2022 22:32, Abhinav Kumar wrote: intf and wb resources are not dependent on the rm global state so need not be allocated during dpu_encoder_virt_atomic_mode_set(). Move the allocation of intf and wb resources to dpu_encoder_setup_display() so that we can utilize the hw caps even during atomic_check() phase. Since dpu_encoder_setup_display() already has protection against setting invalid intf_idx and wb_idx, these checks can now be dropped as well. Fixes: e02a559a720f ("make changes to dpu_encoder to support virtual encoder") Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..e991d4ba8a40 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1048,24 +1048,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "no intf or wb block assigned at idx: %d\n", i); - return; - } - - if (phys->hw_intf && phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "invalid phys both intf and wb block at idx: %d\n", i); - return; - } Please retain these checks in dpu_encoder_setup_display(). It checks that we really have got the intf or wb. For example one might have specified the INTF that leads to INTF_NONE interface. Or non-existing/not supported WB. Right, so the reason I omitted that was dpu_encoder_setup_display() already has these checks: https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c#L2273 Please check lines 2273-2284. Only if all those checks succeeded we call dpu_encoder_virt_add_phys_encs which increments num_phys_encs. As I wrote, it checks indices from phys_params, but not the acquired hardware instances. Thats why I dropped those. Let me know if you have more questions. - phys->cached_mode = crtc_state->adjusted_mode; if (phys->ops.atomic_mode_set) phys->ops.atomic_mode_set(phys, crtc_state, conn_state); @@ -2293,7 +2275,14 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; atomic_set(&phys->vsync_cnt, 0); atomic_set(&phys->underrun_cnt, 0); + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); + + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); } + mutex_unlock(&dpu_enc->enc_lock); return ret; -- With best wishes Dmitry
Re: [Intel-gfx] [PATCH 2/6] drm/i915/gt: Invalidate TLB of the OA unit at TLB invalidations
On Wed, Jun 15, 2022 at 04:27:36PM +0100, Mauro Carvalho Chehab wrote: From: Chris Wilson On gen12 HW, ensure that the TLB of the OA unit is also invalidated as just invalidating the TLB of an engine is not enough. Fixes: 7938d61591d3 ("drm/i915: Flush TLBs before releasing backing store") Signed-off-by: Chris Wilson Cc: Fei Yang Cc: Andi Shyti Cc: sta...@vger.kernel.org Acked-by: Thomas Hellström Signed-off-by: Mauro Carvalho Chehab --- See [PATCH 0/6] at: https://lore.kernel.org/all/cover.1655306128.git.mche...@kernel.org/ drivers/gpu/drm/i915/gt/intel_gt.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index d5ed6a6ac67c..61b7ec5118f9 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -10,6 +10,7 @@ #include "pxp/intel_pxp.h" #include "i915_drv.h" +#include "i915_perf_oa_regs.h" #include "intel_context.h" #include "intel_engine_pm.h" #include "intel_engine_regs.h" @@ -1259,6 +1260,15 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt) awake |= engine->mask; } + /* Wa_2207587034:tgl,dg1,rkl,adl-s,adl-p */ + if (awake && + (IS_TIGERLAKE(i915) || +IS_DG1(i915) || +IS_ROCKETLAKE(i915) || +IS_ALDERLAKE_S(i915) || +IS_ALDERLAKE_P(i915))) + intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1); + This patch can be dropped since this is being done in i915/i915_perf.c -> gen12_oa_disable and is synchronized with OA use cases. Regards, Umesh for_each_engine_masked(engine, gt, awake, tmp) { struct reg_and_bit rb; -- 2.36.1
Re: [PATCH 1/3] drm/msm/dpu: move intf and wb assignment to dpu_encoder_setup_display()
On 6/15/2022 10:04 AM, Dmitry Baryshkov wrote: On 15/06/2022 19:40, Abhinav Kumar wrote: On 6/15/2022 5:36 AM, Dmitry Baryshkov wrote: On 14/06/2022 22:32, Abhinav Kumar wrote: intf and wb resources are not dependent on the rm global state so need not be allocated during dpu_encoder_virt_atomic_mode_set(). Move the allocation of intf and wb resources to dpu_encoder_setup_display() so that we can utilize the hw caps even during atomic_check() phase. Since dpu_encoder_setup_display() already has protection against setting invalid intf_idx and wb_idx, these checks can now be dropped as well. Fixes: e02a559a720f ("make changes to dpu_encoder to support virtual encoder") Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..e991d4ba8a40 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1048,24 +1048,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "no intf or wb block assigned at idx: %d\n", i); - return; - } - - if (phys->hw_intf && phys->hw_wb) { - DPU_ERROR_ENC(dpu_enc, - "invalid phys both intf and wb block at idx: %d\n", i); - return; - } Please retain these checks in dpu_encoder_setup_display(). It checks that we really have got the intf or wb. For example one might have specified the INTF that leads to INTF_NONE interface. Or non-existing/not supported WB. Right, so the reason I omitted that was dpu_encoder_setup_display() already has these checks: https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c#L2273 Please check lines 2273-2284. Only if all those checks succeeded we call dpu_encoder_virt_add_phys_encs which increments num_phys_encs. As I wrote, it checks indices from phys_params, but not the acquired hardware instances. Right but today, both the get_intf() and get_wb() just return the intf/wb corresponding to the index. So as long as the index is valid how will checking hw_wb or hw_intf be different? static inline struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx) { return rm->hw_intf[intf_idx - INTF_0]; } /** * dpu_rm_get_wb - Return a struct dpu_hw_wb instance given it's index. * @rm: DPU Resource Manager handle * @wb_idx: WB index */ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_idx) { return rm->hw_wb[wb_idx - WB_0]; } Thats why I dropped those. Let me know if you have more questions. - phys->cached_mode = crtc_state->adjusted_mode; if (phys->ops.atomic_mode_set) phys->ops.atomic_mode_set(phys, crtc_state, conn_state); @@ -2293,7 +2275,14 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; atomic_set(&phys->vsync_cnt, 0); atomic_set(&phys->underrun_cnt, 0); + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); + + if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) + phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); } + mutex_unlock(&dpu_enc->enc_lock); return ret;
[PATCH v4 0/7] usb: typec: Introduce typec-switch binding
This series introduces a binding for Type-C data lane switches. These control the routing and operating modes of USB Type-C data lanes based on the PD messaging from the Type-C port driver regarding connected peripherals. The first patch introduces a change to the Type-C mux class mode-switch matching code, while the second adds a config guard to a Type-C header. The next couple of patches introduce the new "typec-switch" binding as well as one user of it (the ANX7625 drm bridge). The remaining patches add functionality to the anx7625 driver to register the mode-switches, as well as program its crosspoint switch depending on which Type-C port has a DisplayPort (DP) peripheral connected to it. v3: https://lore.kernel.org/linux-usb/20220614193558.1163205-1-pmal...@chromium.org/ Changes since v3: - Some more modifications to the anx7625 binding patch (4/7). - Picked up 1 more Reviewed-by tag. Pin-Yen Lin (1): drm/bridge: anx7625: Add typec_mux_set callback function Prashant Malani (6): usb: typec: mux: Allow muxes to specify mode-switch usb: typec: mux: Add CONFIG guards for functions dt-bindings: usb: Add Type-C switch binding dt-bindings: drm/bridge: anx7625: Add mode-switch support drm/bridge: anx7625: Register number of Type C switches drm/bridge: anx7625: Register Type-C mode switches .../display/bridge/analogix,anx7625.yaml | 64 .../devicetree/bindings/usb/typec-switch.yaml | 74 + drivers/gpu/drm/bridge/analogix/anx7625.c | 148 ++ drivers/gpu/drm/bridge/analogix/anx7625.h | 20 +++ drivers/usb/typec/mux.c | 8 +- include/linux/usb/typec_mux.h | 44 +- 6 files changed, 350 insertions(+), 8 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml -- 2.36.1.476.g0c4daa206d-goog
[PATCH v4 1/7] usb: typec: mux: Allow muxes to specify mode-switch
Loosen the typec_mux_match() requirements so that searches where an alt mode is not specified, but the target mux device lists the "mode-switch" property, return a success. This is helpful in Type C port drivers which would like to get a pointer to the mux switch associated with a Type C port, but don't want to specify a particular alt mode. Signed-off-by: Prashant Malani Reviewed-by: Heikki Krogerus Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado --- Changes since v3: - No changes. Changes since v2: - Included Reviewed-by and Tested-by tags from v2. Changes since v1: - No changes. drivers/usb/typec/mux.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index fd55c2c516a5..464330776cd6 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -281,9 +281,13 @@ static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id, if (match) goto find_mux; - /* Accessory Mode muxes */ if (!desc) { - match = fwnode_property_present(fwnode, "accessory"); + /* +* Accessory Mode muxes & muxes which explicitly specify +* the required identifier can avoid SVID matching. +*/ + match = fwnode_property_present(fwnode, "accessory") || + fwnode_property_present(fwnode, id); if (match) goto find_mux; return NULL; -- 2.36.1.476.g0c4daa206d-goog
[PATCH v4 2/7] usb: typec: mux: Add CONFIG guards for functions
There are some drivers that can use the Type C mux API, but don't have to. Introduce CONFIG guards for the mux functions so that drivers can include the header file and not run into compilation errors on systems which don't have CONFIG_TYPEC enabled. When CONFIG_TYPEC is not enabled, the Type C mux functions will be stub versions of the original calls. Reported-by: kernel test robot Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Signed-off-by: Prashant Malani --- Changes since v3: - No changes. Changes since v2: - Fix up return types for some of the stubs. Remove 1 unnecessary stub in the else condition. - Remove unnecessary IS_MODULE config guard. - Added Reviewed-by and Tested-by tags. Changes since v1: - Added static inline to stub functions. - Updated function signature of stub functions from "struct typec_mux" to "struct typec_mux_dev" in accordance with updates from commit 713fd49b430c ("usb: typec: mux: Introduce indirection") include/linux/usb/typec_mux.h | 44 ++- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index ee57781dcf28..9292f0e07846 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -58,17 +58,13 @@ struct typec_mux_desc { void *drvdata; }; +#if IS_ENABLED(CONFIG_TYPEC) + struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode, const struct typec_altmode_desc *desc); void typec_mux_put(struct typec_mux *mux); int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state); -static inline struct typec_mux * -typec_mux_get(struct device *dev, const struct typec_altmode_desc *desc) -{ - return fwnode_typec_mux_get(dev_fwnode(dev), desc); -} - struct typec_mux_dev * typec_mux_register(struct device *parent, const struct typec_mux_desc *desc); void typec_mux_unregister(struct typec_mux_dev *mux); @@ -76,4 +72,40 @@ void typec_mux_unregister(struct typec_mux_dev *mux); void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data); void *typec_mux_get_drvdata(struct typec_mux_dev *mux); +#else + +static inline struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode, + const struct typec_altmode_desc *desc) +{ + return NULL; +} + +static inline void typec_mux_put(struct typec_mux *mux) {} + +static inline int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state) +{ + return 0; +} + +static inline struct typec_mux_dev * +typec_mux_register(struct device *parent, const struct typec_mux_desc *desc) +{ + return ERR_PTR(-EOPNOTSUPP); +} +static inline void typec_mux_unregister(struct typec_mux_dev *mux) {} + +static inline void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data) {} +static inline void *typec_mux_get_drvdata(struct typec_mux_dev *mux) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +#endif /* CONFIG_TYPEC */ + +static inline struct typec_mux * +typec_mux_get(struct device *dev, const struct typec_altmode_desc *desc) +{ + return fwnode_typec_mux_get(dev_fwnode(dev), desc); +} + #endif /* __USB_TYPEC_MUX */ -- 2.36.1.476.g0c4daa206d-goog