Re: [PATCH v2 3/8] drm/tegra: Call drm_atomic_helper_shutdown() at shutdown time
On Thu Jun 13, 2024 at 12:23 AM CEST, Douglas Anderson wrote: > Based on grepping through the source code this driver appears to be > missing a call to drm_atomic_helper_shutdown() at system shutdown > time. Among other things, this means that if a panel is in use that it > won't be cleanly powered off at system shutdown time. > > The fact that we should call drm_atomic_helper_shutdown() in the case > of OS shutdown/restart comes straight out of the kernel doc "driver > instance overview" in drm_drv.c. > > Suggested-by: Maxime Ripard > Reviewed-by: Maxime Ripard > Signed-off-by: Douglas Anderson > --- > This commit is only compile-time tested. > > (no changes since v1) > > drivers/gpu/drm/tegra/drm.c | 6 ++ > 1 file changed, 6 insertions(+) Acked-by: Thierry Reding signature.asc Description: PGP signature
Re: [PATCH v5 2/9] scatterlist: Add a flag for the restricted memory
Am 27.06.24 um 05:21 schrieb Jason-JH Lin (林睿祥): On Wed, 2024-06-26 at 19:56 +0200, Daniel Vetter wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > On Wed, Jun 26, 2024 at 12:49:02PM +0200, Christian König wrote: > > Am 26.06.24 um 10:05 schrieb Jason-JH Lin (林睿祥): > > > > > I think I have the same problem as the ECC_FLAG mention in: > > > > > > > > https://lore.kernel.org/linux-media/20240515-dma-buf-ecc-heap-v1-0-54cbbd049...@kernel.org/ > > > > > > > I think it would be better to have the user configurable > private > > > > > information in dma-buf, so all the drivers who have the same > > > > > requirement can get their private information from dma-buf > directly > > > > > and > > > > > no need to change or add the interface. > > > > > > > What's your opinion in this point? > > > > > Well of hand I don't see the need for that. > > > > > What happens if you get a non-secure buffer imported in your > secure > > > > device? > > > > > > We use the same mediatek-drm driver for secure and non-secure > buffer. > > > If non-secure buffer imported to mediatek-drm driver, it's go to > the > > > normal flow with normal hardware settings. > > > > > > We use different configurations to make hardware have different > > > permission to access the buffer it should access. > > > > > > So if we can't get the information of "the buffer is allocated > from > > > restricted_mtk_cma" when importing the buffer into the driver, we > won't > > > be able to configure the hardware correctly. > > > > Why can't you get this information from userspace? > > Same reason amd and i915/xe also pass this around internally in the > kernel, it's just that for those gpus the render and kms node are the > same > driver so this is easy. > The reason I ask is that encryption here looks just like another parameter for the buffer, e.g. like format, stride, tilling etc.. So instead of this during buffer import: mtk_gem->secure = (!strncmp(attach->dmabuf->exp_name, "restricted", 10)); mtk_gem->dma_addr = sg_dma_address(sg->sgl); mtk_gem->size = attach->dmabuf->size; mtk_gem->sg = sg; You can trivially say during use hey this buffer is encrypted. At least that's my 10 mile high view, maybe I'm missing some extensive key exchange or something like that. > But on arm you have split designs everywhere and dma-buf > import/export, so > something else is needed. And neither current kms uapi nor > protocols/extensions have provisions for this (afaik) because it > works on > the big gpus, and on android it's just hacked up with backchannels. > > So yeah essentially I think we probably need something like this, as > much > as it sucks. I see it somewhat similar to handling pcip2pdma > limitations > in the kernel too. > > Not sure where/how it should be handled though, and maybe I've missed > something around protocols, in which case I guess we should add some > secure buffer flags to the ADDFB2 ioctl. Thanks for your hint, I'll try to add the secure flag to the ADDFB2 ioctl. If it works, I'll send the patch. Yeah, exactly what I would suggest as well. I'm not an expert for that part, but as far as I know we already have bunch of device specific tilling flags in there. Adding an MTK_ENCRYPTED flag should be trivial. Regards, Christian. Regards, Jason-JH.Lin > -Sima * MEDIATEK Confidentiality Notice The information contained in this e-mail message (including any attachments) may be confidential, proprietary, privileged, or otherwise exempt from disclosure under applicable laws. It is intended to be conveyed only to the designated recipient(s). Any use, dissemination, distribution, printing, retaining or copying of this e-mail (including its attachments) by unintended recipient(s) is strictly prohibited and may be unlawful. If you are not an intended recipient of this e-mail, or believe that you have received this e-mail in error, please notify the sender immediately (by replying to this e-mail), delete any and all copies of this e-mail (including any attachments) from your system, and do not disclose the content of this e-mail to any other person. Thank you!
Re: [PATCH v5 2/9] scatterlist: Add a flag for the restricted memory
Am 27.06.24 um 05:17 schrieb Jason-JH Lin (林睿祥): On Wed, 2024-06-26 at 12:49 +0200, Christian König wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > Am 26.06.24 um 10:05 schrieb Jason-JH Lin (林睿祥): > > > > > > > In the step 3), we need to verify the dma-buf is allocated from > > > > "restricted_mtk_cma", but there is no way to pass the > > secure flag > > > > or > > > > private data from userspace to the import interface in DRM > > driver. > > > > > > Why do you need to verify that? > > > > I need to know the imported buffer is allocated from restricted cma > > and > > mark it as a secure buffer in mediatek-drm driver. Then, I will add > > some configuration to the hardware if the buffer is secure buffer, > > so > > that it can get the permission to access the secure buffer. > > Yeah so far that makes sense. This is basically what other drivers do > with secure buffers as well. > > But why do you want the kernel to transport that information? Usually > drivers get the information from userspace what to do with a buffer. > > In other words the format, stride, tilling and also if it's a secure > buffer or not comes from userspace. > Thanks for your clear explanation. I think this is what I want, but I can't find any DRM interface to pass the secure flag from userspace. Well stuff like that is usually device driver specific. So you should probably use something device specific which tells the driver that this buffer is encrypted. > What the hardware usually handles internally is things like > encryption keys, but you eventually get the information where to look > for the key from userspace as well. > > Handling inside the kernel would only be necessary if userspace could > for example crash the system with invalid parameters. But for > encryption that is usually not the case. > Yes, that's true. > > > > > > > So I can only verify it like this now: > > > > struct drm_gem_object *mtk_gem_prime_import_sg_table(struct > > > > drm_device > > > > *dev, struct dma_buf_attachment *attach, struct sg_table *sg) > > > > { > > > > struct mtk_gem_obj *mtk_gem; > > > > > > > > /* check if the entries in the sg_table are contiguous */ > > > > if (drm_prime_get_contiguous_size(sg) < > > attach->dmabuf->size) { > > > > DRM_ERROR("sg_table is not contiguous"); > > > > return ERR_PTR(-EINVAL); > > > > } > > > > mtk_gem = mtk_gem_init(dev, attach->dmabuf->size); > > > > if (IS_ERR(mtk_gem)) > > > > return ERR_CAST(mtk_gem); > > > > > > > > + mtk_gem->secure = (!strncmp(attach->dmabuf->exp_name, > > > > "restricted", > > > > 10)); > > > > mtk_gem->dma_addr = sg_dma_address(sg->sgl); > > > > mtk_gem->size = attach->dmabuf->size; > > > > mtk_gem->sg = sg; > > > > > > > > return &mtk_gem->base; > > > > } > > > > > > Complete NAK from my side to that approach. Importing of a DMA- > > buf > > > should be independent of the exporter. > > > > > > What you could do is to provide the secure buffer from a device > > and > > > not a device heap. > > > > > > > You mean I should allocate buffer in mediate-drm driver not > > userspace? > > Well that depends. The question is if you have multiple drivers which > needs to work with this secure buffer? > > If yes then you should have a general allocation heap for it. If no > then the buffers could as well be allocated from the driver interface > directly. > Yes, this buffer needs work with GPU and DRM drivers, so this general "restricted_mtk_cma" will allocated in userspace, then being passed to GPU and DRM. Well do you really need a separate heap for that? In other words is only a certain part of the system memory capable of being encrypted? Or would the "normal" CMA heap do as well and you only need to setup your hardware properly for encryption? Additional to that in most other drivers buffer sharing and encryption are two separate things. In other words other drivers do something like this: 1. Allocate the buffer. 2. Import the buffer using DRM_IOCTL_PRIME_FD_TO_HANDLE. 3. Set additional buffer properties, e.g. format, stride, tilling, if it's secure, which encryption key to use, where to map etc... So as far as I can see the problem you are facing is that you try to mangle everything into DRM_IOCTL_PRIME_FD_TO_HANDLE. Why not make that a separate IOCTL? I mean we intentionally don't provide things like format, stride, tilling etc.. to DRM_IOCTL_PRIME_FD_TO_HANDLE. Encryption is just another of those parameters. Regards, Christian. > > I just have modified this to userspace by the comment here: > > > > https://patchwork.kernel.org/project/linux-mediatek/patch/20240403102701.369-3-shawn.s...@mediatek.com/#25806766 > > > > > > I think I have the same problem as the ECC_FLAG mention in: > > > > > > > > > > https://lore.kernel.org/linux-media/20240515-dma-buf-
Re: [PATCH RESEND] drm: bridge: dw-mipi-dsi: Allow sync-pulses to override the burst vid-mode
Hi Heiko, On 06/26/2024, Heiko Stuebner wrote: > From: Heiko Stuebner > > The state right now is that if the panel has the burst-mode flag it > will take precedence over the sync-pulses mode. Yes. > > While sync-pulses are only relevant for the video-mode, the burst-mode > flag affects both the video-mode as well as the calculated lane_mbps. > > Looking at drivers like the nwl-dsi [0] it only enables burst mode when > the panel's flags do not contain the sync_pulse flag. > > So handle things similar for dw-dsi in that it selects the video-mode This doesn't seem to be necessary. DSI host drivers may choose video modes precedence. DSI device drivers should set video modes in the flag carefully, as any video mode set may be used by a certain DSI host driver. > with sync-pulses if that flag is set and only after that, checks for > the burst-mode. So panels selecting a combination of both burst and > sync-pulses get the sync-pulse mode. > > The case this fixes can be found on the ltk050h3148w . It does need the > lane-rate to be calculated according to burst formulas [1], but without > sync-pulses we see the output shifted around 20 pixels to the right, > meaning that the last 20 pixels from each line appear at the start of > the next display line. This sounds like ltk050h3148w abuses the video modes - it actually uses sync pulse video mode, but needs lane-rate be calculated by using lane_mbps instead of pixel clock which hints it uses burst video mode. Is it a panel initialization code issue or DSI host/PHY configuration issue or clock issue? commit e5f9d543419c78ac58f3b3557bc5a76b20ff600b says ltk050h3148w's driving controller is a Himax HX8394-F. Looking at panel-himax-hx8394.c, "powkiddy,x55-panel" is also a 720x1280 panel with only MIPI_DSI_MODE_VIDEO_BURST set and a different display timing. The panel is in rk3566-powkiddy-x55.dts, which means it also connects with a Synopsys DSI host controller. Maybe, you may try that display timing with burst video mode? > > [0] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/bridge/nwl-dsi.c#n301 > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6c9dbee84cd005bed5f9d07b3a2797ae6414b435 > > Fixes: 93e82bb4de01 ("drm/bridge: synopsys: dw-mipi-dsi: Fix hcomponent lbcc > for burst mode") commit 93e82bb4de01 follows the current state to make sure this driver chooses to take burst video mode as precedence over sync pulse video mode. > Signed-off-by: Heiko Stuebner > --- > resend, because I messed up and somehow forgot to include _all_ > mailing lists. > > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > index 824fb3c65742e..28dd858a751bd 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c > @@ -605,10 +605,10 @@ static void dw_mipi_dsi_video_mode_config(struct > dw_mipi_dsi *dsi) >*/ > val = ENABLE_LOW_POWER; > > - if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) > - val |= VID_MODE_TYPE_BURST; > - else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) > + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) > val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; > + else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) > + val |= VID_MODE_TYPE_BURST; If the precedence really needs to be swapped(which again doesn't seem to be necessary), then change the precedence in dw_mipi_dsi_get_hcomponent_lbcc() too, for the sake of consistency. > else > val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; > -- Regards, Liu Ying
[PATCH v2] drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes
In cdv_intel_lvds_get_modes(), the return value of drm_mode_duplicate() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd. Cc: sta...@vger.kernel.org Fixes: 6a227d5fd6c4 ("gma500: Add support for Cedarview") Signed-off-by: Ma Ke --- Changes in v2: - modified the patch according to suggestions from other patchs; - added Fixes line; - added Cc stable; - Link: https://lore.kernel.org/lkml/20240622072514.1867582-1-mak...@iscas.ac.cn/T/ --- drivers/gpu/drm/gma500/cdv_intel_lvds.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index f08a6803dc18..3adc2c9ab72d 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -311,6 +311,9 @@ static int cdv_intel_lvds_get_modes(struct drm_connector *connector) if (mode_dev->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); return 1; } -- 2.25.1
[PATCH 4/4] drm/vmwgfx: Add basic support for external buffers
Make vmwgfx go through the dma-buf interface to map/unmap imported buffers. The driver used to try to directly manipulate external buffers, assuming that everything that was coming to it had to live in cpu accessible memory. While technically true because what's in the vms is controlled by us, it's semantically completely broken. Fix importing of external buffers by forwarding all memory access requests to the importer. Tested by the vmw_prime basic_vgem test. Signed-off-by: Zack Rusin --- drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 62 +++-- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c index 07185c108218..07567d9519ec 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /* - * Copyright 2021-2023 VMware, Inc. + * Copyright (c) 2021-2024 Broadcom. All Rights Reserved. The term + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -78,6 +79,59 @@ static struct sg_table *vmw_gem_object_get_sg_table(struct drm_gem_object *obj) return drm_prime_pages_to_sg(obj->dev, vmw_tt->dma_ttm.pages, vmw_tt->dma_ttm.num_pages); } +static int vmw_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) +{ + struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(obj); + int ret; + + if (obj->import_attach) { + ret = dma_buf_vmap(obj->import_attach->dmabuf, map); + if (!ret) { + if (drm_WARN_ON(obj->dev, map->is_iomem)) { + dma_buf_vunmap(obj->import_attach->dmabuf, map); + return -EIO; + } + } + } else { + ret = ttm_bo_vmap(bo, map); + } + + return ret; +} + +static void vmw_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) +{ + if (obj->import_attach) { + dma_buf_vunmap(obj->import_attach->dmabuf, map); + } else { + drm_gem_ttm_vunmap(obj, map); + } +} + +static int vmw_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + int ret; + + if (obj->import_attach) { + /* Reset both vm_ops and vm_private_data, so we don't end up with +* vm_ops pointing to our implementation if the dma-buf backend +* doesn't set those fields. +*/ + vma->vm_private_data = NULL; + vma->vm_ops = NULL; + + ret = dma_buf_mmap(obj->dma_buf, vma, 0); + + /* Drop the reference drm_gem_mmap_obj() acquired.*/ + if (!ret) + drm_gem_object_put(obj); + + return ret; + } + + return drm_gem_ttm_mmap(obj, vma); +} + static const struct vm_operations_struct vmw_vm_ops = { .pfn_mkwrite = vmw_bo_vm_mkwrite, .page_mkwrite = vmw_bo_vm_mkwrite, @@ -94,9 +148,9 @@ static const struct drm_gem_object_funcs vmw_gem_object_funcs = { .pin = vmw_gem_object_pin, .unpin = vmw_gem_object_unpin, .get_sg_table = vmw_gem_object_get_sg_table, - .vmap = drm_gem_ttm_vmap, - .vunmap = drm_gem_ttm_vunmap, - .mmap = drm_gem_ttm_mmap, + .vmap = vmw_gem_vmap, + .vunmap = vmw_gem_vunmap, + .mmap = vmw_gem_mmap, .vm_ops = &vmw_vm_ops, }; -- 2.40.1
[PATCH 2/4] drm/vmwgfx: Make sure the screen surface is ref counted
Fix races issues in virtual crc generation by making sure the surface the code uses for crc computation is properly ref counted. Crc generation was trying to be too clever by allowing the surfaces to go in and out of scope, with the hope of always having some kind of screen present. That's not always the code, in particular during atomic disable, so to make sure the surface, when present, is not being actively destroyed at the same time, hold a reference to it. Signed-off-by: Zack Rusin Fixes: 7b0062036c3b ("drm/vmwgfx: Implement virtual crc generation") Cc: Zack Rusin Cc: Martin Krastev Cc: Broadcom internal kernel review list Cc: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c | 37 +--- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c index 3bfcf671fcd5..c35f7df99977 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c @@ -130,22 +130,26 @@ crc_generate_worker(struct work_struct *work) return; spin_lock_irq(&du->vkms.crc_state_lock); - surf = du->vkms.surface; + surf = vmw_surface_reference(du->vkms.surface); spin_unlock_irq(&du->vkms.crc_state_lock); - if (vmw_surface_sync(vmw, surf)) { - drm_warn(crtc->dev, "CRC worker wasn't able to sync the crc surface!\n"); - return; + if (surf) { + if (vmw_surface_sync(vmw, surf)) { + drm_warn( + crtc->dev, + "CRC worker wasn't able to sync the crc surface!\n"); + return; + } + + ret = compute_crc(crtc, surf, &crc32); + if (ret) + return; + vmw_surface_unreference(&surf); } - ret = compute_crc(crtc, surf, &crc32); - if (ret) - return; - spin_lock_irq(&du->vkms.crc_state_lock); frame_start = du->vkms.frame_start; frame_end = du->vkms.frame_end; - crc_pending = du->vkms.crc_pending; du->vkms.frame_start = 0; du->vkms.frame_end = 0; du->vkms.crc_pending = false; @@ -164,7 +168,7 @@ vmw_vkms_vblank_simulate(struct hrtimer *timer) struct vmw_display_unit *du = container_of(timer, struct vmw_display_unit, vkms.timer); struct drm_crtc *crtc = &du->crtc; struct vmw_private *vmw = vmw_priv(crtc->dev); - struct vmw_surface *surf = NULL; + bool has_surface = false; u64 ret_overrun; bool locked, ret; @@ -179,10 +183,10 @@ vmw_vkms_vblank_simulate(struct hrtimer *timer) WARN_ON(!ret); if (!locked) return HRTIMER_RESTART; - surf = du->vkms.surface; + has_surface = du->vkms.surface != NULL; vmw_vkms_unlock(crtc); - if (du->vkms.crc_enabled && surf) { + if (du->vkms.crc_enabled && has_surface) { u64 frame = drm_crtc_accurate_vblank_count(crtc); spin_lock(&du->vkms.crc_state_lock); @@ -336,6 +340,8 @@ vmw_vkms_crtc_cleanup(struct drm_crtc *crtc) { struct vmw_display_unit *du = vmw_crtc_to_du(crtc); + if (du->vkms.surface) + vmw_surface_unreference(&du->vkms.surface); WARN_ON(work_pending(&du->vkms.crc_generator_work)); hrtimer_cancel(&du->vkms.timer); } @@ -497,9 +503,12 @@ vmw_vkms_set_crc_surface(struct drm_crtc *crtc, struct vmw_display_unit *du = vmw_crtc_to_du(crtc); struct vmw_private *vmw = vmw_priv(crtc->dev); - if (vmw->vkms_enabled) { + if (vmw->vkms_enabled && du->vkms.surface != surf) { WARN_ON(atomic_read(&du->vkms.atomic_lock) != VMW_VKMS_LOCK_MODESET); - du->vkms.surface = surf; + if (du->vkms.surface) + vmw_surface_unreference(&du->vkms.surface); + if (surf) + du->vkms.surface = vmw_surface_reference(surf); } } -- 2.40.1
[PATCH 3/4] drm/vmwgfx: Fix handling of dumb buffers
Dumb buffers can be used in kms but also through prime with gallium's resource_from_handle. In the second case the dumb buffers can be rendered by the GPU where with the regular DRM kms interfaces they are mapped and written to by the CPU. Because the same buffer can be written to by the GPU and CPU vmwgfx needs to use vmw_surface (object which properly tracks dirty state of the guest and gpu memory) instead of vmw_bo (which is just guest side memory). Furthermore the dumb buffer handles are expected to be gem objects by a lot of userspace. Make vmwgfx accept gem handles in prime and kms but internally switch to vmw_surface's to properly track the dirty state of the objects between the GPU and CPU. Fixes new kwin and kde on wayland. Signed-off-by: Zack Rusin Fixes: b32233acceff ("drm/vmwgfx: Fix prime import/export") Cc: Broadcom internal kernel review list Cc: dri-devel@lists.freedesktop.org Cc: # v6.9+ --- drivers/gpu/drm/vmwgfx/vmw_surface_cache.h | 10 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 127 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 15 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h| 40 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c| 453 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h| 17 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c| 14 +- drivers/gpu/drm/vmwgfx/vmwgfx_prime.c | 32 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 27 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 33 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 145 +++ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c| 277 - 12 files changed, 688 insertions(+), 502 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmw_surface_cache.h b/drivers/gpu/drm/vmwgfx/vmw_surface_cache.h index b0d87c5f58d8..1ac3cb151b11 100644 --- a/drivers/gpu/drm/vmwgfx/vmw_surface_cache.h +++ b/drivers/gpu/drm/vmwgfx/vmw_surface_cache.h @@ -1,6 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ /** - * Copyright 2021 VMware, Inc. - * SPDX-License-Identifier: GPL-2.0 OR MIT + * + * Copyright (c) 2021-2024 Broadcom. All Rights Reserved. The term + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -31,6 +33,10 @@ #include +#define SVGA3D_FLAGS_UPPER_32(svga3d_flags) ((svga3d_flags) >> 32) +#define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \ + ((svga3d_flags) & ((uint64_t)U32_MAX)) + static inline u32 clamped_umul32(u32 a, u32 b) { uint64_t tmp = (uint64_t) a*b; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index e5eb21a471a6..f6fafb1fc5d8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 OR MIT /** * - * Copyright © 2011-2023 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. + * Copyright (c) 2011-2024 Broadcom. All Rights Reserved. The term + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -28,15 +28,39 @@ #include "vmwgfx_bo.h" #include "vmwgfx_drv.h" - +#include "vmwgfx_resource_priv.h" #include static void vmw_bo_release(struct vmw_bo *vbo) { + struct vmw_resource *res; + WARN_ON(vbo->tbo.base.funcs && kref_read(&vbo->tbo.base.refcount) != 0); vmw_bo_unmap(vbo); + + xa_destroy(&vbo->detached_resources); + WARN_ON(vbo->is_dumb && !vbo->dumb_surface); + if (vbo->is_dumb && vbo->dumb_surface) { + res = &vbo->dumb_surface->res; + WARN_ON(vbo != res->guest_memory_bo); + WARN_ON(!res->guest_memory_bo); + if (res->guest_memory_bo) { + /* Reserve and switch the backing mob. */ + mutex_lock(&res->dev_priv->cmdbuf_mutex); + (void)vmw_resource_reserve(res, false, true); + vmw_resource_mob_detach(res); + if (res->coherent) + vmw_bo_dirty_release(res->guest_memory_bo); + res->guest_memory_bo = NULL; + res->guest_memory_offset = 0; + vmw_resource_unreserve(res, false, false, false, NULL, + 0); + mutex_unlock(&res->dev_priv->cmdbuf_mutex); + } + vmw_surface_unreference(&vbo->dumb_surface); + } drm_gem_object_release(&vbo->tbo.base); } @@ -324,6 +348,11 @@ void vmw_bo_pin_reserved(struct vmw_bo *vbo, bool pin) * */ void *vmw_bo_map_and_cache(struct vmw_bo *v
[PATCH 1/4] drm/vmwgfx: Fix a deadlock in dma buf fence polling
Introduce a version of the fence ops that on release doesn't remove the fence from the pending list, and thus doesn't require a lock to fix poll->fence wait->fence unref deadlocks. vmwgfx overwrites the wait callback to iterate over the list of all fences and update their status, to do that it holds a lock to prevent the list modifcations from other threads. The fence destroy callback both deletes the fence and removes it from the list of pending fences, for which it holds a lock. dma buf polling cb unrefs a fence after it's been signaled: so the poll calls the wait, which signals the fences, which are being destroyed. The destruction tries to acquire the lock on the pending fences list which it can never get because it's held by the wait from which it was called. Old bug, but not a lot of userspace apps were using dma-buf polling interfaces. Fix those, in particular this fixes KDE stalls/deadlock. Signed-off-by: Zack Rusin Fixes: 2298e804e96e ("drm/vmwgfx: rework to new fence interface, v2") Cc: Broadcom internal kernel review list Cc: dri-devel@lists.freedesktop.org Cc: # v6.2+ --- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 26 -- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 5efc6a766f64..76971ef7801a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -32,7 +32,6 @@ #define VMW_FENCE_WRAP (1 << 31) struct vmw_fence_manager { - int num_fence_objects; struct vmw_private *dev_priv; spinlock_t lock; struct list_head fence_list; @@ -120,16 +119,23 @@ static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value) * objects with actions attached to them. */ -static void vmw_fence_obj_destroy(struct dma_fence *f) +static void vmw_fence_obj_destroy_removed(struct dma_fence *f) { struct vmw_fence_obj *fence = container_of(f, struct vmw_fence_obj, base); + WARN_ON(!list_empty(&fence->head)); + fence->destroy(fence); +} + +static void vmw_fence_obj_destroy(struct dma_fence *f) +{ + struct vmw_fence_obj *fence = + container_of(f, struct vmw_fence_obj, base); struct vmw_fence_manager *fman = fman_from_fence(fence); spin_lock(&fman->lock); list_del_init(&fence->head); - --fman->num_fence_objects; spin_unlock(&fman->lock); fence->destroy(fence); } @@ -257,6 +263,13 @@ static const struct dma_fence_ops vmw_fence_ops = { .release = vmw_fence_obj_destroy, }; +static const struct dma_fence_ops vmw_fence_ops_removed = { + .get_driver_name = vmw_fence_get_driver_name, + .get_timeline_name = vmw_fence_get_timeline_name, + .enable_signaling = vmw_fence_enable_signaling, + .wait = vmw_fence_wait, + .release = vmw_fence_obj_destroy_removed, +}; /* * Execute signal actions on fences recently signaled. @@ -355,7 +368,6 @@ static int vmw_fence_obj_init(struct vmw_fence_manager *fman, goto out_unlock; } list_add_tail(&fence->head, &fman->fence_list); - ++fman->num_fence_objects; out_unlock: spin_unlock(&fman->lock); @@ -403,7 +415,7 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, u32 passed_seqno) { u32 goal_seqno; - struct vmw_fence_obj *fence; + struct vmw_fence_obj *fence, *next_fence; if (likely(!fman->seqno_valid)) return false; @@ -413,7 +425,7 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, return false; fman->seqno_valid = false; - list_for_each_entry(fence, &fman->fence_list, head) { + list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { if (!list_empty(&fence->seq_passed_actions)) { fman->seqno_valid = true; vmw_fence_goal_write(fman->dev_priv, @@ -471,6 +483,7 @@ static void __vmw_fences_update(struct vmw_fence_manager *fman) rerun: list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { if (seqno - fence->base.seqno < VMW_FENCE_WRAP) { + fence->base.ops = &vmw_fence_ops_removed; list_del_init(&fence->head); dma_fence_signal_locked(&fence->base); INIT_LIST_HEAD(&action_list); @@ -662,6 +675,7 @@ void vmw_fence_fifo_down(struct vmw_fence_manager *fman) VMW_FENCE_WAIT_TIMEOUT); if (unlikely(ret != 0)) { + fence->base.ops = &vmw_fence_ops_removed; list_del_init(&fence->head); dma_fence_signal(&fence->base); INIT_LIST_HEAD(&action_list); -- 2.40.1
[PATCH 0/4] Fix various buffer mapping/import issues
This small series fixes all known prime/dumb_buffer/buffer dirty tracking issues. Fixing of dumb-buffers turned out to be a lot more complex than I wanted it to be. There's not much that can be done there because the driver has to support old userspace (our Xorg driver expects those to not be gem buffers and special cases a bunch of functionality) and new userspace (which expects the handles to be gem buffers, at least to issue GEM_CLOSE). The third patch deals with it by making the objects returned from dumb-buffers both (raw buffers and surfaces referenced by the same handle), which always works and doesn't require any changes in userspace. This fixes the known KDE (KWin's) buffer rendering issues. Zack Rusin (4): drm/vmwgfx: Fix a deadlock in dma buf fence polling drm/vmwgfx: Make sure the screen surface is ref counted drm/vmwgfx: Fix handling of dumb buffers drm/vmwgfx: Add basic support for external buffers drivers/gpu/drm/vmwgfx/vmw_surface_cache.h | 10 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 127 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 15 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h| 40 +- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 26 +- drivers/gpu/drm/vmwgfx/vmwgfx_gem.c| 62 ++- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c| 453 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h| 17 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c| 14 +- drivers/gpu/drm/vmwgfx/vmwgfx_prime.c | 32 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 27 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 33 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 145 +++ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c| 277 - drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c | 37 +- 15 files changed, 789 insertions(+), 526 deletions(-) -- 2.40.1
Re: [PATCH v4 1/5] clk: sunxi-ng: common: Support minimum and maximum rate
On Thu, Jun 27, 2024 at 9:23 AM Pafford, Robert J. wrote: > > Frank Oltmanns writes: > > > Hi Robert, > > > > 26.06.2024 18:03:24 Pafford, Robert J. : > > > >> Hi Frank, > >> > >> Moving to a new for loop makes sense. Let me know when you have a patch > > > > The patch is here, strange you didn't receive it: > > https://lore.kernel.org/all/20240623-sunxi-ng_fix_common_probe-v1-1-7c97e3282...@oltmanns.dev/ > > Ah, this must have slipped through my inbox. I just applied it on my board > and it is > now cooperating with the min/max clock rates! Please reply to the thread and give a Tested-by. ChenYu > > > >> and I'll be glad to test it on my board. I do also wonder if this may > >> have contributed to some of the HDMI issues seen in the other thread. > > > > My thought's exactly! > > > > Best regards, > > Frank > > > >> > >> Best, > >> Robert > >> > >>> Hi Robert, > >>> > >>> I'm truly sorry for the trouble the patch has caused you and for my late > >>> reply! > >>> > >>> On 2024-06-14 at 23:52:08 +, "Pafford, Robert J." > >>> wrote: > > The Allwinner SoC's typically have an upper and lower limit for their > > clocks' rates. Up until now, support for that has been implemented > > separately for each clock type. > > > > Implement that functionality in the sunxi-ng's common part making use of > > the CCF rate liming capabilities, so that it is available for all clock > > types. > > > > Suggested-by: Maxime Ripard > > Signed-off-by: Frank Oltmanns > > Cc: sta...@vger.kernel.org > > --- > > drivers/clk/sunxi-ng/ccu_common.c | 19 +++ > > drivers/clk/sunxi-ng/ccu_common.h | 3 +++ > > 2 files changed, 22 insertions(+) > > This patch appears to cause a buffer under-read bug due to the call to > 'hw_to_ccu_common', which assumes all entries > in the desc->hw_clocks->hws array are contained in ccu_common structs. > > However, not all clocks in the array are contained in ccu_common > structs. For example, as part > of the "sun20i-d1-ccu" driver, the "pll-video0" clock holds the 'clk_hw' > struct inside of a 'clk_fixed_factor' struct, > as it is a fixed factor clock based on the "pll-video0-4x" clock, > created with the CLK_FIXED_FACTOR_HWS macro. > This results in undefined behavior as the hw_to_ccu_common returns an > invalid pointer referencing memory before the > 'clk_fixed_factor' struct. > > >>> > >>> Great catch! At first glance, it seems to me that calling > >>> clk_hw_set_rate_range() in sunxi_ccu_probe() should not have happenend > >>> in the loop that iterates over the hw_clks. > >>> > >>> Instead we should add one more loop that iterates over the ccu_clks. > >>> Note, that there is already one such loop but, unfortunately, we can't > >>> use that as it happens before the hw_clks loop and we can only call > >>> clk_hw_set_rate_range() after the hw_clk has been registered. > >>> > >>> Hence, I propose to move the offending code to a new loop: > >>> for (i = 0; i < desc->num_ccu_clks; i++) { > >>> struct ccu_common *cclk = desc->ccu_clks[i]; > >>> > >>> if (!cclk) > >>> continue; > >>> > >>> if (cclk->max_rate) > >>> clk_hw_set_rate_range(&cclk->hw, common->min_rate, > >>> common->max_rate); > >>> else > >>> WARN(cclk->min_rate, > >>> "No max_rate, ignoring min_rate of clock %d > >>> - %s\n", > >>> i, cclk->hw.init->name); > >>> } > >>> > >>> I haven't tested (or even compiled) the above, but I'll test and send a > >>> patch within the next few days for you to test. > >>> > >>> Thanks again, > >>> Frank > >>> > > I have attached kernel warnings from a system based on the > "sun8i-t113s.dtsi" device tree, where the memory contains > a non-zero value for the min-rate but a zero value for the max-rate, > triggering the "No max_rate, ignoring min_rate" > warning in the 'sunxi_ccu_probe' function. > > [...] > > Thanks, > Robert
Re: [PATCH v5 2/9] scatterlist: Add a flag for the restricted memory
Re: [PATCH v5 2/9] scatterlist: Add a flag for the restricted memory
[PATCH v2] drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes
In psb_intel_lvds_get_modes(), the return value of drm_mode_duplicate() is assigned to mode, which will lead to a possible NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd. Cc: sta...@vger.kernel.org Fixes: 89c78134cc54 ("gma500: Add Poulsbo support") Signed-off-by: Ma Ke --- Changes in v2: - modified the patch according to suggestions; - added Fixes line; - added Cc stable. --- drivers/gpu/drm/gma500/psb_intel_lvds.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index 8486de230ec9..8d1be94a443b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -504,6 +504,9 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector) if (mode_dev->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); return 1; } -- 2.25.1
[PATCH v2] drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes
In nouveau_connector_get_modes(), the return value of drm_mode_duplicate() is assigned to mode, which will lead to a possible NULL pointer dereference on failure of drm_mode_duplicate(). Add a check to avoid npd. Fixes: 6ee738610f41 ("drm/nouveau: Add DRM driver for NVIDIA GPUs") Signed-off-by: Ma Ke --- Changes in v2: - modified the patch according to suggestions. --- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 856b3ef5edb8..0c71d761d378 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1001,6 +1001,9 @@ nouveau_connector_get_modes(struct drm_connector *connector) struct drm_display_mode *mode; mode = drm_mode_duplicate(dev, nv_connector->native_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); ret = 1; } -- 2.25.1
Re: [PATCH v4 1/5] clk: sunxi-ng: common: Support minimum and maximum rate
Frank Oltmanns writes: > Hi Robert, > > 26.06.2024 18:03:24 Pafford, Robert J. : > >> Hi Frank, >> >> Moving to a new for loop makes sense. Let me know when you have a patch > > The patch is here, strange you didn't receive it: > https://lore.kernel.org/all/20240623-sunxi-ng_fix_common_probe-v1-1-7c97e3282...@oltmanns.dev/ Ah, this must have slipped through my inbox. I just applied it on my board and it is now cooperating with the min/max clock rates! > >> and I'll be glad to test it on my board. I do also wonder if this may >> have contributed to some of the HDMI issues seen in the other thread. > > My thought's exactly! > > Best regards, > Frank > >> >> Best, >> Robert >> >>> Hi Robert, >>> >>> I'm truly sorry for the trouble the patch has caused you and for my late >>> reply! >>> >>> On 2024-06-14 at 23:52:08 +, "Pafford, Robert J." >>> wrote: > The Allwinner SoC's typically have an upper and lower limit for their > clocks' rates. Up until now, support for that has been implemented > separately for each clock type. > > Implement that functionality in the sunxi-ng's common part making use of > the CCF rate liming capabilities, so that it is available for all clock > types. > > Suggested-by: Maxime Ripard > Signed-off-by: Frank Oltmanns > Cc: sta...@vger.kernel.org > --- > drivers/clk/sunxi-ng/ccu_common.c | 19 +++ > drivers/clk/sunxi-ng/ccu_common.h | 3 +++ > 2 files changed, 22 insertions(+) This patch appears to cause a buffer under-read bug due to the call to 'hw_to_ccu_common', which assumes all entries in the desc->hw_clocks->hws array are contained in ccu_common structs. However, not all clocks in the array are contained in ccu_common structs. For example, as part of the "sun20i-d1-ccu" driver, the "pll-video0" clock holds the 'clk_hw' struct inside of a 'clk_fixed_factor' struct, as it is a fixed factor clock based on the "pll-video0-4x" clock, created with the CLK_FIXED_FACTOR_HWS macro. This results in undefined behavior as the hw_to_ccu_common returns an invalid pointer referencing memory before the 'clk_fixed_factor' struct. >>> >>> Great catch! At first glance, it seems to me that calling >>> clk_hw_set_rate_range() in sunxi_ccu_probe() should not have happenend >>> in the loop that iterates over the hw_clks. >>> >>> Instead we should add one more loop that iterates over the ccu_clks. >>> Note, that there is already one such loop but, unfortunately, we can't >>> use that as it happens before the hw_clks loop and we can only call >>> clk_hw_set_rate_range() after the hw_clk has been registered. >>> >>> Hence, I propose to move the offending code to a new loop: >>> for (i = 0; i < desc->num_ccu_clks; i++) { >>> struct ccu_common *cclk = desc->ccu_clks[i]; >>> >>> if (!cclk) >>> continue; >>> >>> if (cclk->max_rate) >>> clk_hw_set_rate_range(&cclk->hw, common->min_rate, >>> common->max_rate); >>> else >>> WARN(cclk->min_rate, >>> "No max_rate, ignoring min_rate of clock %d - >>> %s\n", >>> i, cclk->hw.init->name); >>> } >>> >>> I haven't tested (or even compiled) the above, but I'll test and send a >>> patch within the next few days for you to test. >>> >>> Thanks again, >>> Frank >>> I have attached kernel warnings from a system based on the "sun8i-t113s.dtsi" device tree, where the memory contains a non-zero value for the min-rate but a zero value for the max-rate, triggering the "No max_rate, ignoring min_rate" warning in the 'sunxi_ccu_probe' function. [...] Thanks, Robert
Re: [PATCH net-next v14 13/13] selftests: add ncdevmem, netcat for devmem TCP
On Wed, 26 Jun 2024 15:08:22 -0700 Jakub Kicinski wrote: > On Tue, 25 Jun 2024 19:54:01 + Mina Almasry wrote: > > +CFLAGS += -I../../../net/ynl/generated/ > > +CFLAGS += -I../../../net/ynl/lib/ > > + > > +LDLIBS += ../../../net/ynl/lib/ynl.a ../../../net/ynl/generated/protos.a > > Not as easy as this.. Please add this commit to your series: > https://github.com/kuba-moo/linux/commit/c130e8cc7208be544ec4f6f3627f1d36875d8c47 > > And here's an example of how you then use ynl.mk to code gen and build > for desired families (note the ordering of variables vs includes, > I remember that part was quite inflexible..): > https://github.com/kuba-moo/linux/commit/5d357f97ccd0248ca6136c5e11ca3eadf5091bb3 Investigating this further my patches will not work for O=xyz builds either. Please squash this into the relevant changes: diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile index db60d2718b35..9966e5b7139b 100644 --- a/tools/testing/selftests/drivers/net/Makefile +++ b/tools/testing/selftests/drivers/net/Makefile @@ -9,7 +9,8 @@ TEST_PROGS := \ stats.py \ # end of TEST_PROGS -# YNL files +# YNL files, must be before "include ..lib.mk" +EXTRA_CLEAN += $(OUTPUT)/libynl.a YNL_GEN_FILES := psp_responder TEST_GEN_FILES += $(YNL_GEN_FILES) diff --git a/tools/testing/selftests/net/ynl.mk b/tools/testing/selftests/net/ynl.mk index 0e01ad12b30e..59cb26cf3f73 100644 --- a/tools/testing/selftests/net/ynl.mk +++ b/tools/testing/selftests/net/ynl.mk @@ -18,6 +18,4 @@ $(YNL_OUTPUTS): CFLAGS += \ $(OUTPUT)/libynl.a: $(Q)$(MAKE) -C $(top_srcdir)/tools/net/ynl GENS="$(YNL_GENS)" libynl.a - $(Q)cp $(top_srcdir)/tools/net/ynl/libynl.a ./ - -EXTRA_CLEAN += libynl.a + $(Q)cp $(top_srcdir)/tools/net/ynl/libynl.a $(OUTPUT)/libynl.a
Re: [PATCH v13 09/13] Documentation: core-api: Add math.h macros and functions
On 6/7/24 6:31 AM, Devarsh Thakkar wrote: > Add documentation for rounding, scaling, absolute value and 32-bit division > related macros and functions exported by math.h header file. > > Signed-off-by: Devarsh Thakkar > Reviewed-by: Andy Shevchenko Reviewed-by: Randy Dunlap Tested-by: Randy Dunlap Thanks. > --- > V13: No change > V12: Add Reviewed-by > V11: Fix title for math function header > V10: Patch introduced > V1->V9 (No change) > Documentation/core-api/kernel-api.rst | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/Documentation/core-api/kernel-api.rst > b/Documentation/core-api/kernel-api.rst > index ae92a2571388..7de494e76fa6 100644 > --- a/Documentation/core-api/kernel-api.rst > +++ b/Documentation/core-api/kernel-api.rst > @@ -185,6 +185,12 @@ Division Functions > .. kernel-doc:: lib/math/gcd.c > :export: > > +Rounding, absolute value, division and 32-bit scaling functions > +--- > + > +.. kernel-doc:: include/linux/math.h > + :internal: > + > UUID/GUID > - > -- ~Randy
[PATCH 6/6] drm/bridge: imx8qxp-ldb: Switch to RUNTIME_PM_OPS()
From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c index 7984da9c0a35..b33011f397f0 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c @@ -678,12 +678,12 @@ static void imx8qxp_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_ldb_runtime_suspend(struct device *dev) +static int imx8qxp_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) +static int imx8qxp_ldb_runtime_resume(struct device *dev) { struct imx8qxp_ldb *imx8qxp_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qxp_ldb->base; @@ -695,8 +695,7 @@ static int __maybe_unused imx8qxp_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, - imx8qxp_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, imx8qxp_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_ldb_dt_ids[] = { @@ -709,7 +708,7 @@ static struct platform_driver imx8qxp_ldb_driver = { .probe = imx8qxp_ldb_probe, .remove_new = imx8qxp_ldb_remove, .driver = { - .pm = &imx8qxp_ldb_pm_ops, + .pm = pm_ptr(&imx8qxp_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_ldb_dt_ids, }, -- 2.34.1
[PATCH 5/6] drm/bridge: dw-hdmi-cec: Switch to SYSTEM_SLEEP_PM_OPS()
From: Fabio Estevam Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() alternative. The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c index 673661160e54..d4614de1ae1e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c @@ -312,7 +312,7 @@ static void dw_hdmi_cec_remove(struct platform_device *pdev) cec_unregister_adapter(cec->adap); } -static int __maybe_unused dw_hdmi_cec_resume(struct device *dev) +static int dw_hdmi_cec_resume(struct device *dev) { struct dw_hdmi_cec *cec = dev_get_drvdata(dev); @@ -328,7 +328,7 @@ static int __maybe_unused dw_hdmi_cec_resume(struct device *dev) return 0; } -static int __maybe_unused dw_hdmi_cec_suspend(struct device *dev) +static int dw_hdmi_cec_suspend(struct device *dev) { struct dw_hdmi_cec *cec = dev_get_drvdata(dev); @@ -341,7 +341,7 @@ static int __maybe_unused dw_hdmi_cec_suspend(struct device *dev) } static const struct dev_pm_ops dw_hdmi_cec_pm = { - SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume) + SYSTEM_SLEEP_PM_OPS(dw_hdmi_cec_suspend, dw_hdmi_cec_resume) }; static struct platform_driver dw_hdmi_cec_driver = { @@ -349,7 +349,7 @@ static struct platform_driver dw_hdmi_cec_driver = { .remove_new = dw_hdmi_cec_remove, .driver = { .name = "dw-hdmi-cec", - .pm = &dw_hdmi_cec_pm, + .pm = pm_ptr(&dw_hdmi_cec_pm), }, }; module_platform_driver(dw_hdmi_cec_driver); -- 2.34.1
[PATCH 4/6] drm/bridge: samsung-dsim: Switch to RUNTIME_PM_OPS()
From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/samsung-dsim.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index e7e53a9e42af..73ccf21ae446 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -2043,7 +2043,7 @@ void samsung_dsim_remove(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(samsung_dsim_remove); -static int __maybe_unused samsung_dsim_suspend(struct device *dev) +static int samsung_dsim_suspend(struct device *dev) { struct samsung_dsim *dsi = dev_get_drvdata(dev); const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -2073,7 +2073,7 @@ static int __maybe_unused samsung_dsim_suspend(struct device *dev) return 0; } -static int __maybe_unused samsung_dsim_resume(struct device *dev) +static int samsung_dsim_resume(struct device *dev) { struct samsung_dsim *dsi = dev_get_drvdata(dev); const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -2108,7 +2108,7 @@ static int __maybe_unused samsung_dsim_resume(struct device *dev) } const struct dev_pm_ops samsung_dsim_pm_ops = { - SET_RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL) + RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; @@ -2142,7 +2142,7 @@ static struct platform_driver samsung_dsim_driver = { .remove_new = samsung_dsim_remove, .driver = { .name = "samsung-dsim", - .pm = &samsung_dsim_pm_ops, + .pm = pm_ptr(&samsung_dsim_pm_ops), .of_match_table = samsung_dsim_of_match, }, }; -- 2.34.1
[PATCH 3/6] drm/bridge: imx8qxp-pixel-combiner: Switch to RUNTIME_PM_OPS()
From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c index e6dbbdc87ce2..ce43e4069e21 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c @@ -371,7 +371,7 @@ static void imx8qxp_pc_bridge_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) +static int imx8qxp_pc_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -393,7 +393,7 @@ static int __maybe_unused imx8qxp_pc_runtime_suspend(struct device *dev) return ret; } -static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) +static int imx8qxp_pc_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct imx8qxp_pc *pc = platform_get_drvdata(pdev); @@ -415,8 +415,7 @@ static int __maybe_unused imx8qxp_pc_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qxp_pc_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, - imx8qxp_pc_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qxp_pc_runtime_suspend, imx8qxp_pc_runtime_resume, NULL) }; static const struct of_device_id imx8qxp_pc_dt_ids[] = { @@ -430,7 +429,7 @@ static struct platform_driver imx8qxp_pc_bridge_driver = { .probe = imx8qxp_pc_bridge_probe, .remove_new = imx8qxp_pc_bridge_remove, .driver = { - .pm = &imx8qxp_pc_pm_ops, + .pm = pm_ptr(&imx8qxp_pc_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qxp_pc_dt_ids, }, -- 2.34.1
[PATCH 2/6] drm/bridge: imx8qm-ldb: Switch to RUNTIME_PM_OPS()
From: Fabio Estevam Replace SET_RUNTIME_PM_OPS with its modern RUNTIME_PM_OPS() alternative. The combined usage of pm_ptr() and RUNTIME_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8qm-ldb.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c index 21471a9a28b2..c879e37f5811 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c @@ -542,12 +542,12 @@ static void imx8qm_ldb_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused imx8qm_ldb_runtime_suspend(struct device *dev) +static int imx8qm_ldb_runtime_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) +static int imx8qm_ldb_runtime_resume(struct device *dev) { struct imx8qm_ldb *imx8qm_ldb = dev_get_drvdata(dev); struct ldb *ldb = &imx8qm_ldb->base; @@ -559,8 +559,7 @@ static int __maybe_unused imx8qm_ldb_runtime_resume(struct device *dev) } static const struct dev_pm_ops imx8qm_ldb_pm_ops = { - SET_RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, - imx8qm_ldb_runtime_resume, NULL) + RUNTIME_PM_OPS(imx8qm_ldb_runtime_suspend, imx8qm_ldb_runtime_resume, NULL) }; static const struct of_device_id imx8qm_ldb_dt_ids[] = { @@ -573,7 +572,7 @@ static struct platform_driver imx8qm_ldb_driver = { .probe = imx8qm_ldb_probe, .remove_new = imx8qm_ldb_remove, .driver = { - .pm = &imx8qm_ldb_pm_ops, + .pm = pm_ptr(&imx8qm_ldb_pm_ops), .name = DRIVER_NAME, .of_match_table = imx8qm_ldb_dt_ids, }, -- 2.34.1
[PATCH 1/6] drm/bridge: imx8mp-hdmi-tx: Switch to SYSTEM_SLEEP_PM_OPS()
From: Fabio Estevam Replace SET_SYSTEM_SLEEP_PM_OPS with its modern SYSTEM_SLEEP_PM_OPS() alternative. The combined usage of pm_ptr() and SYSTEM_SLEEP_PM_OPS() allows the compiler to evaluate if the runtime suspend/resume() functions are used at build time or are simply dead code. This allows removing the __maybe_unused notation from the runtime suspend/resume() functions. Signed-off-by: Fabio Estevam --- drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c index 13bc570c5473..4a3a8a3ce250 100644 --- a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c @@ -111,12 +111,12 @@ static void imx8mp_dw_hdmi_remove(struct platform_device *pdev) dw_hdmi_remove(hdmi->dw_hdmi); } -static int __maybe_unused imx8mp_dw_hdmi_pm_suspend(struct device *dev) +static int imx8mp_dw_hdmi_pm_suspend(struct device *dev) { return 0; } -static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) +static int imx8mp_dw_hdmi_pm_resume(struct device *dev) { struct imx8mp_hdmi *hdmi = dev_get_drvdata(dev); @@ -126,8 +126,7 @@ static int __maybe_unused imx8mp_dw_hdmi_pm_resume(struct device *dev) } static const struct dev_pm_ops imx8mp_dw_hdmi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, - imx8mp_dw_hdmi_pm_resume) + SYSTEM_SLEEP_PM_OPS(imx8mp_dw_hdmi_pm_suspend, imx8mp_dw_hdmi_pm_resume) }; static const struct of_device_id imx8mp_dw_hdmi_of_table[] = { @@ -142,7 +141,7 @@ static struct platform_driver imx8mp_dw_hdmi_platform_driver = { .driver = { .name = "imx8mp-dw-hdmi-tx", .of_match_table = imx8mp_dw_hdmi_of_table, - .pm = &imx8mp_dw_hdmi_pm_ops, + .pm = pm_ptr(&imx8mp_dw_hdmi_pm_ops), }, }; -- 2.34.1
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On 27.06.2024 12:32 AM, Rob Clark wrote: > On Wed, Jun 26, 2024 at 2:38 PM Konrad Dybcio > wrote: >> >> On 26.06.2024 8:43 PM, Rob Clark wrote: >>> On Wed, Jun 26, 2024 at 1:24 AM Akhil P Oommen >>> wrote: On Mon, Jun 24, 2024 at 03:53:48PM +0200, Konrad Dybcio wrote: > > > On 6/23/24 13:06, Akhil P Oommen wrote: >> Add support in drm/msm driver for the Adreno X185 gpu found in >> Snapdragon X1 Elite chipset. >> >> Signed-off-by: Akhil P Oommen >> --- >> >> drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ >> drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ >> drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ >> drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + >> 4 files changed, 36 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c >> b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c >> index 0e3dfd4c2bc8..168a4bddfaf2 100644 >> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c >> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c >> @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, >> unsigned int state) >> */ >> gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); >> + if (adreno_is_x185(adreno_gpu)) { >> + chipid = 0x7050001; > > What's wrong with using the logic below? patchid is BITS(7, 0), not (15, 8) in the case of x185. Due to the changes in the chipid scheme within the a7x family, this is a bit confusing. I will try to improve here in another series. >>> >>> I'm thinking we should just add gmu_chipid to struct a6xx_info, tbh >>> >>> Maybe to start with, we can fall back to the existing logic if >>> a6xx_info::gmu_chipid is zero so we don't have to add it for _every_ >>> a6xx/a7xx >> >> If X185 is not the only occurence, I'd second this.. > > basically all a7xx are "special" compared to the original logic, so we > can start with using gmu_chipid for just a7xx That works Konrad
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On Wed, Jun 26, 2024 at 2:38 PM Konrad Dybcio wrote: > > On 26.06.2024 8:43 PM, Rob Clark wrote: > > On Wed, Jun 26, 2024 at 1:24 AM Akhil P Oommen > > wrote: > >> > >> On Mon, Jun 24, 2024 at 03:53:48PM +0200, Konrad Dybcio wrote: > >>> > >>> > >>> On 6/23/24 13:06, Akhil P Oommen wrote: > Add support in drm/msm driver for the Adreno X185 gpu found in > Snapdragon X1 Elite chipset. > > Signed-off-by: Akhil P Oommen > --- > > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ > drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ > drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + > 4 files changed, 36 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > index 0e3dfd4c2bc8..168a4bddfaf2 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, > unsigned int state) > */ > gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); > + if (adreno_is_x185(adreno_gpu)) { > + chipid = 0x7050001; > >>> > >>> What's wrong with using the logic below? > >> > >> patchid is BITS(7, 0), not (15, 8) in the case of x185. Due to the > >> changes in the chipid scheme within the a7x family, this is a bit > >> confusing. I will try to improve here in another series. > > > > I'm thinking we should just add gmu_chipid to struct a6xx_info, tbh > > > > Maybe to start with, we can fall back to the existing logic if > > a6xx_info::gmu_chipid is zero so we don't have to add it for _every_ > > a6xx/a7xx > > If X185 is not the only occurence, I'd second this.. basically all a7xx are "special" compared to the original logic, so we can start with using gmu_chipid for just a7xx BR, -R > Konrad
[PULL] drm-xe-next
Hi Dave and Sima, Here goes our likely last pull-request towards 6.11. If some last minute thing shows up a small one might come next Tuesday. Thanks, Rodrigo. drm-xe-next-2024-06-26: UAPI Changes: - New uapi adding OA functionality to Xe (Ashutosh) Cross-subsystem Changes: - devcoredump: Add dev_coredumpm_timeout (Jose) Driver Changes: - More SRIOV preparation, including GuC communication improvements (Michal) - Kconfig update: do not select ACPI_BUTTON (Jani) - Rework GPU page fault handling (Brost) - Forcewake clean-up and fixes (Himal, Michal) - Drop EXEC_QUEUE_FLAG_BANNED (Brost) - Xe/Xe2 Workarounds fixes and additions (Tejas, Akshata, Sai, Vinay) - Xe devcoredump changes (Jose) - Tracing cleanup and add mmio tracing (RK) - Add BMG PCI IDs (Roper) - Scheduler fixes and improvements (Brost) - Some overal driver clean-up around headers and print macros (Michal) - Rename xe_exec_queue::compute to xe_exec_queue::lr (Francois) - Improve RTP rules to allow easier 'OR' conditions in WA declaration (Lucas) - Use ttm_uncached for BO with NEEDS_UC flag (Michal) - Other OA related work and fixes (Ashutosh, Michal, Jose) - Simplify locking in new_vma (Brost) - Remove xe_irq_shutdown (Ilia) The following changes since commit 541b1b0a8fc235bca355921eb7f3f59a8efa3e9a: agp: add missing MODULE_DESCRIPTION() macros (2024-06-24 16:20:58 +1000) are available in the Git repository at: https://gitlab.freedesktop.org/drm/xe/kernel.git tags/drm-xe-next-2024-06-26 for you to fetch changes up to 406d058dc323ae152d380ac90153eb56a75850c1: drm/xe/oa/uapi: Allow preemption to be disabled on the stream exec queue (2024-06-26 18:25:46 -0400) UAPI Changes: - New uapi adding OA functionality to Xe (Ashutosh) Cross-subsystem Changes: - devcoredump: Add dev_coredumpm_timeout (Jose) Driver Changes: - More SRIOV preparation, including GuC communication improvements (Michal) - Kconfig update: do not select ACPI_BUTTON (Jani) - Rework GPU page fault handling (Brost) - Forcewake clean-up and fixes (Himal, Michal) - Drop EXEC_QUEUE_FLAG_BANNED (Brost) - Xe/Xe2 Workarounds fixes and additions (Tejas, Akshata, Sai, Vinay) - Xe devcoredump changes (Jose) - Tracing cleanup and add mmio tracing (RK) - Add BMG PCI IDs (Roper) - Scheduler fixes and improvements (Brost) - Some overal driver clean-up around headers and print macros (Michal) - Rename xe_exec_queue::compute to xe_exec_queue::lr (Francois) - Improve RTP rules to allow easier 'OR' conditions in WA declaration (Lucas) - Use ttm_uncached for BO with NEEDS_UC flag (Michal) - Other OA related work and fixes (Ashutosh, Michal, Jose) - Simplify locking in new_vma (Brost) - Remove xe_irq_shutdown (Ilia) Akshata Jahagirdar (1): drm/xe/xe2lpg: Add Wa_14021490052 Ashutosh Dixit (21): drm/xe/perf/uapi: "Perf" layer to support multiple perf counter stream types drm/xe/perf/uapi: Add perf_stream_paranoid sysctl drm/xe/oa/uapi: Add OA data formats drm/xe/oa/uapi: Initialize OA units drm/xe/oa/uapi: Add/remove OA config perf ops drm/xe/oa/uapi: Define and parse OA stream properties drm/xe/oa: OA stream initialization (OAG) drm/xe/oa/uapi: Expose OA stream fd drm/xe/oa/uapi: Read file_operation drm/xe/oa: Add OAR support drm/xe/oa: Add OAC support drm/xe/oa/uapi: Query OA unit properties drm/xe/oa/uapi: OA buffer mmap drm/xe/oa: Add MMIO trigger support drm/xe/oa: Override GuC RC with OA on PVC drm/xe/oa: Changes to OA_TAKEN drm/xe/oa: Enable Xe2+ overrun mode drm/xe/oa: Remove WARN_ON's for unsupported configurations drm/xe/oa: Fix kernel doc in xe_drm.h drm/xe/oa: Allow stream enable/disable functions to return error drm/xe/oa/uapi: Allow preemption to be disabled on the stream exec queue Francois Dugast (2): drm/xe/sched_job: Promote xe_sched_job_add_deps() drm/xe/exec_queue: Rename xe_exec_queue::compute to xe_exec_queue::lr Himal Prasad Ghimiray (3): drm/xe: Cleanup force wake registers bit definitions drm/xe: Ensure caller uses sole domain for xe_force_wake_assert_held drm/xe: Check valid domain is passed in xe_force_wake_ref Ilia Levi (1): drm/xe/irq: remove xe_irq_shutdown Jani Nikula (1): drm/xe: do not select ACPI_BUTTON José Roberto de Souza (3): devcoredump: Add dev_coredumpm_timeout() drm/xe: Increase devcoredump timeout drm/xe/oa: Call xe_oa_emit_oa_config() with new config when updating config Lucas De Marchi (5): drm/xe/rtp: Allow to match 0 sr entries drm/xe/rtp: Expand max rules/actions per entry drm/xe/rtp: Allow to OR rules drm/xe/rtp: Add match on any GT drm/xe/xe2: Add proper check for media in Wa_14020756599 Matt Roper (1): drm/xe/bmg: Add PCI IDs Matthew Brost (15): drm/xe: Rework GPU page
[pull] amdgpu drm-fixes-6.10
Hi Dave, Sima, Fixes for 6.10. The following changes since commit f2661062f16b2de5d7b6a5c42a9a5c96326b8454: Linux 6.10-rc5 (2024-06-23 17:08:54 -0400) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-fixes-6.10-2024-06-26 for you to fetch changes up to 48880f9686b1ac2ea0831f65df953a63d1437fc0: drm/amdgpu: Don't show false warning for reg list (2024-06-25 14:22:56 -0400) amd-drm-fixes-6.10-2024-06-26: amdgpu: - SMU 14.x fix - vram info parsing fix - mode1 reset fix - LTTPR fix - Virtual display fix - Avoid spurious error in PSP init Alex Deucher (1): drm/amdgpu/atomfirmware: fix parsing of vram_info Julia Zhang (1): drm/amdgpu: avoid using null object of framebuffer Li Ma (1): drm/amd/swsmu: add MALL init support workaround for smu_v14_0_1 Lijo Lazar (2): drm/amdgpu: Fix pci state save during mode-1 reset drm/amdgpu: Don't show false warning for reg list Michael Strauss (1): drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c| 25 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 18 +- drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h| 5 +- .../display/dc/link/protocols/link_dp_capability.c | 10 ++- drivers/gpu/drm/amd/display/include/dpcd_defs.h| 5 ++ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 13 drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 5 ++ .../amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_ppsmc.h | 4 +- drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h | 4 +- .../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c | 73 ++ 12 files changed, 156 insertions(+), 15 deletions(-)
Re: [PATCH net-next v14 13/13] selftests: add ncdevmem, netcat for devmem TCP
On Tue, 25 Jun 2024 19:54:01 + Mina Almasry wrote: > +CFLAGS += -I../../../net/ynl/generated/ > +CFLAGS += -I../../../net/ynl/lib/ > + > +LDLIBS += ../../../net/ynl/lib/ynl.a ../../../net/ynl/generated/protos.a Not as easy as this.. Please add this commit to your series: https://github.com/kuba-moo/linux/commit/c130e8cc7208be544ec4f6f3627f1d36875d8c47 And here's an example of how you then use ynl.mk to code gen and build for desired families (note the ordering of variables vs includes, I remember that part was quite inflexible..): https://github.com/kuba-moo/linux/commit/5d357f97ccd0248ca6136c5e11ca3eadf5091bb3 Feel free to repost as soon as you got it fixed. -- pw-bot: cr
Re: [PATCH] drm/msm/a6xx: request memory region
On Thu, Jun 27, 2024 at 03:22:18AM GMT, Akhil P Oommen wrote: > << snip >> > > > > > > > > @@ -1503,7 +1497,7 @@ static void __iomem > > > > > > > *a6xx_gmu_get_mmio(struct platform_device *pdev, > > > > > > > return ERR_PTR(-EINVAL); > > > > > > > } > > > > > > > > > > > > > > - ret = ioremap(res->start, resource_size(res)); > > > > > > > + ret = devm_ioremap_resource(&pdev->dev, res); > > > > > > > > > > > > So, this doesn't actually work, failing in > > > > > > __request_region_locked(), > > > > > > because the gmu region partially overlaps with the gpucc region > > > > > > (which > > > > > > is busy). I think this is intentional, since gmu is controlling the > > > > > > gpu clocks, etc. In particular REG_A6XX_GPU_CC_GX_GDSCR is in this > > > > > > overlapping region. Maybe Akhil knows more about GMU. > > > > > > > > > > We don't really need to map gpucc region from driver on behalf of gmu. > > > > > Since we don't access any gpucc register from drm-msm driver, we can > > > > > update the range size to correct this. But due to backward > > > > > compatibility > > > > > requirement with older dt, can we still enable region locking? I > > > > > prefer > > > > > it if that is possible. > > > > > > > > Actually, when I reduced the region size to not overlap with gpucc, > > > > the region is smaller than REG_A6XX_GPU_CC_GX_GDSCR * 4. > > > > > > > > So I guess that register is actually part of gpucc? > > > > > > Yes. It has *GPU_CC* in its name. :P > > > > > > I just saw that we program this register on legacy a6xx targets to > > > ensure retention is really ON before collapsing gdsc. So we can't > > > avoid mapping gpucc region in legacy a6xx GPUs. That is unfortunate! > > > > I guess we could still use devm_ioremap().. idk if there is a better > > way to solve this > > Can we do it without breaking backward compatibility with dt? I think a proper way would be to use devm_ioremap in the gpucc driver, then the GPU driver can use devm_platform_ioremap_resource(). I'll take a look at sketching the gpucc patches in one of the next few days. > > -Akhil > > > > > BR, > > -R > > > > > -Akhil. > > > > > > > > > > > BR, > > > > -R -- With best wishes Dmitry
Re: [PATCH] drm/msm/a6xx: request memory region
<< snip >> > > > > > > @@ -1503,7 +1497,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct > > > > > > platform_device *pdev, > > > > > > return ERR_PTR(-EINVAL); > > > > > > } > > > > > > > > > > > > - ret = ioremap(res->start, resource_size(res)); > > > > > > + ret = devm_ioremap_resource(&pdev->dev, res); > > > > > > > > > > So, this doesn't actually work, failing in __request_region_locked(), > > > > > because the gmu region partially overlaps with the gpucc region (which > > > > > is busy). I think this is intentional, since gmu is controlling the > > > > > gpu clocks, etc. In particular REG_A6XX_GPU_CC_GX_GDSCR is in this > > > > > overlapping region. Maybe Akhil knows more about GMU. > > > > > > > > We don't really need to map gpucc region from driver on behalf of gmu. > > > > Since we don't access any gpucc register from drm-msm driver, we can > > > > update the range size to correct this. But due to backward compatibility > > > > requirement with older dt, can we still enable region locking? I prefer > > > > it if that is possible. > > > > > > Actually, when I reduced the region size to not overlap with gpucc, > > > the region is smaller than REG_A6XX_GPU_CC_GX_GDSCR * 4. > > > > > > So I guess that register is actually part of gpucc? > > > > Yes. It has *GPU_CC* in its name. :P > > > > I just saw that we program this register on legacy a6xx targets to > > ensure retention is really ON before collapsing gdsc. So we can't > > avoid mapping gpucc region in legacy a6xx GPUs. That is unfortunate! > > I guess we could still use devm_ioremap().. idk if there is a better > way to solve this Can we do it without breaking backward compatibility with dt? -Akhil > > BR, > -R > > > -Akhil. > > > > > > > > BR, > > > -R
[PATCH v5 11/12] drm/msm/dpu: allow using two SSPP blocks for a single plane
Virtual wide planes give high amount of flexibility, but it is not always enough: In parallel multirect case only the half of the usual width is supported for tiled formats. Thus the whole width of two tiled multirect rectangles can not be greater than max_linewidth, which is not enough for some platforms/compositors. Another example is as simple as wide YUV plane. YUV planes can not use multirect, so currently they are limited to max_linewidth too. Now that the planes are fully virtualized, add support for allocating two SSPP blocks to drive a single DRM plane. This fixes both mentioned cases and allows all planes to go up to 2*max_linewidth (at the cost of making some of the planes unavailable to the user). Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 161 ++ 1 file changed, 117 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index c72c65bf55e1..0d9f9216420b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -19,7 +19,6 @@ #include "msm_drv.h" #include "dpu_kms.h" -#include "dpu_formats.h" #include "dpu_hw_sspp.h" #include "dpu_hw_util.h" #include "dpu_trace.h" @@ -886,6 +885,28 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane *plane, return 0; } +static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe, + struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) || + drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect)) + return false; + + if (pipe_cfg->rotation & DRM_MODE_ROTATE_90) + return false; + + if (MSM_FORMAT_IS_YUV(fmt)) + return false; + + if (MSM_FORMAT_IS_UBWC(fmt) && + drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) + return false; + + return true; +} + static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, struct drm_atomic_state *state, const struct drm_crtc_state *crtc_state) @@ -899,7 +920,6 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, const struct msm_format *fmt; struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; - uint32_t max_linewidth; uint32_t supported_rotations; const struct dpu_sspp_cfg *pipe_hw_caps; const struct dpu_sspp_sub_blks *sblk; @@ -921,8 +941,6 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, fmt = msm_framebuffer_format(new_plane_state->fb); - max_linewidth = pdpu->catalog->caps->max_linewidth; - supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) @@ -938,41 +956,6 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, return ret; if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) { - /* -* In parallel multirect case only the half of the usual width -* is supported for tiled formats. If we are here, we know that -* full width is more than max_linewidth, thus each rect is -* wider than allowed. -*/ - if (MSM_FORMAT_IS_UBWC(fmt) && - drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n", - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); - return -E2BIG; - } - - if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) || - drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect) || - (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) && -!test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) || - pipe_cfg->rotation & DRM_MODE_ROTATE_90 || - MSM_FORMAT_IS_YUV(fmt)) { - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use split source\n", - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); - return -E2BIG; - } - - /* -* Use multirect for wide plane. We do not support dynamic -* assignment of SSPPs, so
[PATCH v5 08/12] drm/msm/dpu: split dpu_plane_atomic_check()
Split dpu_plane_atomic_check() function into two pieces: dpu_plane_atomic_check_nopipe() performing generic checks on the pstate, without touching the associated pipe, and dpu_plane_atomic_check_pipes(), which takes into account used pipes. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 178 +++--- 1 file changed, 112 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 115c1bd77bdd..9b9fe28052ad 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -788,49 +788,22 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, #define MAX_UPSCALE_RATIO 20 #define MAX_DOWNSCALE_RATIO4 -static int dpu_plane_atomic_check(struct drm_plane *plane, - struct drm_atomic_state *state) +static int dpu_plane_atomic_check_nopipe(struct drm_plane *plane, +struct drm_plane_state *new_plane_state, +const struct drm_crtc_state *crtc_state) { - struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, - plane); int ret = 0, min_scale, max_scale; struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate; struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); - struct dpu_sw_pipe *pipe = &pstate->pipe; - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; - const struct drm_crtc_state *crtc_state = NULL; - const struct msm_format *fmt; struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; struct drm_rect fb_rect = { 0 }; uint32_t max_linewidth; - unsigned int rotation; - uint32_t supported_rotations; - const struct dpu_sspp_cfg *pipe_hw_caps; - const struct dpu_sspp_sub_blks *sblk; - - if (new_plane_state->crtc) - crtc_state = drm_atomic_get_new_crtc_state(state, - new_plane_state->crtc); - - pipe->sspp = dpu_rm_get_sspp(&kms->rm, pdpu->pipe); - r_pipe->sspp = NULL; - if (!pipe->sspp) - return -EINVAL; - - pipe_hw_caps = pipe->sspp->cap; - sblk = pipe->sspp->cap->sblk; - - if (sblk->scaler_blk.len) { - min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO); - max_scale = MAX_DOWNSCALE_RATIO << 16; - } else { - min_scale = DRM_PLANE_NO_SCALING; - max_scale = DRM_PLANE_NO_SCALING; - } + min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO); + max_scale = MAX_DOWNSCALE_RATIO << 16; ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, min_scale, @@ -843,11 +816,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, if (!new_plane_state->visible) return 0; - pipe->multirect_index = DPU_SSPP_RECT_SOLO; - pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; - r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; - r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; - pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos; if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) { DPU_ERROR("> %d plane stages assigned\n", @@ -871,8 +839,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -E2BIG; } - fmt = msm_framebuffer_format(new_plane_state->fb); - max_linewidth = pdpu->catalog->caps->max_linewidth; drm_rect_rotate(&pipe_cfg->src_rect, @@ -881,6 +847,78 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) { + if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) { + DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", + DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); + return -E2BIG; + } + + *r_pipe_cfg = *pipe_cfg; + pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1; + pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1; + r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2; + r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; + } else { + memset(r_pipe_cfg, 0, sizeof(
[PATCH v5 04/12] drm/msm/dpu: use drm_rect_fp_to_int()
Use the drm_rect_fp_to_int() helper instead of using the hand-written code. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 8f2759d16247..4abaf2bb8a08 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -837,13 +837,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - pipe_cfg->src_rect = new_plane_state->src; - /* state->src is 16.16, src_rect is not */ - pipe_cfg->src_rect.x1 >>= 16; - pipe_cfg->src_rect.x2 >>= 16; - pipe_cfg->src_rect.y1 >>= 16; - pipe_cfg->src_rect.y2 >>= 16; + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); pipe_cfg->dst_rect = new_plane_state->dst; -- 2.39.2
[PATCH v5 12/12] drm/msm/dpu: include SSPP allocation state into the dumped state
Make dpu_rm_print_state() also output the SSPP allocation state. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index dbf1f7229e45..3e3b6b8daa5c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -890,4 +890,11 @@ void dpu_rm_print_state(struct drm_printer *p, dpu_rm_print_state_helper(p, rm->cdm_blk, global_state->cdm_to_enc_id); drm_puts(p, "\n"); + + drm_puts(p, "\tsspp="); + /* skip SSPP_NONE and start from the next index */ + for (i = SSPP_NONE + 1; i < ARRAY_SIZE(global_state->sspp_to_crtc_id); i++) + dpu_rm_print_state_helper(p, rm->hw_sspp[i] ? &rm->hw_sspp[i]->base : NULL, + global_state->sspp_to_crtc_id[i]); + drm_puts(p, "\n"); } -- 2.39.2
[PATCH v5 10/12] drm/msm/dpu: add support for virtual planes
Only several SSPP blocks support such features as YUV output or scaling, thus different DRM planes have different features. Properly utilizing all planes requires the attention of the compositor, who should prefer simpler planes to YUV-supporting ones. Otherwise it is very easy to end up in a situation when all featureful planes are already allocated for simple windows, leaving no spare plane for YUV playback. To solve this problem make all planes virtual. Each plane is registered as if it supports all possible features, but then at the runtime during the atomic_check phase the driver selects backing SSPP block for each plane. As the planes are attached to the CRTC and not the the encoder, the SSPP blocks are also allocated per CRTC ID (all other resources are currently allocated per encoder ID). This also matches the hardware requirement, where both rectangles of a single SSPP can only be used with the LM pair. Note, this does not provide support for using two different SSPP blocks for a single plane or using two rectangles of an SSPP to drive two planes. Each plane still gets its own SSPP and can utilize either a solo rectangle or both multirect rectangles depending on the resolution. Note #2: By default support for virtual planes is turned off and the driver still uses old code path with preallocated SSPP block for each plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=1' kernel parameter. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 236 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 16 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 77 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 27 7 files changed, 391 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 9f2164782844..c438cf834320 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1168,6 +1168,49 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate) return false; } +static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) +{ + int total_planes = crtc->dev->mode_config.num_total_plane; + struct drm_atomic_state *state = crtc_state->state; + struct dpu_global_state *global_state; + struct drm_plane_state **states; + struct drm_plane *plane; + int ret; + + global_state = dpu_kms_get_global_state(crtc_state->state); + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + dpu_rm_release_all_sspp(global_state, crtc); + + if (!crtc_state->enable) + return 0; + + states = kcalloc(total_planes, sizeof(*states), GFP_KERNEL); + if (!states) + return -ENOMEM; + + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { + struct drm_plane_state *plane_state = + drm_atomic_get_plane_state(state, plane); + + if (IS_ERR(plane_state)) { + ret = PTR_ERR(plane_state); + goto done; + } + + states[plane_state->normalized_zpos] = plane_state; + } + + ret = dpu_assign_plane_resources(global_state, state, crtc, states, total_planes); + +done: + kfree(states); + return ret; + + return 0; +} + static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -1183,6 +1226,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state); + if (dpu_use_virtual_planes && + (crtc_state->planes_changed || crtc_state->zpos_changed)) { + rc = dpu_crtc_reassign_planes(crtc, crtc_state); + if (rc < 0) + return rc; + } + if (!crtc_state->enable || !drm_atomic_crtc_effectively_active(crtc_state)) { DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n", crtc->base.id, crtc_state->enable, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index d1e2143110f2..449fdc0d33dd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -51,6 +51,9 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" +bool dpu_use_virtual_planes = false; +module_param(dpu_use_virtual_planes, bool, 0); + static int dpu_kms_hw_init(struct msm_kms *kms); static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); @@ -814,8 +817,11 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
[PATCH v5 09/12] drm/msm/dpu: move rot90 checking to dpu_plane_atomic_check_pipe()
Move a call to dpu_plane_check_inline_rotation() to the dpu_plane_atomic_check_pipe() function, so that the rot90 constraints are checked for both pipes. Also move rotation field from struct dpu_plane_state to struct dpu_sw_pipe_cfg. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 55 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 2 -- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 4a910b808687..fc54625ae5d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -142,10 +142,12 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. + * @rotation: simplified drm rotation hint */ struct dpu_sw_pipe_cfg { struct drm_rect src_rect; struct drm_rect dst_rect; + unsigned int rotation; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 9b9fe28052ad..6ad160295341 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -527,8 +527,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe, static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe, const struct msm_format *fmt, bool color_fill, - struct dpu_sw_pipe_cfg *pipe_cfg, - unsigned int rotation) + struct dpu_sw_pipe_cfg *pipe_cfg) { struct dpu_hw_sspp *pipe_hw = pipe->sspp; const struct drm_format_info *info = drm_format_info(fmt->pixel_format); @@ -551,7 +550,7 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe, dst_height, &scaler3_cfg, fmt, info->hsub, info->vsub, - rotation); + pipe_cfg->rotation); /* configure pixel extension based on scalar config */ _dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext, @@ -603,7 +602,7 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate, if (pipe->sspp->ops.setup_rects) pipe->sspp->ops.setup_rects(pipe, &pipe_cfg); - _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation); + _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg); } /** @@ -704,12 +703,17 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane, } static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, - const struct dpu_sspp_sub_blks *sblk, - struct drm_rect src, const struct msm_format *fmt) + struct dpu_sw_pipe *pipe, + struct drm_rect src, + const struct msm_format *fmt) { + const struct dpu_sspp_sub_blks *sblk = pipe->sspp->cap->sblk; size_t num_formats; const u32 *supported_formats; + if (!test_bit(DPU_SSPP_INLINE_ROTATION, &pipe->sspp->cap->features)) + return -EINVAL; + if (!sblk->rotation_cfg) { DPU_ERROR("invalid rotation cfg\n"); return -EINVAL; @@ -739,6 +743,7 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, { uint32_t min_src_size; struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); + int ret; min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1; @@ -776,6 +781,12 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, return -EINVAL; } + if (pipe_cfg->rotation & DRM_MODE_ROTATE_90) { + ret = dpu_plane_check_inline_rotation(pdpu, pipe, pipe_cfg->src_rect, fmt); + if (ret) + return ret; + } + /* max clk check */ if (_dpu_plane_calc_clk(mode, pipe_cfg) > kms->perf.max_core_clk_rate) { DPU_DEBUG_PLANE(pdpu, "plane exceeds max mdp core clk limits\n"); @@ -889,7 +900,6 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; uint32_t max_linewidth; - unsigned int rotation; uint32_t supported_rotations; const struct dpu_sspp_cfg *pipe_hw_caps; const struct dpu_sspp_sub_blks *sblk; @@ -913,6 +923,15 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane *plane, max_linewidth = pdpu->catalog->caps->max_linewidth; + supported_rotations = DRM_MODE_REFLECT_MASK | DRM_
[PATCH v5 01/12] drm/msm/dpu: limit QCM2290 to RGB formats only
The QCM2290 doesn't have CSC blocks, so it can not support YUV formats even on ViG blocks. Fix the formats declared by _VIG_SBLK_NOSCALE(). Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 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 fc178ec73907..648c8d0a4c36 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -308,8 +308,8 @@ static const u32 wb2_formats_rgb_yuv[] = { { \ .maxdwnscale = SSPP_UNITY_SCALE, \ .maxupscale = SSPP_UNITY_SCALE, \ - .format_list = plane_formats_yuv, \ - .num_formats = ARRAY_SIZE(plane_formats_yuv), \ + .format_list = plane_formats, \ + .num_formats = ARRAY_SIZE(plane_formats), \ .virt_format_list = plane_formats, \ .virt_num_formats = ARRAY_SIZE(plane_formats), \ } -- 2.39.2
[PATCH v5 06/12] drm/msm/dpu: drop virt_formats from SSPP subblock configuration
The virt_formats / virt_num_formats are not used by the current driver and are not going to be used in future since formats for virtual planes are handled in a different way, by forbidding unsupported combinations during atomic_check. Drop those fields now. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 2 files changed, 12 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 648c8d0a4c36..a3d29c69bda4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -283,8 +283,6 @@ static const u32 wb2_formats_rgb_yuv[] = { .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ .rotation_cfg = NULL, \ } @@ -299,8 +297,6 @@ static const u32 wb2_formats_rgb_yuv[] = { .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ .rotation_cfg = rot_cfg, \ } @@ -310,8 +306,6 @@ static const u32 wb2_formats_rgb_yuv[] = { .maxupscale = SSPP_UNITY_SCALE, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ } #define _DMA_SBLK() \ @@ -320,8 +314,6 @@ static const u32 wb2_formats_rgb_yuv[] = { .maxupscale = SSPP_UNITY_SCALE, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ } static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 37e18e820a20..3f2646955ae0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -372,8 +372,6 @@ struct dpu_caps { * @csc_blk: * @format_list: Pointer to list of supported formats * @num_formats: Number of supported formats - * @virt_format_list: Pointer to list of supported formats for virtual planes - * @virt_num_formats: Number of supported formats for virtual planes * @dpu_rotation_cfg: inline rotation configuration */ struct dpu_sspp_sub_blks { @@ -386,8 +384,6 @@ struct dpu_sspp_sub_blks { const u32 *format_list; u32 num_formats; - const u32 *virt_format_list; - u32 virt_num_formats; const struct dpu_rotation_cfg *rotation_cfg; }; -- 2.39.2
[PATCH v5 02/12] drm/msm/dpu: relax YUV requirements
YUV formats require only CSC to be enabled. Even decimated formats should not require scaler. Relax the requirement and don't check for the scaler block while checking if YUV format can be enabled. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 1c3a2657450c..148bd79bdcef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -743,10 +743,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1; if (MSM_FORMAT_IS_YUV(fmt) && - (!pipe->sspp->cap->sblk->scaler_blk.len || -!pipe->sspp->cap->sblk->csc_blk.len)) { + !pipe->sspp->cap->sblk->csc_blk.len) { DPU_DEBUG_PLANE(pdpu, - "plane doesn't have scaler/csc for yuv\n"); + "plane doesn't have csc for yuv\n"); return -EINVAL; } -- 2.39.2
[PATCH v5 07/12] drm/msm/dpu: move scaling limitations out of the hw_catalog
Max upscale / downscale factors are constant between platforms. In preparation to adding support for virtual planes and allocating SSPP blocks on demand move max scaling factors out of the HW catalog and handle them in the dpu_plane directly. If any of the scaling blocks gets different limitations, this will have to be handled separately, after the plane refactoring. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 12 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 16 +--- 3 files changed, 13 insertions(+), 19 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 a3d29c69bda4..e9fd6b36a1c4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -113,10 +113,6 @@ #define MAX_HORZ_DECIMATION4 #define MAX_VERT_DECIMATION4 -#define MAX_UPSCALE_RATIO 20 -#define MAX_DOWNSCALE_RATIO4 -#define SSPP_UNITY_SCALE 1 - #define STRCAT(X, Y) (X Y) static const uint32_t plane_formats[] = { @@ -274,8 +270,6 @@ static const u32 wb2_formats_rgb_yuv[] = { /* SSPP common configuration */ #define _VIG_SBLK(scaler_ver) \ { \ - .maxdwnscale = MAX_DOWNSCALE_RATIO, \ - .maxupscale = MAX_UPSCALE_RATIO, \ .scaler_blk = {.name = "scaler", \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -288,8 +282,6 @@ static const u32 wb2_formats_rgb_yuv[] = { #define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \ { \ - .maxdwnscale = MAX_DOWNSCALE_RATIO, \ - .maxupscale = MAX_UPSCALE_RATIO, \ .scaler_blk = {.name = "scaler", \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -302,16 +294,12 @@ static const u32 wb2_formats_rgb_yuv[] = { #define _VIG_SBLK_NOSCALE() \ { \ - .maxdwnscale = SSPP_UNITY_SCALE, \ - .maxupscale = SSPP_UNITY_SCALE, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ } #define _DMA_SBLK() \ { \ - .maxdwnscale = SSPP_UNITY_SCALE, \ - .maxupscale = SSPP_UNITY_SCALE, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 3f2646955ae0..bf86d643887d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -364,8 +364,6 @@ struct dpu_caps { /** * struct dpu_sspp_sub_blks : SSPP sub-blocks * common: Pointer to common configurations shared by sub blocks - * @maxdwnscale: max downscale ratio supported(without DECIMATION) - * @maxupscale: maxupscale ratio supported * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps * @qseed_ver: qseed version * @scaler_blk: @@ -375,8 +373,6 @@ struct dpu_caps { * @dpu_rotation_cfg: inline rotation configuration */ struct dpu_sspp_sub_blks { - u32 maxdwnscale; - u32 maxupscale; u32 max_per_pipe_bw; u32 qseed_ver; struct dpu_scaler_blk scaler_blk; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 325af392e6a2..115c1bd77bdd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -785,12 +785,15 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, return 0; } +#define MAX_UPSCALE_RATIO 20 +#define MAX_DOWNSCALE_RATIO4 + static int dpu_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); - int ret = 0, min_scale; + int ret = 0, min_scale, max_scale; struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate; @@ -821,10 +824,17 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, pipe_hw_caps = pipe->sspp->cap; sblk = pipe->sspp->cap->sblk; - min_scale = FRAC_16_16(1, sblk->maxupscale); + if (sblk->scaler_blk.len) { + min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO); + max_scale = MAX_DOWNSCALE_RATIO << 16; + } else { + min_scale = DRM_PLANE_NO_SCALING; + max_scale = DRM_PLANE_NO_SCALING; + } + ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, min_scale, - sblk->maxdwnscale <<
[PATCH v5 03/12] drm/msm/dpu: take plane rotation into account for wide planes
Take into account the plane rotation and flipping when calculating src positions for the wide plane parts. This is not an issue yet, because rotation is only supported for the UBWC planes and wide UBWC planes are rejected anyway because in parallel multirect case only the half of the usual width is supported for tiled formats. However it's better to fix this now rather than stumbling upon it later. Fixes: 80e8ae3b38ab ("drm/msm/dpu: add support for wide planes") Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 148bd79bdcef..8f2759d16247 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -862,6 +862,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, max_linewidth = pdpu->catalog->caps->max_linewidth; + drm_rect_rotate(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) { /* @@ -911,6 +915,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; } + drm_rect_rotate_inv(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (r_pipe->sspp) + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, &crtc_state->adjusted_mode); if (ret) return ret; -- 2.39.2
[PATCH v5 05/12] drm/msm/dpu: move pstate->pipe initialization to dpu_plane_atomic_check
In preparation for virtualized planes support, move pstate->pipe initialization from dpu_plane_reset() to dpu_plane_atomic_check(). In case of virtual planes the plane's pipe will not be known up to the point of atomic_check() callback. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 25 +++-- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 4abaf2bb8a08..325af392e6a2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -805,13 +805,22 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, uint32_t max_linewidth; unsigned int rotation; uint32_t supported_rotations; - const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap; - const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk; + const struct dpu_sspp_cfg *pipe_hw_caps; + const struct dpu_sspp_sub_blks *sblk; if (new_plane_state->crtc) crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); + pipe->sspp = dpu_rm_get_sspp(&kms->rm, pdpu->pipe); + r_pipe->sspp = NULL; + + if (!pipe->sspp) + return -EINVAL; + + pipe_hw_caps = pipe->sspp->cap; + sblk = pipe->sspp->cap->sblk; + min_scale = FRAC_16_16(1, sblk->maxupscale); ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, min_scale, @@ -828,7 +837,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; - r_pipe->sspp = NULL; pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos; if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) { @@ -1292,7 +1300,6 @@ static void dpu_plane_reset(struct drm_plane *plane) { struct dpu_plane *pdpu; struct dpu_plane_state *pstate; - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); if (!plane) { DPU_ERROR("invalid plane\n"); @@ -1314,16 +1321,6 @@ static void dpu_plane_reset(struct drm_plane *plane) return; } - /* -* Set the SSPP here until we have proper virtualized DPU planes. -* This is the place where the state is allocated, so fill it fully. -*/ - pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); - pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO; - pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE; - - pstate->r_pipe.sspp = NULL; - __drm_atomic_helper_plane_reset(plane, &pstate->base); } -- 2.39.2
[PATCH v5 00/12] drm/msm/dpu: support virtual wide planes
As promised in the basic wide planes support ([1]) here comes a series supporting 2*max_linewidth for all the planes. Note: Unlike v1 and v2 this series finally includes support for additional planes - having more planes than the number of SSPP blocks. Note: this iteration features handling of rotation and reflection of the wide plane. However rot90 is still not tested: it is enabled on sc7280 and it only supports UBWC (tiled) framebuffers, it was quite low on my priority list. [1] https://patchwork.freedesktop.org/series/99909/ To: Rob Clark To: Abhinav Kumar To: Dmitry Baryshkov To: Sean Paul To: Marijn Suijten To: David Airlie To: Daniel Vetter Cc: linux-arm-...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: freedr...@lists.freedesktop.org Cc: linux-ker...@vger.kernel.org Changes in v5: - Dropped extra dpu_kms instance from dpu_plane_atomic_check() (Abhinav) - Use DRM_PLANE_NO_SCALING instead of (1 << 16) (Abhinav) - Dropped excess returns documentation for dpu_rm_reserve_sspp() (Sui Jingfeng, Abhinav) - best_weght -> best_weight (Abhinav) - Moved drm_rect_width() call back to the the patch "split dpu_plane_atomic_check()" (Abhinav) - Got rid of saved_fmt / saved dimensions (Abhinav) - Expanded the commit message to describe SSPP allocation per CRTC id (Abhinav) - Added comment on why the size change also causes resource reallocation (Abhinav) - Dropeed several last "feature" patches, leaving only SSPP reallocation and using 2 SSPPs per plane for now. The rest will be submitted separately. Changes since v3: - Dropped the drm_atomic_helper_check_plane_noscale (Ville) - Reworked the scaling factor according to global value and then check if SSPP has scaler_blk later on. - Split drm_rect_fp_to_int from the rotation-related fix (Abhinav) Changes since v2: - Dropped the encoder-related parts, leave all resource allocation as is (Abhinav) - Significantly reworked the SSPP allocation code - Added debugging code to dump RM state in dri/N/state Changes since v1: - Fixed build error due to me missing one of fixups, it was left uncommitted. - Implementated proper handling of wide plane rotation & reflection. --- Dmitry Baryshkov (12): drm/msm/dpu: limit QCM2290 to RGB formats only drm/msm/dpu: relax YUV requirements drm/msm/dpu: take plane rotation into account for wide planes drm/msm/dpu: use drm_rect_fp_to_int() drm/msm/dpu: move pstate->pipe initialization to dpu_plane_atomic_check drm/msm/dpu: drop virt_formats from SSPP subblock configuration drm/msm/dpu: move scaling limitations out of the hw_catalog drm/msm/dpu: split dpu_plane_atomic_check() drm/msm/dpu: move rot90 checking to dpu_plane_atomic_check_pipe() drm/msm/dpu: add support for virtual planes drm/msm/dpu: allow using two SSPP blocks for a single plane drm/msm/dpu: include SSPP allocation state into the dumped state drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 24 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 8 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h| 2 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h| 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 539 - drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 18 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 84 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 27 ++ 10 files changed, 621 insertions(+), 145 deletions(-) --- base-commit: 0fc4bfab2cd45f9acb86c4f04b5191e114e901ed change-id: 20240626-dpu-virtual-wide-beefb746a900 Best regards, -- Dmitry Baryshkov
Re: [PATCH v1 3/3] arm64: dts: qcom: x1e80100: Add gpu support
On 26.06.2024 11:04 PM, Akhil P Oommen wrote: > On Mon, Jun 24, 2024 at 03:57:35PM +0200, Konrad Dybcio wrote: >> >> >> On 6/23/24 13:06, Akhil P Oommen wrote: >>> Add the necessary dt nodes for gpu support in X1E80100. >>> >>> Signed-off-by: Akhil P Oommen >>> --- >> >> [...] >> >>> + >>> + opp-11 { >>> + opp-hz = /bits/ 64 <11>; >>> + opp-level = >>> ; >>> + opp-peak-kBps = <1650>; >> >> No speedbins? > > Coming soon! I am waiting for some confirmations on some SKU related > data. This is the lowest Fmax among all SKUs which we can safely enable > for now. Sounds good, thanks Konrad
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On 26.06.2024 8:43 PM, Rob Clark wrote: > On Wed, Jun 26, 2024 at 1:24 AM Akhil P Oommen > wrote: >> >> On Mon, Jun 24, 2024 at 03:53:48PM +0200, Konrad Dybcio wrote: >>> >>> >>> On 6/23/24 13:06, Akhil P Oommen wrote: Add support in drm/msm driver for the Adreno X185 gpu found in Snapdragon X1 Elite chipset. Signed-off-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 0e3dfd4c2bc8..168a4bddfaf2 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) */ gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); + if (adreno_is_x185(adreno_gpu)) { + chipid = 0x7050001; >>> >>> What's wrong with using the logic below? >> >> patchid is BITS(7, 0), not (15, 8) in the case of x185. Due to the >> changes in the chipid scheme within the a7x family, this is a bit >> confusing. I will try to improve here in another series. > > I'm thinking we should just add gmu_chipid to struct a6xx_info, tbh > > Maybe to start with, we can fall back to the existing logic if > a6xx_info::gmu_chipid is zero so we don't have to add it for _every_ > a6xx/a7xx If X185 is not the only occurence, I'd second this.. Konrad
Re: [PATCH v2 1/2] drm/msm/adreno: De-spaghettify the use of memory barriers
On Wed, Jun 26, 2024 at 09:59:39AM +0200, Daniel Vetter wrote: > On Tue, Jun 25, 2024 at 08:54:41PM +0200, Konrad Dybcio wrote: > > Memory barriers help ensure instruction ordering, NOT time and order > > of actual write arrival at other observers (e.g. memory-mapped IP). > > On architectures employing weak memory ordering, the latter can be a > > giant pain point, and it has been as part of this driver. > > > > Moreover, the gpu_/gmu_ accessors already use non-relaxed versions of > > readl/writel, which include r/w (respectively) barriers. > > > > Replace the barriers with a readback (or drop altogether where possible) > > that ensures the previous writes have exited the write buffer (as the CPU > > must flush the write to the register it's trying to read back). > > > > Signed-off-by: Konrad Dybcio > > Some in pci these readbacks are actually part of the spec and called > posting reads. I'd very much recommend drivers create a small wrapper > function for these cases with a void return value, because it makes the > code so much more legible and easier to understand. For Adreno which is configured via mmio, we don't need to do this often. GBIF_HALT is a scenario where we need to be extra careful as it can potentially cause some internal lockup. Another scenario I can think of is GPU soft reset where need to keep a delay on cpu side after triggering. We should closely scrutinize any other instance that comes up. So I feel a good justification as a comment here would be enough, to remind the reader. Think of it as a way to discourage the use by making it hard. This is a bit subjective, I am fine if you have a strong opinion on this. -Akhil. > -Sima > > > --- > > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 4 +--- > > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 10 ++ > > 2 files changed, 7 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > index 0e3dfd4c2bc8..09d640165b18 100644 > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > @@ -466,9 +466,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) > > int ret; > > u32 val; > > > > - gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1 << 1); > > - /* Wait for the register to finish posting */ > > - wmb(); > > + gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, BIT(1)); > > > > ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val, > > val & (1 << 1), 100, 1); > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > index c98cdb1e9326..4083d0cad782 100644 > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > @@ -855,14 +855,16 @@ static int hw_init(struct msm_gpu *gpu) > > /* Clear GBIF halt in case GX domain was not collapsed */ > > if (adreno_is_a619_holi(adreno_gpu)) { > > gpu_write(gpu, REG_A6XX_GBIF_HALT, 0); > > + gpu_read(gpu, REG_A6XX_GBIF_HALT); > > + > > gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, 0); > > - /* Let's make extra sure that the GPU can access the memory.. */ > > - mb(); > > + gpu_read(gpu, REG_A6XX_RBBM_GPR0_CNTL); > > } else if (a6xx_has_gbif(adreno_gpu)) { > > gpu_write(gpu, REG_A6XX_GBIF_HALT, 0); > > + gpu_read(gpu, REG_A6XX_GBIF_HALT); > > + > > gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 0); > > - /* Let's make extra sure that the GPU can access the memory.. */ > > - mb(); > > + gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT); > > } > > > > /* Some GPUs are stubborn and take their sweet time to unhalt GBIF! */ > > > > -- > > 2.45.2 > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch
Re: [PATCH] drm/i915/gem: Suppress oom warning in favour of ENOMEM to userspace
Hi Rodrigo, On 6/26/2024 5:50 PM, Rodrigo Vivi wrote: On Wed, Jun 26, 2024 at 05:36:43PM +0200, Nirmoy Das wrote: Hi Rodrigo, On 6/26/2024 5:24 PM, Rodrigo Vivi wrote: On Wed, Jun 26, 2024 at 04:33:18PM +0200, Nirmoy Das wrote: >We report object allocation failures to userspace with ENOMEM >so add __GFP_NOWARN to remove superfluous oom warnings. >Closes: [1]https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4936 >Cc: Andi Shyti [2] >Signed-off-by: Nirmoy Das [3] >--- > drivers/gpu/drm/i915/i915_scatterlist.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) >diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c >index e93d2538f298..4d830740946d 100644 >--- a/drivers/gpu/drm/i915/i915_scatterlist.c >+++ b/drivers/gpu/drm/i915/i915_scatterlist.c >@@ -90,7 +90,7 @@ struct i915_refct_sgt *i915_rsgt_from_mm_node(const struct drm_mm_node *node, > >GEM_BUG_ON(!max_segment); > >- rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL); >+ rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL | __GFP_NOWARN); >if (!rsgt) >return ERR_PTR(-ENOMEM); is it really safe? I don't believe we can guarantee a good fallback plan here if allocation fails. __i915_refct_sgt_init might end up in a null dereference, no?! Kernel is now returning ENOMEM and also throwing a oom warning stack. With __GFP_NOWARN the oom warning stack won't be there in the dmesg but userspace will still get ENOMEM as expected. doh! I had missunderstand the flag. Thanks for the confirmation. Reviewed-by: Rodrigo Vivi BTW, what email clients are you using recently? Using the same client, Thunderbird. it is hard to parse your responses lately. Please check if it is really sending/replying as text-only mode. Thanks for notifying me. May be recent update changed some settings. I will check. Nirmoy Let me know if got your question correctly. Regards, Nirmoy > >@@ -104,7 +104,7 @@ struct i915_refct_sgt *i915_rsgt_from_mm_node(const struct drm_mm_node *node, >} > >if (sg_alloc_table(st, DIV_ROUND_UP_ULL(node->size, segment_pages), >- GFP_KERNEL)) { >+ GFP_KERNEL | __GFP_NOWARN)) { >i915_refct_sgt_put(rsgt); >return ERR_PTR(-ENOMEM); >} >@@ -178,7 +178,7 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res, >GEM_BUG_ON(list_empty(blocks)); >GEM_BUG_ON(!max_segment); > >- rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL); >+ rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL | __GFP_NOWARN); >if (!rsgt) >return ERR_PTR(-ENOMEM); > >@@ -190,7 +190,7 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res, >return ERR_PTR(-E2BIG); >} > >- if (sg_alloc_table(st, PFN_UP(res->size), GFP_KERNEL)) { >+ if (sg_alloc_table(st, PFN_UP(res->size), GFP_KERNEL | __GFP_NOWARN)) { >i915_refct_sgt_put(rsgt); >return ERR_PTR(-ENOMEM); >} >-- >2.42.0 References Visible links 1. https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4936 2. mailto:andi.sh...@linux.intel.com 3. mailto:nirmoy@intel.com
[syzbot] [dri?] WARNING in drm_mode_create_lease_ioctl
Hello, syzbot found the following issue on: HEAD commit:ac2193b4b460 Merge branches 'for-next/misc', 'for-next/kse.. git tree: git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-kernelci console output: https://syzkaller.appspot.com/x/log.txt?x=101cc88298 kernel config: https://syzkaller.appspot.com/x/.config?x=36900d37ec67d13f dashboard link: https://syzkaller.appspot.com/bug?extid=6754751ad05524dae739 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 userspace arch: arm64 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=16c17cd698 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=15879c8298 Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/2c4f87d36ca3/disk-ac2193b4.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/8410475de662/vmlinux-ac2193b4.xz kernel image: https://storage.googleapis.com/syzbot-assets/495a4ced254d/Image-ac2193b4.gz.xz IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+6754751ad05524dae...@syzkaller.appspotmail.com [ cut here ] WARNING: CPU: 0 PID: 6281 at mm/page_alloc.c:4654 __alloc_pages_noprof+0x324/0x6c0 mm/page_alloc.c:4654 Modules linked in: CPU: 0 PID: 6281 Comm: syz-executor181 Tainted: GW 6.10.0-rc3-syzkaller-gac2193b4b460 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024 pstate: 6045 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __alloc_pages_noprof+0x324/0x6c0 mm/page_alloc.c:4654 lr : __alloc_pages_noprof+0xc8/0x6c0 mm/page_alloc.c:4648 sp : 800099017600 x29: 8000990176f0 x28: 800099017620 x27: dfff8000 x26: 700013202ec4 x25: x24: 800099017640 x23: x22: 00040dc0 x21: 100013202ec8 x20: 800099017660 x19: 000b x18: 8000990176e0 x17: c88a x16: 80008afa5980 x15: 0005 x14: 100013202ecc x13: x12: x11: 700013202ed1 x10: 100013202ed0 x9 : 0001 x8 : 80009232a000 x7 : x6 : e07d0900 x5 : e07d0900 x4 : x3 : 0020 x2 : 0008 x1 : x0 : 800099017660 Call trace: __alloc_pages_noprof+0x324/0x6c0 mm/page_alloc.c:4654 __alloc_pages_node_noprof include/linux/gfp.h:269 [inline] alloc_pages_node_noprof include/linux/gfp.h:296 [inline] __kmalloc_large_node+0xbc/0x200 mm/slub.c:4067 __do_kmalloc_node mm/slub.c:4110 [inline] __kmalloc_noprof+0x360/0x494 mm/slub.c:4135 kmalloc_noprof include/linux/slab.h:664 [inline] kmalloc_array_noprof include/linux/slab.h:699 [inline] fill_object_idr drivers/gpu/drm/drm_lease.c:389 [inline] drm_mode_create_lease_ioctl+0x4b0/0x17e4 drivers/gpu/drm/drm_lease.c:522 drm_ioctl_kernel+0x26c/0x368 drivers/gpu/drm/drm_ioctl.c:744 drm_ioctl+0x5e4/0xae4 drivers/gpu/drm/drm_ioctl.c:841 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __arm64_sys_ioctl+0x14c/0x1c8 fs/ioctl.c:893 __invoke_syscall arch/arm64/kernel/syscall.c:34 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:48 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:133 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:152 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:712 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 irq event stamp: 14766 hardirqs last enabled at (14765): [] __exit_to_kernel_mode arch/arm64/kernel/entry-common.c:85 [inline] hardirqs last enabled at (14765): [] exit_to_kernel_mode+0xdc/0x10c arch/arm64/kernel/entry-common.c:95 hardirqs last disabled at (14766): [] el1_dbg+0x24/0x80 arch/arm64/kernel/entry-common.c:470 softirqs last enabled at (8860): [] softirq_handle_end kernel/softirq.c:400 [inline] softirqs last enabled at (8860): [] handle_softirqs+0xa3c/0xbfc kernel/softirq.c:582 softirqs last disabled at (8855): [] __do_softirq+0x14/0x20 kernel/softirq.c:588 ---[ end trace ]--- --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkal...@googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. If the report is already addressed, let syzbot know by replying with: #syz fix: exact-commit-title If you want syzbot to run the reproducer, reply with: #syz test: git://repo/address.git branch-or-commit-hash If you attach or paste a git patch, syzbot will apply it before testing. If you want to overwrite report's subsystems, reply with: #syz set subsystems: new-subsystem (See the list of subsystem names on the web dashboard) If the report is a duplicate of another
Re: [PATCH v1 3/3] arm64: dts: qcom: x1e80100: Add gpu support
On Mon, Jun 24, 2024 at 03:57:35PM +0200, Konrad Dybcio wrote: > > > On 6/23/24 13:06, Akhil P Oommen wrote: > > Add the necessary dt nodes for gpu support in X1E80100. > > > > Signed-off-by: Akhil P Oommen > > --- > > [...] > > > + > > + opp-11 { > > + opp-hz = /bits/ 64 <11>; > > + opp-level = > > ; > > + opp-peak-kBps = <1650>; > > No speedbins? Coming soon! I am waiting for some confirmations on some SKU related data. This is the lowest Fmax among all SKUs which we can safely enable for now. -Akhil. > > Konrad
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On Wed, Jun 26, 2024 at 1:49 PM Akhil P Oommen wrote: > > On Mon, Jun 24, 2024 at 07:28:06AM -0700, Rob Clark wrote: > > On Mon, Jun 24, 2024 at 7:25 AM Rob Clark wrote: > > > > > > On Sun, Jun 23, 2024 at 4:08 AM Akhil P Oommen > > > wrote: > > > > > > > > Add support in drm/msm driver for the Adreno X185 gpu found in > > > > Snapdragon X1 Elite chipset. > > > > > > > > Signed-off-by: Akhil P Oommen > > > > --- > > > > > > > > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ > > > > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ > > > > drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ > > > > drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + > > > > 4 files changed, 36 insertions(+), 8 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > index 0e3dfd4c2bc8..168a4bddfaf2 100644 > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, > > > > unsigned int state) > > > > */ > > > > gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); > > > > > > > > + if (adreno_is_x185(adreno_gpu)) { > > > > + chipid = 0x7050001; > > > > /* NOTE: A730 may also fall in this if-condition with a future > > > > GMU fw update. */ > > > > - if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) { > > > > + } else if (adreno_is_a7xx(adreno_gpu) && > > > > !adreno_is_a730(adreno_gpu)) { > > > > /* A7xx GPUs have obfuscated chip IDs. Use constant maj > > > > = 7 */ > > > > chipid = FIELD_PREP(GENMASK(31, 24), 0x7); > > > > > > > > @@ -1329,9 +1331,18 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct > > > > device *dev, u32 *votes, > > > > if (!pri_count) > > > > return -EINVAL; > > > > > > > > - sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > > - if (IS_ERR(sec)) > > > > - return PTR_ERR(sec); > > > > + /* > > > > +* Some targets have a separate gfx mxc rail. So try to read > > > > that first and then fall back > > > > +* to regular mx rail if it is missing > > > > +*/ > > > > + sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); > > > > + if (PTR_ERR_OR_ZERO(sec) == -EPROBE_DEFER) { > > > > + return -EPROBE_DEFER; > > > > + } else if (IS_ERR(sec)) { > > > > + sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > > + if (IS_ERR(sec)) > > > > + return PTR_ERR(sec); > > > > + } > > > > > > > > sec_count >>= 1; > > > > if (!sec_count) > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > > index 973872ad0474..97837f7f2a40 100644 > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > > @@ -1319,9 +1319,7 @@ static void a6xx_set_cp_protect(struct msm_gpu > > > > *gpu) > > > > count = ARRAY_SIZE(a660_protect); > > > > count_max = 48; > > > > BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48); > > > > - } else if (adreno_is_a730(adreno_gpu) || > > > > - adreno_is_a740(adreno_gpu) || > > > > - adreno_is_a750(adreno_gpu)) { > > > > + } else if (adreno_is_a7xx(adreno_gpu)) { > > > > regs = a730_protect; > > > > count = ARRAY_SIZE(a730_protect); > > > > count_max = 48; > > > > @@ -1891,7 +1889,7 @@ static int hw_init(struct msm_gpu *gpu) > > > > gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1); > > > > > > > > /* Set weights for bicubic filtering */ > > > > - if (adreno_is_a650_family(adreno_gpu)) { > > > > + if (adreno_is_a650_family(adreno_gpu) || > > > > adreno_is_x185(adreno_gpu)) { > > > > gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, > > > > 0); > > > > gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1, > > > > 0x3fe05ff4); > > > > diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c > > > > b/drivers/gpu/drm/msm/adreno/adreno_device.c > > > > index c3703a51287b..139c7d828749 100644 > > > > --- a/drivers/gpu/drm/msm/adreno/adreno_device.c > > > > +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c > > > > @@ -568,6 +568,20 @@ static const struct adreno_info gpulist[] = { > > > > .zapfw = "a740_zap.mdt", > > > > .hwcg = a740_hwcg, > > > > .address_space_size = SZ_16G, > > > > + }, { > > > > + .chip_ids = ADRENO_CHIP_IDS(0x43050c01), /* "C512v2" */ > > > > + .family = ADRENO_7XX_GEN2, > > > > + .fw = { > > > > + [ADRENO_FW_SQE] =
Re: [PATCH v1 3/3] arm64: dts: qcom: x1e80100: Add gpu support
On Mon, Jun 24, 2024 at 12:23:42AM +0300, Dmitry Baryshkov wrote: > On Sun, Jun 23, 2024 at 04:36:30PM GMT, Akhil P Oommen wrote: > > Add the necessary dt nodes for gpu support in X1E80100. > > > > Signed-off-by: Akhil P Oommen > > --- > > > > arch/arm64/boot/dts/qcom/x1e80100.dtsi | 195 + > > 1 file changed, 195 insertions(+) > > > > diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > b/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > index 5f90a0b3c016..3e887286bab4 100644 > > --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi > > @@ -6,6 +6,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > > > + gmu: gmu@3d6a000 { > > + compatible = "qcom,adreno-gmu-x185.1", > > "qcom,adreno-gmu"; > > + reg = <0x0 0x03d5 0x0 0x1>, > > + <0x0 0x03d6a000 0x0 0x35000>, > > + <0x0 0x0b28 0x0 0x1>; > > + reg-names = "rscc", "gmu", "gmu_pdc"; > > Ther @address should match the first resource defined for a device. I will reorder this and move gmu to first. -Akhil. > > > + > -- > With best wishes > Dmitry
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On Wed, Jun 26, 2024 at 11:43:08AM -0700, Rob Clark wrote: > On Wed, Jun 26, 2024 at 1:24 AM Akhil P Oommen > wrote: > > > > On Mon, Jun 24, 2024 at 03:53:48PM +0200, Konrad Dybcio wrote: > > > > > > > > > On 6/23/24 13:06, Akhil P Oommen wrote: > > > > Add support in drm/msm driver for the Adreno X185 gpu found in > > > > Snapdragon X1 Elite chipset. > > > > > > > > Signed-off-by: Akhil P Oommen > > > > --- > > > > > > > > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ > > > > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ > > > > drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ > > > > drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + > > > > 4 files changed, 36 insertions(+), 8 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > index 0e3dfd4c2bc8..168a4bddfaf2 100644 > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > > @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, > > > > unsigned int state) > > > > */ > > > > gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); > > > > + if (adreno_is_x185(adreno_gpu)) { > > > > + chipid = 0x7050001; > > > > > > What's wrong with using the logic below? > > > > patchid is BITS(7, 0), not (15, 8) in the case of x185. Due to the > > changes in the chipid scheme within the a7x family, this is a bit > > confusing. I will try to improve here in another series. > > I'm thinking we should just add gmu_chipid to struct a6xx_info, tbh > > Maybe to start with, we can fall back to the existing logic if > a6xx_info::gmu_chipid is zero so we don't have to add it for _every_ > a6xx/a7xx Agree, I was thinking the same. -Akhil. > > BR, > -R > > > > > > > > /* NOTE: A730 may also fall in this if-condition with a future GMU > > > > fw update. */ > > > > - if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) { > > > > + } else if (adreno_is_a7xx(adreno_gpu) && > > > > !adreno_is_a730(adreno_gpu)) { > > > > /* A7xx GPUs have obfuscated chip IDs. Use constant maj = 7 > > > > */ > > > > chipid = FIELD_PREP(GENMASK(31, 24), 0x7); > > > > @@ -1329,9 +1331,18 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct > > > > device *dev, u32 *votes, > > > > if (!pri_count) > > > > return -EINVAL; > > > > - sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > > - if (IS_ERR(sec)) > > > > - return PTR_ERR(sec); > > > > + /* > > > > +* Some targets have a separate gfx mxc rail. So try to read that > > > > first and then fall back > > > > +* to regular mx rail if it is missing > > > > +*/ > > > > + sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); > > > > + if (PTR_ERR_OR_ZERO(sec) == -EPROBE_DEFER) { > > > > + return -EPROBE_DEFER; > > > > + } else if (IS_ERR(sec)) { > > > > + sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > > + if (IS_ERR(sec)) > > > > + return PTR_ERR(sec); > > > > + } > > > > > > I assume GMXC would always be used if present, although please use the > > > approach Dmitry suggested > > > > Correct. > > > > -Akhil > > > > > > > > > The rest looks good! > > > > > > Konrad
Re: [PATCH v2 2/2] drm/panel: add Ilitek ILI9806E panel driver
On 6/26/2024 7:44 AM, Michael Walle wrote: The Ortustech COM35H3P70ULC panel is based on the ILI9806E DSI display controller. Co-developed-by: Gunnar Dibbern Signed-off-by: Gunnar Dibbern Signed-off-by: Michael Walle Reviewed-by: Jessica Zhang --- MAINTAINERS | 5 + drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + drivers/gpu/drm/panel/panel-ilitek-ili9806e.c | 402 ++ 4 files changed, 417 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9806e.c diff --git a/MAINTAINERS b/MAINTAINERS index e2d8fdda1737..61352f26f2d9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7003,6 +7003,11 @@ S: Maintained F:Documentation/devicetree/bindings/display/panel/ilitek,ili9805.yaml F:drivers/gpu/drm/panel/panel-ilitek-ili9805.c +DRM DRIVER FOR ILITEK ILI9806E PANELS +M: Michael Walle +S: Maintained +F: drivers/gpu/drm/panel/panel-ilitek-ili9806e.c + DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS M:Jagan Teki S:Maintained diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index bf4eadfe21cb..904a928bc60e 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -205,6 +205,15 @@ config DRM_PANEL_ILITEK_ILI9805 Say Y if you want to enable support for panels based on the Ilitek ILI9805 controller. +config DRM_PANEL_ILITEK_ILI9806E + tristate "Ilitek ILI9806E-based panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for panels based on the + Ilitek ILI9806E controller. + config DRM_PANEL_ILITEK_ILI9881C tristate "Ilitek ILI9881C-based panels" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 051b75b3df7b..12ce91416849 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9805) += panel-ilitek-ili9805.o +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9806E) += panel-ilitek-ili9806e.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c new file mode 100644 index ..e4a44cd26c4d --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +struct panel_desc { + const struct drm_display_mode *display_mode; + unsigned long mode_flags; + enum mipi_dsi_pixel_format format; + unsigned int lanes; + void (*init_sequence)(struct mipi_dsi_multi_context *ctx); +}; + +struct ili9806e_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[2]; + const struct panel_desc *desc; + enum drm_panel_orientation orientation; +}; + +static const char * const regulator_names[] = { + "vdd", + "vccio", +}; + +static inline struct ili9806e_panel *to_ili9806e_panel(struct drm_panel *panel) +{ + return container_of(panel, struct ili9806e_panel, panel); +} + +static int ili9806e_power_on(struct ili9806e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret; + + gpiod_set_value(ctx->reset_gpio, 1); + + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret < 0) { + dev_err(&dsi->dev, "regulator bulk enable failed: %d\n", ret); + return ret; + } + + usleep_range(1, 2); + gpiod_set_value(ctx->reset_gpio, 0); + usleep_range(1, 2); + + return 0; +} + +static int ili9806e_power_off(struct ili9806e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret; + + gpiod_set_value(ctx->reset_gpio, 1); + + ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret) + dev_err(&dsi->dev, "regulator bulk disable failed: %d\n", ret); + + return ret; +} + +static int ili9806e_on(struct ili9806e_panel *ili9806e) +{ + struct mipi_dsi_multi_context ctx = { .dsi = ili9806e->dsi }; + + if (ili9806e->desc->init_sequence) + ili9806e->desc->init_sequence(&ctx
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On Mon, Jun 24, 2024 at 07:28:06AM -0700, Rob Clark wrote: > On Mon, Jun 24, 2024 at 7:25 AM Rob Clark wrote: > > > > On Sun, Jun 23, 2024 at 4:08 AM Akhil P Oommen > > wrote: > > > > > > Add support in drm/msm driver for the Adreno X185 gpu found in > > > Snapdragon X1 Elite chipset. > > > > > > Signed-off-by: Akhil P Oommen > > > --- > > > > > > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ > > > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ > > > drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ > > > drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + > > > 4 files changed, 36 insertions(+), 8 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > index 0e3dfd4c2bc8..168a4bddfaf2 100644 > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, > > > unsigned int state) > > > */ > > > gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); > > > > > > + if (adreno_is_x185(adreno_gpu)) { > > > + chipid = 0x7050001; > > > /* NOTE: A730 may also fall in this if-condition with a future > > > GMU fw update. */ > > > - if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) { > > > + } else if (adreno_is_a7xx(adreno_gpu) && > > > !adreno_is_a730(adreno_gpu)) { > > > /* A7xx GPUs have obfuscated chip IDs. Use constant maj = > > > 7 */ > > > chipid = FIELD_PREP(GENMASK(31, 24), 0x7); > > > > > > @@ -1329,9 +1331,18 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct > > > device *dev, u32 *votes, > > > if (!pri_count) > > > return -EINVAL; > > > > > > - sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > - if (IS_ERR(sec)) > > > - return PTR_ERR(sec); > > > + /* > > > +* Some targets have a separate gfx mxc rail. So try to read that > > > first and then fall back > > > +* to regular mx rail if it is missing > > > +*/ > > > + sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); > > > + if (PTR_ERR_OR_ZERO(sec) == -EPROBE_DEFER) { > > > + return -EPROBE_DEFER; > > > + } else if (IS_ERR(sec)) { > > > + sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > + if (IS_ERR(sec)) > > > + return PTR_ERR(sec); > > > + } > > > > > > sec_count >>= 1; > > > if (!sec_count) > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > index 973872ad0474..97837f7f2a40 100644 > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > > > @@ -1319,9 +1319,7 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) > > > count = ARRAY_SIZE(a660_protect); > > > count_max = 48; > > > BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48); > > > - } else if (adreno_is_a730(adreno_gpu) || > > > - adreno_is_a740(adreno_gpu) || > > > - adreno_is_a750(adreno_gpu)) { > > > + } else if (adreno_is_a7xx(adreno_gpu)) { > > > regs = a730_protect; > > > count = ARRAY_SIZE(a730_protect); > > > count_max = 48; > > > @@ -1891,7 +1889,7 @@ static int hw_init(struct msm_gpu *gpu) > > > gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1); > > > > > > /* Set weights for bicubic filtering */ > > > - if (adreno_is_a650_family(adreno_gpu)) { > > > + if (adreno_is_a650_family(adreno_gpu) || > > > adreno_is_x185(adreno_gpu)) { > > > gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, 0); > > > gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1, > > > 0x3fe05ff4); > > > diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c > > > b/drivers/gpu/drm/msm/adreno/adreno_device.c > > > index c3703a51287b..139c7d828749 100644 > > > --- a/drivers/gpu/drm/msm/adreno/adreno_device.c > > > +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c > > > @@ -568,6 +568,20 @@ static const struct adreno_info gpulist[] = { > > > .zapfw = "a740_zap.mdt", > > > .hwcg = a740_hwcg, > > > .address_space_size = SZ_16G, > > > + }, { > > > + .chip_ids = ADRENO_CHIP_IDS(0x43050c01), /* "C512v2" */ > > > + .family = ADRENO_7XX_GEN2, > > > + .fw = { > > > + [ADRENO_FW_SQE] = "gen70500_sqe.fw", > > > + [ADRENO_FW_GMU] = "gen70500_gmu.bin", > > > + }, > > > + .gmem = 3 * SZ_1M, > > > + .inactive_period = DRM_MSM_INACTIVE_PERIOD, > > > + .quirks = ADRENO_QUIRK_HAS_CACHED_COHERE
[PATCH v5 2/2] drm/msm: Extend gpu devcore dumps with pgtbl info
From: Rob Clark In the case of iova fault triggered devcore dumps, include additional debug information based on what we think is the current page tables, including the TTBR0 value (which should match what we have in adreno_smmu_fault_info unless things have gone horribly wrong), and the pagetable entries traversed in the process of resolving the faulting iova. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 ++ drivers/gpu/drm/msm/msm_gpu.c | 9 + drivers/gpu/drm/msm/msm_gpu.h | 8 drivers/gpu/drm/msm/msm_iommu.c | 25 + drivers/gpu/drm/msm/msm_mmu.h | 3 ++- 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 99661af8d941..422dae873b6b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -861,6 +861,16 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, drm_printf(p, " - dir=%s\n", info->flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ"); drm_printf(p, " - type=%s\n", info->type); drm_printf(p, " - source=%s\n", info->block); + + /* Information extracted from what we think are the current +* pgtables. Hopefully the TTBR0 matches what we've extracted +* from the SMMU registers in smmu_info! +*/ + drm_puts(p, "pgtable-fault-info:\n"); + drm_printf(p, " - ttbr0: %.16llx\n", (u64)info->pgtbl_ttbr0); + drm_printf(p, " - asid: %d\n", info->asid); + drm_printf(p, " - ptes: %.16llx %.16llx %.16llx %.16llx\n", + info->ptes[0], info->ptes[1], info->ptes[2], info->ptes[3]); } drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status); diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 3666b42b4ecd..bf2f8b2a7ccc 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -281,6 +281,15 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, if (submit) { int i; + if (state->fault_info.ttbr0) { + struct msm_gpu_fault_info *info = &state->fault_info; + struct msm_mmu *mmu = submit->aspace->mmu; + + msm_iommu_pagetable_params(mmu, &info->pgtbl_ttbr0, + &info->asid); + msm_iommu_pagetable_walk(mmu, info->iova, info->ptes); + } + state->bos = kcalloc(submit->nr_bos, sizeof(struct msm_gpu_state_bo), GFP_KERNEL); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 1f02bb9956be..82e838ba8c80 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -101,6 +101,14 @@ struct msm_gpu_fault_info { int flags; const char *type; const char *block; + + /* Information about what we think/expect is the current SMMU state, +* for example expected_ttbr0 should match smmu_info.ttbr0 which +* was read back from SMMU registers. +*/ + phys_addr_t pgtbl_ttbr0; + u64 ptes[4]; + int asid; }; /** diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index d5512037c38b..a235b0d0afb5 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -195,6 +195,31 @@ struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu) return &iommu->domain->geometry; } +int +msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova, uint64_t ptes[4]) +{ + struct msm_iommu_pagetable *pagetable; + struct io_pgtable_walk_data wd = {}; + int ret; + + if (mmu->type != MSM_MMU_IOMMU_PAGETABLE) + return -EINVAL; + + pagetable = to_pagetable(mmu); + + if (!pagetable->pgtbl_ops->pgtable_walk) + return -EINVAL; + + ret = pagetable->pgtbl_ops->pgtable_walk(pagetable->pgtbl_ops, iova, &wd); + if (ret) + return ret; + + for (int i = 0; i < ARRAY_SIZE(wd.ptes); i++) + ptes[i] = wd.ptes[i]; + + return 0; +} + static const struct msm_mmu_funcs pagetable_funcs = { .map = msm_iommu_pagetable_map, .unmap = msm_iommu_pagetable_unmap, diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 88af4f490881..96e509bd96a6 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -53,7 +53,8 @@ static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg, struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent); int msm_iommu_pagetable_params(struct msm_mmu *mmu, phys_addr_t
[PATCH v5 0/2] io-pgtable-arm + drm/msm: Extend iova fault debugging
From: Rob Clark This series extends io-pgtable-arm with a method to retrieve the page table entries traversed in the process of address translation, and then beefs up drm/msm gpu devcore dump to include this (and additional info) in the devcore dump. This is a respin of https://patchwork.freedesktop.org/series/94968/ (minus a patch that was already merged) v2: Fix an armv7/32b build error in the last patch v3: Incorperate Will Deacon's suggestion to make the interface callback based. v4: Actually wire up the callback v5: Drop the callback approach Rob Clark (2): iommu/io-pgtable-arm: Add way to debug pgtable walk drm/msm: Extend gpu devcore dumps with pgtbl info drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 drivers/gpu/drm/msm/msm_gpu.c | 9 +++ drivers/gpu/drm/msm/msm_gpu.h | 8 ++ drivers/gpu/drm/msm/msm_iommu.c | 25 ++ drivers/gpu/drm/msm/msm_mmu.h | 3 ++- drivers/iommu/io-pgtable-arm.c | 34 ++--- include/linux/io-pgtable.h | 16 7 files changed, 95 insertions(+), 10 deletions(-) -- 2.45.2
[PATCH] drm/amd/display: Add null check before access structs
In enable_phantom_plane, we should better check null pointer before accessing various structs. Fixes: 09a4ec5da92c ("drm/amd/display: Refactor dc_state interface") Signed-off-by: Ma Ke --- drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c index 282d70e2b18a..3d29169dd6bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c @@ -750,6 +750,8 @@ static void enable_phantom_plane(struct dml2_context *ctx, ctx->config.svp_pstate.callbacks.dc, state, curr_pipe->plane_state); + if (!phantom_plane) + return; } memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address)); -- 2.25.1
Re: [PATCH v4 1/5] clk: sunxi-ng: common: Support minimum and maximum rate
Hi Frank, Moving to a new for loop makes sense. Let me know when you have a patch and I'll be glad to test it on my board. I do also wonder if this may have contributed to some of the HDMI issues seen in the other thread. Best, Robert > Hi Robert, > > I'm truly sorry for the trouble the patch has caused you and for my late > reply! > > On 2024-06-14 at 23:52:08 +, "Pafford, Robert J." > wrote: >>> The Allwinner SoC's typically have an upper and lower limit for their >>> clocks' rates. Up until now, support for that has been implemented >>> separately for each clock type. >>> >>> Implement that functionality in the sunxi-ng's common part making use of >>> the CCF rate liming capabilities, so that it is available for all clock >>> types. >>> >>> Suggested-by: Maxime Ripard >>> Signed-off-by: Frank Oltmanns >>> Cc: sta...@vger.kernel.org >>> --- >>> drivers/clk/sunxi-ng/ccu_common.c | 19 +++ >>> drivers/clk/sunxi-ng/ccu_common.h | 3 +++ >>> 2 files changed, 22 insertions(+) >> >> This patch appears to cause a buffer under-read bug due to the call to >> 'hw_to_ccu_common', which assumes all entries >> in the desc->hw_clocks->hws array are contained in ccu_common structs. >> >> However, not all clocks in the array are contained in ccu_common structs. >> For example, as part >> of the "sun20i-d1-ccu" driver, the "pll-video0" clock holds the 'clk_hw' >> struct inside of a 'clk_fixed_factor' struct, >> as it is a fixed factor clock based on the "pll-video0-4x" clock, created >> with the CLK_FIXED_FACTOR_HWS macro. >> This results in undefined behavior as the hw_to_ccu_common returns an >> invalid pointer referencing memory before the >> 'clk_fixed_factor' struct. >> > > Great catch! At first glance, it seems to me that calling > clk_hw_set_rate_range() in sunxi_ccu_probe() should not have happenend > in the loop that iterates over the hw_clks. > > Instead we should add one more loop that iterates over the ccu_clks. > Note, that there is already one such loop but, unfortunately, we can't > use that as it happens before the hw_clks loop and we can only call > clk_hw_set_rate_range() after the hw_clk has been registered. > > Hence, I propose to move the offending code to a new loop: > for (i = 0; i < desc->num_ccu_clks; i++) { > struct ccu_common *cclk = desc->ccu_clks[i]; > > if (!cclk) > continue; > > if (cclk->max_rate) > clk_hw_set_rate_range(&cclk->hw, common->min_rate, > common->max_rate); > else > WARN(cclk->min_rate, > "No max_rate, ignoring min_rate of clock %d - > %s\n", > i, cclk->hw.init->name); > } > > I haven't tested (or even compiled) the above, but I'll test and send a > patch within the next few days for you to test. > > Thanks again, > Frank > >> >> I have attached kernel warnings from a system based on the >> "sun8i-t113s.dtsi" device tree, where the memory contains >> a non-zero value for the min-rate but a zero value for the max-rate, >> triggering the "No max_rate, ignoring min_rate" >> warning in the 'sunxi_ccu_probe' function. >> >> [...]
Re: [PATCH] drm/etnaviv: Create an accel device node if compute-only
On Wed, 26 Jun 2024 at 18:52, Daniel Vetter wrote: > On Wed, Jun 26, 2024 at 11:39:01AM +0100, Daniel Stone wrote: > > On Wed, 26 Jun 2024 at 09:28, Lucas Stach wrote: > > > So we are kind of stuck here between breaking one or the other use- > > > case. I'm leaning heavily into the direction of just fixing Mesa, so we > > > can specify the type of screen we need at creation time to avoid the > > > renderonly issue, porting this change as far back as reasonably > > > possible and file old userspace into shit-happens. > > > > Yeah, honestly this sounds like the best solution to me too. > > Yeah mesa sounds kinda broken here ... > > What might work in the kernel is if you publish a fake 3d engine that's > too new for broken mesa, if that's enough to make it fail to bind? And if > mesa still happily binds against that, then yeah it's probably too broken > and we need etnaviv-v2 (as a drm driver uapi name, I think that's what > mesa filters?) for anything new (including the NN-only ones). > > I would still try to avoid that, but just in case someone screams about > regressions. It's not just etnaviv, it's literally every Mesa driver which works with decoupled render/display. So that would be etnaviv-v2, panfrost-v2, panthor-v2, v3d-v2, powervr-v2, ... albeit those don't tend to have multiple instances. Anyway, I'm still leaning towards the answer being: this is not an etnaviv regression caused by NPU, it's a longstanding generic Mesa issue for which the answer is to fix the known fragility. Cheers, Daniel
RE: [PATCH v16 0/9] mm/gup: Introduce memfd_pin_folios() for pinning memfd folios
Hi Andrew, > Subject: [PATCH v16 0/9] mm/gup: Introduce memfd_pin_folios() for pinning > memfd folios > > Currently, some drivers (e.g, Udmabuf) that want to longterm-pin > the pages/folios associated with a memfd, do so by simply taking a > reference on them. This is not desirable because the pages/folios > may reside in Movable zone or CMA block. > > Therefore, having drivers use memfd_pin_folios() API ensures that > the folios are appropriately pinned via FOLL_PIN for longterm DMA. > > This patchset also introduces a few helpers and converts the Udmabuf > driver to use folios and memfd_pin_folios() API to longterm-pin > the folios for DMA. Two new Udmabuf selftests are also included to > test the driver and the new API. > > --- > > Patchset overview: > > Patch 1-2:GUP helpers to migrate and unpin one or more folios > Patch 3: Introduce memfd_pin_folios() API > Patch 4-6:Udmabuf driver bug fixes for Qemu + hugetlb=on, blob=true case > Patch 7-9:Convert Udmabuf to use memfd_pin_folios() and add selftests > > This series is tested using the following methods: > - Run the subtests added in the last patch > - Run Qemu (master) with the following options and a few additional > patches to Spice: > qemu-system-x86_64 -m 4096m > -device virtio-gpu-pci,max_outputs=1,blob=true,xres=1920,yres=1080 > -spice port=3001,gl=on,disable-ticketing=on,preferred- > codec=gstreamer:h264 > -object memory-backend-memfd,hugetlb=on,id=mem1,size=4096M > -machine memory-backend=mem1 > - Run source ./run_vmtests.sh -t gup_test -a to check GUP regressions > > Changelog: > > v15 -> v16: > - Instead of passing GFP_USER while allocating a hugetlb folio, use > htlb_alloc_mask(h) & ~(__GFP_HIGHMEM | __GFP_MOVABLE) as gfp mask > to discourage new users from passing GFP_xxx flags. Also add comments > to explain this situation (Oscar) > - Replace NUMA_NO_NODE with numa_node_id() while allocating the htlb > folio to discourage new users from passing NUMA_NO_NODE > > v14 -> v15: > - Add an error check start < 0 in memfd_pin_folios() > - Return an error in udmabuf driver if memfd_pin_folios() returns 0 > These two checks fix the following issue identified by syzbot: > https://syzkaller.appspot.com/bug?extid=40c7dad27267f61839d4 > - Set memfd = NULL before dmabuf export to ensure that memfd is > not closed twice. This fixes the following syzbot issue: > https://syzkaller.appspot.com/bug?extid=b2cfdac9ae5278d4b621 The issues identified by syzbot have been fixed in v15 and the concern raised by Oscar is addressed in v16. I think this patch series can now be merged into mm-unstable for further testing. Thanks, Vivek > > v13 -> v14: > - Drop the redundant comments before > check_and_migrate_movable_pages() > and refer to check_and_migrate_movable_folios() comments (David) > - Use appropriate ksft_* functions for printing and KSFT_* codes for > exit() in udmabuf selftest (Shuah) > - Add Mike Kravetz's suggested-by tag in udmabuf selftest patch (Shuah) > - Collect Ack and Rb tags from David > > v12 -> v13: (suggestions from David) > - Drop the sanity checks in unpin_folio()/unpin_folios() due to > unavailability of per folio anon-exclusive flag > - Export unpin_folio()/unpin_folios() using EXPORT_SYMBOL_GPL > instead of EXPORT_SYMBOL > - Have check_and_migrate_movable_pages() just call > check_and_migrate_movable_folios() instead of calling other helpers > - Slightly improve the comments and commit messages > > v11 -> v12: > - Rebased and tested on mm-unstable > > v10 -> v11: > - Remove the version string from the patch subject (Andrew) > - Move the changelog from the patches into the cover letter > - Rearrange the patchset to have GUP patches at the beginning > > v9 -> v10: > - Introduce and use unpin_folio(), unpin_folios() and > check_and_migrate_movable_folios() helpers > - Use a list to track the folios that need to be unpinned in udmabuf > > v8 -> v9: (suggestions from Matthew) > - Drop the extern while declaring memfd_alloc_folio() > - Fix memfd_alloc_folio() declaration to have it return struct folio * > instead of struct page * when CONFIG_MEMFD_CREATE is not defined > - Use folio_pfn() on the folio instead of page_to_pfn() on head page > in udmabuf > - Don't split the arguments to shmem_read_folio() on multiple lines > in udmabuf > > v7 -> v8: (suggestions from David) > - Have caller pass [start, end], max_folios instead of start, nr_pages > - Replace offsets array with just offset into the first page > - Add comments explaning the need for next_idx > - Pin (and return) the folio (via FOLL_PIN) only once > > v6 -> v7: > - Rename this API to memfd_pin_folios() and make it return folios > and offsets instead of pages (David) > - Don't continue processing the folios in the batch returned by > filemap_get_folios_contig() if they do not have correct next_idx > - Add the R-b tag from Christoph > > v5 -> v6: (suggestions from Christoph) > - Rename this API
Re: [PATCH] drm/amd/display: Add null check before access structs
> > In enable_phantom_plane, we should better check null pointer before > > accessing various structs. > > Thanks for the fix, I'll apply this. Do you care for better commit messages and summary phrases? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.10-rc5#n45 Regards, Markus
Re: [PATCH RFC 3/5] drm/connector: implement generic HDMI codec helpers
On Wed, Jun 26, 2024 at 06:07:50PM GMT, Dave Stevenson wrote: > Hi Dmitry > > On Wed, 26 Jun 2024 at 17:11, Dmitry Baryshkov > wrote: > > > > On Wed, Jun 26, 2024 at 04:10:05PM GMT, Dave Stevenson wrote: > > > Hi Maxime and Dmitry > > > > > > On Wed, 26 Jun 2024 at 15:05, Maxime Ripard wrote: > > > > > > > > On Fri, Jun 21, 2024 at 02:09:04PM GMT, Dmitry Baryshkov wrote: > > > > > On Fri, 21 Jun 2024 at 12:27, Maxime Ripard > > > > > wrote: > > > > > > > > > > > > Hi, > > > > > > > > > > > > Sorry for taking some time to review this series. > > > > > > > > > > No problem, that's not long. > > > > > > > > > > > > > > > > > On Sat, Jun 15, 2024 at 08:53:32PM GMT, Dmitry Baryshkov wrote: > > > > > > > Several DRM drivers implement HDMI codec support (despite its > > > > > > > name it > > > > > > > applies to both HDMI and DisplayPort drivers). Implement generic > > > > > > > framework to be used by these drivers. This removes a requirement > > > > > > > to > > > > > > > implement get_eld() callback and provides default implementation > > > > > > > for > > > > > > > codec's plug handling. > > > > > > > > > > > > > > The framework is integrated with the DRM HDMI Connector > > > > > > > framework, but > > > > > > > can be used by DisplayPort drivers. > > > > > > > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > > > > --- > > > > > > > drivers/gpu/drm/Makefile | 1 + > > > > > > > drivers/gpu/drm/drm_connector.c| 8 ++ > > > > > > > drivers/gpu/drm/drm_connector_hdmi_codec.c | 157 > > > > > > > + > > > > > > > include/drm/drm_connector.h| 33 ++ > > > > > > > 4 files changed, 199 insertions(+) > > > > > > > > > > > [...] > > > > > > > > > + > > > > > > > +static int drm_connector_hdmi_codec_get_eld(struct device *dev, > > > > > > > void *data, > > > > > > > + uint8_t *buf, size_t > > > > > > > len) > > > > > > > +{ > > > > > > > + struct drm_connector *connector = data; > > > > > > > + > > > > > > > + // FIXME: locking against drm_edid_to_eld ? > > > > > > > + memcpy(buf, connector->eld, min(sizeof(connector->eld), > > > > > > > len)); > > > > > > > + > > > > > > > + return 0; > > > > > > > +} > > > > > > > + > > > > > > > +static int drm_connector_hdmi_codec_hook_plugged_cb(struct > > > > > > > device *dev, > > > > > > > + void *data, > > > > > > > + > > > > > > > hdmi_codec_plugged_cb fn, > > > > > > > + struct device > > > > > > > *codec_dev) > > > > > > > +{ > > > > > > > + struct drm_connector *connector = data; > > > > > > > + > > > > > > > + mutex_lock(&connector->hdmi_codec.lock); > > > > > > > + > > > > > > > + connector->hdmi_codec.plugged_cb = fn; > > > > > > > + connector->hdmi_codec.plugged_cb_dev = codec_dev; > > > > > > > + > > > > > > > + fn(codec_dev, connector->hdmi_codec.last_state); > > > > > > > + > > > > > > > + mutex_unlock(&connector->hdmi_codec.lock); > > > > > > > + > > > > > > > + return 0; > > > > > > > +} > > > > > > > + > > > > > > > +void drm_connector_hdmi_codec_plugged_notify(struct > > > > > > > drm_connector *connector, > > > > > > > + bool plugged) > > > > > > > +{ > > > > > > > + mutex_lock(&connector->hdmi_codec.lock); > > > > > > > + > > > > > > > + connector->hdmi_codec.last_state = plugged; > > > > > > > + > > > > > > > + if (connector->hdmi_codec.plugged_cb && > > > > > > > + connector->hdmi_codec.plugged_cb_dev) > > > > > > > + > > > > > > > connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev, > > > > > > > + > > > > > > > connector->hdmi_codec.last_state); > > > > > > > + > > > > > > > + mutex_unlock(&connector->hdmi_codec.lock); > > > > > > > +} > > > > > > > +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify); > > > > > > > > > > > > I think we should do this the other way around, or rather, like we > > > > > > do > > > > > > for drm_connector_hdmi_init. We'll need a hotplug handler for > > > > > > multiple > > > > > > things (CEC, HDMI 2.0, audio), so it would be best to have a single > > > > > > function to call from drivers, that will perform whatever is needed > > > > > > depending on the driver's capabilities. > > > > > > > > > > I see, this API is probably misnamed. The hdmi_codec_ops use the > > > > > 'plugged' term, > > > > > > > > Is it misnamed? > > > > > > > > It's documented as: > > > > > > > > Hook callback function to handle connector plug event. Optional. > > > > > > > > > but most of the drivers notify the ASoC / codec during atomic_enable / > > > > > atomic_disable path, because usually the audio path can not work with > > > > > the video path being disabled. > > > > > > >
Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
On Mon, Jun 24, 2024 at 8:14 AM Will Deacon wrote: > > On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote: > > From: Rob Clark > > > > Add an io-pgtable method to walk the pgtable returning the raw PTEs that > > would be traversed for a given iova access. > > > > Signed-off-by: Rob Clark > > --- > > drivers/iommu/io-pgtable-arm.c | 51 -- > > include/linux/io-pgtable.h | 4 +++ > > 2 files changed, 46 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c > > index f7828a7aad41..f47a0e64bb35 100644 > > --- a/drivers/iommu/io-pgtable-arm.c > > +++ b/drivers/iommu/io-pgtable-arm.c > > @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct > > io_pgtable_ops *ops, unsigned long iov > > data->start_level, ptep); > > } > > > > -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops, > > - unsigned long iova) > > +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long > > iova, > > + int (*cb)(void *cb_data, void *pte, int level), > > + void *cb_data) > > { > > struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); > > arm_lpae_iopte pte, *ptep = data->pgd; > > int lvl = data->start_level; > > + int ret; > > > > do { > > /* Valid IOPTE pointer? */ > > if (!ptep) > > - return 0; > > + return -EFAULT; > > nit: -ENOENT might be a little better, as we're only checking against a > NULL entry rather than strictly any faulting entry. > > > /* Grab the IOPTE we're interested in */ > > ptep += ARM_LPAE_LVL_IDX(iova, lvl, data); > > @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct > > io_pgtable_ops *ops, > > > > /* Valid entry? */ > > if (!pte) > > - return 0; > > + return -EFAULT; > > Same here (and at the end of the function). > > > + > > + ret = cb(cb_data, &pte, lvl); > > Since pte is on the stack, rather than pointing into the actual pgtable, > I think it would be clearer to pass it by value to the callback. > > > + if (ret) > > + return ret; > > > > - /* Leaf entry? */ > > + /* Leaf entry? If so, we've found the translation */ > > if (iopte_leaf(pte, lvl, data->iop.fmt)) > > - goto found_translation; > > + return 0; > > > > /* Take it to the next level */ > > ptep = iopte_deref(pte, data); > > } while (++lvl < ARM_LPAE_MAX_LEVELS); > > > > /* Ran out of page tables to walk */ > > + return -EFAULT; > > +} > > + > > +struct iova_to_phys_walk_data { > > + arm_lpae_iopte pte; > > + int level; > > +}; > > Expanding a little on Robin's suggestion, why don't we drop this structure > in favour of something more generic: > > struct arm_lpae_walk_data { > arm_lpae_iopte ptes[ARM_LPAE_MAX_LEVELS]; > }; > > and then do something in the walker like: > > if (cb && !cb(pte, lvl)) > walk_data->ptes[lvl] = pte; > So thinking about this some more... if I use a walk_data struct to return the PTEs, I can just get rid of the callback entirely. That ends up looking more like my first version. The callback taking void* was mainly to avoid coding the PTE size in the generic io_pgtable interface. But if we just go with u64, because that is the biggest PTE size we need to deal with, then it all gets simpler. (The callback was actually a semi-awkward interface to use from drm/msm.) BR, -R > which could return the physical address at the end, if it reaches a leaf > entry. That way arm_lpae_iova_to_phys() is just passing a NULL callback > to the walker and your debug callback just needs to return 0 (i.e. the > callback is basically just saying whether or not to continue the walk). > > Will
[rerere PATCH] nightly.conf: Merge drm-msm trees into drm-tip
In order to improve testing of drm/msm branches, add drm-msm trees to the list of the trees to be merged into drm-tip. Cc: Rob Clark Signed-off-by: Dmitry Baryshkov --- nightly.conf | 8 1 file changed, 8 insertions(+) diff --git a/nightly.conf b/nightly.conf index 49abf3fb2a72..f2e181aa29e2 100644 --- a/nightly.conf +++ b/nightly.conf @@ -47,6 +47,11 @@ git://anongit.freedesktop.org/drm-intel https://anongit.freedesktop.org/git/drm/drm-intel https://anongit.freedesktop.org/git/drm/drm-intel.git " +drm_tip_repos[drm-msm]=" +g...@gitlab.freedesktop.org:drm/msm.git +https://gitlab.freedesktop.org/drm/msm.git +ssh://g...@gitlab.freedesktop.org/drm/msm.git +" drm_tip_repos[drm-misc]=" g...@gitlab.freedesktop.org:drm/misc/kernel.git https://gitlab.freedesktop.org/drm/misc/kernel.git @@ -91,16 +96,19 @@ drm_tip_config=( "drm-misc drm-misc-fixes" "drm-intel drm-intel-fixes" "drm-xe drm-xe-fixes" + "drm-msmmsm-fixes" "drmdrm-next" "drm-misc drm-misc-next-fixes" "drm-intel drm-intel-next-fixes" "drm-xe drm-xe-next-fixes" + #no msm-next-fixes in drm-msm "drm-misc drm-misc-next" "drm-intel drm-intel-next" "drm-intel drm-intel-gt-next" "drm-xe drm-xe-next" + "drm-msmmsm-next" "drm-intel topic/core-for-CI" "drm-xe topic/xe-for-CI" -- 2.43.0
Re: [PATCH v1 2/3] drm/msm/adreno: Add support for X185 GPU
On Wed, Jun 26, 2024 at 1:24 AM Akhil P Oommen wrote: > > On Mon, Jun 24, 2024 at 03:53:48PM +0200, Konrad Dybcio wrote: > > > > > > On 6/23/24 13:06, Akhil P Oommen wrote: > > > Add support in drm/msm driver for the Adreno X185 gpu found in > > > Snapdragon X1 Elite chipset. > > > > > > Signed-off-by: Akhil P Oommen > > > --- > > > > > > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 19 +++ > > > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ++ > > > drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++ > > > drivers/gpu/drm/msm/adreno/adreno_gpu.h| 5 + > > > 4 files changed, 36 insertions(+), 8 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > index 0e3dfd4c2bc8..168a4bddfaf2 100644 > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c > > > @@ -830,8 +830,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, > > > unsigned int state) > > > */ > > > gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052); > > > + if (adreno_is_x185(adreno_gpu)) { > > > + chipid = 0x7050001; > > > > What's wrong with using the logic below? > > patchid is BITS(7, 0), not (15, 8) in the case of x185. Due to the > changes in the chipid scheme within the a7x family, this is a bit > confusing. I will try to improve here in another series. I'm thinking we should just add gmu_chipid to struct a6xx_info, tbh Maybe to start with, we can fall back to the existing logic if a6xx_info::gmu_chipid is zero so we don't have to add it for _every_ a6xx/a7xx BR, -R > > > > > /* NOTE: A730 may also fall in this if-condition with a future GMU fw > > > update. */ > > > - if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) { > > > + } else if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) > > > { > > > /* A7xx GPUs have obfuscated chip IDs. Use constant maj = 7 */ > > > chipid = FIELD_PREP(GENMASK(31, 24), 0x7); > > > @@ -1329,9 +1331,18 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct > > > device *dev, u32 *votes, > > > if (!pri_count) > > > return -EINVAL; > > > - sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > - if (IS_ERR(sec)) > > > - return PTR_ERR(sec); > > > + /* > > > +* Some targets have a separate gfx mxc rail. So try to read that > > > first and then fall back > > > +* to regular mx rail if it is missing > > > +*/ > > > + sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); > > > + if (PTR_ERR_OR_ZERO(sec) == -EPROBE_DEFER) { > > > + return -EPROBE_DEFER; > > > + } else if (IS_ERR(sec)) { > > > + sec = cmd_db_read_aux_data("mx.lvl", &sec_count); > > > + if (IS_ERR(sec)) > > > + return PTR_ERR(sec); > > > + } > > > > I assume GMXC would always be used if present, although please use the > > approach Dmitry suggested > > Correct. > > -Akhil > > > > > > The rest looks good! > > > > Konrad
Re: [PATCH] drm/ast: Inline drm_simple_encoder_init()
On Wed, Jun 26, 2024 at 11:01:11AM +0200, Thomas Zimmermann wrote: > Hi > > Am 26.06.24 um 06:34 schrieb Dmitry Baryshkov: > > On Tue, Jun 25, 2024 at 03:18:09PM GMT, Thomas Zimmermann wrote: > > > The function drm_simple_encoder_init() is a trivial helper and > > > deprecated. Replace it with the regular call to drm_encoder_init(). > > > Resolves the dependency on drm_simple_kms_helper.h. No functional > > > changes. > > > > > > Signed-off-by: Thomas Zimmermann > > > --- > > > drivers/gpu/drm/ast/ast_mode.c | 45 ++ > > > 1 file changed, 40 insertions(+), 5 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/ast/ast_mode.c > > > b/drivers/gpu/drm/ast/ast_mode.c > > > index 6695af70768f..2fd9c78eab73 100644 > > > --- a/drivers/gpu/drm/ast/ast_mode.c > > > +++ b/drivers/gpu/drm/ast/ast_mode.c > > > @@ -45,7 +45,6 @@ > > > #include > > > #include > > > #include > > > -#include > > > #include "ast_ddc.h" > > > #include "ast_drv.h" > > > @@ -1358,6 +1357,14 @@ static int ast_crtc_init(struct drm_device *dev) > > > return 0; > > > } > > > +/* > > > + * VGA Encoder > > > + */ > > > + > > > +static const struct drm_encoder_funcs ast_vga_encoder_funcs = { > > > + .destroy = drm_encoder_cleanup, > > > +}; > > > + > > > /* > > >* VGA Connector > > >*/ > > > @@ -1411,7 +1418,8 @@ static int ast_vga_output_init(struct ast_device > > > *ast) > > > struct drm_connector *connector = &ast->output.vga.connector; > > > int ret; > > > - ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); > > > + ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs, > > > +DRM_MODE_ENCODER_DAC, NULL); > > What about using drmm_encoder_init() instead? It will call > > drm_encoder_cleanup automatically. > > IIRC the original use case for the drmm_encoder_*() funcs was to solve > problems with the clean-up order if the encoder was added dynamically. The > hardware for ast is entirely static and ast uses drmm_mode_config_init() for > auto-cleaning up the modesetting pipeline. Using drmm_encoder_init() seems > like a bit of wasted resources for no gain. The idea of drmm_ is that you use them all. That the managed version of drm_mode_config_init also happens to still work with the unmanaged encoder/connector/crtc/plane cleanup is just to facilitate gradual conversions. And see my other reply, for drmm_encoder_init supporting the NULL funcs case actually makes full sense. Also, any driver can be hotunbound through sysfs, no hotunplug of the hw needed at all. -Sima -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH] drm/amd/display: Add null check before access structs
Thanks for the fix, I'll apply this. On 6/26/24 9:06 AM, Ma Ke wrote: In enable_phantom_plane, we should better check null pointer before accessing various structs. Fixes: 09a4ec5da92c ("drm/amd/display: Refactor dc_state interface") Signed-off-by: Ma Ke --- drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c index 282d70e2b18a..3d29169dd6bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c @@ -750,6 +750,8 @@ static void enable_phantom_plane(struct dml2_context *ctx, ctx->config.svp_pstate.callbacks.dc, state, curr_pipe->plane_state); + if (!phantom_plane) + return; } memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address)); -- -- Thanks & Regards, Aurabindo Pillai
Re: [PATCH v5 2/9] scatterlist: Add a flag for the restricted memory
On Wed, Jun 26, 2024 at 12:49:02PM +0200, Christian König wrote: > Am 26.06.24 um 10:05 schrieb Jason-JH Lin (林睿祥): > > > > I think I have the same problem as the ECC_FLAG mention in: > > > > > > https://lore.kernel.org/linux-media/20240515-dma-buf-ecc-heap-v1-0-54cbbd049...@kernel.org/ > > > > > > I think it would be better to have the user configurable private > > > > information in dma-buf, so all the drivers who have the same > > > > requirement can get their private information from dma-buf directly > > > > and > > > > no need to change or add the interface. > > > > > > What's your opinion in this point? > > > > Well of hand I don't see the need for that. > > > > What happens if you get a non-secure buffer imported in your secure > > > device? > > > > We use the same mediatek-drm driver for secure and non-secure buffer. > > If non-secure buffer imported to mediatek-drm driver, it's go to the > > normal flow with normal hardware settings. > > > > We use different configurations to make hardware have different > > permission to access the buffer it should access. > > > > So if we can't get the information of "the buffer is allocated from > > restricted_mtk_cma" when importing the buffer into the driver, we won't > > be able to configure the hardware correctly. > > Why can't you get this information from userspace? Same reason amd and i915/xe also pass this around internally in the kernel, it's just that for those gpus the render and kms node are the same driver so this is easy. But on arm you have split designs everywhere and dma-buf import/export, so something else is needed. And neither current kms uapi nor protocols/extensions have provisions for this (afaik) because it works on the big gpus, and on android it's just hacked up with backchannels. So yeah essentially I think we probably need something like this, as much as it sucks. I see it somewhat similar to handling pcip2pdma limitations in the kernel too. Not sure where/how it should be handled though, and maybe I've missed something around protocols, in which case I guess we should add some secure buffer flags to the ADDFB2 ioctl. -Sima -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH] drm/etnaviv: Create an accel device node if compute-only
On Wed, Jun 26, 2024 at 11:39:01AM +0100, Daniel Stone wrote: > Hi, > > On Wed, 26 Jun 2024 at 09:28, Lucas Stach wrote: > > Mesa doesn't cope right now. Mostly because of the renderonly thing > > where we magically need to match render devices to otherwise render > > incapable KMS devices. The way this matching works is that the > > renderonly code tries to open a screen on a rendernode and if that > > succeeds we treat it as the matching render device. > > > > The core of the issue is that we have no way of specifying which kind > > of screen we need at that point, i.e. if the screen should have 3D > > render capabilities or if compute-only or even NN-accel-only would be > > okay. So we can't fail screen creation if there is no 3D engine, as > > this would break the teflon case, which needs a screen for the NN > > accel, but once we successfully create a screen reanderonly might treat > > the thing as a rendering device. > > So we are kind of stuck here between breaking one or the other use- > > case. I'm leaning heavily into the direction of just fixing Mesa, so we > > can specify the type of screen we need at creation time to avoid the > > renderonly issue, porting this change as far back as reasonably > > possible and file old userspace into shit-happens. > > Yeah, honestly this sounds like the best solution to me too. Yeah mesa sounds kinda broken here ... What might work in the kernel is if you publish a fake 3d engine that's too new for broken mesa, if that's enough to make it fail to bind? And if mesa still happily binds against that, then yeah it's probably too broken and we need etnaviv-v2 (as a drm driver uapi name, I think that's what mesa filters?) for anything new (including the NN-only ones). I would still try to avoid that, but just in case someone screams about regressions. -Sima -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH] drm/etnaviv: Create an accel device node if compute-only
On Wed, Jun 26, 2024 at 11:42:24AM +0300, Dmitry Baryshkov wrote: > On Wed, Jun 26, 2024 at 09:26:40AM GMT, Daniel Vetter wrote: > > On Thu, May 09, 2024 at 05:41:18PM +0300, Oded Gabbay wrote: > > > On Thu, May 09, 2024 at 03:53:01PM +0200, Tomeu Vizoso wrote: > > > > Oded, Dave, > > > > > > > > Do you have an opinion on this? > > > > > > > > Thanks, > > > > > > > > Tomeu > > > Hi Tomeu, > > > > > > Sorry for not replying earlier, I was down with Covid (again...). > > > > > > To your question, I don't have an objection to what you are > > > suggesting. My personal view of accel is that it is an integral part of > > > DRM and therefore, if there is an *existing* drm driver that wants to > > > create an accel node, I'm not against it. > > > > Yeah, there's a continum from "clearly 3d gpu" to "compute AI > > accelerator", with everything possible in-between shipping somewhere. > > Collaboration is the important part, hair-splitting on where exactly the > > driver should be is kinda secondary. I mean beyond "don't put a pure 3d > > driver into accel or vice versa" of course :-) > > > > > There is the question of why you want to expose an accel node, and > > > here I would like to hear Dave's and Sima's opinion on your suggested > > > solution as it may affect the direction of other drm drivers. > > > > So existing userspace that blindly assumes that any render node will give > > it useful 3d acceleration, then that's broken already. > > > > - kernel with new driver support but old mesa without that driver already > > gives you that, even for a pure 3d chip. > > > > - intel (and I think also amd) have pure compute chips without 3d, so this > > issue already exists > > > > Same for the other directions, 3d gpus have variable amounts of compute > > chips nowadays. > > > > That leaves imo just the pragmatic choice, and if we need to complicate > > the init flow of the kernel driver just for a different charnode major, > > then I don't really see the point. > > > > And if we do see the point in this, I think the right approach would be if > > we split the init flow further into allocating the drm_device, and then in > > a 2nd step either allocate the accel or render uapi stuff as needed. The > > DRIVER_FOO flags just aren't super flexible for this kinda of stuff and > > have a bit a midlayer taste to them. > > Being able to defer render allocation would be extremely useful for MSM > too as it's not currently possible to mask the driver_features during > drm_dev_init() Eh I think less driver_features and more explicit (like drm_mode_config_init() instead of also having to set DRIVER_MODESET) stuff would be better in general. But they keep popping up, because it's an easy hack to get things going. Over the years I've managed to remove a lot of them tough. -Sima -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: Time for drm-ci-next?
On Wed, Jun 26, 2024 at 11:38:30AM +0300, Dmitry Baryshkov wrote: > On Wed, Jun 26, 2024 at 09:32:44AM GMT, Daniel Vetter wrote: > > On Mon, Jun 24, 2024 at 10:25:25AM -0300, Helen Koike wrote: > > > > > > > > > On 24/06/2024 02:34, Vignesh Raman wrote: > > > > Hi, > > > > > > > > On 15/03/24 22:50, Rob Clark wrote: > > > > > Basically, I often find myself needing to merge CI patches on top of > > > > > msm-next in order to run CI, and then after a clean CI run, reset HEAD > > > > > back before the merge and force-push. Which isn't really how things > > > > > should work. > > > > This sounds more like you want an integration tree like drm-tip. Get msm > > branches integrated there, done. Backmerges just for integration testing > > are not a good idea indeed. > > Is it fine to get drm/msm{-fixes,-next} into drm-tip? Should be. > > What exactly is the issue in backmerging drm-misc-next (well through > > drm-next really)? > > drm-misc-next is its own tree with separate cadence, its own bugs and > misfeatures. But probably just picking up drm-next for the tests should > be fine. Well, more CI should make the situation better for everyone. And I don't think you can avoid issues with topic branches, since usually there's enough stuff going on that you still often need parts of drm-next. The clean topic branches only tend to happen with other subsystems, where the interactions are much less. I think aim for more integration testing first with something like drm-tip, one-off topic branches if really needed for e.g. the gitlab version upgrade (but still prefer backmerges if that's enough) and see where it goes? If other trees introduce bugs it's imo much better to hit them early than in the middle of the next merge window, which is what you'd get with maximum amount of topic branches and tree separation. And the merge window is already really wobbly, we need to make that better. Cheers, Sima > > Also if there is an issue, generally we do ad-hoc topic branches. > > > > I'm very very skeptical of boutique trees with tiny focus, we've had that > > before drm-misc, it's a mess. Definitely no enthusiasm for getting back > > to that kind of world. > > -Sima > > -- > With best wishes > Dmitry -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
Re: [PATCH v2 1/2] dt-bindings: display: bridge: add TI TDP158
On 26/06/2024 18:08, Conor Dooley wrote: > On Tue, Jun 25, 2024 at 06:38:12PM +0200, Marc Gonzalez wrote: > >> The TI TDP158 is an HDMI to TMDS Redriver. >> >> Signed-off-by: Marc Gonzalez >> --- >> .../bindings/display/bridge/ti,tdp158.yaml | 48 >> ++ >> 1 file changed, 48 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml >> b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml >> new file mode 100644 >> index 0..b687699e2ba80 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml >> @@ -0,0 +1,48 @@ >> +# SPDX-License-Identifier: GPL-2.0-only >> +%YAML 1.2 >> +--- >> +$id: http://devicetree.org/schemas/display/bridge/ti,tdp158.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: TI TDP158 HDMI to TMDS Redriver >> + >> +maintainers: >> + - Arnaud Vrac >> + >> +properties: >> + compatible: >> +const: ti,tdp158 >> + >> + reg: >> +description: I2C address of the device >> + >> + enable-gpios: >> +description: GPIO controlling bridge enable >> + >> + vcc-supply: >> +description: Power supply 3.3V >> + >> + vdd-supply: >> +description: Power supply 1.1V > > Are these supplies not also required? Surely the device needs the power > to function? Maybe if the hamsters spin fast enough in their wheels, these supplies won't be required? :) The reason I hesitated to mark them as required, is because the HW engineer told us that on our board they were connected to a power line that is shared between several functional blocks. I suppose that's not a reason? Required means "device doesn't work if they're not connected" ? Regards
Re: [PATCH RFC 3/5] drm/connector: implement generic HDMI codec helpers
Hi Dmitry On Wed, 26 Jun 2024 at 17:11, Dmitry Baryshkov wrote: > > On Wed, Jun 26, 2024 at 04:10:05PM GMT, Dave Stevenson wrote: > > Hi Maxime and Dmitry > > > > On Wed, 26 Jun 2024 at 15:05, Maxime Ripard wrote: > > > > > > On Fri, Jun 21, 2024 at 02:09:04PM GMT, Dmitry Baryshkov wrote: > > > > On Fri, 21 Jun 2024 at 12:27, Maxime Ripard wrote: > > > > > > > > > > Hi, > > > > > > > > > > Sorry for taking some time to review this series. > > > > > > > > No problem, that's not long. > > > > > > > > > > > > > > On Sat, Jun 15, 2024 at 08:53:32PM GMT, Dmitry Baryshkov wrote: > > > > > > Several DRM drivers implement HDMI codec support (despite its name > > > > > > it > > > > > > applies to both HDMI and DisplayPort drivers). Implement generic > > > > > > framework to be used by these drivers. This removes a requirement to > > > > > > implement get_eld() callback and provides default implementation for > > > > > > codec's plug handling. > > > > > > > > > > > > The framework is integrated with the DRM HDMI Connector framework, > > > > > > but > > > > > > can be used by DisplayPort drivers. > > > > > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > > > --- > > > > > > drivers/gpu/drm/Makefile | 1 + > > > > > > drivers/gpu/drm/drm_connector.c| 8 ++ > > > > > > drivers/gpu/drm/drm_connector_hdmi_codec.c | 157 > > > > > > + > > > > > > include/drm/drm_connector.h| 33 ++ > > > > > > 4 files changed, 199 insertions(+) > > > > > > > > [...] > > > > > > > + > > > > > > +static int drm_connector_hdmi_codec_get_eld(struct device *dev, > > > > > > void *data, > > > > > > + uint8_t *buf, size_t len) > > > > > > +{ > > > > > > + struct drm_connector *connector = data; > > > > > > + > > > > > > + // FIXME: locking against drm_edid_to_eld ? > > > > > > + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +static int drm_connector_hdmi_codec_hook_plugged_cb(struct device > > > > > > *dev, > > > > > > + void *data, > > > > > > + > > > > > > hdmi_codec_plugged_cb fn, > > > > > > + struct device > > > > > > *codec_dev) > > > > > > +{ > > > > > > + struct drm_connector *connector = data; > > > > > > + > > > > > > + mutex_lock(&connector->hdmi_codec.lock); > > > > > > + > > > > > > + connector->hdmi_codec.plugged_cb = fn; > > > > > > + connector->hdmi_codec.plugged_cb_dev = codec_dev; > > > > > > + > > > > > > + fn(codec_dev, connector->hdmi_codec.last_state); > > > > > > + > > > > > > + mutex_unlock(&connector->hdmi_codec.lock); > > > > > > + > > > > > > + return 0; > > > > > > +} > > > > > > + > > > > > > +void drm_connector_hdmi_codec_plugged_notify(struct drm_connector > > > > > > *connector, > > > > > > + bool plugged) > > > > > > +{ > > > > > > + mutex_lock(&connector->hdmi_codec.lock); > > > > > > + > > > > > > + connector->hdmi_codec.last_state = plugged; > > > > > > + > > > > > > + if (connector->hdmi_codec.plugged_cb && > > > > > > + connector->hdmi_codec.plugged_cb_dev) > > > > > > + > > > > > > connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev, > > > > > > + > > > > > > connector->hdmi_codec.last_state); > > > > > > + > > > > > > + mutex_unlock(&connector->hdmi_codec.lock); > > > > > > +} > > > > > > +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify); > > > > > > > > > > I think we should do this the other way around, or rather, like we do > > > > > for drm_connector_hdmi_init. We'll need a hotplug handler for multiple > > > > > things (CEC, HDMI 2.0, audio), so it would be best to have a single > > > > > function to call from drivers, that will perform whatever is needed > > > > > depending on the driver's capabilities. > > > > > > > > I see, this API is probably misnamed. The hdmi_codec_ops use the > > > > 'plugged' term, > > > > > > Is it misnamed? > > > > > > It's documented as: > > > > > > Hook callback function to handle connector plug event. Optional. > > > > > > > but most of the drivers notify the ASoC / codec during atomic_enable / > > > > atomic_disable path, because usually the audio path can not work with > > > > the video path being disabled. > > > > > > That's not clear to me either: > > > > > > - rockchip/cdn-dp, msm/dp/dp-audio, dw-hdmi, seem to call it at > > > enable/disable > > > > > > - anx7625, mtk_hdmi and mtk_dp calls it in detect > > > > > > - adv7511, ite-it66121, lontium-lt9611, lontium-lt9611uxc, sii902x, > > > exynos, tda998x, msm_hdmi, sti, tegra, vc4 don't call it at all. > > > > FWIW I have a patch in the ne
Re: [PATCH v4 1/5] clk: sunxi-ng: common: Support minimum and maximum rate
Hi Robert, 26.06.2024 18:03:24 Pafford, Robert J. : > Hi Frank, > > Moving to a new for loop makes sense. Let me know when you have a patch The patch is here, strange you didn't receive it: https://lore.kernel.org/all/20240623-sunxi-ng_fix_common_probe-v1-1-7c97e3282...@oltmanns.dev/ > and I'll be glad to test it on my board. I do also wonder if this may > have contributed to some of the HDMI issues seen in the other thread. My thought's exactly! Best regards, Frank > > Best, > Robert > >> Hi Robert, >> >> I'm truly sorry for the trouble the patch has caused you and for my late >> reply! >> >> On 2024-06-14 at 23:52:08 +, "Pafford, Robert J." >> wrote: The Allwinner SoC's typically have an upper and lower limit for their clocks' rates. Up until now, support for that has been implemented separately for each clock type. Implement that functionality in the sunxi-ng's common part making use of the CCF rate liming capabilities, so that it is available for all clock types. Suggested-by: Maxime Ripard Signed-off-by: Frank Oltmanns Cc: sta...@vger.kernel.org --- drivers/clk/sunxi-ng/ccu_common.c | 19 +++ drivers/clk/sunxi-ng/ccu_common.h | 3 +++ 2 files changed, 22 insertions(+) >>> >>> This patch appears to cause a buffer under-read bug due to the call to >>> 'hw_to_ccu_common', which assumes all entries >>> in the desc->hw_clocks->hws array are contained in ccu_common structs. >>> >>> However, not all clocks in the array are contained in ccu_common structs. >>> For example, as part >>> of the "sun20i-d1-ccu" driver, the "pll-video0" clock holds the 'clk_hw' >>> struct inside of a 'clk_fixed_factor' struct, >>> as it is a fixed factor clock based on the "pll-video0-4x" clock, created >>> with the CLK_FIXED_FACTOR_HWS macro. >>> This results in undefined behavior as the hw_to_ccu_common returns an >>> invalid pointer referencing memory before the >>> 'clk_fixed_factor' struct. >>> >> >> Great catch! At first glance, it seems to me that calling >> clk_hw_set_rate_range() in sunxi_ccu_probe() should not have happenend >> in the loop that iterates over the hw_clks. >> >> Instead we should add one more loop that iterates over the ccu_clks. >> Note, that there is already one such loop but, unfortunately, we can't >> use that as it happens before the hw_clks loop and we can only call >> clk_hw_set_rate_range() after the hw_clk has been registered. >> >> Hence, I propose to move the offending code to a new loop: >> for (i = 0; i < desc->num_ccu_clks; i++) { >> struct ccu_common *cclk = desc->ccu_clks[i]; >> >> if (!cclk) >> continue; >> >> if (cclk->max_rate) >> clk_hw_set_rate_range(&cclk->hw, common->min_rate, >> common->max_rate); >> else >> WARN(cclk->min_rate, >> "No max_rate, ignoring min_rate of clock %d - >> %s\n", >> i, cclk->hw.init->name); >> } >> >> I haven't tested (or even compiled) the above, but I'll test and send a >> patch within the next few days for you to test. >> >> Thanks again, >> Frank >> >>> >>> I have attached kernel warnings from a system based on the >>> "sun8i-t113s.dtsi" device tree, where the memory contains >>> a non-zero value for the min-rate but a zero value for the max-rate, >>> triggering the "No max_rate, ignoring min_rate" >>> warning in the 'sunxi_ccu_probe' function. >>> >>> [...]
Re: [PATCH 2/2] drm/panel: simple: Add AUO G104STN01 panel entry
On 26/06/2024 06:36, Paul Gerber wrote: Add support for the AUO G104STN01 10.4" (800x600) LCD-TFT panel. Signed-off-by: Paul Gerber --- Tested on TQ MBa8MPxL with TQMa8MPxL. drivers/gpu/drm/panel/panel-simple.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index dcb6d0b6ced0..5eacd2085a53 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1081,6 +1081,30 @@ static const struct panel_desc auo_g104sn02 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct drm_display_mode auo_g104stn01_mode = { + .clock = 4, + .hdisplay = 800, + .hsync_start = 800 + 40, + .hsync_end = 800 + 40 + 88, + .htotal = 800 + 40 + 88 + 128, + .vdisplay = 600, + .vsync_start = 600 + 1, + .vsync_end = 600 + 1 + 23, + .vtotal = 600 + 1 + 23 + 4, +}; + +static const struct panel_desc auo_g104stn01 = { + .modes = &auo_g104stn01_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 211, + .height = 158, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing auo_g121ean01_timing = { .pixelclock = { 6000, 7440, 9000 }, .hactive = { 1280, 1280, 1280 }, @@ -4434,6 +4458,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "auo,g104sn02", .data = &auo_g104sn02, + }, { + .compatible = "auo,g104stn01", + .data = &auo_g104stn01, }, { .compatible = "auo,g121ean01", .data = &auo_g121ean01, Reviewed-by: Neil Armstrong
Re: [PATCH 2/2] drm/panel: simple: Add Jiangsu Smartwin SMMT043480272A-A19 panel
On 26/06/2024 18:17, Marco Felsch wrote: From: Rouven Czerwinski Add support for the Jiangsu Smartwin SMMT043480272A-A19 4.3" 480x272 TFT-LCD panel. The timings are based on the ILI6485 controller IC datasheet. Signed-off-by: Rouven Czerwinski Signed-off-by: Marco Felsch --- drivers/gpu/drm/panel/panel-simple.c | 32 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index dcb6d0b6ced0..a06ad2cd76f0 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2719,6 +2719,35 @@ static const struct panel_desc innolux_zj070na_01p = { }, }; +static const struct display_timing jiangsu_smartwin_smmt043480272a_a19_timing = { + .pixelclock = { 800, 900, 1200 }, + .hactive = { 480, 480, 480 }, + .hback_porch = { 1, 43, 43 }, + .hfront_porch = { 4, 8, 75 }, + .hsync_len = { 2, 4, 75 }, + .vactive = { 272, 272, 272 }, + .vback_porch = { 2, 12, 12 }, + .vfront_porch = { 2, 8, 37 }, + .vsync_len = { 2, 4, 37 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | +DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE | +DISPLAY_FLAGS_SYNC_POSEDGE, +}; + +static const struct panel_desc jiangsu_smartwin_smmt043480272a_a19 = { + .timings = &jiangsu_smartwin_smmt043480272a_a19_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 95, + .height = 54, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | +DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | +DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE, +}; + static const struct display_timing koe_tx14d24vm1bpa_timing = { .pixelclock = { 558, 585, 620 }, .hactive = { 320, 320, 320 }, @@ -4626,6 +4655,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "innolux,zj070na-01p", .data = &innolux_zj070na_01p, + }, { + .compatible = "jianda,smmt043480272a-a19", + .data = &jiangsu_smartwin_smmt043480272a_a19, }, { .compatible = "koe,tx14d24vm1bpa", .data = &koe_tx14d24vm1bpa, Reviewed-by: Neil Armstrong
Re: [PATCH v2 0/2] drm/panel: initial support for the Ortustech COM35H3P70ULC
Hi, On Wed, 26 Jun 2024 16:44:31 +0200, Michael Walle wrote: > Add initial support for the 480x640 DSI panel from Ortustech. The > panel uses an Ilitek ILI9806E panel driver IC. > > v2: > - use drm_connector_helper_get_modes_fixed(), thanks Dmitry. > - slight header files cleanup > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/2] dt-bindings: display: panel: add Ilitek ili9806e panel controller https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/b7a0c0e9d80756da52d5c88f24b5253a08108724 [2/2] drm/panel: add Ilitek ILI9806E panel driver https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/baf272bac637d3275bb83c17ac849b44a4590655 -- Neil
Re: [PATCH v2 0/3] drm: panel: add support lincolntech LCD197 panel
Hi, On Wed, 26 Jun 2024 16:22:06 +0200, Jerome Brunet wrote: > This patchset adds support for the Lincolntech LCD197 1080x1920 DSI panel. > > Changes since v1 [1]: > * Rebased on drm-misc-next > * Drop vendor prefix change (lincolntech recently added) > * Use mipi_dsi_dcs_*multi() > * Drop the shutdown callback > * Insert mipi_dsi_usleep_range() for _multi usage as suggested. > * Downcase hexadecimal values > > [...] Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/3] dt-bindings: panel-simple-dsi: add lincoln LCD197 panel bindings https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/47d5c1934edcbda13d4fab4d7019b9ec8be0fe08 [2/3] drm/mipi-dsi: add mipi_dsi_usleep_range helper https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/3ebc76c424bc0f0768f5c346667e8f51217917ba [3/3] drm/panel: add lincolntech lcd197 support https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/c5207ed4638314aca89afb45629902288efe5f4e -- Neil
Re: [PATCH] drm/panel: sitronix-st7703: transition to mipi_dsi wrapped functions
Hi, On Wed, 26 Jun 2024 10:22:41 +0530, Tejas Vipin wrote: > Use functions introduced in commit 966e397e4f60 ("drm/mipi-dsi: > Introduce mipi_dsi_*_write_seq_multi()") and commit f79d6d28d8fe > ("drm/mipi-dsi: wrap more functions for streamline handling") for > sitronix-st7703 based panels. > > Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next) [1/1] drm/panel: sitronix-st7703: transition to mipi_dsi wrapped functions https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/68145ceb9b6dc5c11ecb470ccdab8e146ebf294b -- Neil
Re: [PATCH v2 2/2] drm/panel: add Ilitek ILI9806E panel driver
On 26/06/2024 16:44, Michael Walle wrote: The Ortustech COM35H3P70ULC panel is based on the ILI9806E DSI display controller. Co-developed-by: Gunnar Dibbern Signed-off-by: Gunnar Dibbern Signed-off-by: Michael Walle --- MAINTAINERS | 5 + drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile| 1 + drivers/gpu/drm/panel/panel-ilitek-ili9806e.c | 402 ++ 4 files changed, 417 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9806e.c diff --git a/MAINTAINERS b/MAINTAINERS index e2d8fdda1737..61352f26f2d9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7003,6 +7003,11 @@ S: Maintained F:Documentation/devicetree/bindings/display/panel/ilitek,ili9805.yaml F:drivers/gpu/drm/panel/panel-ilitek-ili9805.c +DRM DRIVER FOR ILITEK ILI9806E PANELS +M: Michael Walle +S: Maintained +F: drivers/gpu/drm/panel/panel-ilitek-ili9806e.c + DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS M:Jagan Teki S:Maintained diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index bf4eadfe21cb..904a928bc60e 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -205,6 +205,15 @@ config DRM_PANEL_ILITEK_ILI9805 Say Y if you want to enable support for panels based on the Ilitek ILI9805 controller. +config DRM_PANEL_ILITEK_ILI9806E + tristate "Ilitek ILI9806E-based panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for panels based on the + Ilitek ILI9806E controller. + config DRM_PANEL_ILITEK_ILI9881C tristate "Ilitek ILI9881C-based panels" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 051b75b3df7b..12ce91416849 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9805) += panel-ilitek-ili9805.o +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9806E) += panel-ilitek-ili9806e.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c new file mode 100644 index ..e4a44cd26c4d --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +struct panel_desc { + const struct drm_display_mode *display_mode; + unsigned long mode_flags; + enum mipi_dsi_pixel_format format; + unsigned int lanes; + void (*init_sequence)(struct mipi_dsi_multi_context *ctx); +}; + +struct ili9806e_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[2]; + const struct panel_desc *desc; + enum drm_panel_orientation orientation; +}; + +static const char * const regulator_names[] = { + "vdd", + "vccio", +}; + +static inline struct ili9806e_panel *to_ili9806e_panel(struct drm_panel *panel) +{ + return container_of(panel, struct ili9806e_panel, panel); +} + +static int ili9806e_power_on(struct ili9806e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret; + + gpiod_set_value(ctx->reset_gpio, 1); + + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret < 0) { + dev_err(&dsi->dev, "regulator bulk enable failed: %d\n", ret); + return ret; + } + + usleep_range(1, 2); + gpiod_set_value(ctx->reset_gpio, 0); + usleep_range(1, 2); + + return 0; +} + +static int ili9806e_power_off(struct ili9806e_panel *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + int ret; + + gpiod_set_value(ctx->reset_gpio, 1); + + ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret) + dev_err(&dsi->dev, "regulator bulk disable failed: %d\n", ret); + + return ret; +} + +static int ili9806e_on(struct ili9806e_panel *ili9806e) +{ + struct mipi_dsi_multi_context ctx = { .dsi = ili9806e->dsi }; + + if (ili9806e->desc->init_sequence) + ili9806e->desc->init_sequence(&ctx); + + mipi_dsi_dcs_exit_sleep
Re: [PATCH v2 3/3] drm/panel: add lincolntech lcd197 support
On 26/06/2024 16:22, Jerome Brunet wrote: Add support for the Lincoln Technologies LCD197 1080x1920 DSI panel. Signed-off-by: Jerome Brunet --- drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile| 1 + .../gpu/drm/panel/panel-lincolntech-lcd197.c | 262 ++ 3 files changed, 274 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-lincolntech-lcd197.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index bf4eadfe21cb..30206be56f68 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -328,6 +328,17 @@ config DRM_PANEL_LEADTEK_LTK500HD1829 24 bit RGB per pixel. It provides a MIPI DSI interface to the host and has a built-in LED backlight. +config DRM_PANEL_LINCOLNTECH_LCD197 + tristate "Lincoln Technologies lcd197 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for lincolntech lcd197 + TFT-LCD modules. The panel has a 1080x1920 resolution and uses + 24 bit RGB per pixel. It provides a MIPI DSI interface to + the host. + config DRM_PANEL_LG_LB035Q02 tristate "LG LB035Q024573 RGB panel" depends on GPIOLIB && OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 051b75b3df7b..7706ff9087d8 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_DRM_PANEL_KHADAS_TS050) += panel-khadas-ts050.o obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o +obj-$(CONFIG_DRM_PANEL_LINCOLNTECH_LCD197) += panel-lincolntech-lcd197.o obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o diff --git a/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c b/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c new file mode 100644 index ..032c542aab0f --- /dev/null +++ b/drivers/gpu/drm/panel/panel-lincolntech-lcd197.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 BayLibre, SAS + * Author: Jerome Brunet + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +struct lincoln_lcd197_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct regulator *supply; + struct gpio_desc *enable_gpio; + struct gpio_desc *reset_gpio; +}; + +static inline +struct lincoln_lcd197_panel *to_lincoln_lcd197_panel(struct drm_panel *panel) +{ + return container_of(panel, struct lincoln_lcd197_panel, panel); +} + +static int lincoln_lcd197_panel_prepare(struct drm_panel *panel) +{ + struct lincoln_lcd197_panel *lcd = to_lincoln_lcd197_panel(panel); + struct mipi_dsi_multi_context ctx = { .dsi = lcd->dsi }; + int err; + + gpiod_set_value_cansleep(lcd->enable_gpio, 0); + err = regulator_enable(lcd->supply); + if (err < 0) + return err; + + gpiod_set_value_cansleep(lcd->enable_gpio, 1); + usleep_range(1000, 2000); + gpiod_set_value_cansleep(lcd->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(lcd->reset_gpio, 0); + msleep(50); + + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xff, 0x83, 0x99); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x55); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x02, 0x04, 0x70, 0x90, 0x01, + 0x32, 0x33, 0x11, 0x11, 0x4d, 0x57, 0x56, 0x73, + 0x02, 0x02); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x00, 0x80, 0x80, 0xae, 0x0a, + 0x0e, 0x75, 0x11, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0xff, 0x04, 0xa4, 0x02, + 0xa0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, + 0x24, 0x02, 0x04, 0x0a, 0x21, 0x03, 0x00, 0x00, + 0x08, 0xa6, 0x88, 0x04, 0xa4, 0x02, 0xa0, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x24, 0x02, + 0x04, 0x0a, 0x00, 0x00, 0x08, 0xa6, 0x00, 0x08, + 0x11); + mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x32, 0x10, 0x09, 0x00, 0x09, + 0x32, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x02, 0x02, 0x03, 0x00, + 0x00, 0x00, 0x0a, 0x40); + mipi_d
Re: [PATCH v2 2/3] drm/mipi-dsi: add mipi_dsi_usleep_range helper
On 26/06/2024 16:22, Jerome Brunet wrote: Like for mipi_dsi_msleep(), usleep_range() may often be called in between mipi_dsi_dcs_*() functions and needs a multi compatible counter part. Suggested-by: Dmitry Baryshkov Signed-off-by: Jerome Brunet --- include/drm/drm_mipi_dsi.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 71d121aeef24..0f520eeeaa8e 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -10,6 +10,7 @@ #define __DRM_MIPI_DSI_H__ #include +#include struct mipi_dsi_host; struct mipi_dsi_device; @@ -297,6 +298,12 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, msleep(delay); \ } while (0) +#define mipi_dsi_usleep_range(ctx, min, max) \ + do {\ + if (!(ctx)->accum_err) \ + usleep_range(min, max); \ + } while (0) + /** * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking Reviewed-by: Neil Armstrong
Re: [PATCH] drm/panel: sitronix-st7703: transition to mipi_dsi wrapped functions
On 26/06/2024 06:52, Tejas Vipin wrote: Use functions introduced in commit 966e397e4f60 ("drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()") and commit f79d6d28d8fe ("drm/mipi-dsi: wrap more functions for streamline handling") for sitronix-st7703 based panels. Signed-off-by: Tejas Vipin --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 836 +- 1 file changed, 400 insertions(+), 436 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 77b30e045a57..67e8e45498cb 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -69,7 +69,7 @@ struct st7703_panel_desc { unsigned int lanes; unsigned long mode_flags; enum mipi_dsi_pixel_format format; - int (*init_sequence)(struct st7703 *ctx); + void (*init_sequence)(struct mipi_dsi_multi_context *dsi_ctx); }; static inline struct st7703 *panel_to_st7703(struct drm_panel *panel) @@ -77,62 +77,58 @@ static inline struct st7703 *panel_to_st7703(struct drm_panel *panel) return container_of(panel, struct st7703, panel); } -static int jh057n_init_sequence(struct st7703 *ctx) +static void jh057n_init_sequence(struct mipi_dsi_multi_context *dsi_ctx) { - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); - /* * Init sequence was supplied by the panel vendor. Most of the commands * resemble the ST7703 but the number of parameters often don't match * so it's likely a clone. */ - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETEXTC, - 0xF1, 0x12, 0x83); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETRGBIF, - 0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00, - 0x00, 0x00); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETSCR, - 0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70, - 0x00); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETDISP, 0xF0, 0x12, 0x30); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETEQ, - 0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETBGP, 0x08, 0x08); - msleep(20); - - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETVCOM, 0x3F, 0x3F); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP1, - 0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 0x12, - 0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38, - 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88, - 0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64, - 0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP2, - 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88, - 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13, - 0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0A, - 0xA5, 0x00, 0x00, 0x00, 0x00); - mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETGAMMA, - 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37, - 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11, - 0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, - 0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, - 0x11, 0x18); - msleep(20); - - return 0; + mipi_dsi_generic_write_seq_multi(dsi_ctx, ST7703_CMD_SETEXTC, +0xF1, 0x12, 0x83); + mipi_dsi_generic_write_seq_multi(dsi_ctx, ST7703_CMD_SETRGBIF, +
Re: [PATCH] drm/amd/display: Add null check before access structs
> In enable_phantom_plane, we should better check null pointer before > accessing various structs. 1. Can a wording approach (like the following) be a better change description? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.10-rc5#n45 A null pointer is stored in the local variable “phantom_plane” after a call of the function “create_phantom_plane” (as a data structure menber) failed. This pointer was used in subsequent statements where an undesirable dereference will be performed then. Thus add a corresponding return value check. 2. How do you think about to use a summary phrase like “Prevent null pointer dereference in enable_phantom_plane()”? Regards, Markus
Re: [PATCH] printk: Add a short description string to kmsg_dump()
On Tue, Jun 25, 2024 at 02:39:29PM +0200, Jocelyn Falempe wrote: > kmsg_dump doesn't forward the panic reason string to the kmsg_dumper > callback. > This patch adds a new parameter "const char *desc" to the kmsg_dumper > dump() callback, and update all drivers that are using it. > > To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc() > function and a macro for backward compatibility. > > I've written this for drm_panic, but it can be useful for other > kmsg_dumper. > It allows to see the panic reason, like "sysrq triggered crash" > or "VFS: Unable to mount root fs on " on the drm panic screen. Seems reasonable. Given the prototype before/after: dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason) dump(struct kmsg_dumper *dumper, enum kmsg_dump_reason reason, const char *desc) Perhaps this should instead be a struct that the panic fills in? Then it'll be easy to adjust the struct in the future: struct kmsg_dump_detail { enum kmsg_dump_reason reason; const char *description; }; dump(struct kmsg_dumper *dumper, struct kmsg_dump *detail) This .cocci could do the conversion: @ dump_func @ identifier DUMPER, CALLBACK; @@ struct kmsg_dumper DUMPER = { .dump = CALLBACK, }; @ detail @ identifier dump_func.CALLBACK; identifier DUMPER, REASON; @@ CALLBACK(struct kmsg_dumper *DUMPER, -enum kmsg_dump_reason REASON +struct kmsg_dump_detail *detail ) { <... - REASON + detail->reason ...> } Also, just to double-check, doesn't the panic reason show up in the kmsg_dump log itself (at the end?) I ask since for pstore, "desc" is likely redundant since it's capturing the entire console log. -Kees Here's the patch from the above cocci: diff -u -p a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c --- a/drivers/hv/hv_common.c +++ b/drivers/hv/hv_common.c @@ -207,13 +207,13 @@ static int hv_die_panic_notify_crash(str * buffer and call into Hyper-V to transfer the data. */ static void hv_kmsg_dump(struct kmsg_dumper *dumper, -enum kmsg_dump_reason reason) +struct kmsg_dump_detail *detail) { struct kmsg_dump_iter iter; size_t bytes_written; /* We are only interested in panics. */ - if (reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg) + if (detail->reason != KMSG_DUMP_PANIC || !sysctl_record_panic_msg) return; /* diff -u -p a/arch/powerpc/platforms/powernv/opal-kmsg.c b/arch/powerpc/platforms/powernv/opal-kmsg.c --- a/arch/powerpc/platforms/powernv/opal-kmsg.c +++ b/arch/powerpc/platforms/powernv/opal-kmsg.c @@ -20,13 +20,13 @@ * message, it just ensures that OPAL completely flushes the console buffer. */ static void kmsg_dump_opal_console_flush(struct kmsg_dumper *dumper, -enum kmsg_dump_reason reason) +struct kmsg_dump_detail *detail) { /* * Outside of a panic context the pollers will continue to run, * so we don't need to do any special flushing. */ - if (reason != KMSG_DUMP_PANIC) + if (detail->reason != KMSG_DUMP_PANIC) return; opal_flush_console(0); diff -u -p a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -73,7 +73,7 @@ static const char *nvram_os_partitions[] }; static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason); + struct kmsg_dump_detail *detail); static struct kmsg_dumper nvram_kmsg_dumper = { .dump = oops_to_nvram @@ -643,7 +643,7 @@ void __init nvram_init_oops_partition(in * partition. If that's too much, go back and capture uncompressed text. */ static void oops_to_nvram(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason) + struct kmsg_dump_detail *detail) { struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf; static unsigned int oops_count = 0; @@ -655,7 +655,7 @@ static void oops_to_nvram(struct kmsg_du unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; int rc = -1; - switch (reason) { + switch (detail->reason) { case KMSG_DUMP_SHUTDOWN: /* These are almost always orderly shutdowns. */ return; @@ -671,7 +671,7 @@ static void oops_to_nvram(struct kmsg_du break; default: pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n", - __func__, (int) reason); + __func__, (int) detail->reason); return; } warning: detail, node 59: record.reason = ... ;[1,2,21,22,32] in pstore_dump may be inco
Re: [PATCH v2 2/2] drm/bridge: add support for TI TDP158
On Wed, Jun 26, 2024 at 05:26:10PM GMT, Marc Gonzalez wrote: > On 26/06/2024 06:47, Dmitry Baryshkov wrote: > > > On Tue, Jun 25, 2024 at 06:38:13PM GMT, Marc Gonzalez wrote: > > > >> The TI TDP158 is an AC-Coupled HDMI signal to TMDS Redriver supporting > >> DVI 1.0 and HDMI 1.4b and 2.0b output signals. > >> > >> The default settings work fine for our use-case. > >> > >> Signed-off-by: Marc Gonzalez > >> --- > >> drivers/gpu/drm/bridge/Kconfig | 6 +++ > >> drivers/gpu/drm/bridge/Makefile| 1 + > >> drivers/gpu/drm/bridge/ti-tdp158.c | 103 > >> + > >> 3 files changed, 110 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/bridge/Kconfig > >> b/drivers/gpu/drm/bridge/Kconfig > >> index c621be1a99a89..0859f85cb4b69 100644 > >> --- a/drivers/gpu/drm/bridge/Kconfig > >> +++ b/drivers/gpu/drm/bridge/Kconfig > >> @@ -368,6 +368,12 @@ config DRM_TI_DLPC3433 > >> It supports up to 720p resolution with 60 and 120 Hz refresh > >> rates. > >> > >> +config DRM_TI_TDP158 > >> + tristate "TI TDP158 HDMI/TMDS bridge" > >> + depends on OF > >> + help > >> +Texas Instruments TDP158 HDMI/TMDS Bridge driver > > > > Please run ./scripts/checkpatch.pl on your patch. > > Oops, sorry, will do. > For the record, I did run: > $ make -j16 dt_binding_check DT_SCHEMA_FILES=ti,tdp158.yaml > > > >> + if ((err = regulator_enable(tdp158->vcc))) > >> + pr_err("%s: vcc: %d", __func__, err); > > > > - dev_err > > - please expand error messages > > - ERROR: do not use assignment in if condition > > simple-bridge.c uses DRM_ERROR, but it says: > "NOTE: this is deprecated in favor of pr_err()" > Hence, I used pr_err. > Are you saying I need to record the dev, > just to be able to call dev_err? Yes, please. Otherwise it's just random 'foo: vcc: -1'. Note, that most of the error-reporting codes doesn't use __func__. > > > > empty line > > Will do. > > >> + return drm_bridge_attach(bridge->encoder, tdp158->next, bridge, > >> DRM_BRIDGE_ATTACH_NO_CONNECTOR); > > > > No. Pass flags directly. > > Oh, just pass the flags argument here? OK. Yes > > > >> + tdp158->next = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); > > > > Missing `select DRM_PANEL_BRIDGE` > > OK. > > >> + if (IS_ERR(tdp158->next)) > >> + return dev_err_probe(dev, PTR_ERR(tdp158->next), "next"); > > > > This results in a cryptic message 'foo: ESOMETHING: next'. Please > > expand. > > OK. > > Thanks for the in-depth review & suggestions. > Will respin with fixes. > > Regards > -- With best wishes Dmitry
Re: [PATCH 1/3] drm/dp_mst: Fix all mstb marked as not probed after suspend/resume
Thanks! Reviewed-by: Lyude Paul On Wed, 2024-06-26 at 16:48 +0800, Wayne Lin wrote: > [Why] > After supend/resume, with topology unchanged, observe that > link_address_sent of all mstb are marked as false even the topology > probing > is done without any error. > > It is caused by wrongly also include "ret == 0" case as a probing > failure > case. > > [How] > Remove inappropriate checking conditions. > > Cc: Lyude Paul > Cc: Harry Wentland > Cc: Jani Nikula > Cc: Imre Deak > Cc: Daniel Vetter > Cc: sta...@vger.kernel.org > Fixes: 37dfdc55ffeb ("drm/dp_mst: Cleanup drm_dp_send_link_address() > a bit") > Signed-off-by: Wayne Lin > --- > drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c > b/drivers/gpu/drm/display/drm_dp_mst_topology.c > index 7f8e1cfbe19d..68831f4e502a 100644 > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c > @@ -2929,7 +2929,7 @@ static int drm_dp_send_link_address(struct > drm_dp_mst_topology_mgr *mgr, > > /* FIXME: Actually do some real error handling here */ > ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); > - if (ret <= 0) { > + if (ret < 0) { > drm_err(mgr->dev, "Sending link address failed with > %d\n", ret); > goto out; > } > @@ -2981,7 +2981,7 @@ static int drm_dp_send_link_address(struct > drm_dp_mst_topology_mgr *mgr, > mutex_unlock(&mgr->lock); > > out: > - if (ret <= 0) > + if (ret < 0) > mstb->link_address_sent = false; > kfree(txmsg); > return ret < 0 ? ret : changed; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH 2/3] drm/dp_mst: Skip CSN if topology probing is not done yet
Some comments down below: On Wed, 2024-06-26 at 16:48 +0800, Wayne Lin wrote: > [Why] > During resume, observe that we receive CSN event before we start > topology > probing. Handling CSN at this moment based on uncertain topology is > unnecessary. > > [How] > Add checking condition in drm_dp_mst_handle_up_req() to skip handling > CSN > if the topology is yet to be probed. > > Cc: Lyude Paul > Cc: Harry Wentland > Cc: Jani Nikula > Cc: Imre Deak > Cc: Daniel Vetter > Cc: sta...@vger.kernel.org > Signed-off-by: Wayne Lin > --- > drivers/gpu/drm/display/drm_dp_mst_topology.c | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c > b/drivers/gpu/drm/display/drm_dp_mst_topology.c > index 68831f4e502a..fc2ceae61db2 100644 > --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c > +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c > @@ -4069,6 +4069,7 @@ static int drm_dp_mst_handle_up_req(struct > drm_dp_mst_topology_mgr *mgr) > if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { > const struct drm_dp_connection_status_notify > *conn_stat = > &up_req->msg.u.conn_stat; > + bool handle_csn; > > drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: > %d mcs: %d ip: %d pdt: %d\n", > conn_stat->port_number, > @@ -4077,6 +4078,16 @@ static int drm_dp_mst_handle_up_req(struct > drm_dp_mst_topology_mgr *mgr) > conn_stat->message_capability_status, > conn_stat->input_port, > conn_stat->peer_device_type); > + > + mutex_lock(&mgr->probe_lock); > + handle_csn = mgr->mst_primary->link_address_sent; > + mutex_unlock(&mgr->probe_lock); > + > + if (!handle_csn) { > + drm_dbg_kms(mgr->dev, "Got CSN before finish > topology probing. Skip it."); > + kfree(up_req); > + goto out; > + } Hm. I think you're definitely on the right track here with not handling CSNs immediately after resume. My one question though is whether dropping the event entirely here is a good idea? In theory, we could receive a CSN at any time during the probe - including receiving a CSN for a connector that we've already probed in the initial post-resume process, which could result in us missing CSNs coming out of resume and still having an outdated topology layout. I'm not totally sure about the solution I'm going to suggest but it seems like it would certainly be worth trying: what if we added a flag to drm_dp_mst_topology_mgr called something like "csn_during_resume" and simply set it to true in response to getting a CSN before we've finished reprobing? Then we at the end of the reprobe, we can simply restart the reprobing process if csn_during_resume gets set - which should still ensure we're up to date with reality. > } else if (up_req->msg.req_type == > DP_RESOURCE_STATUS_NOTIFY) { > const struct drm_dp_resource_status_notify *res_stat > = > &up_req->msg.u.resource_stat; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
[PATCH 1/2] dt-bindings: display: simple: Add Jiangsu Smartwin SMMT043480272A-A19
Add compatible to panel-simple for Jiangsu Smartwin Electronics SMMT043480272A-A19 4.3" 480x272 LCD-TFT panel. Signed-off-by: Marco Felsch --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 5067f5c0a272..6fcb1ebb86f9 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -206,6 +206,8 @@ properties: - innolux,p120zdg-bf1 # Innolux Corporation 7.0" WSVGA (1024x600) TFT LCD panel - innolux,zj070na-01p +# Jiangsu Smartwin Electronics 4.3" (480x272) TFT LCD panel + - jianda,smmt043480272a-a19 # King & Display KD116N21-30NV-A010 eDP TFT LCD panel - kingdisplay,kd116n21-30nv-a010 # Kaohsiung Opto-Electronics Inc. 5.7" QVGA (320 x 240) TFT LCD panel -- 2.39.2
[PATCH 2/2] drm/panel: simple: Add Jiangsu Smartwin SMMT043480272A-A19 panel
From: Rouven Czerwinski Add support for the Jiangsu Smartwin SMMT043480272A-A19 4.3" 480x272 TFT-LCD panel. The timings are based on the ILI6485 controller IC datasheet. Signed-off-by: Rouven Czerwinski Signed-off-by: Marco Felsch --- drivers/gpu/drm/panel/panel-simple.c | 32 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index dcb6d0b6ced0..a06ad2cd76f0 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2719,6 +2719,35 @@ static const struct panel_desc innolux_zj070na_01p = { }, }; +static const struct display_timing jiangsu_smartwin_smmt043480272a_a19_timing = { + .pixelclock = { 800, 900, 1200 }, + .hactive = { 480, 480, 480 }, + .hback_porch = { 1, 43, 43 }, + .hfront_porch = { 4, 8, 75 }, + .hsync_len = { 2, 4, 75 }, + .vactive = { 272, 272, 272 }, + .vback_porch = { 2, 12, 12 }, + .vfront_porch = { 2, 8, 37 }, + .vsync_len = { 2, 4, 37 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | +DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE | +DISPLAY_FLAGS_SYNC_POSEDGE, +}; + +static const struct panel_desc jiangsu_smartwin_smmt043480272a_a19 = { + .timings = &jiangsu_smartwin_smmt043480272a_a19_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 95, + .height = 54, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | +DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | +DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE, +}; + static const struct display_timing koe_tx14d24vm1bpa_timing = { .pixelclock = { 558, 585, 620 }, .hactive = { 320, 320, 320 }, @@ -4626,6 +4655,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "innolux,zj070na-01p", .data = &innolux_zj070na_01p, + }, { + .compatible = "jianda,smmt043480272a-a19", + .data = &jiangsu_smartwin_smmt043480272a_a19, }, { .compatible = "koe,tx14d24vm1bpa", .data = &koe_tx14d24vm1bpa, -- 2.39.2
Re: [PATCH RFC 3/5] drm/connector: implement generic HDMI codec helpers
On Wed, Jun 26, 2024 at 04:10:05PM GMT, Dave Stevenson wrote: > Hi Maxime and Dmitry > > On Wed, 26 Jun 2024 at 15:05, Maxime Ripard wrote: > > > > On Fri, Jun 21, 2024 at 02:09:04PM GMT, Dmitry Baryshkov wrote: > > > On Fri, 21 Jun 2024 at 12:27, Maxime Ripard wrote: > > > > > > > > Hi, > > > > > > > > Sorry for taking some time to review this series. > > > > > > No problem, that's not long. > > > > > > > > > > > On Sat, Jun 15, 2024 at 08:53:32PM GMT, Dmitry Baryshkov wrote: > > > > > Several DRM drivers implement HDMI codec support (despite its name it > > > > > applies to both HDMI and DisplayPort drivers). Implement generic > > > > > framework to be used by these drivers. This removes a requirement to > > > > > implement get_eld() callback and provides default implementation for > > > > > codec's plug handling. > > > > > > > > > > The framework is integrated with the DRM HDMI Connector framework, but > > > > > can be used by DisplayPort drivers. > > > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > > --- > > > > > drivers/gpu/drm/Makefile | 1 + > > > > > drivers/gpu/drm/drm_connector.c| 8 ++ > > > > > drivers/gpu/drm/drm_connector_hdmi_codec.c | 157 > > > > > + > > > > > include/drm/drm_connector.h| 33 ++ > > > > > 4 files changed, 199 insertions(+) > > > > > [...] > > > > > + > > > > > +static int drm_connector_hdmi_codec_get_eld(struct device *dev, void > > > > > *data, > > > > > + uint8_t *buf, size_t len) > > > > > +{ > > > > > + struct drm_connector *connector = data; > > > > > + > > > > > + // FIXME: locking against drm_edid_to_eld ? > > > > > + memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); > > > > > + > > > > > + return 0; > > > > > +} > > > > > + > > > > > +static int drm_connector_hdmi_codec_hook_plugged_cb(struct device > > > > > *dev, > > > > > + void *data, > > > > > + > > > > > hdmi_codec_plugged_cb fn, > > > > > + struct device > > > > > *codec_dev) > > > > > +{ > > > > > + struct drm_connector *connector = data; > > > > > + > > > > > + mutex_lock(&connector->hdmi_codec.lock); > > > > > + > > > > > + connector->hdmi_codec.plugged_cb = fn; > > > > > + connector->hdmi_codec.plugged_cb_dev = codec_dev; > > > > > + > > > > > + fn(codec_dev, connector->hdmi_codec.last_state); > > > > > + > > > > > + mutex_unlock(&connector->hdmi_codec.lock); > > > > > + > > > > > + return 0; > > > > > +} > > > > > + > > > > > +void drm_connector_hdmi_codec_plugged_notify(struct drm_connector > > > > > *connector, > > > > > + bool plugged) > > > > > +{ > > > > > + mutex_lock(&connector->hdmi_codec.lock); > > > > > + > > > > > + connector->hdmi_codec.last_state = plugged; > > > > > + > > > > > + if (connector->hdmi_codec.plugged_cb && > > > > > + connector->hdmi_codec.plugged_cb_dev) > > > > > + > > > > > connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev, > > > > > + > > > > > connector->hdmi_codec.last_state); > > > > > + > > > > > + mutex_unlock(&connector->hdmi_codec.lock); > > > > > +} > > > > > +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify); > > > > > > > > I think we should do this the other way around, or rather, like we do > > > > for drm_connector_hdmi_init. We'll need a hotplug handler for multiple > > > > things (CEC, HDMI 2.0, audio), so it would be best to have a single > > > > function to call from drivers, that will perform whatever is needed > > > > depending on the driver's capabilities. > > > > > > I see, this API is probably misnamed. The hdmi_codec_ops use the > > > 'plugged' term, > > > > Is it misnamed? > > > > It's documented as: > > > > Hook callback function to handle connector plug event. Optional. > > > > > but most of the drivers notify the ASoC / codec during atomic_enable / > > > atomic_disable path, because usually the audio path can not work with > > > the video path being disabled. > > > > That's not clear to me either: > > > > - rockchip/cdn-dp, msm/dp/dp-audio, dw-hdmi, seem to call it at > > enable/disable > > > > - anx7625, mtk_hdmi and mtk_dp calls it in detect > > > > - adv7511, ite-it66121, lontium-lt9611, lontium-lt9611uxc, sii902x, > > exynos, tda998x, msm_hdmi, sti, tegra, vc4 don't call it at all. > > FWIW I have a patch in the next set that adds the call to vc4. The > downstream version of the patch is at [1]. Nice! > > So it doesn't look like there's a majority we can align with, and > > neither should we: we need to figure out what we *need* to do and when, > > and do that. > > > > From the documentation and quickly through the code though, handling i
Re: [PATCH RFC 3/5] drm/connector: implement generic HDMI codec helpers
On Wed, Jun 26, 2024 at 04:05:01PM GMT, Maxime Ripard wrote: > On Fri, Jun 21, 2024 at 02:09:04PM GMT, Dmitry Baryshkov wrote: > > On Fri, 21 Jun 2024 at 12:27, Maxime Ripard wrote: > > > > > > Hi, > > > > > > Sorry for taking some time to review this series. > > > > No problem, that's not long. > > > > > > > > On Sat, Jun 15, 2024 at 08:53:32PM GMT, Dmitry Baryshkov wrote: > > > > Several DRM drivers implement HDMI codec support (despite its name it > > > > applies to both HDMI and DisplayPort drivers). Implement generic > > > > framework to be used by these drivers. This removes a requirement to > > > > implement get_eld() callback and provides default implementation for > > > > codec's plug handling. > > > > > > > > The framework is integrated with the DRM HDMI Connector framework, but > > > > can be used by DisplayPort drivers. > > > > > > > > Signed-off-by: Dmitry Baryshkov > > > > --- > > > > drivers/gpu/drm/Makefile | 1 + > > > > drivers/gpu/drm/drm_connector.c| 8 ++ > > > > drivers/gpu/drm/drm_connector_hdmi_codec.c | 157 > > > > + > > > > include/drm/drm_connector.h| 33 ++ > > > > 4 files changed, 199 insertions(+) > > > > > > > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > > > > index 68cc9258ffc4..e113a6eade23 100644 > > > > --- a/drivers/gpu/drm/Makefile > > > > +++ b/drivers/gpu/drm/Makefile > > > > @@ -45,6 +45,7 @@ drm-y := \ > > > > drm_client_modeset.o \ > > > > drm_color_mgmt.o \ > > > > drm_connector.o \ > > > > + drm_connector_hdmi_codec.o \ > > > > drm_crtc.o \ > > > > drm_displayid.o \ > > > > drm_drv.o \ > > > > diff --git a/drivers/gpu/drm/drm_connector.c > > > > b/drivers/gpu/drm/drm_connector.c > > > > index 3d73a981004c..66d6e9487339 100644 > > > > --- a/drivers/gpu/drm/drm_connector.c > > > > +++ b/drivers/gpu/drm/drm_connector.c > > > > @@ -279,6 +279,7 @@ static int __drm_connector_init(struct drm_device > > > > *dev, > > > > mutex_init(&connector->mutex); > > > > mutex_init(&connector->edid_override_mutex); > > > > mutex_init(&connector->hdmi.infoframes.lock); > > > > + mutex_init(&connector->hdmi_codec.lock); > > > > connector->edid_blob_ptr = NULL; > > > > connector->epoch_counter = 0; > > > > connector->tile_blob_ptr = NULL; > > > > @@ -529,6 +530,12 @@ int drmm_connector_hdmi_init(struct drm_device > > > > *dev, > > > > > > > > connector->hdmi.funcs = hdmi_funcs; > > > > > > > > + if (connector->hdmi_codec.i2s || connector->hdmi_codec.spdif) { > > > > + ret = drmm_connector_hdmi_codec_alloc(dev, connector, > > > > hdmi_funcs->codec_ops); > > > > + if (ret) > > > > + return ret; > > > > + } > > > > + > > > > return 0; > > > > } > > > > EXPORT_SYMBOL(drmm_connector_hdmi_init); > > > > @@ -665,6 +672,7 @@ void drm_connector_cleanup(struct drm_connector > > > > *connector) > > > > connector->funcs->atomic_destroy_state(connector, > > > > connector->state); > > > > > > > > + mutex_destroy(&connector->hdmi_codec.lock); > > > > mutex_destroy(&connector->hdmi.infoframes.lock); > > > > mutex_destroy(&connector->mutex); > > > > > > > > diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c > > > > b/drivers/gpu/drm/drm_connector_hdmi_codec.c > > > > new file mode 100644 > > > > index ..a3a7ad117f6f > > > > --- /dev/null > > > > +++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c > > > > @@ -0,0 +1,157 @@ > > > > +/* > > > > + * Copyright (c) 2024 Linaro Ltd > > > > + * > > > > + * Permission to use, copy, modify, distribute, and sell this software > > > > and its > > > > + * documentation for any purpose is hereby granted without fee, > > > > provided that > > > > + * the above copyright notice appear in all copies and that both that > > > > copyright > > > > + * notice and this permission notice appear in supporting > > > > documentation, and > > > > + * that the name of the copyright holders not be used in advertising or > > > > + * publicity pertaining to distribution of the software without > > > > specific, > > > > + * written prior permission. The copyright holders make no > > > > representations > > > > + * about the suitability of this software for any purpose. It is > > > > provided "as > > > > + * is" without express or implied warranty. > > > > + * > > > > + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS > > > > SOFTWARE, > > > > + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN > > > > NO > > > > + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, > > > > INDIRECT OR > > > > + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS > > > > OF USE, > > > > + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR > > > > OT
Re: [PATCH v2 1/2] dt-bindings: display: bridge: add TI TDP158
On Tue, Jun 25, 2024 at 06:38:12PM +0200, Marc Gonzalez wrote: > The TI TDP158 is an HDMI to TMDS Redriver. > > Signed-off-by: Marc Gonzalez > --- > .../bindings/display/bridge/ti,tdp158.yaml | 48 > ++ > 1 file changed, 48 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml > b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml > new file mode 100644 > index 0..b687699e2ba80 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml > @@ -0,0 +1,48 @@ > +# SPDX-License-Identifier: GPL-2.0-only > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/bridge/ti,tdp158.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: TI TDP158 HDMI to TMDS Redriver > + > +maintainers: > + - Arnaud Vrac > + > +properties: > + compatible: > +const: ti,tdp158 > + > + reg: > +description: I2C address of the device > + > + enable-gpios: > +description: GPIO controlling bridge enable > + > + vcc-supply: > +description: Power supply 3.3V > + > + vdd-supply: > +description: Power supply 1.1V Are these supplies not also required? Surely the device needs the power to function? Cheers, Conor. > + > + ports: > +$ref: /schemas/graph.yaml#/properties/ports > + > +properties: > + port@0: > +$ref: /schemas/graph.yaml#/properties/port > +description: Bridge input > + > + port@1: > +$ref: /schemas/graph.yaml#/properties/port > +description: Bridge output > + > +required: > + - port@0 > + - port@1 > + > +required: > + - compatible > + - ports > + > +additionalProperties: false > > -- > 2.34.1 > signature.asc Description: PGP signature
Re: [PATCH v5] drm/display: split DSC helpers from DP helpers
Hi Am 23.06.24 um 00:44 schrieb Dmitry Baryshkov: Currently the DRM DSC functions are selected by the DRM_DISPLAY_DP_HELPER Kconfig symbol. This is not optimal, since the DSI code (both panel and host drivers) end up selecting the seemingly irrelevant DP helpers. Split the DSC code to be guarded by the separate DRM_DISPLAY_DSC_HELPER Kconfig symbol. Reviewed-by: Jessica Zhang Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov --- To: Alex Deucher To: Christian König To: Pan, Xinhui To: David Airlie To: Daniel Vetter To: Maarten Lankhorst To: Maxime Ripard To: Thomas Zimmermann To: Jani Nikula To: Joonas Lahtinen To: Rodrigo Vivi To: Tvrtko Ursulin To: Rob Clark To: Abhinav Kumar To: Sean Paul To: Marijn Suijten To: Neil Armstrong To: Jessica Zhang Cc: amd-...@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Cc: linux-ker...@vger.kernel.org Cc: intel-...@lists.freedesktop.org Cc: linux-arm-...@vger.kernel.org Cc: freedr...@lists.freedesktop.org Signed-off-by: Dmitry Baryshkov Changes in v5: - Drop applied patches - Link to v4: https://lore.kernel.org/r/20240528-panel-sw43408-fix-v4-0-330b42445...@linaro.org Changes in v4: - Reoder patches so that fixes come first, to be able to land them to drm-misc-fixes - Link to v3: https://lore.kernel.org/r/20240522-panel-sw43408-fix-v3-0-6902285ad...@linaro.org Changes in v3: - Split DRM_DISPLAY_DSC_HELPER from DRM_DISPLAY_DP_HELPER - Added missing Fixes tags - Link to v2: https://lore.kernel.org/r/20240510-panel-sw43408-fix-v2-0-d1ef91ee1...@linaro.org Changes in v2: - use SELECT instead of DEPEND to follow the reverted Kconfig changes - Link to v1: https://lore.kernel.org/r/20240420-panel-sw43408-fix-v1-0-b282ff725...@linaro.org --- drivers/gpu/drm/amd/amdgpu/Kconfig | 1 + drivers/gpu/drm/display/Kconfig| 6 ++ drivers/gpu/drm/display/Makefile | 3 ++- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/msm/Kconfig| 1 + drivers/gpu/drm/panel/Kconfig | 6 +++--- 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 4232ab27f990..5933ca8c6b96 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -6,6 +6,7 @@ config DRM_AMDGPU depends on !UML select FW_LOADER select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 479e62690d75..a2e42014ffe0 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -59,6 +59,12 @@ config DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG If in doubt, say "N". +config DRM_DISPLAY_DSC_HELPER + bool + depends on DRM_DISPLAY_HELPER + help + DRM display helpers for VESA DSC (used by DSI and DisplayPort). + config DRM_DISPLAY_HDCP_HELPER bool depends on DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile index 629df2f4d322..df8f22c7e916 100644 --- a/drivers/gpu/drm/display/Makefile +++ b/drivers/gpu/drm/display/Makefile @@ -6,7 +6,8 @@ drm_display_helper-y := drm_display_helper_mod.o drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \ drm_dp_dual_mode_helper.o \ drm_dp_helper.o \ - drm_dp_mst_topology.o \ + drm_dp_mst_topology.o +drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \ drm_dsc_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \ nit: DSC_HELPER should go after DP_TUNNEL to keep it sorted alphabetically. Best regards Thomas drm_dp_tunnel.o diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index faa253b27664..db400aad88fa 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -11,6 +11,7 @@ config DRM_I915 select SHMEM select TMPFS select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_DSC_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HDMI_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 1931ecf73e32..6dcd26180611 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -111,6 +111,7 @@ config DRM_MSM_DSI depends on DRM_MSM select DRM_PANEL select DRM_MIPI_DSI + select DRM_DISPLAY_DSC_HELPER default y help Choose this option if you have a need for MIPI DSI connector diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index bf4eadfe21cb..afae8b130e9a 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -349,7 +349,7 @@ config DRM_PANEL_LG_SW43408 depends on OF depends on DRM_MIPI_DSI depen
Re: [PATCH v5] drm/display: split DSC helpers from DP helpers
On Sun, Jun 23, 2024 at 01:44:19AM +0300, Dmitry Baryshkov wrote: > Currently the DRM DSC functions are selected by the > DRM_DISPLAY_DP_HELPER Kconfig symbol. This is not optimal, since the DSI > code (both panel and host drivers) end up selecting the seemingly > irrelevant DP helpers. Split the DSC code to be guarded by the separate > DRM_DISPLAY_DSC_HELPER Kconfig symbol. > > Reviewed-by: Jessica Zhang > Reviewed-by: Marijn Suijten > Signed-off-by: Dmitry Baryshkov > --- > To: Alex Deucher > To: Christian König > To: Pan, Xinhui > To: David Airlie > To: Daniel Vetter > To: Maarten Lankhorst > To: Maxime Ripard > To: Thomas Zimmermann > To: Jani Nikula > To: Joonas Lahtinen > To: Rodrigo Vivi > To: Tvrtko Ursulin > To: Rob Clark > To: Abhinav Kumar > To: Sean Paul > To: Marijn Suijten > To: Neil Armstrong > To: Jessica Zhang > Cc: amd-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org > Cc: linux-ker...@vger.kernel.org > Cc: intel-...@lists.freedesktop.org > Cc: linux-arm-...@vger.kernel.org > Cc: freedr...@lists.freedesktop.org > Signed-off-by: Dmitry Baryshkov > > Changes in v5: > - Drop applied patches > - Link to v4: > https://lore.kernel.org/r/20240528-panel-sw43408-fix-v4-0-330b42445...@linaro.org > > Changes in v4: > - Reoder patches so that fixes come first, to be able to land them to > drm-misc-fixes > - Link to v3: > https://lore.kernel.org/r/20240522-panel-sw43408-fix-v3-0-6902285ad...@linaro.org > > Changes in v3: > - Split DRM_DISPLAY_DSC_HELPER from DRM_DISPLAY_DP_HELPER > - Added missing Fixes tags > - Link to v2: > https://lore.kernel.org/r/20240510-panel-sw43408-fix-v2-0-d1ef91ee1...@linaro.org > > Changes in v2: > - use SELECT instead of DEPEND to follow the reverted Kconfig changes > - Link to v1: > https://lore.kernel.org/r/20240420-panel-sw43408-fix-v1-0-b282ff725...@linaro.org > --- > drivers/gpu/drm/amd/amdgpu/Kconfig | 1 + > drivers/gpu/drm/display/Kconfig| 6 ++ > drivers/gpu/drm/display/Makefile | 3 ++- > drivers/gpu/drm/i915/Kconfig | 1 + > drivers/gpu/drm/msm/Kconfig| 1 + > drivers/gpu/drm/panel/Kconfig | 6 +++--- > 6 files changed, 14 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig > b/drivers/gpu/drm/amd/amdgpu/Kconfig > index 4232ab27f990..5933ca8c6b96 100644 > --- a/drivers/gpu/drm/amd/amdgpu/Kconfig > +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig > @@ -6,6 +6,7 @@ config DRM_AMDGPU > depends on !UML > select FW_LOADER > select DRM_DISPLAY_DP_HELPER > + select DRM_DISPLAY_DSC_HELPER > select DRM_DISPLAY_HDMI_HELPER > select DRM_DISPLAY_HDCP_HELPER > select DRM_DISPLAY_HELPER > diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig > index 479e62690d75..a2e42014ffe0 100644 > --- a/drivers/gpu/drm/display/Kconfig > +++ b/drivers/gpu/drm/display/Kconfig > @@ -59,6 +59,12 @@ config DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG > > If in doubt, say "N". > > +config DRM_DISPLAY_DSC_HELPER > + bool > + depends on DRM_DISPLAY_HELPER > + help > + DRM display helpers for VESA DSC (used by DSI and DisplayPort). > + > config DRM_DISPLAY_HDCP_HELPER > bool > depends on DRM_DISPLAY_HELPER > diff --git a/drivers/gpu/drm/display/Makefile > b/drivers/gpu/drm/display/Makefile > index 629df2f4d322..df8f22c7e916 100644 > --- a/drivers/gpu/drm/display/Makefile > +++ b/drivers/gpu/drm/display/Makefile > @@ -6,7 +6,8 @@ drm_display_helper-y := drm_display_helper_mod.o > drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \ > drm_dp_dual_mode_helper.o \ > drm_dp_helper.o \ > - drm_dp_mst_topology.o \ > + drm_dp_mst_topology.o > +drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \ > drm_dsc_helper.o > drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \ > drm_dp_tunnel.o > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig > index faa253b27664..db400aad88fa 100644 > --- a/drivers/gpu/drm/i915/Kconfig > +++ b/drivers/gpu/drm/i915/Kconfig > @@ -11,6 +11,7 @@ config DRM_I915 > select SHMEM > select TMPFS > select DRM_DISPLAY_DP_HELPER > + select DRM_DISPLAY_DSC_HELPER Acked-by: Rodrigo Vivi #i915 > select DRM_DISPLAY_HDCP_HELPER > select DRM_DISPLAY_HDMI_HELPER > select DRM_DISPLAY_HELPER > diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig > index 1931ecf73e32..6dcd26180611 100644 > --- a/drivers/gpu/drm/msm/Kconfig > +++ b/drivers/gpu/drm/msm/Kconfig > @@ -111,6 +111,7 @@ config DRM_MSM_DSI > depends on DRM_MSM > select DRM_PANEL > select DRM_MIPI_DSI > + select DRM_DISPLAY_DSC_HELPER > default y > help > Choose this option if you have a need for MIPI DSI connector > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index bf4eadfe21cb..afae8b130e9a 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b
dma_buf_detach lockdep splat
Hi! I'm seeing the below lockdep splat 1) with the xe driver in an imported dma-buf object destruction path. It's not because we hold the dma_resv lock at that point, but rather because we hold *another* dma_resv lock at that point, and the dma_resv detach happens when the object is idle, in this case it was idle at the final put(), and dma_buf_detach() is called in the putting process. Holding another dma-buf lock might happen as part of drm_exec_unlock_all, or simply if the wider vm dma_resv was held at object put time, so it's not an uncommon pattern, even if the drm_exec instance can be fixed by putting all bos after unlocking them all. Two solutions coming to mind here: 1) Provide a dma_buf_detach_locked() 2) Have TTM always take the delayed delete path for imported dma-buf objects. I'd prefer 1) since I think the correct place to call this is in the TTM callback delete_mem_notify() where the bo is already locked, and I figure non-TTM gem backends may come to suffer from the same problem. Opinions, suggestions? [1] [ 99.136161] [ 99.136162] WARNING: possible recursive locking detected [ 99.136163] 6.10.0-rc2+ #6 Tainted: G U [ 99.136165] [ 99.136166] glxgears:sh0/4675 is trying to acquire lock: [ 99.136167] 9967dcdd91a8 (reservation_ww_class_mutex){+.+.}- {3:3}, at: dma_buf_detach+0x3b/0xf0 [ 99.136184] but task is already holding lock: [ 99.136186] 9967d8c145a8 (reservation_ww_class_mutex){+.+.}- {3:3}, at: drm_exec_lock_obj+0x49/0x2b0 [drm_exec] [ 99.136191] other info that might help us debug this: [ 99.136192] Possible unsafe locking scenario: [ 99.136194]CPU0 [ 99.136194] [ 99.136195] lock(reservation_ww_class_mutex); [ 99.136197] lock(reservation_ww_class_mutex); [ 99.136199] *** DEADLOCK *** [ 99.136199] May be due to missing lock nesting notation [ 99.136200] 5 locks held by glxgears:sh0/4675: [ 99.136202] #0: 9967d8c104c8 (&xef->vm.lock){+.+.}-{3:3}, at: xe_file_close+0xde/0x1c0 [xe] [ 99.136272] #1: 9967d5bb7480 (&vm->lock){}-{3:3}, at: xe_vm_close_and_put+0x161/0x9b0 [xe] [ 99.136350] #2: 9967ef88a970 (&val->lock){.+.+}-{3:3}, at: xe_validation_ctx_init+0x6d/0x70 [xe] [ 99.136440] #3: bd6a085577b8 (reservation_ww_class_acquire){+.+.}-{0:0}, at: xe_vma_destroy_unlocked+0x7f/0xe0 [xe] [ 99.136546] #4: 9967d8c145a8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: drm_exec_lock_obj+0x49/0x2b0 [drm_exec] [ 99.136552] stack backtrace: [ 99.136553] CPU: 10 PID: 4675 Comm: glxgears:sh0 Tainted: G U 6.10.0-rc2+ #6 [ 99.136555] Hardware name: ASUS System Product Name/PRIME B560M-A AC, BIOS 2001 02/01/2023 [ 99.136557] Call Trace: [ 99.136558] [ 99.136560] dump_stack_lvl+0x77/0xb0 [ 99.136564] __lock_acquire+0x1232/0x2160 [ 99.136569] lock_acquire+0xcb/0x2d0 [ 99.136570] ? dma_buf_detach+0x3b/0xf0 [ 99.136574] ? __lock_acquire+0x417/0x2160 [ 99.136577] __ww_mutex_lock.constprop.0+0xd0/0x13b0 [ 99.136580] ? dma_buf_detach+0x3b/0xf0 [ 99.136584] ? dma_buf_detach+0x3b/0xf0 [ 99.136588] ? ww_mutex_lock+0x2b/0x90 [ 99.136590] ww_mutex_lock+0x2b/0x90 [ 99.136592] dma_buf_detach+0x3b/0xf0 [ 99.136595] drm_prime_gem_destroy+0x2f/0x40 [drm] [ 99.136638] xe_ttm_bo_destroy+0x32/0x220 [xe] [ 99.136734] ? __mutex_unlock_slowpath+0x3a/0x290 [ 99.136738] drm_exec_unlock_all+0xa1/0xd0 [drm_exec] [ 99.136741] drm_exec_fini+0x12/0xb0 [drm_exec] [ 99.136743] xe_validation_ctx_fini+0x15/0x40 [xe] [ 99.136848] xe_vma_destroy_unlocked+0xb1/0xe0 [xe] [ 99.136954] xe_vm_close_and_put+0x41a/0x9b0 [xe] [ 99.137056] ? xa_find+0xe3/0x1e0 [ 99.137060] xe_file_close+0x10a/0x1c0 [xe] [ 99.137157] drm_file_free+0x22a/0x280 [drm] [ 99.137193] drm_release_noglobal+0x22/0x70 [drm] [ 99.137227] __fput+0xf1/0x2d0 [ 99.137231] task_work_run+0x59/0x90 [ 99.137235] do_exit+0x330/0xb40 [ 99.137238] do_group_exit+0x36/0xa0 [ 99.137241] get_signal+0xbd2/0xbe0 [ 99.137245] arch_do_signal_or_restart+0x3e/0x240 [ 99.137249] syscall_exit_to_user_mode+0x1e7/0x290 [ 99.137252] do_syscall_64+0xa1/0x180 [ 99.137255] ? _raw_spin_unlock+0x23/0x40 [ 99.137257] ? look_up_lock_class+0x6f/0x120 [ 99.137261] ? __lock_acquire+0x417/0x2160 [ 99.137264] ? lock_acquire+0xcb/0x2d0 [ 99.137266] ? __set_task_comm+0x28/0x1e0 [ 99.137268] ? find_held_lock+0x2b/0x80 [ 99.137271] ? __set_task_comm+0xe1/0x1e0 [ 99.137273] ? lock_release+0xca/0x290 [ 99.137277] ? __do_sys_prctl+0x245/0xab0 [ 99.137279] ? lockdep_hardirqs_on_prepare+0xde/0x190 [ 99.137281] ? syscall_exit_to_user_mode+0xb0/0x290 [ 99.137284] ? do_syscall_64+0xa1/0x180 [ 99.137286] ? cpuset_cpus_allowed+0x36/0x140 [ 99.137289] ? find_held_lock+0x2b/0x80 [ 99.137291] ? find_
Re: [PATCH] drm/mipi-dsi: Fix devm unregister & detach
On 26/06/2024 18:07, Maxime Ripard wrote: On Wed, Jun 26, 2024 at 12:55:39PM GMT, Tomi Valkeinen wrote: On 26/06/2024 11:49, Maxime Ripard wrote: Hi, On Wed, Jun 19, 2024 at 12:07:48PM GMT, Tomi Valkeinen wrote: From: Tomi Valkeinen When a bridge driver uses devm_mipi_dsi_device_register_full() or devm_mipi_dsi_attach(), the resource management is moved to devres, which releases the resource automatically when the bridge driver is unbound. However, if the DSI host goes away first, the host unregistration code will automatically detach and unregister any DSI peripherals, without notifying the devres about it. So when the bridge driver later is unbound, the resources are released a second time, leading to crash. That's super surprising. mipi_dsi_device_unregister calls device_unregister, which calls device_del, which in turn calls devres_release_all. Hmm, right. If that doesn't work like that, then it's what needs to be fixed, and not worked around in the MIPI-DSI bus. Well, something causes a crash for both the device register/unregister case and the attach/detach case, and the call stacks and debug prints showed a double unregister/detach... I need to dig up the board and check again why the devres_release_all() in device_del() doesn't solve this. But I can probably only get back to this in August, so it's perhaps best to ignore this patch for now. However, the attach/detach case is still valid? I see no devres calls in the detach paths. I'm not sure what you mean by the attach/detach case. Do you expect device resources allocated in attach to be freed when detach run? Ah, never mind, the devres_release_all() would of course deal with that too. However, I just realized/remembered why it crashes. devm_mipi_dsi_device_register_full() and devm_mipi_dsi_attach() are given a device which is used for the devres. This device is probably always the bridge device. So when the bridge device goes away, so do those resources. The mipi_dsi_device_unregister() call deals with a DSI device, which was created in devm_mipi_dsi_device_register_full(). Unregistering that DSI device, which does happen when the DSI host is removed, does not affect the devres of the bridge. So, unloading the DSI host driver causes mipi_dsi_device_unregister() and mipi_dsi_detach() to be called (as part of mipi_dsi_host_unregister()), and unloading the bridge driver causes them to be called again via devres. Tomi
Re: [PATCH] drm/i915/gem: Suppress oom warning in favour of ENOMEM to userspace
On Wed, Jun 26, 2024 at 05:36:43PM +0200, Nirmoy Das wrote: >Hi Rodrigo, > > > >On 6/26/2024 5:24 PM, Rodrigo Vivi wrote: > > > >On Wed, Jun 26, 2024 at 04:33:18PM +0200, Nirmoy Das wrote: > > > >>We report object allocation failures to userspace with ENOMEM > >>so add __GFP_NOWARN to remove superfluous oom warnings. > > > >>Closes: [1]https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/4936 > >>Cc: Andi Shyti [2] > >>Signed-off-by: Nirmoy Das [3] > >>--- > >> drivers/gpu/drm/i915/i915_scatterlist.c | 8 > >> 1 file changed, 4 insertions(+), 4 deletions(-) > > > >>diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c > b/drivers/gpu/drm/i915/i915_scatterlist.c >>index e93d2538f298..4d830740946d 100644 > >>--- a/drivers/gpu/drm/i915/i915_scatterlist.c > >>+++ b/drivers/gpu/drm/i915/i915_scatterlist.c > >>@@ -90,7 +90,7 @@ struct i915_refct_sgt *i915_rsgt_from_mm_node(const > struct drm_mm_node *node, >> > >>GEM_BUG_ON(!max_segment); > >> > >>- rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL); > >>+ rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL | __GFP_NOWARN); > >>if (!rsgt) > >>return ERR_PTR(-ENOMEM); > > > >is it really safe? > >I don't believe we can guarantee a good fallback plan here if allocation > fails. >__i915_refct_sgt_init > >might end up in a null dereference, no?! > > > >Kernel is now returning ENOMEM and also throwing a oom warning stack. > >With __GFP_NOWARN > > > >the oom warning stack won't be there in the dmesg but userspace will still > >get ENOMEM as expected. > doh! I had missunderstand the flag. Thanks for the confirmation. Reviewed-by: Rodrigo Vivi BTW, what email clients are you using recently? it is hard to parse your responses lately. Please check if it is really sending/replying as text-only mode. > > >Let me know if got your question correctly. > > > >Regards, > > > >Nirmoy > > > > > > > >> > >>@@ -104,7 +104,7 @@ struct i915_refct_sgt *i915_rsgt_from_mm_node(const > struct drm_mm_node *node, >>} > >> > >>if (sg_alloc_table(st, DIV_ROUND_UP_ULL(node->size, > segment_pages), >>- GFP_KERNEL)) { > >>+
Re: (subset) [PATCH] backlight: lm3509_bl: Fix early returns in for_each_child_of_node()
On Mon, 24 Jun 2024 17:30:50 +0200, Javier Carrasco wrote: > The for_each_child_of_node() macro automatically decrements the child > refcount at the end of every iteration. On early exits, of_node_put() > must be used to manually decrement the refcount and avoid memory leaks. > > The scoped version of the macro accounts for such early breaks, fixing > the early exits without the need for explicit calls to of_node_put(). > > [...] Applied, thanks! [1/1] backlight: lm3509_bl: Fix early returns in for_each_child_of_node() commit: b337cc3ce47549528fc3ee0b8c7ebd33348a3126 -- Lee Jones [李琼斯]