RE: [PATCH 0/5] udmbuf bug fix and some improvements

2024-08-01 Thread Kasireddy, Vivek
Hi Huan,

> This patchset attempts to fix some errors in udmabuf and remove the
> upin_list structure.
> 
> Some of this fix just gather the patches which I upload before.
> 
> Patch1
> ===
> Try to remove page fault mmap and direct map it.
> Due to current udmabuf has already obtained and pinned the folio
> upon completion of the creation.This means that the physical memory has
> already been acquired, rather than being accessed dynamically. The
> current page fault method only saves some page table memory.
> 
> As a result, the page fault mechanism has lost its purpose as a demanding
> page. Due to the fact that page fault requires trapping into kernel mode
> and filling in when accessing the corresponding virtual address in mmap,
> this means that user mode access to virtual addresses needs to trap into
> kernel mode.
> 
> Therefore, when creating a large size udmabuf, this represents a
> considerable overhead.
Just want to mention that for the main use-case the udmabuf driver is designed 
for,
(sharing Qemu Guest FB with Host for GPU DMA), udmabufs are not created very
frequently. And, I think providing CPU access via mmap is just a backup, mainly
intended for debugging purposes.

> 
> Therefore, the current patch removes the page fault method of mmap and
> instead fills it directly when mmap is triggered.
> 
> This is achieved by using the scatter-gather table to establish a
> linear relationship for the page. Calling remap_pfn_range does not cause
> the previously set VMA flags to become invalid.
> 
> Patch2
> ===
> This is the same to patch:
> https://lore.kernel.org/all/20240725021349.580574-1-l...@vivo.com/
> I just gather it to this patchset.
> 
> Patch3
> ===
> The current implementation of udmabuf's vmap has issues.
> 
> It does not correctly set each page of the folio to the page structure,
> so that when vmap is called, all pages are the head page of the folio.
> 
> This implementation is not the same as this patch:
> https://lore.kernel.org/all/20240731090233.1343559-1-l...@vivo.com/
> 
> This reuse sgt table to map all page into vmalloc area.
> 
> Patch4
> ===
> Wrap the repeated calls to get_sg_table, add a helper function to do it.
> Set to udmabuf->sg use cmpxchg, It should be able to prevent concurrent
> access situations. (I see mmap do not use lock)
> 
> Patch5
> ===
> Attempt to remove unpin_list and other related data structures.
> 
> In order to adapt to Folio, we established the unpin_list data structure
> to unpin all folios and maintain the page mapping relationship.
> 
> However, this data structure requires 24 bytes for each page and has low
> traversal performance for the list. And maintaining the offset structure
> also consumes a portion of memory.
> 
> This patch attempts to remove these data structures and modify the
> semantics of some existing data structures.
> 
> udmabuf:
>   folios -> folios array, which only contain's the folio, org contains
> duplicate.
>   add item_offset -> base on create item count, record it's start offset
> in every memfd.
>   add item_size -> base on create item count, record it's size in every
> memfd.
>   add nr_folios -> folios array number
I am not sure if these changes improve the readability. Instead, I think it 
makes
sense to add comments to the existing code.

> 
> So, when building the sg table, it is necessary to iterate in this way:
>   if size cross item->size, take care of it's start offset in folio.
>   if got folio, set each page into sgl until reach into folio size.
> 
> This patch also remove single folios' create on each create item, use it
> be the ubuf->folios arrays' pointer, slide to fill the corresponding
> folio under the item into the array.
> 
> After the modification, the various data structures in udmabuf have the
> following corresponding relationships:
>   pagecount * PAGESIZE = sum(folios_size(folios[i])) i=0->nr_folios
>   pagecount * PAGESIZE = sum(item_size[i]) i=0, item_count (do not
> record)
>   item_offset use to record each memfd offset if exist, else 0.
> 
> Huan Yang (5):
>   udmabuf: cancel mmap page fault, direct map it
>   udmabuf: change folios array from kmalloc to kvmalloc
>   udmabuf: fix vmap_udmabuf error page set
Do you have a test-case to test this patch?

>   udmabuf: add get_sg_table helper function
>   udmabuf: remove folio pin list
Please run the newly added udmabuf selftests to make sure that these
patches are not causing any regressions. And, we also need to make sure that
the main use-cases (Qemu with memfd + shmem and Qemu with memfd + hugetlb)
are working as expected given the invasive changes. 

I'll be able to test and provide more detailed feedback on all patches once I 
am back from
vacation late next week.

Thanks,
Vivek 

> 
>  drivers/dma-buf/udmabuf.c | 270 +-
>  1 file changed, 148 insertions(+), 122 deletions(-)
> 
> 
> base-commit: cd19ac2f903276b820f5d0d89de0c896c27036ed
> --
> 2.45.2



[PATCH 2/2] drm/vmwgfx: Fix prime with external buffers

2024-08-01 Thread Zack Rusin
Make sure that for external buffers mapping goes through the dma_buf
interface instead of trying to access pages directly.

External buffers might not provide direct access to readable/writable
pages so to make sure the bo's created from external dma_bufs can be
read dma_buf interface has to be used.

Fixes crashes in IGT's kms_prime with vgem. Regular desktop usage won't
trigger this due to the fact that virtual machines will not have
multiple GPUs but it enables better test coverage in IGT.

Signed-off-by: Zack Rusin 
Fixes: b32233acceff ("drm/vmwgfx: Fix prime import/export")
Cc:  # v6.6+
Cc: Broadcom internal kernel review list 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v6.9+
---
 drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 112 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c |  12 +--
 3 files changed, 116 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
index 717d624e9a05..3140414d027e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
@@ -27,6 +27,8 @@
  **/
 
 #include "vmwgfx_drv.h"
+
+#include "vmwgfx_bo.h"
 #include 
 
 /*
@@ -420,13 +422,103 @@ static int vmw_bo_cpu_blit_line(struct 
vmw_bo_blit_line_data *d,
return 0;
 }
 
+static void *map_external(struct vmw_bo *bo, struct iosys_map *map)
+{
+   struct vmw_private *vmw =
+   container_of(bo->tbo.bdev, struct vmw_private, bdev);
+   void *ptr = NULL;
+   int ret;
+
+   if (bo->tbo.base.import_attach) {
+   ret = dma_buf_vmap(bo->tbo.base.dma_buf, map);
+   if (ret) {
+   drm_dbg_driver(>drm,
+  "Wasn't able to map external bo!\n");
+   goto out;
+   }
+   ptr = map->vaddr;
+   } else {
+   ptr = vmw_bo_map_and_cache(bo);
+   }
+
+out:
+   return ptr;
+}
+
+static void unmap_external(struct vmw_bo *bo, struct iosys_map *map)
+{
+   if (bo->tbo.base.import_attach)
+   dma_buf_vunmap(bo->tbo.base.dma_buf, map);
+   else
+   vmw_bo_unmap(bo);
+}
+
+static int vmw_external_bo_copy(struct vmw_bo *dst, u32 dst_offset,
+   u32 dst_stride, struct vmw_bo *src,
+   u32 src_offset, u32 src_stride,
+   u32 width_in_bytes, u32 height,
+   struct vmw_diff_cpy *diff)
+{
+   struct vmw_private *vmw =
+   container_of(dst->tbo.bdev, struct vmw_private, bdev);
+   size_t dst_size = dst->tbo.resource->size;
+   size_t src_size = src->tbo.resource->size;
+   struct iosys_map dst_map = {0};
+   struct iosys_map src_map = {0};
+   int ret, i;
+   u8 *vsrc;
+   u8 *vdst;
+
+   vsrc = map_external(src, _map);
+   if (!vsrc) {
+   drm_dbg_driver(>drm, "Wasn't able to map src\n");
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   vdst = map_external(dst, _map);
+   if (!vdst) {
+   drm_dbg_driver(>drm, "Wasn't able to map dst\n");
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   vsrc += src_offset;
+   vdst += dst_offset;
+   if (src_stride == dst_stride) {
+   dst_size -= dst_offset;
+   src_size -= src_offset;
+   memcpy(vdst, vsrc,
+  min(dst_stride * height, min(dst_size, src_size)));
+   } else {
+   WARN_ON(dst_stride < width_in_bytes);
+   for (i = 0; i < height; ++i) {
+   memcpy(vdst, vsrc, width_in_bytes);
+   vsrc += src_stride;
+   vdst += dst_stride;
+   }
+   }
+
+   diff->rect.y1 = dst_offset % dst_stride;
+   diff->rect.x1 = (dst_offset - dst_offset * diff->rect.y1) / diff->cpp;
+   diff->rect.x2 = diff->rect.x1 + width_in_bytes / diff->cpp;
+   diff->rect.y2 = diff->rect.y1 + height;
+
+   ret = 0;
+out:
+   unmap_external(src, _map);
+   unmap_external(dst, _map);
+
+   return ret;
+}
+
 /**
  * vmw_bo_cpu_blit - in-kernel cpu blit.
  *
- * @dst: Destination buffer object.
+ * @vmw_dst: Destination buffer object.
  * @dst_offset: Destination offset of blit start in bytes.
  * @dst_stride: Destination stride in bytes.
- * @src: Source buffer object.
+ * @vmw_src: Source buffer object.
  * @src_offset: Source offset of blit start in bytes.
  * @src_stride: Source stride in bytes.
  * @w: Width of blit.
@@ -444,13 +536,15 @@ static int vmw_bo_cpu_blit_line(struct 
vmw_bo_blit_line_data *d,
  * Neither of the buffer objects may be placed in PCI memory
  * (Fixed memory in TTM terminology) when using this function.
  */
-int vmw_bo_cpu_blit(struct 

[PATCH 1/2] drm/vmwgfx: Prevent unmapping active read buffers

2024-08-01 Thread Zack Rusin
The kms paths keep a persistent map active to read and compare the cursor
buffer. These maps can race with each other in simple scenario where:
a) buffer "a" mapped for update
b) buffer "a" mapped for compare
c) do the compare
d) unmap "a" for compare
e) update the cursor
f) unmap "a" for update
At step "e" the buffer has been unmapped and the read contents is bogus.

Prevent unmapping of active read buffers by simply keeping a count of
how many paths have currently active maps and unmap only when the count
reaches 0.

Fixes: 485d98d472d5 ("drm/vmwgfx: Add support for CursorMob and CursorBypass 4")
Cc: Broadcom internal kernel review list 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v5.19+
Signed-off-by: Zack Rusin 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 13 +++--
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h |  1 +
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index f42ebc4a7c22..a0e433fbcba6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -360,6 +360,8 @@ void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t 
size)
void *virtual;
int ret;
 
+   atomic_inc(>map_count);
+
virtual = ttm_kmap_obj_virtual(>map, _used);
if (virtual)
return virtual;
@@ -383,11 +385,17 @@ void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, 
size_t size)
  */
 void vmw_bo_unmap(struct vmw_bo *vbo)
 {
+   int map_count;
+
if (vbo->map.bo == NULL)
return;
 
-   ttm_bo_kunmap(>map);
-   vbo->map.bo = NULL;
+   map_count = atomic_dec_return(>map_count);
+
+   if (!map_count) {
+   ttm_bo_kunmap(>map);
+   vbo->map.bo = NULL;
+   }
 }
 
 
@@ -421,6 +429,7 @@ static int vmw_bo_init(struct vmw_private *dev_priv,
vmw_bo->tbo.priority = 3;
vmw_bo->res_tree = RB_ROOT;
xa_init(_bo->detached_resources);
+   atomic_set(_bo->map_count, 0);
 
params->size = ALIGN(params->size, PAGE_SIZE);
drm_gem_private_object_init(vdev, _bo->tbo.base, params->size);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
index 62b4342d5f7c..dc13f1e996c1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
@@ -90,6 +90,7 @@ struct vmw_bo {
u32 res_prios[TTM_MAX_BO_PRIORITY];
struct xarray detached_resources;
 
+   atomic_t map_count;
atomic_t cpu_writers;
/* Not ref-counted.  Protected by binding_mutex */
struct vmw_resource *dx_query_ctx;
-- 
2.43.0



[PATCH v2] drm: Add documentation for struct drm_pane_size_hint

2024-08-01 Thread abid-sayyad
Fixed warning for the following:
./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member
'width' not described in 'drm_plane_size_hint'
./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member
'height' not described in 'drm_plane_size_hint'

Signed-off-by: abid-sayyad 
---
My sincere apologies for the spam and the patch subject error
Changes in v2:
- Adress review feedback regarding indentation in the fix
- Link to v1
https://lore.kernel.org/all/20240801102239.572718-1-sayyad.abi...@gmail.com/

 include/uapi/drm/drm_mode.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index d390011b89b4..9d398335d871 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -864,7 +864,13 @@ struct drm_color_lut {
  * array of struct drm_plane_size_hint.
  */
 struct drm_plane_size_hint {
+   /**
+* @width: width of the plane in pixels.
+*/
__u16 width;
+   /**
+* @height: height of the plane in pixels.
+*/
__u16 height;
 };

--
2.39.2



[PATCH] [PATCH v2] drm: Add documentation for struct drm_pane_size_hint

2024-08-01 Thread abid-sayyad
Fixed warning for the following:
./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member
'width' not described in 'drm_plane_size_hint'
./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member
'height' not described in 'drm_plane_size_hint'

Signed-off-by: abid-sayyad 
---
Changes in v2:
- Adress review feedback regarding indentation in the fix
- Link to v1
https://lore.kernel.org/all/20240801102239.572718-1-sayyad.abi...@gmail.com/

 include/uapi/drm/drm_mode.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index d390011b89b4..9d398335d871 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -864,7 +864,13 @@ struct drm_color_lut {
  * array of struct drm_plane_size_hint.
  */
 struct drm_plane_size_hint {
+   /**
+* @width: width of the plane in pixels.
+*/
__u16 width;
+   /**
+* @height: height of the plane in pixels.
+*/
__u16 height;
 };

--
2.39.2



Re: [PATCH] drm: bridge: adv7511: Accept audio sample widths of 32 bits via I2S

2024-08-01 Thread Laurent Pinchart
On Mon, Jul 29, 2024 at 10:15:55AM +0200, Ricard Wanderlof wrote:
> 
> Hi,
> 
> I submitted the patch below a while ago (two months) but as far as I can 
> make out it has not been included. There was an initial concern from 
> Dmitry Baryshkov which was subsequently addressed but no other objections. 
> 
> On Tue, 28 May 2024, Ricard Wanderlof wrote:
> 
> > 
> > Even though data is truncated to 24 bits, the I2S interface does
> > accept 32 bit data (the slot widths according to the data sheet
> > can be 16 or 32 bits) so let the hw_params callback reflect this,
> > even if the lowest 8 bits are not used when 32 bits are specified.
> > 
> > This is normally how 24 bit audio data is handled (i.e. as 32 bit
> > data, with the LSB:s unused) and this is also reflected in other
> > bridge drivers which handle audio, for instance sii902x.c and
> > synopsis/dw-hdmi-i2s-audio.c .
> > 
> > Signed-off-by: Ricard Wanderlof 
> > ---
> >  drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 11 +++
> >  1 file changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c 
> > b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
> > index 61f4a38e7d2b..4563f5d8136f 100644
> > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
> > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
> > @@ -101,11 +101,14 @@ static int adv7511_hdmi_hw_params(struct device *dev, 
> > void *data,
> > case 20:
> > len = ADV7511_I2S_SAMPLE_LEN_20;
> > break;
> > -   case 32:
> > -   if (fmt->bit_fmt != SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
> > -   return -EINVAL;
> > -   fallthrough;
> > case 24:
> > +   case 32:
> > +   /*
> > +* 32 bits are handled like 24 bits, except that the lowest
> > +* 8 bits are discarded. In fact, the accepted I2S slot widths
> > +* are 16 and 32 bits, so the chip is fully compatible with
> > +* 32 bit data.
> > +*/
> > len = ADV7511_I2S_SAMPLE_LEN_24;
> > break;
> > default:
> 
> I recently discovered that the maintainer for the ADV7511 driver (in the 
> I2C) framework is not included by the get_maintainers script, so perhaps 
> this is the reason?
> 
> Otherwise, please enlighten me on what I need to do to get this patch 
> accepted!

I have no experience with HDMI audio, so I didn't comment on your patch.

Hans, is this within your area of expertise ?

-- 
Regards,

Laurent Pinchart


[Bug 219117] amdgpu: amdgpu_device_ip_init failed

2024-08-01 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=219117

Artem S. Tashkinov (a...@gmx.com) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |ANSWERED

--- Comment #1 from Artem S. Tashkinov (a...@gmx.com) ---
Please report here instead: https://gitlab.freedesktop.org/drm/amd/-/issues

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 219118] Linux 6.10.x [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx timeout VM fault / GPU fault detected

2024-08-01 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=219118

Artem S. Tashkinov (a...@gmx.com) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |ANSWERED

--- Comment #1 from Artem S. Tashkinov (a...@gmx.com) ---
Please report here instead: https://gitlab.freedesktop.org/drm/amd/-/issues

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH 0/2] Use pcim_request_region() in vboxvideo

2024-08-01 Thread Bjorn Helgaas
On Mon, Jul 29, 2024 at 11:36:24AM +0200, Philipp Stanner wrote:
> Hi everyone,
> 
> Now that we've got the simplified PCI devres API available we can slowly
> start using it in drivers and step by step phase the more problematic
> API out.
> 
> vboxvideo currently does not have a region request, so it is a suitable
> first user.
> 
> P.
> 
> Philipp Stanner (2):
>   PCI: Make pcim_request_region() a public function
>   drm/vboxvideo: Add PCI region request
> 
>  drivers/gpu/drm/vboxvideo/vbox_main.c | 4 
>  drivers/pci/devres.c  | 1 +
>  drivers/pci/pci.h | 2 --
>  include/linux/pci.h   | 1 +
>  4 files changed, 6 insertions(+), 2 deletions(-)

Applied with Hans' ack to pci/devres for v6.12, thanks!


Re: [PATCH 0/2] Add MSM8996/MSM8953 dpu catalog

2024-08-01 Thread Barnabás Czémán
Should i resend this patch set?

On June 28, 2024 4:39:38 PM GMT+02:00, "Barnabás Czémán" 
 wrote:
>This patch series add dpu support for MSM8996/MSM8953 devices.
>
>Note, by default these platforms are still handled by the MDP5 driver
>unless the `msm.prefer_mdp5=false' parameter is provided.
>
>Signed-off-by: Barnabás Czémán 
>---
>Dmitry Baryshkov (1):
>  drm/msm/dpu: add support for MSM8953
>
>Konrad Dybcio (1):
>  drm/msm/dpu: Add MSM8996 support
>
> .../drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h   | 218 +
> .../drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h| 348 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 106 +++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   2 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   2 +
> drivers/gpu/drm/msm/msm_drv.c  |   2 +
> 6 files changed, 678 insertions(+)
>---
>base-commit: df9574a57d02b265322e77fb8628d4d33641dda9
>change-id: 20240528-dpu-msm8953-msm8996-5d0fb7e387b8
>
>Best regards,


[Bug 219118] New: Linux 6.10.x [drm:amdgpu_job_timedout [amdgpu]] *ERROR* ring gfx timeout VM fault / GPU fault detected

2024-08-01 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=219118

Bug ID: 219118
   Summary: Linux 6.10.x [drm:amdgpu_job_timedout [amdgpu]]
*ERROR* ring gfx timeout VM fault / GPU fault detected
   Product: Drivers
   Version: 2.5
  Hardware: All
OS: Linux
Status: NEW
  Severity: high
  Priority: P3
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: mjevans1...@gmail.com
Regression: No

I'm not sure if this should be filed under Console/Framebuffers, Video(DRI -
non Intel), or Video(Other).

I thought I'd created the bug in the correct location,
https://gitlab.freedesktop.org/drm/amd/-/issues/3510 but no maintainer has
commented or otherwise notably interacted with the report.  Initially I thought
it was just an MPV bug since VLC didn't trigger the issue
https://github.com/mpv-player/mpv/issues/14600 .

It looks like a developer's personal(?) drm-fixes-6.11 branch cherry picked the
commit that appeared to fix the issue completely for my test cases:
https://gitlab.freedesktop.org/agd5f/linux/-/commit/f3572db3c049b4d32bb5ba77ad5305616c44c7c1

However that isn't for the earlier 6.10.x series which also needs the fix,
unless it's dead.

This appears to be a Swiss cheese sort of bug situation.  If software
requests/provides contiguous buffers then the error results are more subtle,
such as momentary video corruption if the kernel's access isn't out of bounds
but rather rarely scrambled.  It's only when both the userspace and driver
don't enforce contiguous buffer segments that out of bounds accesses result in
a GPU reset and consequently terminated userspace.


ArchLinux (rolling release)
Linux 6.10.1-arch1-1 #1 (closed) SMP PREEMPT_DYNAMIC Wed, 24 Jul 2024 22:25:43
+ x86_64 GNU/Linux
amdgpu + OpenGL version string: 4.6 (Compatibility Profile) Mesa 24.1.4-arch1.2
ArchLinux current stable builds


[ 1766.321165] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x0a22c802
[ 1766.321171] amdgpu :01:00.0: amdgpu:  for process plasmashell pid 2961
thread plasmashel:cs0 pid 3007
[ 1766.321172] amdgpu :01:00.0: amdgpu:   VM_CONTEXT1_PROTECTION_FAULT_ADDR
  0x00101F44
[ 1766.321174] amdgpu :01:00.0: amdgpu:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B0C8002
[ 1766.321175] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid
32772) at page 1056580, write from 'TC3' (0x54433300) (200)
[ 1766.321237] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x07f2a002
[ 1766.321238] amdgpu :01:00.0: amdgpu:  for process plasmashell pid 2961
thread plasmashel:cs0 pid 3007
[ 1766.321239] amdgpu :01:00.0: amdgpu:   VM_CONTEXT1_PROTECTION_FAULT_ADDR
  0x0010120C
[ 1766.321240] amdgpu :01:00.0: amdgpu:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B020002
[ 1766.321241] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid
32772) at page 1053196, write from 'CB2' (0x43423200) (32)
[ 1766.321244] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x07b29002
[ 1766.321245] amdgpu :01:00.0: amdgpu:  for process plasmashell pid 2961
thread plasmashel:cs0 pid 3007
[ 1766.321247] amdgpu :01:00.0: amdgpu:   VM_CONTEXT1_PROTECTION_FAULT_ADDR
  0x00101237
[ 1766.321247] amdgpu :01:00.0: amdgpu:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B010002
[ 1766.321248] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid
32772) at page 1053239, write from 'CB3' (0x43423300) (16)
[ 1766.321255] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x0772e002
[ 1766.321256] amdgpu :01:00.0: amdgpu:  for process plasmashell pid 2961
thread plasmashel:cs0 pid 3007
[ 1766.321257] amdgpu :01:00.0: amdgpu:   VM_CONTEXT1_PROTECTION_FAULT_ADDR
  0x00101200
[ 1766.321258] amdgpu :01:00.0: amdgpu:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B0A0002
[ 1766.321258] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid
32772) at page 1053184, write from 'CB4' (0x43423400) (160)
[ 1766.321262] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x0772d002
[ 1766.321263] amdgpu :01:00.0: amdgpu:  for process plasmashell pid 2961
thread plasmashel:cs0 pid 3007
[ 1766.321264] amdgpu :01:00.0: amdgpu:   VM_CONTEXT1_PROTECTION_FAULT_ADDR
  0x00101232
[ 1766.321264] amdgpu :01:00.0: amdgpu:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B0A0002
[ 1766.321265] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid
32772) at page 1053234, write from 'CB4' (0x43423400) (160)
[ 1766.321268] amdgpu :01:00.0: amdgpu: GPU fault detected: 147 0x07729002
[ 1766.321269] amdgpu :01:00.0: amdgpu:  for process plasmashell pid 2961
thread plasmashel:cs0 pid 3007
[ 1766.321271] amdgpu :01:00.0: amdgpu:   VM_CONTEXT1_PROTECTION_FAULT_ADDR
  0x0010123A
[ 1766.321271] amdgpu :01:00.0: amdgpu:  
VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x0B050002
[ 1766.321272] amdgpu :01:00.0: amdgpu: VM fault (0x02, vmid 5, pasid
32772) at 

Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage

2024-08-01 Thread Connor Abbott
On Thu, Aug 1, 2024 at 3:26 PM Vladimir Lypak  wrote:
>
> On Thu, Aug 01, 2024 at 01:52:32PM +0100, Connor Abbott wrote:
> > On Thu, Aug 1, 2024 at 1:25 PM Vladimir Lypak  
> > wrote:
> > >
> > > On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote:
> > > > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak
> > > >  wrote:
> > > > >
> > > > > On A5XX GPUs when preemption is used it's invietable to enter a soft
> > > > > lock-up state in which GPU is stuck at empty ring-buffer doing 
> > > > > nothing.
> > > > > This appears as full UI lockup and not detected as GPU hang (because
> > > > > it's not). This happens due to not triggering preemption when it was
> > > > > needed. Sometimes this state can be recovered by some new submit but
> > > > > generally it won't happen because applications are waiting for old
> > > > > submits to retire.
> > > > >
> > > > > One of the reasons why this happens is a race between a5xx_submit and
> > > > > a5xx_preempt_trigger called from IRQ during submit retire. Former 
> > > > > thread
> > > > > updates ring->cur of previously empty and not current ring right after
> > > > > latter checks it for emptiness. Then both threads can just exit 
> > > > > because
> > > > > for first one preempt_state wasn't NONE yet and for second one all 
> > > > > rings
> > > > > appeared to be empty.
> > > > >
> > > > > To prevent such situations from happening we need to establish 
> > > > > guarantee
> > > > > for preempt_trigger to be called after each submit. To implement it 
> > > > > this
> > > > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if 
> > > > > we
> > > > > should switch to non-empty or higher priority ring. Also we find next
> > > > > ring in new preemption state "EVALUATE". If the thread that updated 
> > > > > some
> > > > > ring with new submit sees this state it should wait until it passes.
> > > > >
> > > > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
> > > > > Signed-off-by: Vladimir Lypak 
> > > > > ---
> > > > >  drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  6 +++---
> > > > >  drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++
> > > > >  drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 
> > > > > +++
> > > > >  3 files changed, 30 insertions(+), 11 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> > > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > > > index 6c80d3003966..266744ee1d5f 100644
> > > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu 
> > > > > *gpu, struct msm_gem_submit *submit
> > > > > }
> > > > >
> > > > > a5xx_flush(gpu, ring, true);
> > > > > -   a5xx_preempt_trigger(gpu);
> > > > > +   a5xx_preempt_trigger(gpu, true);
> > > > >
> > > > > /* we might not necessarily have a cmd from userspace to
> > > > >  * trigger an event to know that submit has completed, so
> > > > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, 
> > > > > struct msm_gem_submit *submit)
> > > > > a5xx_flush(gpu, ring, false);
> > > > >
> > > > > /* Check to see if we need to start preemption */
> > > > > -   a5xx_preempt_trigger(gpu);
> > > > > +   a5xx_preempt_trigger(gpu, true);
> > > > >  }
> > > > >
> > > > >  static const struct adreno_five_hwcg_regs {
> > > > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
> > > > > a5xx_gpmu_err_irq(gpu);
> > > > >
> > > > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) {
> > > > > -   a5xx_preempt_trigger(gpu);
> > > > > +   a5xx_preempt_trigger(gpu, false);
> > > > > msm_gpu_retire(gpu);
> > > > > }
> > > > >
> > > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h 
> > > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > > > index c7187bcc5e90..1120824853d4 100644
> > > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, 
> > > > > struct drm_minor *minor);
> > > > >   * through the process.
> > > > >   *
> > > > >   * PREEMPT_NONE - no preemption in progress.  Next state START.
> > > > > - * PREEMPT_START - The trigger is evaulating if preemption is 
> > > > > possible. Next
> > > > > - * states: TRIGGERED, NONE
> > > > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is 
> > > > > possible. Next
> > > > > + * states: START, ABORT
> > > > >   * PREEMPT_ABORT - An intermediate state before moving back to NONE. 
> > > > > Next
> > > > >   * state: NONE.
> > > > > + * PREEMPT_START - The trigger is preparing for preemption. Next 
> > > > > state:
> > > > > + * TRIGGERED
> > > > >   * PREEMPT_TRIGGERED: A preemption has been executed on the 
> > > > > hardware. Next
> > 

[PATCH] drm/i915/gt: Delete sysfs entries for engines on driver unload

2024-08-01 Thread Krzysztof Niemiec
While the sysfs entries for engines are added in intel_engines_init()
during driver load, the corresponding function intel_engines_release()
does not correctly get rid of them. This can lead to a UAF if, after
failed initialization (for example when gt is set wedged on init), we
try to access the engines.

Empty the engines llist in intel_engines_release().

Suggested-by: Chris Wilson 
Signed-off-by: Krzysztof Niemiec 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 3b740ca25000..4d30a86016f2 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -693,6 +693,8 @@ void intel_engines_release(struct intel_gt *gt)
 
memset(>reset, 0, sizeof(engine->reset));
}
+
+   llist_del_all(>i915->uabi_engines_llist);
 }
 
 void intel_engine_free_request_pool(struct intel_engine_cs *engine)
-- 
2.45.2



[PATCH v5 2/3] drm/printer: Allow NULL data in devcoredump printer

2024-08-01 Thread Matthew Brost
We want to determine the size of the devcoredump before writing it out.
To that end, we will run the devcoredump printer with NULL data to get
the size, alloc data based on the generated offset, then run the
devcorecump again with a valid data pointer to print.  This necessitates
not writing data to the data pointer on the initial pass, when it is
NULL.

v5:
 - Better commit message (Jonathan)
 - Add kerenl doc with examples (Jani)

Cc: Maarten Lankhorst 
Acked-by: Maarten Lankhorst 
Signed-off-by: Matthew Brost 
Reviewed-by: Jonathan Cavitt 
---
 drivers/gpu/drm/drm_print.c | 13 +
 include/drm/drm_print.h | 54 -
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index cf24dfdeb6b2..a1a4de9f9c44 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char 
*str)
copy = iterator->remain;
 
/* Copy out the bit of the string that we need */
-   memcpy(iterator->data,
-   str + (iterator->start - iterator->offset), copy);
+   if (iterator->data)
+   memcpy(iterator->data,
+   str + (iterator->start - iterator->offset), 
copy);
 
iterator->offset = iterator->start + copy;
iterator->remain -= copy;
@@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char 
*str)
 
len = min_t(ssize_t, strlen(str), iterator->remain);
 
-   memcpy(iterator->data + pos, str, len);
+   if (iterator->data)
+   memcpy(iterator->data + pos, str, len);
 
iterator->offset += len;
iterator->remain -= len;
@@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct 
va_format *vaf)
if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
ssize_t pos = iterator->offset - iterator->start;
 
-   snprintf(((char *) iterator->data) + pos,
-   iterator->remain, "%pV", vaf);
+   if (iterator->data)
+   snprintf(((char *) iterator->data) + pos,
+   iterator->remain, "%pV", vaf);
 
iterator->offset += len;
iterator->remain -= len;
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 5d9dff5149c9..d2676831d765 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -221,7 +221,8 @@ drm_vprintf(struct drm_printer *p, const char *fmt, va_list 
*va)
 
 /**
  * struct drm_print_iterator - local struct used with drm_printer_coredump
- * @data: Pointer to the devcoredump output buffer
+ * @data: Pointer to the devcoredump output buffer, can be NULL if using
+ * drm_printer_coredump to determine size of devcoredump
  * @start: The offset within the buffer to start writing
  * @remain: The number of bytes to write for this iteration
  */
@@ -266,6 +267,57 @@ struct drm_print_iterator {
  * coredump_read, ...)
  * }
  *
+ * The above example has a time complexity of O(N^2), where N is the size of 
the
+ * devcoredump. This is acceptable for small devcoredumps but scales poorly for
+ * larger ones.
+ *
+ * Another use case for drm_coredump_printer is to capture the devcoredump into
+ * a saved buffer before the dev_coredump() callback. This involves two passes:
+ * one to determine the size of the devcoredump and another to print it to a
+ * buffer. Then, in dev_coredump(), copy from the saved buffer into the
+ * devcoredump read buffer.
+ *
+ * For example::
+ *
+ * char *devcoredump_saved_buffer;
+ *
+ * ssize_t __coredump_print(char *buffer, ssize_t count, ...)
+ * {
+ * struct drm_print_iterator iter;
+ * struct drm_printer p;
+ *
+ * iter.data = buffer;
+ * iter.start = 0;
+ * iter.remain = count;
+ *
+ * p = drm_coredump_printer();
+ *
+ * drm_printf(p, "foo=%d\n", foo);
+ * ...
+ * return count - iter.remain;
+ * }
+ *
+ * void coredump_print(...)
+ * {
+ * ssize_t count;
+ *
+ * count = __coredump_print(NULL, INT_MAX, ...);
+ * devcoredump_saved_buffer = kvmalloc(count, GFP_KERNEL);
+ * __coredump_print(devcoredump_saved_buffer, count, ...);
+ * }
+ *
+ * void coredump_read(char *buffer, loff_t offset, size_t count,
+ *void *data, size_t datalen)
+ * {
+ * ...
+ * memcpy(buffer, devcoredump_saved_buffer + offset, count);
+ * ...
+ * }
+ *
+ * The above example has a time complexity of O(N*2), where N is the size of 
the
+ * devcoredump. This scales better than the previous example for 

[PATCH v5 3/3] drm/xe: Faster devcoredump

2024-08-01 Thread Matthew Brost
The current algorithm to read out devcoredump is O(N*N) where N is the
size of coredump due to usage of the drm_coredump_printer in
xe_devcoredump_read. Switch to a O(N) algorithm which prints the
devcoredump into a readable format in snapshot work and update
xe_devcoredump_read to memcpy from the readable format directly.

v2:
 - Fix double free on devcoredump removal (Testing)
 - Set read_data_size after snap work flush
 - Adjust remaining in iterator upon realloc (Testing)
 - Set read_data upon realloc (Testing)
v3:
 - Kernel doc
v4:
 - Two pass algorithm to determine size (Maarten)
v5:
 - Use scope for reading variables (Johnathan)

Reported-by: Paulo Zanoni 
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/2408
Cc: Rodrigo Vivi 
Cc: Maarten Lankhorst 
Signed-off-by: Matthew Brost 
Reviewed-by: Jonathan Cavitt 
---
 drivers/gpu/drm/xe/xe_devcoredump.c   | 111 --
 drivers/gpu/drm/xe/xe_devcoredump_types.h |   8 ++
 2 files changed, 88 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c 
b/drivers/gpu/drm/xe/xe_devcoredump.c
index d8d8ca2c19d3..bdb76e834e4c 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -66,22 +66,9 @@ static struct xe_guc *exec_queue_to_guc(struct xe_exec_queue 
*q)
return >gt->uc.guc;
 }
 
-static void xe_devcoredump_deferred_snap_work(struct work_struct *work)
-{
-   struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), 
work);
-
-   /* keep going if fw fails as we still want to save the memory and SW 
data */
-   if (xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL))
-   xe_gt_info(ss->gt, "failed to get forcewake for coredump 
capture\n");
-   xe_vm_snapshot_capture_delayed(ss->vm);
-   xe_guc_exec_queue_snapshot_capture_delayed(ss->ge);
-   xe_force_wake_put(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL);
-}
-
-static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
-  size_t count, void *data, size_t datalen)
+static ssize_t __xe_devcoredump_read(char *buffer, size_t count,
+struct xe_devcoredump *coredump)
 {
-   struct xe_devcoredump *coredump = data;
struct xe_device *xe;
struct xe_devcoredump_snapshot *ss;
struct drm_printer p;
@@ -89,18 +76,11 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t 
offset,
struct timespec64 ts;
int i;
 
-   if (!coredump)
-   return -ENODEV;
-
xe = coredump_to_xe(coredump);
ss = >snapshot;
 
-   /* Ensure delayed work is captured before continuing */
-   flush_work(>work);
-
iter.data = buffer;
-   iter.offset = 0;
-   iter.start = offset;
+   iter.start = 0;
iter.remain = count;
 
p = drm_coredump_printer();
@@ -134,10 +114,83 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t 
offset,
return count - iter.remain;
 }
 
+static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
+{
+   int i;
+
+   xe_guc_ct_snapshot_free(ss->ct);
+   ss->ct = NULL;
+
+   xe_guc_exec_queue_snapshot_free(ss->ge);
+   ss->ge = NULL;
+
+   xe_sched_job_snapshot_free(ss->job);
+   ss->job = NULL;
+
+   for (i = 0; i < XE_NUM_HW_ENGINES; i++)
+   if (ss->hwe[i]) {
+   xe_hw_engine_snapshot_free(ss->hwe[i]);
+   ss->hwe[i] = NULL;
+   }
+
+   xe_vm_snapshot_free(ss->vm);
+   ss->vm = NULL;
+}
+
+static void xe_devcoredump_deferred_snap_work(struct work_struct *work)
+{
+   struct xe_devcoredump_snapshot *ss = container_of(work, typeof(*ss), 
work);
+   struct xe_devcoredump *coredump = container_of(ss, typeof(*coredump), 
snapshot);
+
+   /* keep going if fw fails as we still want to save the memory and SW 
data */
+   if (xe_force_wake_get(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL))
+   xe_gt_info(ss->gt, "failed to get forcewake for coredump 
capture\n");
+   xe_vm_snapshot_capture_delayed(ss->vm);
+   xe_guc_exec_queue_snapshot_capture_delayed(ss->ge);
+   xe_force_wake_put(gt_to_fw(ss->gt), XE_FORCEWAKE_ALL);
+
+   /* Calculate devcoredump size */
+   ss->read.size = __xe_devcoredump_read(NULL, INT_MAX, coredump);
+
+   ss->read.buffer = kvmalloc(ss->read.size, GFP_USER);
+   if (!ss->read.buffer)
+   return;
+
+   __xe_devcoredump_read(ss->read.buffer, ss->read.size, coredump);
+   xe_devcoredump_snapshot_free(ss);
+}
+
+static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
+  size_t count, void *data, size_t datalen)
+{
+   struct xe_devcoredump *coredump = data;
+   struct xe_devcoredump_snapshot *ss;
+   ssize_t byte_copied;
+
+   if (!coredump)
+   return -ENODEV;
+
+   ss = >snapshot;
+
+   /* Ensure delayed work is 

[PATCH v5 1/3] drm/xe: Take ref to VM in delayed snapshot

2024-08-01 Thread Matthew Brost
Kernel BO's don't take a ref to the VM, we need the VM for the
delayed snapshot, so take a ref to the VM in delayed snapshot.

v2:
 - Check for lrc_bo before taking a VM ref (CI)
 - Check lrc_bo->vm before taking / dropping a VM ref (CI)
 - Drop VM in xe_lrc_snapshot_free
v5:
 - Fix commit message wording (Johnathan)

47058633d9c5 ("drm/xe: Move lrc snapshot capturing to xe_lrc.c")
Cc: Cc: Maarten Lankhorst 
Signed-off-by: Matthew Brost 
Reviewed-by: Jonathan Cavitt 
---
 drivers/gpu/drm/xe/xe_lrc.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index 94ff62e1d95e..58121821f081 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -1634,6 +1634,9 @@ struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct 
xe_lrc *lrc)
if (!snapshot)
return NULL;
 
+   if (lrc->bo && lrc->bo->vm)
+   xe_vm_get(lrc->bo->vm);
+
snapshot->context_desc = xe_lrc_ggtt_addr(lrc);
snapshot->indirect_context_desc = xe_lrc_indirect_ring_ggtt_addr(lrc);
snapshot->head = xe_lrc_ring_head(lrc);
@@ -1653,12 +1656,14 @@ struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct 
xe_lrc *lrc)
 void xe_lrc_snapshot_capture_delayed(struct xe_lrc_snapshot *snapshot)
 {
struct xe_bo *bo;
+   struct xe_vm *vm;
struct iosys_map src;
 
if (!snapshot)
return;
 
bo = snapshot->lrc_bo;
+   vm = bo->vm;
snapshot->lrc_bo = NULL;
 
snapshot->lrc_snapshot = kvmalloc(snapshot->lrc_size, GFP_KERNEL);
@@ -1678,6 +1683,8 @@ void xe_lrc_snapshot_capture_delayed(struct 
xe_lrc_snapshot *snapshot)
xe_bo_unlock(bo);
 put_bo:
xe_bo_put(bo);
+   if (vm)
+   xe_vm_put(vm);
 }
 
 void xe_lrc_snapshot_print(struct xe_lrc_snapshot *snapshot, struct 
drm_printer *p)
@@ -1727,8 +1734,14 @@ void xe_lrc_snapshot_free(struct xe_lrc_snapshot 
*snapshot)
return;
 
kvfree(snapshot->lrc_snapshot);
-   if (snapshot->lrc_bo)
+   if (snapshot->lrc_bo) {
+   struct xe_vm *vm;
+
+   vm = snapshot->lrc_bo->vm;
xe_bo_put(snapshot->lrc_bo);
+   if (vm)
+   xe_vm_put(vm);
+   }
kfree(snapshot);
 }
 
-- 
2.34.1



[PATCH v5 0/3] Faster devcoredump and fixes

2024-08-01 Thread Matthew Brost
Combine [1] [2] for complete series to speedup devcoredump and fix it.

[1] https://patchwork.freedesktop.org/series/136541/
[2] https://patchwork.freedesktop.org/series/136545/

Matthew Brost (3):
  drm/xe: Take ref to VM in delayed snapshot
  drm/printer: Allow NULL data in devcoredump printer
  drm/xe: Faster devcoredump

 drivers/gpu/drm/drm_print.c   |  13 ++-
 drivers/gpu/drm/xe/xe_devcoredump.c   | 111 --
 drivers/gpu/drm/xe/xe_devcoredump_types.h |   8 ++
 drivers/gpu/drm/xe/xe_lrc.c   |  15 ++-
 include/drm/drm_print.h   |  54 ++-
 5 files changed, 163 insertions(+), 38 deletions(-)

-- 
2.34.1



Re: [PATCH 0/2] Use pcim_request_region() in vboxvideo

2024-08-01 Thread Hans de Goede
Hi Bjorn,

On 7/31/24 9:36 PM, Bjorn Helgaas wrote:
> On Mon, Jul 29, 2024 at 11:36:24AM +0200, Philipp Stanner wrote:
>> Hi everyone,
>>
>> Now that we've got the simplified PCI devres API available we can slowly
>> start using it in drivers and step by step phase the more problematic
>> API out.
>>
>> vboxvideo currently does not have a region request, so it is a suitable
>> first user.
>>
>> P.
>>
>> Philipp Stanner (2):
>>   PCI: Make pcim_request_region() a public function
>>   drm/vboxvideo: Add PCI region request
>>
>>  drivers/gpu/drm/vboxvideo/vbox_main.c | 4 
>>  drivers/pci/devres.c  | 1 +
>>  drivers/pci/pci.h | 2 --
>>  include/linux/pci.h   | 1 +
>>  4 files changed, 6 insertions(+), 2 deletions(-)
> 
> Given an ack from the vboxvideo maintainers, I can apply both of these
> via the PCI tree so there's no race during the merge window.

I'm the vboxvideo maintainer, merging both through the PCI tree
sounds good to me:

Acked-by: Hans de Goede 

Regards,

Hans






Re: [PATCH 0/2] Use pcim_request_region() in vboxvideo

2024-08-01 Thread Hans de Goede
Hi,

On 7/29/24 11:36 AM, Philipp Stanner wrote:
> Hi everyone,
> 
> Now that we've got the simplified PCI devres API available we can slowly
> start using it in drivers and step by step phase the more problematic
> API out.
> 
> vboxvideo currently does not have a region request, so it is a suitable
> first user.

I have given both patches a test-run on top of 6.11-rc1 in a VirtualBox
VM using the vboxsvga virtual vga card:

Tested-by: Hans de Goede 

Also both patches look good to me:

Reviewed-by: Hans de Goede 

for the series.

Regards,

Hans





Re: [PATCH v2 2/3] drm/rockchip: Explicitly include bits header

2024-08-01 Thread Krzysztof Kozlowski
On 01/08/2024 04:25, Cristian Ciocaltea wrote:
> Driver makes use of the BIT() macro, but relies on the bits header being
> implicitly included.
> 
> Explicitly pull the header in to avoid potential build failures in some
> configurations.
> 
> While at it, reorder include directives alphabetically.
> 
> Fixes: 8c8546546f25 ("drm/rockchip: move output interface related definition 
> to rockchip_drm_drv.h")

There is no bug here to be fixed. Drop. Especially bugfixes should not
be combined with cleanups.

Best regards,
Krzysztof



Re: [PATCH v2 1/3] dt-bindings: display: rockchip: Add schema for RK3588 HDMI TX Controller

2024-08-01 Thread Krzysztof Kozlowski
On 01/08/2024 11:50, Cristian Ciocaltea wrote:
> On 8/1/24 6:37 AM, Rob Herring (Arm) wrote:
>>
>> On Thu, 01 Aug 2024 05:25:52 +0300, Cristian Ciocaltea wrote:
>>> Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1
>>> Quad-Pixel (QP) TX controller IP.
>>>
>>> Since this is a new IP block, quite different from those used in the
>>> previous generations of Rockchip SoCs, add a dedicated binding file.
>>>
>>> Signed-off-by: Cristian Ciocaltea 
>>> ---
>>>  .../display/rockchip/rockchip,dw-hdmi-qp.yaml  | 188 
>>> +
>>>  1 file changed, 188 insertions(+)
>>>
>>
>> My bot found errors running 'make dt_binding_check' on your patch:
> 
> This is because the referenced synopsys,dw-hdmi-qp.yaml is provided by a
> separate patchset:
> 
> https://lore.kernel.org/lkml/20240801-dw-hdmi-qp-tx-v1-1-148f542de...@collabora.com/


So you made things untestable. No, this must be one patchset. Do not
send some library/helper and users of it in separate patchsets.

Best regards,
Krzysztof



RE: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer

2024-08-01 Thread Cavitt, Jonathan
-Original Message-
From: Brost, Matthew  
Sent: Thursday, August 1, 2024 7:30 AM
To: Cavitt, Jonathan 
Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
> 
> On Thu, Aug 01, 2024 at 08:00:21AM -0600, Cavitt, Jonathan wrote:
> > -Original Message-
> > From: Brost, Matthew  
> > Sent: Wednesday, July 31, 2024 5:03 PM
> > To: Cavitt, Jonathan 
> > Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
> > maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
> > Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump 
> > printer
> > > 
> > > On Wed, Jul 31, 2024 at 04:22:03PM -0600, Cavitt, Jonathan wrote:
> > > > -Original Message-
> > > > From: Intel-xe  On Behalf Of 
> > > > Matthew Brost
> > > > Sent: Wednesday, July 31, 2024 2:32 PM
> > > > To: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> > > > Cc: maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
> > > > 
> > > > Subject: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump 
> > > > printer
> > > > > 
> > > > > Useful to determine size of devcoreump before writing it out.
> > > > > 
> > > > > Cc: Maarten Lankhorst 
> > > > > Signed-off-by: Matthew Brost 
> > > > 
> > > > It seems this patch prevents us from copying strings into the data 
> > > > field if the data
> > > > field hasn't been initialized.  I'm not certain if it could ever be 
> > > > uninitialized at this
> > > > point, but I recognize it as good practice to check just in case 
> > > > regardless.
> > > > 
> > > 
> > > That's not the intent. The intent to call the print functions with NULL
> > > data so the printer can calculate the size of buffer required to print
> > > out all the devcoredump data.
> > 
> > So if iterator->data is NULL, you want to NOT copy into it?
> > -Jonathan Cavitt
> 
> Yes, exactly. Run devcoredump printer with NULL data to get size, alloc
> data based on devcoredump printer offset, run it again with a valid data
> pointer to print.

Okay, I think I understand.  That might be good to add to the commit message,
then.  Something like:

"""
We want to determine the size of the devcoredump before writing it out.
To that end, we will run the devcoredump printer with NULL data to get
the size, alloc data based on the generated offset, then run the
devcorecump again with a valid data pointer to print.  This necessitates
not writing data to the data pointer on the initial pass, when it is NULL.
"""

Maybe that's a bit overboard?  In either case, my RB still stands,
regardless of if the commit message is updated or not.
-Jonathan Cavitt

> 
> Matt
> 
> > 
> > > 
> > > Matt
> > > 
> > > > Reviewed-by: Jonathan Cavitt 
> > > > -Jonathan Cavitt
> > > > 
> > > > > ---
> > > > >  drivers/gpu/drm/drm_print.c | 13 -
> > > > >  1 file changed, 8 insertions(+), 5 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> > > > > index cf24dfdeb6b2..a1a4de9f9c44 100644
> > > > > --- a/drivers/gpu/drm/drm_print.c
> > > > > +++ b/drivers/gpu/drm/drm_print.c
> > > > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, 
> > > > > const char *str)
> > > > >   copy = iterator->remain;
> > > > >  
> > > > >   /* Copy out the bit of the string that we need */
> > > > > - memcpy(iterator->data,
> > > > > - str + (iterator->start - iterator->offset), 
> > > > > copy);
> > > > > + if (iterator->data)
> > > > > + memcpy(iterator->data,
> > > > > + str + (iterator->start - 
> > > > > iterator->offset), copy);
> > > > >  
> > > > >   iterator->offset = iterator->start + copy;
> > > > >   iterator->remain -= copy;
> > > > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, 
> > > > > const char *str)
> > > > >  
> > > > >   len = min_t(ssize_t, strlen(str), iterator->remain);
> > > > >  
> > > > > - memcpy(iterator->data + pos, str, len);
> > > > > + if (iterator->data)
> > > > > + memcpy(iterator->data + pos, str, len);
> > > > >  
> > > > >   iterator->offset += len;
> > > > >   iterator->remain -= len;
> > > > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer 
> > > > > *p, struct va_format *vaf)
> > > > >   if ((iterator->offset >= iterator->start) && (len < 
> > > > > iterator->remain)) {
> > > > >   ssize_t pos = iterator->offset - iterator->start;
> > > > >  
> > > > > - snprintf(((char *) iterator->data) + pos,
> > > > > - iterator->remain, "%pV", vaf);
> > > > > + if (iterator->data)
> > > > > + snprintf(((char *) iterator->data) + pos,
> > > > > +

Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer

2024-08-01 Thread Matthew Brost
On Thu, Aug 01, 2024 at 08:00:21AM -0600, Cavitt, Jonathan wrote:
> -Original Message-
> From: Brost, Matthew  
> Sent: Wednesday, July 31, 2024 5:03 PM
> To: Cavitt, Jonathan 
> Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
> maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
> Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump 
> printer
> > 
> > On Wed, Jul 31, 2024 at 04:22:03PM -0600, Cavitt, Jonathan wrote:
> > > -Original Message-
> > > From: Intel-xe  On Behalf Of 
> > > Matthew Brost
> > > Sent: Wednesday, July 31, 2024 2:32 PM
> > > To: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> > > Cc: maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
> > > 
> > > Subject: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump 
> > > printer
> > > > 
> > > > Useful to determine size of devcoreump before writing it out.
> > > > 
> > > > Cc: Maarten Lankhorst 
> > > > Signed-off-by: Matthew Brost 
> > > 
> > > It seems this patch prevents us from copying strings into the data field 
> > > if the data
> > > field hasn't been initialized.  I'm not certain if it could ever be 
> > > uninitialized at this
> > > point, but I recognize it as good practice to check just in case 
> > > regardless.
> > > 
> > 
> > That's not the intent. The intent to call the print functions with NULL
> > data so the printer can calculate the size of buffer required to print
> > out all the devcoredump data.
> 
> So if iterator->data is NULL, you want to NOT copy into it?
> -Jonathan Cavitt

Yes, exactly. Run devcoredump printer with NULL data to get size, alloc
data based on devcoredump printer offset, run it again with a valid data
pointer to print.

Matt

> 
> > 
> > Matt
> > 
> > > Reviewed-by: Jonathan Cavitt 
> > > -Jonathan Cavitt
> > > 
> > > > ---
> > > >  drivers/gpu/drm/drm_print.c | 13 -
> > > >  1 file changed, 8 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> > > > index cf24dfdeb6b2..a1a4de9f9c44 100644
> > > > --- a/drivers/gpu/drm/drm_print.c
> > > > +++ b/drivers/gpu/drm/drm_print.c
> > > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, 
> > > > const char *str)
> > > > copy = iterator->remain;
> > > >  
> > > > /* Copy out the bit of the string that we need */
> > > > -   memcpy(iterator->data,
> > > > -   str + (iterator->start - iterator->offset), 
> > > > copy);
> > > > +   if (iterator->data)
> > > > +   memcpy(iterator->data,
> > > > +   str + (iterator->start - 
> > > > iterator->offset), copy);
> > > >  
> > > > iterator->offset = iterator->start + copy;
> > > > iterator->remain -= copy;
> > > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, 
> > > > const char *str)
> > > >  
> > > > len = min_t(ssize_t, strlen(str), iterator->remain);
> > > >  
> > > > -   memcpy(iterator->data + pos, str, len);
> > > > +   if (iterator->data)
> > > > +   memcpy(iterator->data + pos, str, len);
> > > >  
> > > > iterator->offset += len;
> > > > iterator->remain -= len;
> > > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, 
> > > > struct va_format *vaf)
> > > > if ((iterator->offset >= iterator->start) && (len < 
> > > > iterator->remain)) {
> > > > ssize_t pos = iterator->offset - iterator->start;
> > > >  
> > > > -   snprintf(((char *) iterator->data) + pos,
> > > > -   iterator->remain, "%pV", vaf);
> > > > +   if (iterator->data)
> > > > +   snprintf(((char *) iterator->data) + pos,
> > > > +   iterator->remain, "%pV", vaf);
> > > >  
> > > > iterator->offset += len;
> > > > iterator->remain -= len;
> > > > -- 
> > > > 2.34.1
> > > > 
> > > > 
> > 


Re: [RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen

2024-08-01 Thread John Ogness
On 2024-08-01, Jocelyn Falempe  wrote:
> I think I can also register one console for each drm driver, which
> will simplify drm_log even further. (currently it would mean having a
> circular buffer and work function for each driver which is a bit too
> much).

Indeed.

> Do you know if there is a chance to have write_thread() in 6.12 or
> 6.13 ?

Sorry, I have no crystal ball. Petr Mladek and I are working really hard
to get things in shape for mainline. I do think there is a chance for
the 6.12 merge window. But it would also need to get past Linus. Our
recent atomic console efforts were rejected [0] for the 6.11 merge
window. We are working to get that series in shape for 6.12 in parallel.

John

[0] 
https://lore.kernel.org/lkml/CAHk-=whU_woFnFN-3Jv2hNCmwLg_fkrT42AWwxm-=ha5bmn...@mail.gmail.com


Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer

2024-08-01 Thread Matthew Brost
On Thu, Aug 01, 2024 at 11:05:21AM +0300, Jani Nikula wrote:
> On Wed, 31 Jul 2024, Matthew Brost  wrote:
> > Useful to determine size of devcoreump before writing it out.
> 
> I find it useful to have this special case documented, with an example,
> so it's easier to see how handy this really is.
> 

Good idea, will add some kernel doc explaining the problem devcoredump
in Xe and how use a devcoredump printer with NULL to make it faster.

Matt

> BR,
> Jani.
> 
> 
> >
> > Cc: Maarten Lankhorst 
> > Signed-off-by: Matthew Brost 
> > ---
> >  drivers/gpu/drm/drm_print.c | 13 -
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> > index cf24dfdeb6b2..a1a4de9f9c44 100644
> > --- a/drivers/gpu/drm/drm_print.c
> > +++ b/drivers/gpu/drm/drm_print.c
> > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const 
> > char *str)
> > copy = iterator->remain;
> >  
> > /* Copy out the bit of the string that we need */
> > -   memcpy(iterator->data,
> > -   str + (iterator->start - iterator->offset), copy);
> > +   if (iterator->data)
> > +   memcpy(iterator->data,
> > +   str + (iterator->start - iterator->offset), 
> > copy);
> >  
> > iterator->offset = iterator->start + copy;
> > iterator->remain -= copy;
> > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const 
> > char *str)
> >  
> > len = min_t(ssize_t, strlen(str), iterator->remain);
> >  
> > -   memcpy(iterator->data + pos, str, len);
> > +   if (iterator->data)
> > +   memcpy(iterator->data + pos, str, len);
> >  
> > iterator->offset += len;
> > iterator->remain -= len;
> > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, 
> > struct va_format *vaf)
> > if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
> > ssize_t pos = iterator->offset - iterator->start;
> >  
> > -   snprintf(((char *) iterator->data) + pos,
> > -   iterator->remain, "%pV", vaf);
> > +   if (iterator->data)
> > +   snprintf(((char *) iterator->data) + pos,
> > +   iterator->remain, "%pV", vaf);
> >  
> > iterator->offset += len;
> > iterator->remain -= len;
> 
> -- 
> Jani Nikula, Intel


Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage

2024-08-01 Thread Vladimir Lypak
On Thu, Aug 01, 2024 at 01:52:32PM +0100, Connor Abbott wrote:
> On Thu, Aug 1, 2024 at 1:25 PM Vladimir Lypak  
> wrote:
> >
> > On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote:
> > > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak
> > >  wrote:
> > > >
> > > > On A5XX GPUs when preemption is used it's invietable to enter a soft
> > > > lock-up state in which GPU is stuck at empty ring-buffer doing nothing.
> > > > This appears as full UI lockup and not detected as GPU hang (because
> > > > it's not). This happens due to not triggering preemption when it was
> > > > needed. Sometimes this state can be recovered by some new submit but
> > > > generally it won't happen because applications are waiting for old
> > > > submits to retire.
> > > >
> > > > One of the reasons why this happens is a race between a5xx_submit and
> > > > a5xx_preempt_trigger called from IRQ during submit retire. Former thread
> > > > updates ring->cur of previously empty and not current ring right after
> > > > latter checks it for emptiness. Then both threads can just exit because
> > > > for first one preempt_state wasn't NONE yet and for second one all rings
> > > > appeared to be empty.
> > > >
> > > > To prevent such situations from happening we need to establish guarantee
> > > > for preempt_trigger to be called after each submit. To implement it this
> > > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if we
> > > > should switch to non-empty or higher priority ring. Also we find next
> > > > ring in new preemption state "EVALUATE". If the thread that updated some
> > > > ring with new submit sees this state it should wait until it passes.
> > > >
> > > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
> > > > Signed-off-by: Vladimir Lypak 
> > > > ---
> > > >  drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  6 +++---
> > > >  drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++
> > > >  drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++
> > > >  3 files changed, 30 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > > index 6c80d3003966..266744ee1d5f 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, 
> > > > struct msm_gem_submit *submit
> > > > }
> > > >
> > > > a5xx_flush(gpu, ring, true);
> > > > -   a5xx_preempt_trigger(gpu);
> > > > +   a5xx_preempt_trigger(gpu, true);
> > > >
> > > > /* we might not necessarily have a cmd from userspace to
> > > >  * trigger an event to know that submit has completed, so
> > > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
> > > > msm_gem_submit *submit)
> > > > a5xx_flush(gpu, ring, false);
> > > >
> > > > /* Check to see if we need to start preemption */
> > > > -   a5xx_preempt_trigger(gpu);
> > > > +   a5xx_preempt_trigger(gpu, true);
> > > >  }
> > > >
> > > >  static const struct adreno_five_hwcg_regs {
> > > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
> > > > a5xx_gpmu_err_irq(gpu);
> > > >
> > > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) {
> > > > -   a5xx_preempt_trigger(gpu);
> > > > +   a5xx_preempt_trigger(gpu, false);
> > > > msm_gpu_retire(gpu);
> > > > }
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h 
> > > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > > index c7187bcc5e90..1120824853d4 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct 
> > > > drm_minor *minor);
> > > >   * through the process.
> > > >   *
> > > >   * PREEMPT_NONE - no preemption in progress.  Next state START.
> > > > - * PREEMPT_START - The trigger is evaulating if preemption is 
> > > > possible. Next
> > > > - * states: TRIGGERED, NONE
> > > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is 
> > > > possible. Next
> > > > + * states: START, ABORT
> > > >   * PREEMPT_ABORT - An intermediate state before moving back to NONE. 
> > > > Next
> > > >   * state: NONE.
> > > > + * PREEMPT_START - The trigger is preparing for preemption. Next state:
> > > > + * TRIGGERED
> > > >   * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. 
> > > > Next
> > > >   * states: FAULTED, PENDING
> > > >   * PREEMPT_FAULTED: A preemption timed out (never completed). This 
> > > > will trigger
> > > > @@ -71,8 +73,9 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct 
> > > > drm_minor *minor);
> > > >
> > > >  enum preempt_state {
> > > > PREEMPT_NONE = 0,
> > > > -   PREEMPT_START,
> > > > +   

Re: [PATCH 1/2] dt-bindings: display: bridge: Add schema for Synopsys DW HDMI QP TX IP

2024-08-01 Thread Krzysztof Kozlowski
On 01/08/2024 11:29, Cristian Ciocaltea wrote:
> On 8/1/24 11:38 AM, Krzysztof Kozlowski wrote:> On 01/08/2024 04:05, Cristian 
> Ciocaltea wrote:
>>> Add dt-binding schema containing the common properties for the Synopsys
>>> DesignWare HDMI QP TX controller.
>>>
>>> Note this is not a full dt-binding specification, but is meant to be
>>> referenced by platform-specific bindings for this IP core.
>>
>> Please provide an user for this binding. Otherwise it is a no-op.
> 
> The first user of this is RK3588 HDMI TX Controller [1].

Patchsets do not work like this. Splitting things causes that your other
patch simply cannot even be tested because you introduced dependency.

Combine patches so bindings referencing common properties can properly
be tested by automation.

Best regards,
Krzysztof



Re: [PATCH 2/2] drm/bridge: synopsys: Add DW HDMI QP TX Controller driver

2024-08-01 Thread Krzysztof Kozlowski
On 01/08/2024 11:43, Cristian Ciocaltea wrote:
> On 8/1/24 11:50 AM, Krzysztof Kozlowski wrote:
>> On 01/08/2024 04:05, Cristian Ciocaltea wrote:
>>> The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller supports
>>> the following features, among others:
>>
>> ...
>>
>>> +
>>> +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi)
>>> +{
>>> +}
>>> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind);
>>
>> This looks like quite useless export. Drop.
>>
>>
>>> +
>>> +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
>>> +{
>>> +   dw_hdmi_qp_init_hw(hdmi);
>>> +}
>>> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
>>> +
>>> +MODULE_AUTHOR("Algea Cao ");
>>> +MODULE_AUTHOR("Cristian Ciocaltea ");
>>> +MODULE_DESCRIPTION("DW HDMI QP transmitter driver");
>>> +MODULE_LICENSE("GPL");
>>> +MODULE_ALIAS("platform:dw-hdmi-qp");
>>
>> That's not a platform driver. That does not look like driver at all,
>> just some helper code without any user
> 
> This is actually used to provide RK3588 HDMI output support:
> 
> https://lore.kernel.org/lkml/20240801-b4-rk3588-bridge-upstream-v2-3-9fa657a4e...@collabora.com/

That is supposed to be in one patchset, so we can see how you use the
introduced functions.


Best regards,
Krzysztof



RE: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer

2024-08-01 Thread Cavitt, Jonathan
-Original Message-
From: Brost, Matthew  
Sent: Wednesday, July 31, 2024 5:03 PM
To: Cavitt, Jonathan 
Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; 
maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
Subject: Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
> 
> On Wed, Jul 31, 2024 at 04:22:03PM -0600, Cavitt, Jonathan wrote:
> > -Original Message-
> > From: Intel-xe  On Behalf Of 
> > Matthew Brost
> > Sent: Wednesday, July 31, 2024 2:32 PM
> > To: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> > Cc: maarten.lankho...@linux.intel.com; Vivi, Rodrigo 
> > 
> > Subject: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer
> > > 
> > > Useful to determine size of devcoreump before writing it out.
> > > 
> > > Cc: Maarten Lankhorst 
> > > Signed-off-by: Matthew Brost 
> > 
> > It seems this patch prevents us from copying strings into the data field if 
> > the data
> > field hasn't been initialized.  I'm not certain if it could ever be 
> > uninitialized at this
> > point, but I recognize it as good practice to check just in case regardless.
> > 
> 
> That's not the intent. The intent to call the print functions with NULL
> data so the printer can calculate the size of buffer required to print
> out all the devcoredump data.

So if iterator->data is NULL, you want to NOT copy into it?
-Jonathan Cavitt

> 
> Matt
> 
> > Reviewed-by: Jonathan Cavitt 
> > -Jonathan Cavitt
> > 
> > > ---
> > >  drivers/gpu/drm/drm_print.c | 13 -
> > >  1 file changed, 8 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> > > index cf24dfdeb6b2..a1a4de9f9c44 100644
> > > --- a/drivers/gpu/drm/drm_print.c
> > > +++ b/drivers/gpu/drm/drm_print.c
> > > @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const 
> > > char *str)
> > >   copy = iterator->remain;
> > >  
> > >   /* Copy out the bit of the string that we need */
> > > - memcpy(iterator->data,
> > > - str + (iterator->start - iterator->offset), copy);
> > > + if (iterator->data)
> > > + memcpy(iterator->data,
> > > + str + (iterator->start - iterator->offset), 
> > > copy);
> > >  
> > >   iterator->offset = iterator->start + copy;
> > >   iterator->remain -= copy;
> > > @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const 
> > > char *str)
> > >  
> > >   len = min_t(ssize_t, strlen(str), iterator->remain);
> > >  
> > > - memcpy(iterator->data + pos, str, len);
> > > + if (iterator->data)
> > > + memcpy(iterator->data + pos, str, len);
> > >  
> > >   iterator->offset += len;
> > >   iterator->remain -= len;
> > > @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, 
> > > struct va_format *vaf)
> > >   if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
> > >   ssize_t pos = iterator->offset - iterator->start;
> > >  
> > > - snprintf(((char *) iterator->data) + pos,
> > > - iterator->remain, "%pV", vaf);
> > > + if (iterator->data)
> > > + snprintf(((char *) iterator->data) + pos,
> > > + iterator->remain, "%pV", vaf);
> > >  
> > >   iterator->offset += len;
> > >   iterator->remain -= len;
> > > -- 
> > > 2.34.1
> > > 
> > > 
> 


Re: [RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen

2024-08-01 Thread Jocelyn Falempe



On 01/08/2024 12:51, John Ogness wrote:

On 2024-08-01, Jocelyn Falempe  wrote:

  * It uses a circular buffer so the console->write() callback is very
quick, and will never stall.
  * Drawing is done asynchronously using a workqueue.


For CON_NBCON, neither of the above points are necessary. You can draw
directly from the write_thread() callback. See below:


+static bool drm_log_work_draw(void)
+{
+   unsigned int len;
+   char buf[512];
+
+   len = drm_log_buf_read(buf, sizeof(buf));
+   if (len)
+   drm_log_draw_all(buf, len);
+   return len != 0;
+}


For CON_NBCON, this is essentially your write_thread() callback:

void drm_log_write_thread(struct console *con,
  struct nbcon_write_context *wctxt)
{
drm_log_draw_all(wctxt->outbuf, wctxt->len);
}

You cannot implement a write_atomic() callback because the console must
be able to print directly in NMI context and must not defer. But
write_atomic() is optional, so you should be fine there.

Disclaimer: Only in PREEMPT_RT patchset at the moment.


Thanks, so that means the circular buffer and workqueue are only 
necessary until write_thread() is merged in mainline. It will be a nice 
simplification.
I think I can also register one console for each drm driver, which will 
simplify drm_log even further. (currently it would mean having a 
circular buffer and work function for each driver which is a bit too much).

Do you know if there is a chance to have write_thread() in 6.12 or 6.13 ?



John Ogness >


Best regards

--

Jocelyn



Re: [PATCH 2/4] drm/msm/a5xx: properly clear preemption records on resume

2024-08-01 Thread Akhil P Oommen
On Thu, Jul 11, 2024 at 10:00:19AM +, Vladimir Lypak wrote:
> Two fields of preempt_record which are used by CP aren't reset on
> resume: "data" and "info". This is the reason behind faults which happen
> when we try to switch to the ring that was active last before suspend.
> In addition those faults can't be recovered from because we use suspend
> and resume to do so (keeping values of those fields again).
> 
> Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
> Signed-off-by: Vladimir Lypak 
> ---
>  drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c 
> b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
> index f58dd564d122..67a8ef4adf6b 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
> @@ -204,6 +204,8 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
>   return;
>  
>   for (i = 0; i < gpu->nr_rings; i++) {
> + a5xx_gpu->preempt[i]->data = 0;
> + a5xx_gpu->preempt[i]->info = 0;

I don't see this bit in the downstream driver. Just curious, do we need
to clear both fields to avoid the gpu faults?

-Akhil
>   a5xx_gpu->preempt[i]->wptr = 0;
>   a5xx_gpu->preempt[i]->rptr = 0;
>   a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
> -- 
> 2.45.2
> 


[PATCH] drm/client: Use common display mode for cloned outputs

2024-08-01 Thread Thomas Zimmermann
For cloned outputs, don't pick a default resolution of 1024x768 as
most hardware can do better. Instead look through the modes of all
connectors to find a common mode for all of them.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_client_modeset.c | 54 +---
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 31af5cf37a09..67b422dc8e7f 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -266,7 +266,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
 {
int count, i, j;
bool can_clone = false;
-   struct drm_display_mode *dmt_mode, *mode;
+   struct drm_display_mode *mode, *common_mode = NULL;
 
/* only contemplate cloning in the single crtc case */
if (dev->mode_config.num_crtc > 1)
@@ -309,35 +309,49 @@ static bool drm_client_target_cloned(struct drm_device 
*dev,
return true;
}
 
-   /* try and find a 1024x768 mode on each connector */
-   can_clone = true;
-   dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
-
-   if (!dmt_mode)
-   goto fail;
+   /* try and find a mode common among connectors */
 
+   can_clone = false;
for (i = 0; i < connector_count; i++) {
if (!enabled[i])
continue;
 
-   list_for_each_entry(mode, [i]->modes, head) {
-   if (drm_mode_match(mode, dmt_mode,
-  DRM_MODE_MATCH_TIMINGS |
-  DRM_MODE_MATCH_CLOCK |
-  DRM_MODE_MATCH_FLAGS |
-  DRM_MODE_MATCH_3D_FLAGS))
-   modes[i] = mode;
+   list_for_each_entry(common_mode, [i]->modes, head) {
+   can_clone = true;
+
+   for (j = 1; j < connector_count; j++) {
+   if (!enabled[i])
+   continue;
+
+   can_clone = false;
+   list_for_each_entry(mode, 
[j]->modes, head) {
+   can_clone = drm_mode_match(common_mode, 
mode,
+  
DRM_MODE_MATCH_TIMINGS |
+   
DRM_MODE_MATCH_CLOCK |
+   
DRM_MODE_MATCH_FLAGS |
+   
DRM_MODE_MATCH_3D_FLAGS);
+   if (can_clone)
+   break; // found common mode on 
connector
+   }
+   if (!can_clone)
+   break; // try next common mode
+   }
+   if (can_clone)
+   break; // found common mode among all connectors
}
-   if (!modes[i])
-   can_clone = false;
+   break;
}
-   kfree(dmt_mode);
-
if (can_clone) {
-   drm_dbg_kms(dev, "can clone using 1024x768\n");
+   for (i = 0; i < connector_count; i++) {
+   if (!enabled[i])
+   continue;
+   modes[i] = common_mode;
+
+   }
+   drm_dbg_kms(dev, "can clone using" DRM_MODE_FMT "\n", 
DRM_MODE_ARG(common_mode));
return true;
}
-fail:
+
drm_info(dev, "kms: can't enable cloning when we probably wanted 
to.\n");
return false;
 }
-- 
2.45.2



Re: [PATCH v3 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors

2024-08-01 Thread Jani Nikula
On Thu, 01 Aug 2024, Thomas Zimmermann  wrote:
> Hi
>
> Am 01.08.24 um 14:33 schrieb Jani Nikula:
>> On Mon, 01 Jul 2024, Xaver Hugl  wrote:
>>> Am Do., 20. Juni 2024 um 22:22 Uhr schrieb Xaver Hugl 
>>> :
 Merging can only happen once a real world userspace application has
 implemented support for it. I'll try to do that sometime next week in
 KWin
>>> Here's the promised implementation:
>>> https://invent.kde.org/plasma/kwin/-/merge_requests/6028
>> The requirement is that the userspace patches must be reviewed and ready
>> for merging into a suitable and canonical upstream project.
>>
>> Are they?
>
> I already saw this series in today's PR for drm-misc-next. :/

Exactly what triggered the question!

BR,
Jani.


>
> Best regards
> Thomas
>
>>
>>
>> BR,
>> Jani.
>>
>>
>>> In testing with the patches on top of kernel 6.9.6, setting the
>>> property to `Require color accuracy` makes the sysfs file correctly
>>> report "Device or resource busy" when trying to change the power
>>> saving level, but setting the property to zero doesn't really work.
>>> Once KWin sets the property to zero, changing the power saving level
>>> "works" but the screen blanks for a moment (might just be a single
>>> frame) and reading from the file returns zero again, with the visuals
>>> and backlight level unchanged as well.

-- 
Jani Nikula, Intel


Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage

2024-08-01 Thread Connor Abbott
On Thu, Aug 1, 2024 at 1:25 PM Vladimir Lypak  wrote:
>
> On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote:
> > On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak
> >  wrote:
> > >
> > > On A5XX GPUs when preemption is used it's invietable to enter a soft
> > > lock-up state in which GPU is stuck at empty ring-buffer doing nothing.
> > > This appears as full UI lockup and not detected as GPU hang (because
> > > it's not). This happens due to not triggering preemption when it was
> > > needed. Sometimes this state can be recovered by some new submit but
> > > generally it won't happen because applications are waiting for old
> > > submits to retire.
> > >
> > > One of the reasons why this happens is a race between a5xx_submit and
> > > a5xx_preempt_trigger called from IRQ during submit retire. Former thread
> > > updates ring->cur of previously empty and not current ring right after
> > > latter checks it for emptiness. Then both threads can just exit because
> > > for first one preempt_state wasn't NONE yet and for second one all rings
> > > appeared to be empty.
> > >
> > > To prevent such situations from happening we need to establish guarantee
> > > for preempt_trigger to be called after each submit. To implement it this
> > > patch adds trigger call at the end of a5xx_preempt_irq to re-check if we
> > > should switch to non-empty or higher priority ring. Also we find next
> > > ring in new preemption state "EVALUATE". If the thread that updated some
> > > ring with new submit sees this state it should wait until it passes.
> > >
> > > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
> > > Signed-off-by: Vladimir Lypak 
> > > ---
> > >  drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  6 +++---
> > >  drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++
> > >  drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++
> > >  3 files changed, 30 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > index 6c80d3003966..266744ee1d5f 100644
> > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, 
> > > struct msm_gem_submit *submit
> > > }
> > >
> > > a5xx_flush(gpu, ring, true);
> > > -   a5xx_preempt_trigger(gpu);
> > > +   a5xx_preempt_trigger(gpu, true);
> > >
> > > /* we might not necessarily have a cmd from userspace to
> > >  * trigger an event to know that submit has completed, so
> > > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
> > > msm_gem_submit *submit)
> > > a5xx_flush(gpu, ring, false);
> > >
> > > /* Check to see if we need to start preemption */
> > > -   a5xx_preempt_trigger(gpu);
> > > +   a5xx_preempt_trigger(gpu, true);
> > >  }
> > >
> > >  static const struct adreno_five_hwcg_regs {
> > > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
> > > a5xx_gpmu_err_irq(gpu);
> > >
> > > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) {
> > > -   a5xx_preempt_trigger(gpu);
> > > +   a5xx_preempt_trigger(gpu, false);
> > > msm_gpu_retire(gpu);
> > > }
> > >
> > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h 
> > > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > index c7187bcc5e90..1120824853d4 100644
> > > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct 
> > > drm_minor *minor);
> > >   * through the process.
> > >   *
> > >   * PREEMPT_NONE - no preemption in progress.  Next state START.
> > > - * PREEMPT_START - The trigger is evaulating if preemption is possible. 
> > > Next
> > > - * states: TRIGGERED, NONE
> > > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is 
> > > possible. Next
> > > + * states: START, ABORT
> > >   * PREEMPT_ABORT - An intermediate state before moving back to NONE. Next
> > >   * state: NONE.
> > > + * PREEMPT_START - The trigger is preparing for preemption. Next state:
> > > + * TRIGGERED
> > >   * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. 
> > > Next
> > >   * states: FAULTED, PENDING
> > >   * PREEMPT_FAULTED: A preemption timed out (never completed). This will 
> > > trigger
> > > @@ -71,8 +73,9 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct 
> > > drm_minor *minor);
> > >
> > >  enum preempt_state {
> > > PREEMPT_NONE = 0,
> > > -   PREEMPT_START,
> > > +   PREEMPT_EVALUATE,
> > > PREEMPT_ABORT,
> > > +   PREEMPT_START,
> > > PREEMPT_TRIGGERED,
> > > PREEMPT_FAULTED,
> > > PREEMPT_PENDING,
> > > @@ -156,7 +159,7 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state);
> > >
> > >  void 

Introduction and Seeking Advice on X.Org Evoc Mentorship Program

2024-08-01 Thread 22-Priyansu Rout
Hello everyone,

Hello, my name is Priyansu Rout I am from India. I am right now in my
second year of B. Tech in Computer Science and Engineering. I have been
developing in blockchain projects and now I would like to get experience in
X. Org, especially on the kernel level.

I am very much interested in being a mentee in the X. Org Evoc Mentorship
Program. I would really be grateful for any pointers on how to proceed in
contributing to X. Org and how the mentorship process works.

Thanks for your time and I am looking forward to enrich this community
through learning and sharing.


Re: [PATCH v3 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors

2024-08-01 Thread Thomas Zimmermann

Hi

Am 01.08.24 um 14:33 schrieb Jani Nikula:

On Mon, 01 Jul 2024, Xaver Hugl  wrote:

Am Do., 20. Juni 2024 um 22:22 Uhr schrieb Xaver Hugl :

Merging can only happen once a real world userspace application has
implemented support for it. I'll try to do that sometime next week in
KWin

Here's the promised implementation:
https://invent.kde.org/plasma/kwin/-/merge_requests/6028

The requirement is that the userspace patches must be reviewed and ready
for merging into a suitable and canonical upstream project.

Are they?


I already saw this series in today's PR for drm-misc-next. :/

Best regards
Thomas




BR,
Jani.



In testing with the patches on top of kernel 6.9.6, setting the
property to `Require color accuracy` makes the sysfs file correctly
report "Device or resource busy" when trying to change the power
saving level, but setting the property to zero doesn't really work.
Once KWin sets the property to zero, changing the power saving level
"works" but the screen blanks for a moment (might just be a single
frame) and reading from the file returns zero again, with the visuals
and backlight level unchanged as well.


--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: [PATCH 1/4] drm/msm/a5xx: disable preemption in submits by default

2024-08-01 Thread Akhil P Oommen
On Mon, Jul 15, 2024 at 02:00:10PM -0700, Rob Clark wrote:
> On Thu, Jul 11, 2024 at 3:02 AM Vladimir Lypak  
> wrote:
> >
> > Fine grain preemption (switching from/to points within submits)
> > requires extra handling in command stream of those submits, especially
> > when rendering with tiling (using GMEM). However this handling is
> > missing at this point in mesa (and always was). For this reason we get
> > random GPU faults and hangs if more than one priority level is used
> > because local preemption is enabled prior to executing command stream
> > from submit.
> > With that said it was ahead of time to enable local preemption by
> > default considering the fact that even on downstream kernel it is only
> > enabled if requested via UAPI.
> >
> > Fixes: a7a4c19c36de ("drm/msm/a5xx: fix setting of the 
> > CP_PREEMPT_ENABLE_LOCAL register")
> > Signed-off-by: Vladimir Lypak 
> > ---
> >  drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > index c0b5373e90d7..6c80d3003966 100644
> > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > @@ -150,9 +150,13 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
> > msm_gem_submit *submit)
> > OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
> > OUT_RING(ring, 1);
> >
> > -   /* Enable local preemption for finegrain preemption */
> > +   /*
> > +* Disable local preemption by default because it requires
> > +* user-space to be aware of it and provide additional handling
> > +* to restore rendering state or do various flushes on switch.
> > +*/
> > OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
> > -   OUT_RING(ring, 0x1);
> > +   OUT_RING(ring, 0x0);
> 
> From a quick look at the a530 pfp fw, it looks like
> CP_PREEMPT_ENABLE_LOCAL is allowed in IB1/IB2 (ie. not restricted to
> kernel RB).  So we should just disable it in the kernel, and let
> userspace send a CP_PREEMPT_ENABLE_LOCAL to enable local preemption.

Ack. AFAIU about a5x preemption, this should work.

-Akhil

> 
> BR,
> -R
> 
> > /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
> > OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
> > --
> > 2.45.2
> >


Re: [PATCH v3 2/2] drm/amd: Add power_saving_policy drm property to eDP connectors

2024-08-01 Thread Jani Nikula
On Mon, 01 Jul 2024, Xaver Hugl  wrote:
> Am Do., 20. Juni 2024 um 22:22 Uhr schrieb Xaver Hugl :
>> Merging can only happen once a real world userspace application has
>> implemented support for it. I'll try to do that sometime next week in
>> KWin
>
> Here's the promised implementation:
> https://invent.kde.org/plasma/kwin/-/merge_requests/6028

The requirement is that the userspace patches must be reviewed and ready
for merging into a suitable and canonical upstream project.

Are they?


BR,
Jani.


>
> In testing with the patches on top of kernel 6.9.6, setting the
> property to `Require color accuracy` makes the sysfs file correctly
> report "Device or resource busy" when trying to change the power
> saving level, but setting the property to zero doesn't really work.
> Once KWin sets the property to zero, changing the power saving level
> "works" but the screen blanks for a moment (might just be a single
> frame) and reading from the file returns zero again, with the visuals
> and backlight level unchanged as well.

-- 
Jani Nikula, Intel


Re: [PATCH] backlight: pwm_bl: print errno for probe errors

2024-08-01 Thread Lee Jones
On Thu, 01 Aug 2024, Martin Kepplinger-Novaković wrote:

> This makes debugging often easier.
> 
> Signed-off-by: Martin Kepplinger-Novaković 
> 
> ---
>  drivers/video/backlight/pwm_bl.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)

Please refrain from signing your mails like this.  It means that some of
us have to physically click a pop-up box as we are parsing our inboxes.

I'm deleting all mails in this thread.

-- 
Lee Jones [李琼斯]


Re: [PATCH 3/4] drm/msm/a5xx: fix races in preemption evaluation stage

2024-08-01 Thread Vladimir Lypak
On Mon, Jul 29, 2024 at 06:26:45PM +0100, Connor Abbott wrote:
> On Thu, Jul 11, 2024 at 11:10 AM Vladimir Lypak
>  wrote:
> >
> > On A5XX GPUs when preemption is used it's invietable to enter a soft
> > lock-up state in which GPU is stuck at empty ring-buffer doing nothing.
> > This appears as full UI lockup and not detected as GPU hang (because
> > it's not). This happens due to not triggering preemption when it was
> > needed. Sometimes this state can be recovered by some new submit but
> > generally it won't happen because applications are waiting for old
> > submits to retire.
> >
> > One of the reasons why this happens is a race between a5xx_submit and
> > a5xx_preempt_trigger called from IRQ during submit retire. Former thread
> > updates ring->cur of previously empty and not current ring right after
> > latter checks it for emptiness. Then both threads can just exit because
> > for first one preempt_state wasn't NONE yet and for second one all rings
> > appeared to be empty.
> >
> > To prevent such situations from happening we need to establish guarantee
> > for preempt_trigger to be called after each submit. To implement it this
> > patch adds trigger call at the end of a5xx_preempt_irq to re-check if we
> > should switch to non-empty or higher priority ring. Also we find next
> > ring in new preemption state "EVALUATE". If the thread that updated some
> > ring with new submit sees this state it should wait until it passes.
> >
> > Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
> > Signed-off-by: Vladimir Lypak 
> > ---
> >  drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  6 +++---
> >  drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 11 +++
> >  drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++
> >  3 files changed, 30 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > index 6c80d3003966..266744ee1d5f 100644
> > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> > @@ -110,7 +110,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, 
> > struct msm_gem_submit *submit
> > }
> >
> > a5xx_flush(gpu, ring, true);
> > -   a5xx_preempt_trigger(gpu);
> > +   a5xx_preempt_trigger(gpu, true);
> >
> > /* we might not necessarily have a cmd from userspace to
> >  * trigger an event to know that submit has completed, so
> > @@ -240,7 +240,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
> > msm_gem_submit *submit)
> > a5xx_flush(gpu, ring, false);
> >
> > /* Check to see if we need to start preemption */
> > -   a5xx_preempt_trigger(gpu);
> > +   a5xx_preempt_trigger(gpu, true);
> >  }
> >
> >  static const struct adreno_five_hwcg_regs {
> > @@ -1296,7 +1296,7 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
> > a5xx_gpmu_err_irq(gpu);
> >
> > if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) {
> > -   a5xx_preempt_trigger(gpu);
> > +   a5xx_preempt_trigger(gpu, false);
> > msm_gpu_retire(gpu);
> > }
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h 
> > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > index c7187bcc5e90..1120824853d4 100644
> > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
> > @@ -57,10 +57,12 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct 
> > drm_minor *minor);
> >   * through the process.
> >   *
> >   * PREEMPT_NONE - no preemption in progress.  Next state START.
> > - * PREEMPT_START - The trigger is evaulating if preemption is possible. 
> > Next
> > - * states: TRIGGERED, NONE
> > + * PREEMPT_EVALUATE - The trigger is evaulating if preemption is possible. 
> > Next
> > + * states: START, ABORT
> >   * PREEMPT_ABORT - An intermediate state before moving back to NONE. Next
> >   * state: NONE.
> > + * PREEMPT_START - The trigger is preparing for preemption. Next state:
> > + * TRIGGERED
> >   * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. Next
> >   * states: FAULTED, PENDING
> >   * PREEMPT_FAULTED: A preemption timed out (never completed). This will 
> > trigger
> > @@ -71,8 +73,9 @@ void a5xx_debugfs_init(struct msm_gpu *gpu, struct 
> > drm_minor *minor);
> >
> >  enum preempt_state {
> > PREEMPT_NONE = 0,
> > -   PREEMPT_START,
> > +   PREEMPT_EVALUATE,
> > PREEMPT_ABORT,
> > +   PREEMPT_START,
> > PREEMPT_TRIGGERED,
> > PREEMPT_FAULTED,
> > PREEMPT_PENDING,
> > @@ -156,7 +159,7 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state);
> >
> >  void a5xx_preempt_init(struct msm_gpu *gpu);
> >  void a5xx_preempt_hw_init(struct msm_gpu *gpu);
> > -void a5xx_preempt_trigger(struct msm_gpu *gpu);
> > +void a5xx_preempt_trigger(struct msm_gpu *gpu, bool new_submit);
> >  void a5xx_preempt_irq(struct msm_gpu *gpu);
> >  void 

[Bug 219117] New: amdgpu: amdgpu_device_ip_init failed

2024-08-01 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=219117

Bug ID: 219117
   Summary: amdgpu: amdgpu_device_ip_init failed
   Product: Drivers
   Version: 2.5
Kernel Version: 6.11.0-rc1
  Hardware: All
OS: Linux
Status: NEW
  Severity: blocking
  Priority: P3
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: jean-christo...@guillain.net
Regression: Yes
   Bisected 064d92436b6924937ef414894d9174fa4465f788
 commit-id:

Hello !

Since the last kernel RC (6.11-rc1), the boot process hangs on my computer
after a GPU error :

Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: [drm:amdgpu_ring_test_helper
[amdgpu]] *ERROR* ring gfx test failed (-110)
Jul 30 10:18:10 youpi kernel: [drm:amdgpu_device_init [amdgpu]] *ERROR* hw_init
of IP block  failed -110
Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: amdgpu:
amdgpu_device_ip_init failed
Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: amdgpu: Fatal error during
GPU init
Jul 30 10:18:10 youpi kernel: amdgpu :00:01.0: amdgpu: amdgpu: finishing
device.
Jul 30 10:18:10 youpi kernel: [ cut here ]
Jul 30 10:18:10 youpi kernel: WARNING: CPU: 0 PID: 186 at
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c:631 amdgpu_irq_put+0x45/0x70 [amdgpu]
Jul 30 10:18:10 youpi kernel: Modules linked in: sd_mod usbhid uas hid
usb_storage amdgpu(+) amdxcp drm_exec gpu_sched drm_buddy i2c_algo_bit
drm_suballoc_helper drm>
Jul 30 10:18:10 youpi kernel: CPU: 0 UID: 0 PID: 186 Comm: (udev-worker) Not
tainted 6.11.0-rc1-jcg+ #1
Jul 30 10:18:10 youpi kernel: Hardware name: LENOVO 10VGS02P00/3130, BIOS
M1XKT57A 02/10/2022
Jul 30 10:18:10 youpi kernel: RIP: 0010:amdgpu_irq_put+0x45/0x70 [amdgpu]
Jul 30 10:18:10 youpi kernel: Code: 48 8b 4e 10 48 83 39 00 74 2c 89 d1 48 8d
04 88 8b 08 85 c9 74 14 f0 ff 08 b8 00 00 00 00 74 05 e9 50 c5 f7 d8 e9 6b fd
ff ff <0f>
Jul 30 10:18:10 youpi kernel: RSP: 0018:af1480677940 EFLAGS: 00010246
Jul 30 10:18:10 youpi kernel: RAX: 94f286417540 RBX: 94f285818880 RCX:

Jul 30 10:18:10 youpi kernel: RDX:  RSI: 94f2858254c0 RDI:
94f28580
Jul 30 10:18:10 youpi kernel: RBP: 94f285810208 R08: 0002 R09:
0003
Jul 30 10:18:10 youpi kernel: R10: af1480677768 R11: 9a4c96c8 R12:
94f2858105e8
Jul 30 10:18:10 youpi kernel: R13: 94f285800010 R14: 94f28580 R15:
94f2858254c0
Jul 30 10:18:10 youpi kernel: FS:  7f03450bb8c0()
GS:94f31760() knlGS:
Jul 30 10:18:10 youpi kernel: CS:  0010 DS:  ES:  CR0: 80050033
Jul 30 10:18:10 youpi kernel: CR2: 7f03450b2028 CR3: 0001458d8000 CR4:
001506f0
Jul 30 10:18:10 youpi kernel: Call Trace:
Jul 30 10:18:10 youpi kernel:  
Jul 30 10:18:10 youpi kernel:  ? __warn+0x7c/0x120
Jul 30 10:18:10 youpi kernel:  ? amdgpu_irq_put+0x45/0x70 [amdgpu]
Jul 30 10:18:10 youpi kernel:  ? report_bug+0x155/0x170
Jul 30 10:18:10 youpi kernel:  ? handle_bug+0x3f/0x80
Jul 30 10:18:10 youpi kernel:  ? exc_invalid_op+0x13/0x60
Jul 30 10:18:10 youpi kernel:  ? asm_exc_invalid_op+0x16/0x20
Jul 30 10:18:10 youpi kernel:  ? amdgpu_irq_put+0x45/0x70 [amdgpu]
Jul 30 10:18:10 youpi kernel:  amdgpu_fence_driver_hw_fini+0xfa/0x130 [amdgpu]
Jul 30 10:18:10 youpi kernel:  amdgpu_device_fini_hw+0xa2/0x3f0 [amdgpu]
Jul 30 10:18:10 youpi kernel:  amdgpu_driver_load_kms+0x79/0xb0 [amdgpu]
Jul 30 10:18:10 youpi kernel:  amdgpu_pci_probe+0x195/0x520 [amdgpu]
Jul 30 10:18:10 youpi kernel:  local_pci_probe+0x41/0x90
Jul 30 10:18:10 youpi kernel:  pci_device_probe+0xbb/0x1e0
Jul 30 10:18:10 youpi kernel:  really_probe+0xd6/0x390
Jul 30 10:18:10 youpi kernel:  ? __pfx___driver_attach+0x10/0x10
Jul 30 10:18:10 youpi kernel:  __driver_probe_device+0x78/0x150
Jul 30 10:18:10 youpi kernel:  driver_probe_device+0x1f/0x90
Jul 30 10:18:10 youpi kernel:  __driver_attach+0xce/0x1c0
Jul 30 10:18:10 youpi kernel:  bus_for_each_dev+0x84/0xd0
Jul 30 10:18:10 youpi kernel:  bus_add_driver+0x10e/0x240
Jul 30 10:18:10 youpi kernel:  driver_register+0x55/0x100
Jul 30 10:18:10 youpi kernel:  ? __pfx_amdgpu_init+0x10/0x10 [amdgpu]
Jul 30 10:18:10 youpi kernel:  do_one_initcall+0x57/0x320
Jul 30 10:18:10 youpi kernel:  do_init_module+0x60/0x230
Jul 30 10:18:10 youpi kernel:  init_module_from_file+0x86/0xc0
Jul 30 10:18:10 youpi kernel:  idempotent_init_module+0x11b/0x2b0
Jul 30 10:18:10 youpi kernel:  __x64_sys_finit_module+0x5a/0xb0
Jul 30 10:18:10 youpi kernel:  do_syscall_64+0x7e/0x190
Jul 30 10:18:10 youpi kernel:  ? syscall_exit_to_user_mode+0xc/0x1d0
Jul 30 10:18:10 youpi kernel:  ? do_syscall_64+0x8a/0x190
Jul 30 10:18:10 youpi kernel:  ? do_syscall_64+0x8a/0x190
Jul 30 10:18:10 youpi kernel:  ? syscall_exit_to_user_mode+0xc/0x1d0
Jul 30 10:18:10 youpi kernel:  ? do_syscall_64+0x8a/0x190
Jul 30 10:18:10 youpi kernel:  ? 

[PULL] drm-misc-next

2024-08-01 Thread Thomas Zimmermann
Hi Dave, Sima,

here's the first PR for drm-misc-next for what will become Linux v6.12.
It's the ususal mix of new features and bug fixes. Nouveau got a larger
refactoring, there are some improvements within TTM, work on the panic
screen progresses, mgag200 now supports VBLANK interrupts.

Best regards
Thomas

drm-misc-next-2024-08-01:
drm-misc-next for v6.12:

UAPI Changes:

virtio:
- Define DRM capset

Cross-subsystem Changes:

dma-buf:
- heaps: Clean up documentation

printk:
- Pass description to kmsg_dump()

Core Changes:

CI:
- Update IGT tests
- Point upstream repo to GitLab instance

modesetting:
- Introduce Power Saving Policy property for connectors
- Add might_fault() to drm_modeset_lock priming
- Add dynamic per-crtc vblank configuration support

panic:
- Avoid build-time interference with framebuffer console

docs:
- Document Colorspace property

scheduler:
- Remove full_recover from drm_sched_start

TTM:
- Make LRU walk restartable after dropping locks
- Allow direct reclaim to allocate local memory

Driver Changes:

amdgpu:
- Support Power Saving Policy connector property

ast:
- astdp: Support AST2600 with VGA; Clean up HPD

bridge:
- Silence error message on -EPROBE_DEFER
- analogix: Clean aup
- bridge-connector: Fix double free
- lt6505: Disable interrupt when powered off
- tc358767: Make default DP port preemphasis configurable

gma500:
- Update i2c terminology

ivpu:
- Add MODULE_FIRMWARE()

lcdif:
- Fix pixel clock

loongson:
- Use GEM refcount over TTM's

mgag200:
- Improve BMC handling
- Support VBLANK intterupts

nouveau:
- Refactor and clean up internals
- Use GEM refcount over TTM's

panel:
- Shutdown fixes plus documentation
- Refactor several drivers for better code sharing
- boe-th101mb31ig002: Support for starry-er88577 MIPI-DSI panel plus
  DT; Fix porch parameter
- edp: Support AOU B116XTN02.3, AUO B116XAN06.1, AOU B116XAT04.1,
  BOE NV140WUM-N41, BOE NV133WUM-N63, BOE NV116WHM-A4D, CMN N116BCA-EA2,
  CMN N116BCP-EA2, CSW MNB601LS1-4
- himax-hx8394: Support Microchip AC40T08A MIPI Display panel plus DT
- ilitek-ili9806e: Support Densitron DMT028VGHMCMI-1D TFT plus DT
- jd9365da: Support Melfas lmfbx101117480 MIPI-DSI panel plus DT; Refactor
  for code sharing

sti:
- Fix module owner

stm:
- Avoid UAF wih managed plane and CRTC helpers
- Fix module owner
- Fix error handling in probe
- Depend on COMMON_CLK
- ltdc: Fix transparency after disabling plane; Remove unused interrupt

tegra:
- Call drm_atomic_helper_shutdown()

v3d:
- Clean up perfmon

vkms:
- Clean up
The following changes since commit d4ef5d2b7ee0cbb5f2d864716140366a618400d6:

  Merge tag 'amd-drm-fixes-6.11-2024-07-25' of 
https://gitlab.freedesktop.org/agd5f/linux into drm-next (2024-07-26 09:52:15 
+1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-next-2024-08-01

for you to fetch changes up to d97e71e449373efbd2403f1d7a32d416599f32ac:

  drm/bridge: synopsys: dw-mipi-dsi: enable EoTp by default (2024-08-01 
13:34:18 +0200)


drm-misc-next for v6.12:

UAPI Changes:

virtio:
- Define DRM capset

Cross-subsystem Changes:

dma-buf:
- heaps: Clean up documentation

printk:
- Pass description to kmsg_dump()

Core Changes:

CI:
- Update IGT tests
- Point upstream repo to GitLab instance

modesetting:
- Introduce Power Saving Policy property for connectors
- Add might_fault() to drm_modeset_lock priming
- Add dynamic per-crtc vblank configuration support

panic:
- Avoid build-time interference with framebuffer console

docs:
- Document Colorspace property

scheduler:
- Remove full_recover from drm_sched_start

TTM:
- Make LRU walk restartable after dropping locks
- Allow direct reclaim to allocate local memory

Driver Changes:

amdgpu:
- Support Power Saving Policy connector property

ast:
- astdp: Support AST2600 with VGA; Clean up HPD

bridge:
- Silence error message on -EPROBE_DEFER
- analogix: Clean aup
- bridge-connector: Fix double free
- lt6505: Disable interrupt when powered off
- tc358767: Make default DP port preemphasis configurable

gma500:
- Update i2c terminology

ivpu:
- Add MODULE_FIRMWARE()

lcdif:
- Fix pixel clock

loongson:
- Use GEM refcount over TTM's

mgag200:
- Improve BMC handling
- Support VBLANK intterupts

nouveau:
- Refactor and clean up internals
- Use GEM refcount over TTM's

panel:
- Shutdown fixes plus documentation
- Refactor several drivers for better code sharing
- boe-th101mb31ig002: Support for starry-er88577 MIPI-DSI panel plus
  DT; Fix porch parameter
- edp: Support AOU B116XTN02.3, AUO B116XAN06.1, AOU B116XAT04.1,
  BOE NV140WUM-N41, BOE NV133WUM-N63, BOE NV116WHM-A4D, CMN N116BCA-EA2,
  CMN N116BCP-EA2, CSW MNB601LS1-4
- himax-hx8394: Support Microchip AC40T08A MIPI Display panel plus DT
- ilitek-ili9806e: Support Densitron DMT028VGHMCMI-1D TFT plus DT
- jd9365da: Support Melfas lmfbx101117480 MIPI-DSI panel plus DT; Refactor
  for code sharing

[PATCH rdma-next 6/8] RDMA: Pass uverbs_attr_bundle as part of '.reg_user_mr_dmabuf' API

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Pass uverbs_attr_bundle as part of '.reg_user_mr_dmabuf' API instead of
udata.

This enables passing some new ioctl attributes to the drivers, as will
be introduced in the next patches for mlx5 driver.

Change the involved drivers accordingly.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/core/uverbs_std_types_mr.c | 2 +-
 drivers/infiniband/hw/bnxt_re/ib_verbs.c  | 3 ++-
 drivers/infiniband/hw/bnxt_re/ib_verbs.h  | 2 +-
 drivers/infiniband/hw/efa/efa.h   | 2 +-
 drivers/infiniband/hw/efa/efa_verbs.c | 4 ++--
 drivers/infiniband/hw/irdma/verbs.c   | 2 +-
 drivers/infiniband/hw/mlx5/mlx5_ib.h  | 2 +-
 drivers/infiniband/hw/mlx5/mr.c   | 2 +-
 include/rdma/ib_verbs.h   | 2 +-
 9 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/core/uverbs_std_types_mr.c 
b/drivers/infiniband/core/uverbs_std_types_mr.c
index 03e1db5d1e8c..7ebc7bd3caae 100644
--- a/drivers/infiniband/core/uverbs_std_types_mr.c
+++ b/drivers/infiniband/core/uverbs_std_types_mr.c
@@ -239,7 +239,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_REG_DMABUF_MR)(
 
mr = pd->device->ops.reg_user_mr_dmabuf(pd, offset, length, iova, fd,
access_flags,
-   >driver_udata);
+   attrs);
if (IS_ERR(mr))
return PTR_ERR(mr);
 
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c 
b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 7c757351a016..43a68e7de02a 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -4122,7 +4122,8 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, 
u64 start, u64 length,
 
 struct ib_mr *bnxt_re_reg_user_mr_dmabuf(struct ib_pd *ib_pd, u64 start,
 u64 length, u64 virt_addr, int fd,
-int mr_access_flags, struct ib_udata 
*udata)
+int mr_access_flags,
+struct uverbs_attr_bundle *attrs)
 {
struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
struct bnxt_re_dev *rdev = pd->rdev;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h 
b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index e98cb1717338..3ddeda312376 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -242,7 +242,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd, u64 
start, u64 length,
 struct ib_mr *bnxt_re_reg_user_mr_dmabuf(struct ib_pd *ib_pd, u64 start,
 u64 length, u64 virt_addr,
 int fd, int mr_access_flags,
-struct ib_udata *udata);
+struct uverbs_attr_bundle *attrs);
 int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata);
 void bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
 int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
diff --git a/drivers/infiniband/hw/efa/efa.h b/drivers/infiniband/hw/efa/efa.h
index e580e087e9da..d7fc9d5eeefd 100644
--- a/drivers/infiniband/hw/efa/efa.h
+++ b/drivers/infiniband/hw/efa/efa.h
@@ -168,7 +168,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 
length,
 struct ib_mr *efa_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start,
 u64 length, u64 virt_addr,
 int fd, int access_flags,
-struct ib_udata *udata);
+struct uverbs_attr_bundle *attrs);
 int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
 int efa_get_port_immutable(struct ib_device *ibdev, u32 port_num,
   struct ib_port_immutable *immutable);
diff --git a/drivers/infiniband/hw/efa/efa_verbs.c 
b/drivers/infiniband/hw/efa/efa_verbs.c
index b1e0a1b7c59d..cc13415ff7e7 100644
--- a/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/drivers/infiniband/hw/efa/efa_verbs.c
@@ -1684,14 +1684,14 @@ static int efa_register_mr(struct ib_pd *ibpd, struct 
efa_mr *mr, u64 start,
 struct ib_mr *efa_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start,
 u64 length, u64 virt_addr,
 int fd, int access_flags,
-struct ib_udata *udata)
+struct uverbs_attr_bundle *attrs)
 {
struct efa_dev *dev = to_edev(ibpd->device);
struct ib_umem_dmabuf *umem_dmabuf;
struct efa_mr *mr;
int err;
 
-   mr = efa_alloc_mr(ibpd, access_flags, udata);
+   mr = efa_alloc_mr(ibpd, access_flags, >driver_udata);
if 

[PATCH rdma-next 8/8] RDMA/mlx5: Introduce GET_DATA_DIRECT_SYSFS_PATH ioctl

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Introduce the 'GET_DATA_DIRECT_SYSFS_PATH' ioctl to return the sysfs
path of the affiliated 'data direct' device for a given device.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/hw/mlx5/std_types.c   | 55 +++-
 include/uapi/rdma/mlx5_user_ioctl_cmds.h |  5 +++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/mlx5/std_types.c 
b/drivers/infiniband/hw/mlx5/std_types.c
index bbfcce3bdc84..ffeb1e1a1538 100644
--- a/drivers/infiniband/hw/mlx5/std_types.c
+++ b/drivers/infiniband/hw/mlx5/std_types.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include "mlx5_ib.h"
+#include "data_direct.h"
 
 #define UVERBS_MODULE_NAME mlx5_ib
 #include 
@@ -183,6 +184,50 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_QUERY_PORT)(
 sizeof(info));
 }
 
+static int UVERBS_HANDLER(MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH)(
+   struct uverbs_attr_bundle *attrs)
+{
+   struct mlx5_data_direct_dev *data_direct_dev;
+   struct mlx5_ib_ucontext *c;
+   struct mlx5_ib_dev *dev;
+   int out_len = uverbs_attr_get_len(attrs,
+   MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH);
+   u32 dev_path_len;
+   char *dev_path;
+   int ret;
+
+   c = to_mucontext(ib_uverbs_get_ucontext(attrs));
+   if (IS_ERR(c))
+   return PTR_ERR(c);
+   dev = to_mdev(c->ibucontext.device);
+   mutex_lock(>data_direct_lock);
+   data_direct_dev = dev->data_direct_dev;
+   if (!data_direct_dev) {
+   ret = -ENODEV;
+   goto end;
+   }
+
+   dev_path = kobject_get_path(_direct_dev->device->kobj, GFP_KERNEL);
+   if (!dev_path) {
+   ret = -ENOMEM;
+   goto end;
+   }
+
+   dev_path_len = strlen(dev_path) + 1;
+   if (dev_path_len > out_len) {
+   ret = -ENOSPC;
+   goto end;
+   }
+
+   ret = uverbs_copy_to(attrs, MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH, 
dev_path,
+dev_path_len);
+   kfree(dev_path);
+
+end:
+   mutex_unlock(>data_direct_lock);
+   return ret;
+}
+
 DECLARE_UVERBS_NAMED_METHOD(
MLX5_IB_METHOD_QUERY_PORT,
UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_QUERY_PORT_PORT_NUM,
@@ -193,9 +238,17 @@ DECLARE_UVERBS_NAMED_METHOD(
   reg_c0),
UA_MANDATORY));
 
+DECLARE_UVERBS_NAMED_METHOD(
+   MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH,
+   UVERBS_ATTR_PTR_OUT(
+   MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH,
+   UVERBS_ATTR_MIN_SIZE(0),
+   UA_MANDATORY));
+
 ADD_UVERBS_METHODS(mlx5_ib_device,
   UVERBS_OBJECT_DEVICE,
-  _METHOD(MLX5_IB_METHOD_QUERY_PORT));
+  _METHOD(MLX5_IB_METHOD_QUERY_PORT),
+  _METHOD(MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH));
 
 DECLARE_UVERBS_NAMED_METHOD(
MLX5_IB_METHOD_PD_QUERY,
diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h 
b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
index 106276a4cce7..fd2e4a3a56b3 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -348,6 +348,7 @@ enum mlx5_ib_pd_methods {
 
 enum mlx5_ib_device_methods {
MLX5_IB_METHOD_QUERY_PORT = (1U << UVERBS_ID_NS_SHIFT),
+   MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH,
 };
 
 enum mlx5_ib_query_port_attrs {
@@ -355,4 +356,8 @@ enum mlx5_ib_query_port_attrs {
MLX5_IB_ATTR_QUERY_PORT,
 };
 
+enum mlx5_ib_get_data_direct_sysfs_path_attrs {
+   MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH = (1U << UVERBS_ID_NS_SHIFT),
+};
+
 #endif
-- 
2.45.2



[PATCH rdma-next 7/8] RDMA/mlx5: Add support for DMABUF MR registrations with Data-direct

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Add support for DMABUF MR registrations with Data-direct device.

Upon userspace calling to register a DMABUF MR with the data direct bit
set, the below algorithm will be followed.

1) Obtain a pinned DMABUF umem from the IB core using the user input
parameters (FD, offset, length) and the DMA PF device.  The DMA PF
device is needed to allow the IOMMU to enable the DMA PF to access the
user buffer over PCI.

2) Create a KSM MKEY by setting its entries according to the user buffer
VA to IOVA mapping, with the MKEY being the data direct device-crossed
MKEY. This KSM MKEY is umrable and will be used as part of the MR cache.
The PD for creating it is the internal device 'data direct' kernel one.

3) Create a crossing MKEY that points to the KSM MKEY using the crossing
access mode.

4) Manage the KSM MKEY by adding it to a list of 'data direct' MKEYs
managed on the mlx5_ib device.

5) Return the crossing MKEY to the user, created with its supplied PD.

Upon DMA PF unbind flow, the driver will revoke the KSM entries.
The final deregistration will occur under the hood once the application
deregisters its MKEY.

Notes:
- This version supports only the PINNED UMEM mode, so there is no
  dependency on ODP.
- The IOVA supplied by the application must be system page aligned due to
  HW translations of KSM.
- The crossing MKEY will not be umrable or part of the MR cache, as we
  cannot change its crossed (i.e. KSM) MKEY over UMR.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/hw/mlx5/main.c |  11 +
 drivers/infiniband/hw/mlx5/mlx5_ib.h  |   8 +
 drivers/infiniband/hw/mlx5/mr.c   | 304 +++---
 drivers/infiniband/hw/mlx5/odp.c  |   5 +-
 drivers/infiniband/hw/mlx5/umr.c  |  93 ---
 drivers/infiniband/hw/mlx5/umr.h  |   1 +
 include/uapi/rdma/mlx5_user_ioctl_cmds.h  |   4 +
 include/uapi/rdma/mlx5_user_ioctl_verbs.h |   4 +
 8 files changed, 358 insertions(+), 72 deletions(-)

diff --git a/drivers/infiniband/hw/mlx5/main.c 
b/drivers/infiniband/hw/mlx5/main.c
index fc0562f07249..b85ad3c0bfa1 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -3490,6 +3490,7 @@ static int mlx5_ib_data_direct_init(struct mlx5_ib_dev 
*dev)
if (ret)
return ret;
 
+   INIT_LIST_HEAD(>data_direct_mr_list);
ret = mlx5_data_direct_ib_reg(dev, vuid);
if (ret)
mlx5_ib_free_data_direct_resources(dev);
@@ -3882,6 +3883,14 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
   dump_fill_mkey),
UA_MANDATORY));
 
+ADD_UVERBS_ATTRIBUTES_SIMPLE(
+   mlx5_ib_reg_dmabuf_mr,
+   UVERBS_OBJECT_MR,
+   UVERBS_METHOD_REG_DMABUF_MR,
+   UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_REG_DMABUF_MR_ACCESS_FLAGS,
+enum mlx5_ib_uapi_reg_dmabuf_flags,
+UA_OPTIONAL));
+
 static const struct uapi_definition mlx5_ib_defs[] = {
UAPI_DEF_CHAIN(mlx5_ib_devx_defs),
UAPI_DEF_CHAIN(mlx5_ib_flow_defs),
@@ -3891,6 +3900,7 @@ static const struct uapi_definition mlx5_ib_defs[] = {
UAPI_DEF_CHAIN(mlx5_ib_create_cq_defs),
 
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DEVICE, _ib_query_context),
+   UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR, _ib_reg_dmabuf_mr),
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_VAR,
UAPI_DEF_IS_OBJ_SUPPORTED(var_is_supported)),
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_UAR),
@@ -4396,6 +4406,7 @@ void mlx5_ib_data_direct_bind(struct mlx5_ib_dev *ibdev,
 void mlx5_ib_data_direct_unbind(struct mlx5_ib_dev *ibdev)
 {
mutex_lock(>data_direct_lock);
+   mlx5_ib_revoke_data_direct_mrs(ibdev);
ibdev->data_direct_dev = NULL;
mutex_unlock(>data_direct_lock);
 }
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h 
b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index e915a62da49c..be83a4d91a34 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -682,6 +682,8 @@ struct mlx5_ib_mr {
struct mlx5_ib_mkey mmkey;
 
struct ib_umem *umem;
+   /* The mr is data direct related */
+   u8 data_direct :1;
 
union {
/* Used only by kernel MRs (umem == NULL) */
@@ -719,6 +721,10 @@ struct mlx5_ib_mr {
} odp_destroy;
struct ib_odp_counters odp_stats;
bool is_odp_implicit;
+   /* The affilated data direct crossed mr */
+   struct mlx5_ib_mr *dd_crossed_mr;
+   struct list_head dd_node;
+   u8 revoked :1;
};
};
 };
@@ -1169,6 +1175,7 @@ struct mlx5_ib_dev {
/* protect resources needed as part of reset flow */
spinlock_t  reset_flow_resource_lock;
struct list_headqp_list;
+   

[PATCH rdma-next 2/8] RDMA/mlx5: Introduce the 'data direct' driver

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Introduce the 'data direct' driver for a ConnectX-8 Data Direct device.

The 'data direct' driver functions as the affiliated DMA device for one
or more capable mlx5_ib devices. This DMA device, as the name suggests,
is used exclusively for DMA operations. It can be considered a DMA engine
managed by a PF/VF, lacking network capabilities and having minimal overall
capabilities.

Consequently, the DMA NIC PF will not be exposed to or directly used by
software applications. The driver will not have any direct interface or
interaction with the firmware (no command interface, no capabilities,
etc.). It will operate solely over PCI to enable its DMA functionality.

Registration and un-registration of the driver are handled as part of
the mlx5_ib initialization and exit processes, as the mlx5_ib devices
will effectively be its clients.

The driver will serve as the DMA device for accessing another PCI device
to achieve optimal performance (both on the same NUMA node, P2P access,
etc.).

Upon probing, it will read its VUID over PCI to handle mlx5_ib device
registrations with the same VUID.

Upon removal, it will notify its clients to allow them to clean up the
resources that were mmaped with its DMA device.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/hw/mlx5/Makefile  |   1 +
 drivers/infiniband/hw/mlx5/data_direct.c | 227 +++
 drivers/infiniband/hw/mlx5/data_direct.h |  23 +++
 drivers/infiniband/hw/mlx5/main.c|  24 +++
 drivers/infiniband/hw/mlx5/mlx5_ib.h |   6 +
 5 files changed, 281 insertions(+)
 create mode 100644 drivers/infiniband/hw/mlx5/data_direct.c
 create mode 100644 drivers/infiniband/hw/mlx5/data_direct.h

diff --git a/drivers/infiniband/hw/mlx5/Makefile 
b/drivers/infiniband/hw/mlx5/Makefile
index 72a526236c2e..b38961f5058e 100644
--- a/drivers/infiniband/hw/mlx5/Makefile
+++ b/drivers/infiniband/hw/mlx5/Makefile
@@ -6,6 +6,7 @@ mlx5_ib-y := ah.o \
 cong.o \
 counters.o \
 cq.o \
+data_direct.o \
 dm.o \
 doorbell.o \
 gsi.o \
diff --git a/drivers/infiniband/hw/mlx5/data_direct.c 
b/drivers/infiniband/hw/mlx5/data_direct.c
new file mode 100644
index ..b9ba84afaae2
--- /dev/null
+++ b/drivers/infiniband/hw/mlx5/data_direct.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved
+ */
+
+#include "mlx5_ib.h"
+#include "data_direct.h"
+
+static LIST_HEAD(mlx5_data_direct_dev_list);
+static LIST_HEAD(mlx5_data_direct_reg_list);
+
+/*
+ * This mutex should be held when accessing either of the above lists
+ */
+static DEFINE_MUTEX(mlx5_data_direct_mutex);
+
+struct mlx5_data_direct_registration {
+   struct mlx5_ib_dev *ibdev;
+   char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1];
+   struct list_head list;
+};
+
+static const struct pci_device_id mlx5_data_direct_pci_table[] = {
+   { PCI_VDEVICE(MELLANOX, 0x2100) }, /* ConnectX-8 Data Direct */
+   { 0, }
+};
+
+static int mlx5_data_direct_vpd_get_vuid(struct mlx5_data_direct_dev *dev)
+{
+   struct pci_dev *pdev = dev->pdev;
+   unsigned int vpd_size, kw_len;
+   u8 *vpd_data;
+   int start;
+   int ret;
+
+   vpd_data = pci_vpd_alloc(pdev, _size);
+   if (IS_ERR(vpd_data)) {
+   pci_err(pdev, "Unable to read VPD, err=%ld\n", 
PTR_ERR(vpd_data));
+   return PTR_ERR(vpd_data);
+   }
+
+   start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, "VU", _len);
+   if (start < 0) {
+   ret = start;
+   pci_err(pdev, "VU keyword not found, err=%d\n", ret);
+   goto end;
+   }
+
+   dev->vuid = kmemdup_nul(vpd_data + start, kw_len, GFP_KERNEL);
+   ret = dev->vuid ? 0 : -ENOMEM;
+
+end:
+   kfree(vpd_data);
+   return ret;
+}
+
+static void mlx5_data_direct_shutdown(struct pci_dev *pdev)
+{
+   pci_disable_device(pdev);
+}
+
+static int mlx5_data_direct_set_dma_caps(struct pci_dev *pdev)
+{
+   int err;
+
+   err = dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(64));
+   if (err) {
+   dev_warn(>dev,
+"Warning: couldn't set 64-bit PCI DMA mask, err=%d\n", 
err);
+   err = dma_set_mask_and_coherent(>dev, DMA_BIT_MASK(32));
+   if (err) {
+   dev_err(>dev, "Can't set PCI DMA mask, err=%d\n", 
err);
+   return err;
+   }
+   }
+
+   dma_set_max_seg_size(>dev, SZ_2G);
+   return 0;
+}
+
+int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid)
+{
+   struct mlx5_data_direct_registration *reg;
+   struct mlx5_data_direct_dev *dev;
+
+   reg = kzalloc(sizeof(*reg), GFP_KERNEL);
+   if (!reg)
+   return -ENOMEM;
+
+   reg->ibdev = ibdev;
+   strcpy(reg->vuid, 

[PATCH rdma-next 4/8] RDMA/umem: Add support for creating pinned DMABUF umem with a given dma device

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Add support for creating pinned DMABUF umem with a specified DMA device
instead of the DMA device of the given IB device.

This API will be utilized in the upcoming patches of the series when
multiple path DMAs are implemented.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/core/umem_dmabuf.c | 45 ---
 include/rdma/ib_umem.h| 15 +
 2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/core/umem_dmabuf.c 
b/drivers/infiniband/core/umem_dmabuf.c
index 39357dc2d229..726a09786547 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -110,10 +110,12 @@ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf 
*umem_dmabuf)
 }
 EXPORT_SYMBOL(ib_umem_dmabuf_unmap_pages);
 
-struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
- unsigned long offset, size_t size,
- int fd, int access,
- const struct dma_buf_attach_ops *ops)
+static struct ib_umem_dmabuf *
+ib_umem_dmabuf_get_with_dma_device(struct ib_device *device,
+  struct device *dma_device,
+  unsigned long offset, size_t size,
+  int fd, int access,
+  const struct dma_buf_attach_ops *ops)
 {
struct dma_buf *dmabuf;
struct ib_umem_dmabuf *umem_dmabuf;
@@ -152,7 +154,7 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device 
*device,
 
umem_dmabuf->attach = dma_buf_dynamic_attach(
dmabuf,
-   device->dma_device,
+   dma_device,
ops,
umem_dmabuf);
if (IS_ERR(umem_dmabuf->attach)) {
@@ -168,6 +170,15 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device 
*device,
dma_buf_put(dmabuf);
return ret;
 }
+
+struct ib_umem_dmabuf *ib_umem_dmabuf_get(struct ib_device *device,
+ unsigned long offset, size_t size,
+ int fd, int access,
+ const struct dma_buf_attach_ops *ops)
+{
+   return ib_umem_dmabuf_get_with_dma_device(device, device->dma_device,
+ offset, size, fd, access, 
ops);
+}
 EXPORT_SYMBOL(ib_umem_dmabuf_get);
 
 static void
@@ -184,16 +195,18 @@ static struct dma_buf_attach_ops 
ib_umem_dmabuf_attach_pinned_ops = {
.move_notify = ib_umem_dmabuf_unsupported_move_notify,
 };
 
-struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
-unsigned long offset,
-size_t size, int fd,
-int access)
+struct ib_umem_dmabuf *
+ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
+ struct device *dma_device,
+ unsigned long offset, size_t size,
+ int fd, int access)
 {
struct ib_umem_dmabuf *umem_dmabuf;
int err;
 
-   umem_dmabuf = ib_umem_dmabuf_get(device, offset, size, fd, access,
-_umem_dmabuf_attach_pinned_ops);
+   umem_dmabuf = ib_umem_dmabuf_get_with_dma_device(device, dma_device, 
offset,
+size, fd, access,
+
_umem_dmabuf_attach_pinned_ops);
if (IS_ERR(umem_dmabuf))
return umem_dmabuf;
 
@@ -217,6 +230,16 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct 
ib_device *device,
ib_umem_release(_dmabuf->umem);
return ERR_PTR(err);
 }
+EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device);
+
+struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device,
+unsigned long offset,
+size_t size, int fd,
+int access)
+{
+   return ib_umem_dmabuf_get_pinned_with_dma_device(device, 
device->dma_device,
+offset, size, fd, 
access);
+}
 EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned);
 
 void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf)
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 565a85044541..de05268ed632 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -150,6 +150,11 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct 
ib_device 

[PATCH rdma-next 5/8] RDMA/umem: Introduce an option to revoke DMABUF umem

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Introduce an option to revoke DMABUF umem.

This option will retain the umem allocation while revoking its DMA
mapping. Furthermore, any subsequent attempts to map the pages should
fail once the umem has been revoked.

This functionality will be utilized in the upcoming patches in the
series, where we aim to delay umem deallocation until the mkey
deregistration. However, we must unmap its pages immediately.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/core/umem_dmabuf.c | 21 +++--
 include/rdma/ib_umem.h|  3 +++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/umem_dmabuf.c 
b/drivers/infiniband/core/umem_dmabuf.c
index 726a09786547..9fcd37761264 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -23,6 +23,9 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf 
*umem_dmabuf)
 
dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
 
+   if (umem_dmabuf->revoked)
+   return -EINVAL;
+
if (umem_dmabuf->sgt)
goto wait_fence;
 
@@ -242,15 +245,29 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct 
ib_device *device,
 }
 EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned);
 
-void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf)
+void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf)
 {
struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
 
dma_resv_lock(dmabuf->resv, NULL);
+   if (umem_dmabuf->revoked)
+   goto end;
ib_umem_dmabuf_unmap_pages(umem_dmabuf);
-   if (umem_dmabuf->pinned)
+   if (umem_dmabuf->pinned) {
dma_buf_unpin(umem_dmabuf->attach);
+   umem_dmabuf->pinned = 0;
+   }
+   umem_dmabuf->revoked = 1;
+end:
dma_resv_unlock(dmabuf->resv);
+}
+EXPORT_SYMBOL(ib_umem_dmabuf_revoke);
+
+void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf)
+{
+   struct dma_buf *dmabuf = umem_dmabuf->attach->dmabuf;
+
+   ib_umem_dmabuf_revoke(umem_dmabuf);
 
dma_buf_detach(dmabuf, umem_dmabuf->attach);
dma_buf_put(dmabuf);
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index de05268ed632..7dc7b1cc71b5 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -38,6 +38,7 @@ struct ib_umem_dmabuf {
unsigned long last_sg_trim;
void *private;
u8 pinned : 1;
+   u8 revoked : 1;
 };
 
 static inline struct ib_umem_dmabuf *to_ib_umem_dmabuf(struct ib_umem *umem)
@@ -158,6 +159,7 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device 
*device,
 int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf);
 void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf);
 void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf);
+void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
 
 #else /* CONFIG_INFINIBAND_USER_MEM */
 
@@ -217,6 +219,7 @@ static inline int ib_umem_dmabuf_map_pages(struct 
ib_umem_dmabuf *umem_dmabuf)
 }
 static inline void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf 
*umem_dmabuf) { }
 static inline void ib_umem_dmabuf_release(struct ib_umem_dmabuf *umem_dmabuf) 
{ }
+static inline void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) {}
 
 #endif /* CONFIG_INFINIBAND_USER_MEM */
 #endif /* IB_UMEM_H */
-- 
2.45.2



[PATCH rdma-next 3/8] RDMA/mlx5: Add the initialization flow to utilize the 'data direct' device

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Add the NET device initialization flow to utilize the 'data
direct' device.

When a NET mlx5_ib device is capable of 'data direct', the following
sequence of actions will occur:
- Find its affiliated 'data direct' VUID via a firmware command.
- Create its own private PD and 'data direct' mkey.
- Register to be notified when its 'data direct' driver is probed or removed.

The DMA device of the affiliated 'data direct' device, including the
private PD and the 'data direct' mkey, will be used later during MR
registrations that request the data direct functionality.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 drivers/infiniband/hw/mlx5/cmd.c | 21 +++
 drivers/infiniband/hw/mlx5/cmd.h |  2 +
 drivers/infiniband/hw/mlx5/main.c| 90 
 drivers/infiniband/hw/mlx5/mlx5_ib.h |  6 ++
 4 files changed, 119 insertions(+)

diff --git a/drivers/infiniband/hw/mlx5/cmd.c b/drivers/infiniband/hw/mlx5/cmd.c
index 895b62cc528d..7c08e3008927 100644
--- a/drivers/infiniband/hw/mlx5/cmd.c
+++ b/drivers/infiniband/hw/mlx5/cmd.c
@@ -245,3 +245,24 @@ int mlx5_cmd_uar_dealloc(struct mlx5_core_dev *dev, u32 
uarn, u16 uid)
MLX5_SET(dealloc_uar_in, in, uid, uid);
return mlx5_cmd_exec_in(dev, dealloc_uar, in);
 }
+
+int mlx5_cmd_query_vuid(struct mlx5_core_dev *dev, bool data_direct,
+   char *out_vuid)
+{
+   u8 out[MLX5_ST_SZ_BYTES(query_vuid_out) +
+   MLX5_ST_SZ_BYTES(array1024_auto)] = {};
+   u8 in[MLX5_ST_SZ_BYTES(query_vuid_in)] = {};
+   char *vuid;
+   int err;
+
+   MLX5_SET(query_vuid_in, in, opcode, MLX5_CMD_OPCODE_QUERY_VUID);
+   MLX5_SET(query_vuid_in, in, vhca_id, MLX5_CAP_GEN(dev, vhca_id));
+   MLX5_SET(query_vuid_in, in, data_direct, data_direct);
+   err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+   if (err)
+   return err;
+
+   vuid = MLX5_ADDR_OF(query_vuid_out, out, vuid);
+   memcpy(out_vuid, vuid, MLX5_ST_SZ_BYTES(array1024_auto));
+   return 0;
+}
diff --git a/drivers/infiniband/hw/mlx5/cmd.h b/drivers/infiniband/hw/mlx5/cmd.h
index e5cd31270443..e6c88b6ebd0d 100644
--- a/drivers/infiniband/hw/mlx5/cmd.h
+++ b/drivers/infiniband/hw/mlx5/cmd.h
@@ -58,4 +58,6 @@ int mlx5_cmd_mad_ifc(struct mlx5_ib_dev *dev, const void 
*inb, void *outb,
 u16 opmod, u8 port);
 int mlx5_cmd_uar_alloc(struct mlx5_core_dev *dev, u32 *uarn, u16 uid);
 int mlx5_cmd_uar_dealloc(struct mlx5_core_dev *dev, u32 uarn, u16 uid);
+int mlx5_cmd_query_vuid(struct mlx5_core_dev *dev, bool data_direct,
+   char *out_vuid);
 #endif /* MLX5_IB_CMD_H */
diff --git a/drivers/infiniband/hw/mlx5/main.c 
b/drivers/infiniband/hw/mlx5/main.c
index de254cf03173..fc0562f07249 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -3025,6 +3025,59 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev 
*dev)
mutex_destroy(>srq_lock);
 }
 
+static int
+mlx5_ib_create_data_direct_resources(struct mlx5_ib_dev *dev)
+{
+   int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
+   struct mlx5_core_dev *mdev = dev->mdev;
+   void *mkc;
+   u32 mkey;
+   u32 pdn;
+   u32 *in;
+   int err;
+
+   err = mlx5_core_alloc_pd(mdev, );
+   if (err)
+   return err;
+
+   in = kvzalloc(inlen, GFP_KERNEL);
+   if (!in) {
+   err = -ENOMEM;
+   goto err;
+   }
+
+   MLX5_SET(create_mkey_in, in, data_direct, 1);
+   mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
+   MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_PA);
+   MLX5_SET(mkc, mkc, lw, 1);
+   MLX5_SET(mkc, mkc, lr, 1);
+   MLX5_SET(mkc, mkc, rw, 1);
+   MLX5_SET(mkc, mkc, rr, 1);
+   MLX5_SET(mkc, mkc, a, 1);
+   MLX5_SET(mkc, mkc, pd, pdn);
+   MLX5_SET(mkc, mkc, length64, 1);
+   MLX5_SET(mkc, mkc, qpn, 0xff);
+   err = mlx5_core_create_mkey(mdev, , in, inlen);
+   kvfree(in);
+   if (err)
+   goto err;
+
+   dev->ddr.mkey = mkey;
+   dev->ddr.pdn = pdn;
+   return 0;
+
+err:
+   mlx5_core_dealloc_pd(mdev, pdn);
+   return err;
+}
+
+static void
+mlx5_ib_free_data_direct_resources(struct mlx5_ib_dev *dev)
+{
+   mlx5_core_destroy_mkey(dev->mdev, dev->ddr.mkey);
+   mlx5_core_dealloc_pd(dev->mdev, dev->ddr.pdn);
+}
+
 static u32 get_core_cap_flags(struct ib_device *ibdev,
  struct mlx5_hca_vport_context *rep)
 {
@@ -3421,6 +3474,38 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev 
*ibdev,
return false;
 }
 
+static int mlx5_ib_data_direct_init(struct mlx5_ib_dev *dev)
+{
+   char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1] = {};
+   int ret;
+
+   if (!MLX5_CAP_GEN(dev->mdev, data_direct))
+   return 0;
+
+   ret = mlx5_cmd_query_vuid(dev->mdev, true, 

[PATCH mlx5-next 1/8] net/mlx5: Add IFC related stuff for data direct

2024-08-01 Thread Leon Romanovsky
From: Yishai Hadas 

Add IFC related stuff for data direct.

Signed-off-by: Yishai Hadas 
Signed-off-by: Leon Romanovsky 
---
 include/linux/mlx5/mlx5_ifc.h | 51 +++
 1 file changed, 46 insertions(+), 5 deletions(-)

diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index cab228cf51c6..970c9d8473ef 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -313,6 +313,7 @@ enum {
MLX5_CMD_OP_MODIFY_VHCA_STATE = 0xb0e,
MLX5_CMD_OP_SYNC_CRYPTO   = 0xb12,
MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS   = 0xb16,
+   MLX5_CMD_OPCODE_QUERY_VUID= 0xb22,
MLX5_CMD_OP_MAX
 };
 
@@ -1885,7 +1886,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 
u8 reserved_at_5a0[0x10];
u8 enhanced_cqe_compression[0x1];
-   u8 reserved_at_5b1[0x2];
+   u8 reserved_at_5b1[0x1];
+   u8 crossing_vhca_mkey[0x1];
u8 log_max_dek[0x5];
u8 reserved_at_5b8[0x4];
u8 mini_cqe_resp_stride_index[0x1];
@@ -1954,7 +1956,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 dynamic_msix_table_size[0xc];
u8 reserved_at_740[0xc];
u8 min_dynamic_vf_msix_table_size[0x4];
-   u8 reserved_at_750[0x4];
+   u8 reserved_at_750[0x2];
+   u8 data_direct[0x1];
+   u8 reserved_at_753[0x1];
u8 max_dynamic_vf_msix_table_size[0xc];
 
u8 reserved_at_760[0x3];
@@ -1982,7 +1986,9 @@ struct mlx5_ifc_cmd_hca_cap_2_bits {
u8 reserved_at_0[0x80];
 
u8 migratable[0x1];
-   u8 reserved_at_81[0x1f];
+   u8 reserved_at_81[0x11];
+   u8 query_vuid[0x1];
+   u8 reserved_at_93[0xd];
 
u8 max_reformat_insert_size[0x8];
u8 max_reformat_insert_offset[0x8];
@@ -4154,6 +4160,7 @@ enum {
MLX5_MKC_ACCESS_MODE_KSM   = 0x3,
MLX5_MKC_ACCESS_MODE_SW_ICM = 0x4,
MLX5_MKC_ACCESS_MODE_MEMIC = 0x5,
+   MLX5_MKC_ACCESS_MODE_CROSSING = 0x6,
 };
 
 struct mlx5_ifc_mkc_bits {
@@ -4196,7 +4203,10 @@ struct mlx5_ifc_mkc_bits {
 
u8 bsf_octword_size[0x20];
 
-   u8 reserved_at_120[0x80];
+   u8 reserved_at_120[0x60];
+
+   u8 crossing_target_vhca_id[0x10];
+   u8 reserved_at_190[0x10];
 
u8 translations_octword_size[0x20];
 
@@ -5124,6 +5134,36 @@ struct mlx5_ifc_query_vport_state_out_bits {
u8 state[0x4];
 };
 
+struct mlx5_ifc_array1024_auto_bits {
+   u8 array1024_auto[32][0x20];
+};
+
+struct mlx5_ifc_query_vuid_in_bits {
+   u8 opcode[0x10];
+   u8 uid[0x10];
+
+   u8 reserved_at_20[0x40];
+
+   u8 query_vfs_vuid[0x1];
+   u8 data_direct[0x1];
+   u8 reserved_at_62[0xe];
+   u8 vhca_id[0x10];
+};
+
+struct mlx5_ifc_query_vuid_out_bits {
+   u8status[0x8];
+   u8reserved_at_8[0x18];
+
+   u8syndrome[0x20];
+
+   u8reserved_at_40[0x1a0];
+
+   u8reserved_at_1e0[0x10];
+   u8num_of_entries[0x10];
+
+   struct mlx5_ifc_array1024_auto_bits vuid[];
+};
+
 enum {
MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT  = 0x0,
MLX5_VPORT_STATE_OP_MOD_ESW_VPORT   = 0x1,
@@ -8989,7 +9029,8 @@ struct mlx5_ifc_create_mkey_in_bits {
 
u8 pg_access[0x1];
u8 mkey_umem_valid[0x1];
-   u8 reserved_at_62[0x1e];
+   u8 data_direct[0x1];
+   u8 reserved_at_63[0x1d];
 
struct mlx5_ifc_mkc_bits memory_key_mkey_entry;
 
-- 
2.45.2



[PATCH rdma-next 0/8] Introducing Multi-Path DMA Support for mlx5 RDMA Driver

2024-08-01 Thread Leon Romanovsky
From: Leon Romanovsky 

>From Yishai,

Overview

This patch series aims to enable multi-path DMA support, allowing an
mlx5 RDMA device to issue DMA commands through multiple paths. This
feature is critical for improving performance and reaching line rate
in certain environments where issuing PCI transactions over one path
may be significantly faster than over another. These differences can
arise from various PCI generations in the system or the specific system
topology.

To achieve this functionality, we introduced a data direct DMA device
that can serve the RDMA device by issuing DMA transactions on its behalf.

The main key features and changes are described below.

Multi-Path Discovery

API Implementation:
 * Introduced an API to discover multiple paths for a given mlx5 RDMA device.
IOCTL Command: 
 * Added a new IOCTL command, MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH, to
   the DEVICE object. When an affiliated Data-Direct/DMA device is present,
   its sysfs path is returned.

Feature Activation by mlx5 RDMA Application
---
UVERBS Extension:
 * Extended UVERBS_METHOD_REG_DMABUF_MR over UVERBS_OBJECT_MR to include
   mlx5 extended flags.
Access Flag: 
 * Introduced the MLX5_IB_UAPI_REG_DMABUF_ACCESS_DATA_DIRECT flag, allowing
   applications to request the use of the affiliated DMA device for DMABUF
   registration.

Data-Direct/DMA Device
--
New Driver:
 * Introduced a new driver to manage the new DMA PF device ID (0x2100).
   Its registration/un-registration is handled as part of the mlx5_ib init/exit
   flows, with mlx5 IB devices as its clients.
Functionality: 
 * The driver does not interface directly with the firmware (no command 
interface,
   no caps, etc.) but works over PCI to activate its DMA functionality. It 
serves
   as the DMA device for efficiently accessing other PCI devices (e.g., GPU PF) 
and
   reads its VUID over PCI to handle NICs registrations with the same VUID.

mlx5 IB RDMA Device
---
VUID Query: 
 * Reads its affiliated DMA PF VUID via the QUERY_VUID command with the 
data_direct
   bit set.
Driver Registration:
 * Registers with the DMA PF driver to be notified upon bind/unbind.
Application Request Handling: 
 * Uses the DMA PF device upon application request as described above.

DMABUF over Umem

Introduced an option to obtain a DMABUF UMEM using a different DMA
device instead of the IB device, allowing the device to register over
IOMMU with the expected DMA device for a given buffer registration.

Further details are provided in the commit logs of the patches in this
series.

Thanks

Yishai Hadas (8):
  net/mlx5: Add IFC related stuff for data direct
  RDMA/mlx5: Introduce the 'data direct' driver
  RDMA/mlx5: Add the initialization flow to utilize the 'data direct'
device
  RDMA/umem: Add support for creating pinned DMABUF umem with a given
dma device
  RDMA/umem: Introduce an option to revoke DMABUF umem
  RDMA: Pass uverbs_attr_bundle as part of '.reg_user_mr_dmabuf' API
  RDMA/mlx5: Add support for DMABUF MR registrations with Data-direct
  RDMA/mlx5: Introduce GET_DATA_DIRECT_SYSFS_PATH ioctl

 drivers/infiniband/core/umem_dmabuf.c |  66 +++-
 drivers/infiniband/core/uverbs_std_types_mr.c |   2 +-
 drivers/infiniband/hw/bnxt_re/ib_verbs.c  |   3 +-
 drivers/infiniband/hw/bnxt_re/ib_verbs.h  |   2 +-
 drivers/infiniband/hw/efa/efa.h   |   2 +-
 drivers/infiniband/hw/efa/efa_verbs.c |   4 +-
 drivers/infiniband/hw/irdma/verbs.c   |   2 +-
 drivers/infiniband/hw/mlx5/Makefile   |   1 +
 drivers/infiniband/hw/mlx5/cmd.c  |  21 ++
 drivers/infiniband/hw/mlx5/cmd.h  |   2 +
 drivers/infiniband/hw/mlx5/data_direct.c  | 227 +
 drivers/infiniband/hw/mlx5/data_direct.h  |  23 ++
 drivers/infiniband/hw/mlx5/main.c | 125 +++
 drivers/infiniband/hw/mlx5/mlx5_ib.h  |  22 +-
 drivers/infiniband/hw/mlx5/mr.c   | 304 +++---
 drivers/infiniband/hw/mlx5/odp.c  |   5 +-
 drivers/infiniband/hw/mlx5/std_types.c|  55 +++-
 drivers/infiniband/hw/mlx5/umr.c  |  93 --
 drivers/infiniband/hw/mlx5/umr.h  |   1 +
 include/linux/mlx5/mlx5_ifc.h |  51 ++-
 include/rdma/ib_umem.h|  18 ++
 include/rdma/ib_verbs.h   |   2 +-
 include/uapi/rdma/mlx5_user_ioctl_cmds.h  |   9 +
 include/uapi/rdma/mlx5_user_ioctl_verbs.h |   4 +
 24 files changed, 944 insertions(+), 100 deletions(-)
 create mode 100644 drivers/infiniband/hw/mlx5/data_direct.c
 create mode 100644 drivers/infiniband/hw/mlx5/data_direct.h

-- 
2.45.2



Re: [PATCH 2/9] drm/i915: Use backlight power constants

2024-08-01 Thread Jani Nikula
On Wed, 31 Jul 2024, Thomas Zimmermann  wrote:
> Hi
>
> Am 31.07.24 um 14:56 schrieb Jani Nikula:
>> On Wed, 31 Jul 2024, Thomas Zimmermann  wrote:
>>> Replace FB_BLANK_ constants with their counterparts from the
>>> backlight subsystem. The values are identical, so there's no
>>> change in functionality or semantics.
>>>
>>> Signed-off-by: Thomas Zimmermann 
>>> Cc: Jani Nikula 
>>> Cc: Rodrigo Vivi 
>>> Cc: Joonas Lahtinen 
>>> Cc: Tvrtko Ursulin 
>> Reviewed-by: Jani Nikula 
>
> Thanks.
>
>>
>> Do you want us to take this via drm-intel-next, or all together via
>> drm-misc? Either is fine.
>
> drm-intel-next is fine.

Pushed to drm-intel-next, thanks for the patch.

BR,
Jani.


-- 
Jani Nikula, Intel


Re: [PATCH v2 1/2] drm/mipi-dsi: add more multi functions for better error handling

2024-08-01 Thread Tejas Vipin



On 8/1/24 4:39 PM, Jani Nikula wrote:
> On Tue, 30 Jul 2024, Tejas Vipin  wrote:
>> Add more functions that can benefit from being multi style and mark
>> older variants as deprecated to eventually convert all mipi_dsi functions
>> to multi style.
> 
> What?
> 
> Why would a lot of regular DSI commands that are not exclusively used
> for one time setup need to be deprecated or converted to _multi()?
> 

All of the functions I've marked as deprecated here have a good amount
of their usage in conjunction with other mipi_dsi functions (an
exception being mipi_dsi_dcs_get_display_brightness which I have
realized is not suitable for this type of conversion). Them being
rewritten as multi style functions saves a lot of early returns and
errors being repeated over and over again across the codebase.

In the cases where they are just called by themselves, there is very little
overhead in replacing them with a multi variant. These functions would
be better off converted to multi variants, and the old versions removed
when all the function calls are replaced.

> BR,
> Jani.
> 
>>
>> Signed-off-by: Tejas Vipin 
>> ---
>>  drivers/gpu/drm/drm_mipi_dsi.c | 226 +
>>  include/drm/drm_mipi_dsi.h |  12 ++
>>  2 files changed, 238 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
>> index a471c46f5ca6..05ea7df5dec1 100644
>> --- a/drivers/gpu/drm/drm_mipi_dsi.c
>> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
>> @@ -603,6 +603,8 @@ EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
>>   * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() 
>> instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
>> @@ -652,6 +654,7 @@ EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
>>   * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS 
>> entries
>>   *
>>   * Enable or disable Display Stream Compression on the peripheral.
>> + * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() 
>> instead.
>>   *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>> @@ -703,6 +706,7 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode);
>>   * @pps: VESA DSC 1.1 Picture Parameter Set
>>   *
>>   * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
>> + * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() 
>> instead.
>>   *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>> @@ -1037,6 +1041,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_read);
>>   * mipi_dsi_dcs_nop() - send DCS nop packet
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
>> @@ -1055,6 +1061,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_nop);
>>   * mipi_dsi_dcs_soft_reset() - perform a software reset of the display 
>> module
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
>> @@ -1124,6 +1132,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
>>   *display module except interface communication
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() 
>> instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
>> @@ -1143,6 +1153,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
>>   *module
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() 
>> instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
>> @@ -1162,6 +1174,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
>>   *display device
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() 
>> instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
>> @@ -1181,6 +1195,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
>>   *display device
>>   * @dsi: DSI peripheral device
>>   *
>> + * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() 
>> instead.
>> + *
>>   * Return: 0 on success or a negative error code on failure
>>   */
>>  int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
>> @@ -1202,6 +1218,9 

Re: [PATCH] drm: Add documentation for struct drm_pane_size_hint

2024-08-01 Thread Jani Nikula
On Thu, 01 Aug 2024, abid-sayyad  wrote:
> Fixed warning for the following:
> ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct 
> member
>   'width' not described in 'drm_plane_size_hint'
> ./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct 
> member
>   'height' not described in 'drm_plane_size_hint'
>
> Signed-off-by: abid-sayyad 
> ---
>  include/uapi/drm/drm_mode.h | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index d390011b89b4..b581d384d4b5 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -864,7 +864,13 @@ struct drm_color_lut {
>   * array of struct drm_plane_size_hint.
>   */
>  struct drm_plane_size_hint {
> + /**
> +  * @width : width of the plane in pixels.

Please no space before :.

BR,
Jani.

> +  */
>   __u16 width;
> + /**
> +  * @height : height of the plane in pixels.
> +  */
>   __u16 height;
>  };

-- 
Jani Nikula, Intel


Re: [PATCH v2 1/2] drm/mipi-dsi: add more multi functions for better error handling

2024-08-01 Thread Jani Nikula
On Tue, 30 Jul 2024, Tejas Vipin  wrote:
> Add more functions that can benefit from being multi style and mark
> older variants as deprecated to eventually convert all mipi_dsi functions
> to multi style.

What?

Why would a lot of regular DSI commands that are not exclusively used
for one time setup need to be deprecated or converted to _multi()?

BR,
Jani.

>
> Signed-off-by: Tejas Vipin 
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 226 +
>  include/drm/drm_mipi_dsi.h |  12 ++
>  2 files changed, 238 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index a471c46f5ca6..05ea7df5dec1 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -603,6 +603,8 @@ EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
>   * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_turn_on_peripheral_multi() 
> instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
> @@ -652,6 +654,7 @@ EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
>   * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS 
> entries
>   *
>   * Enable or disable Display Stream Compression on the peripheral.
> + * This function is deprecated. Use mipi_dsi_compression_mode_ext_multi() 
> instead.
>   *
>   * Return: 0 on success or a negative error code on failure.
>   */
> @@ -703,6 +706,7 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode);
>   * @pps: VESA DSC 1.1 Picture Parameter Set
>   *
>   * Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
> + * This function is deprecated. Use mipi_dsi_picture_parameter_set_multi() 
> instead.
>   *
>   * Return: 0 on success or a negative error code on failure.
>   */
> @@ -1037,6 +1041,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_read);
>   * mipi_dsi_dcs_nop() - send DCS nop packet
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_nop_multi() instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
> @@ -1055,6 +1061,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_nop);
>   * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_soft_reset_multi() instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
> @@ -1124,6 +1132,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
>   *display module except interface communication
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_enter_sleep_mode_multi() 
> instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
> @@ -1143,6 +1153,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
>   *module
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_exit_sleep_mode_multi() 
> instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
> @@ -1162,6 +1174,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
>   *display device
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_set_display_off_multi() 
> instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
> @@ -1181,6 +1195,8 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
>   *display device
>   * @dsi: DSI peripheral device
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_set_display_on_multi() 
> instead.
> + *
>   * Return: 0 on success or a negative error code on failure
>   */
>  int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
> @@ -1202,6 +1218,9 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
>   * @start: first column of frame memory
>   * @end: last column of frame memory
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_set_column_address_multi()
> + * instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
> @@ -1226,6 +1245,9 @@ EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
>   * @start: first page of frame memory
>   * @end: last page of frame memory
>   *
> + * This function is deprecated. Use mipi_dsi_dcs_set_page_address_multi()
> + * instead.
> + *
>   * Return: 0 on success or a negative error code on failure.
>   */
>  int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
> @@ -1268,6 +1290,8 @@ 

Re: [PATCH 1/5] udmabuf: cancel mmap page fault, direct map it

2024-08-01 Thread Huan Yang



在 2024/8/1 18:50, Christian König 写道:

Am 01.08.24 um 12:45 schrieb Huan Yang:
The current udmabuf mmap uses a page fault mechanism to populate the 
vma.


However, the current udmabuf has already obtained and pinned the folio
upon completion of the creation.This means that the physical memory has
already been acquired, rather than being accessed dynamically. The
current page fault method only saves some page table memory.

As a result, the page fault mechanism has lost its purpose as a 
demanding

page. Due to the fact that page fault requires trapping into kernel mode
and filling in when accessing the corresponding virtual address in mmap,
this means that user mode access to virtual addresses needs to trap into
kernel mode.

Therefore, when creating a large size udmabuf, this represents a
considerable overhead.

Therefore, the current patch removes the page fault method of mmap and
instead fills it directly when mmap is triggered.

Signed-off-by: Huan Yang 
---
  drivers/dma-buf/udmabuf.c | 70 ++-
  1 file changed, 39 insertions(+), 31 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 047c3cd2ceff..d69aeada7367 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -38,36 +38,39 @@ struct udmabuf_folio {
  struct list_head list;
  };
  -static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
-{
-    struct vm_area_struct *vma = vmf->vma;
-    struct udmabuf *ubuf = vma->vm_private_data;
-    pgoff_t pgoff = vmf->pgoff;
-    unsigned long pfn;
-
-    if (pgoff >= ubuf->pagecount)
-    return VM_FAULT_SIGBUS;
-
-    pfn = folio_pfn(ubuf->folios[pgoff]);
-    pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT;
-
-    return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
-static const struct vm_operations_struct udmabuf_vm_ops = {
-    .fault = udmabuf_vm_fault,
-};
+static struct sg_table *get_sg_table(struct device *dev, struct 
dma_buf *buf,

+ enum dma_data_direction direction);
    static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)

  {
  struct udmabuf *ubuf = buf->priv;
+    struct sg_table *table = ubuf->sg;
+    unsigned long addr = vma->vm_start;
+    struct sg_page_iter piter;
+    int ret;
    if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
  return -EINVAL;
  -    vma->vm_ops = _vm_ops;
-    vma->vm_private_data = ubuf;
-    vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+    if (!table) {
+    table = get_sg_table(NULL, buf, 0);
+    if (IS_ERR(table))
+    return PTR_ERR(table);
+    ubuf->sg = table;
+    }
+
+    for_each_sgtable_page(table, , vma->vm_pgoff) {


That might not work correctly. We intentionally remove the pages from 
the sgtable when it is shared between devices.


Additional to that the sgtable is *not* a page container, but rather a 
DMA address container. So that here is also a rather bad idea from the 
design side.


Sorry for that and patch 1 3 4's ops. I was not aware of this before. 
All idea to do this in mmap/vmap is just like system_heap and any other 
heaps that I learned.


But well to learn it.

BTW, sgtable is a wrong idea to maintain page, maybe we need to both 
setup page's array(order 0 page), and folio's array(only the folio, use 
for unpin)?


Or else, mapping page to vm_off and vma solely through folio's array is 
quite challenging.
Moreover, even in this way, the memory overhead is smaller than the 
current unpin list.


Thanks for your correct.:)



Regards,
Christian.


+    struct page *page = sg_page_iter_page();
+
+    ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE,
+  vma->vm_page_prot);
+    if (ret)
+    return ret;
+    addr += PAGE_SIZE;
+    if (addr >= vma->vm_end)
+    return 0;
+    }
+
  return 0;
  }
  @@ -126,6 +129,10 @@ static struct sg_table *get_sg_table(struct 
device *dev, struct dma_buf *buf,

  sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE,
   ubuf->offsets[i]);
  +    // if dev is NULL, no need to sync.
+    if (!dev)
+    return sg;
+
  ret = dma_map_sgtable(dev, sg, direction, 0);
  if (ret < 0)
  goto err_map;
@@ -206,20 +213,21 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
  {
  struct udmabuf *ubuf = buf->priv;
  struct device *dev = ubuf->device->this_device;
-    int ret = 0;
+    struct sg_table *sg;
  -    if (!ubuf->sg) {
-    ubuf->sg = get_sg_table(dev, buf, direction);
-    if (IS_ERR(ubuf->sg)) {
-    ret = PTR_ERR(ubuf->sg);
-    ubuf->sg = NULL;
-    }
-    } else {
+    if (ubuf->sg) {
  dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
  direction);
+    return 0;
  }
  -    return ret;
+    sg = get_sg_table(dev, buf, direction);
+    if (IS_ERR(sg))
+    return PTR_ERR(sg);
+
+    ubuf->sg = sg;
+
+    return 0;
  }
   

Re: [PATCH] backlight: pwm_bl: print errno for probe errors

2024-08-01 Thread Kepplinger-Novakovic Martin
Am Donnerstag, dem 01.08.2024 um 12:09 +0200 schrieb Uwe Kleine-König:
> Hello Martin,
> 
> On Thu, Aug 01, 2024 at 09:52:01AM +, Kepplinger-Novakovic Martin
> wrote:
> > Am Donnerstag, dem 01.08.2024 um 11:26 +0200 schrieb Uwe Kleine-
> > König:
> > > On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-
> > > Novaković
> > > wrote:
> > > > diff --git a/drivers/video/backlight/pwm_bl.c
> > > > b/drivers/video/backlight/pwm_bl.c
> > > > index f1005bd0c41e3..cc7e7af71891f 100644
> > > > --- a/drivers/video/backlight/pwm_bl.c
> > > > +++ b/drivers/video/backlight/pwm_bl.c
> > > > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct
> > > > platform_device *pdev)
> > > >   GPIOD_ASIS);
> > > > if (IS_ERR(pb->enable_gpio)) {
> > > > ret = dev_err_probe(>dev, PTR_ERR(pb-
> > > > > enable_gpio),
> > > > -   "failed to acquire enable
> > > > GPIO\n");
> > > > +   "failed to acquire enable
> > > > GPIO:
> > > > %ld\n",
> > > > +   PTR_ERR(pb->enable_gpio));
> > > 
> > > AFAIK dev_err_probe already emits the error code passed as 2nd
> > > parameter. So I wonder about this patch's benefit.
> > > 
> > 
> > It does. Other messages only take the deferred_probe_reason without
> > the
> > error code. It's actually fine if users properly enable debugging
> > after
> > seeing an error and then this change is not needed :)
> 
> I'm unsure what you intend to say here. Do you agree that this patch
> doesn't need to be applied as it doesn't add any information to the
> emitted messages? Or do you think there is a value because "users
> don't
> need to enable debugging" then. In the latter case I don't see where
> users would see "failed to acquire enable GPIO" before, but not the
> value of the error code.
> 

hi Uwe, sorry, I agree that this patch doesn't add any information. I
think it can be expected to look at debug when drivers don't probe.

thanks,
 martin


smime.p7s
Description: S/MIME cryptographic signature


[PATCH] backlight: pwm_bl: print errno for probe errors

2024-08-01 Thread Martin Kepplinger-Novaković
This makes debugging often easier.

Signed-off-by: Martin Kepplinger-Novaković 

---
 drivers/video/backlight/pwm_bl.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index f1005bd0c41e3..cc7e7af71891f 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
  GPIOD_ASIS);
if (IS_ERR(pb->enable_gpio)) {
ret = dev_err_probe(>dev, PTR_ERR(pb->enable_gpio),
-   "failed to acquire enable GPIO\n");
+   "failed to acquire enable GPIO: %ld\n",
+   PTR_ERR(pb->enable_gpio));
goto err_alloc;
}
 
@@ -513,7 +514,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->power_supply = NULL;
} else {
dev_err_probe(>dev, ret,
- "failed to acquire power regulator\n");
+ "failed to acquire power regulator: %d\n",
+ ret);
goto err_alloc;
}
}
@@ -521,7 +523,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->pwm = devm_pwm_get(>dev, NULL);
if (IS_ERR(pb->pwm)) {
ret = dev_err_probe(>dev, PTR_ERR(pb->pwm),
-   "unable to request PWM\n");
+   "unable to request PWM: %ld\n",
+   PTR_ERR(pb->pwm));
goto err_alloc;
}
 
-- 
2.39.2


smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH] backlight: pwm_bl: print errno for probe errors

2024-08-01 Thread Kepplinger-Novakovic Martin
Am Donnerstag, dem 01.08.2024 um 11:26 +0200 schrieb Uwe Kleine-König:
> Hello Martin,
> 
> On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-Novaković
> wrote:
> > This makes debugging often easier.
> > 
> > Signed-off-by: Martin Kepplinger-Novaković
> > 
> > ---
> >  drivers/video/backlight/pwm_bl.c | 9 ++---
> >  1 file changed, 6 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/video/backlight/pwm_bl.c
> > b/drivers/video/backlight/pwm_bl.c
> > index f1005bd0c41e3..cc7e7af71891f 100644
> > --- a/drivers/video/backlight/pwm_bl.c
> > +++ b/drivers/video/backlight/pwm_bl.c
> > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct
> > platform_device *pdev)
> >   GPIOD_ASIS);
> > if (IS_ERR(pb->enable_gpio)) {
> > ret = dev_err_probe(>dev, PTR_ERR(pb-
> > >enable_gpio),
> > -   "failed to acquire enable
> > GPIO\n");
> > +   "failed to acquire enable GPIO:
> > %ld\n",
> > +   PTR_ERR(pb->enable_gpio));
> 
> AFAIK dev_err_probe already emits the error code passed as 2nd
> parameter. So I wonder about this patch's benefit.
> 

It does. Other messages only take the deferred_probe_reason without the
error code. It's actually fine if users properly enable debugging after
seeing an error and then this change is not needed :)

thanks,
   martin


smime.p7s
Description: S/MIME cryptographic signature


[PATCH] drm: Add documentation for struct drm_pane_size_hint

2024-08-01 Thread abid-sayyad
Fixed warning for the following:
./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member
'width' not described in 'drm_plane_size_hint'
./include/uapi/drm/drm_mode.h:869: warning: Function parameter or struct member
'height' not described in 'drm_plane_size_hint'

Signed-off-by: abid-sayyad 
---
 include/uapi/drm/drm_mode.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index d390011b89b4..b581d384d4b5 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -864,7 +864,13 @@ struct drm_color_lut {
  * array of struct drm_plane_size_hint.
  */
 struct drm_plane_size_hint {
+   /**
+* @width : width of the plane in pixels.
+*/
__u16 width;
+   /**
+* @height : height of the plane in pixels.
+*/
__u16 height;
 };
 
-- 
2.39.2



[PATCH] [V2] drm: panel-orientation-quirks: Also handle rotation for DeckHD equipped LCDs units

2024-08-01 Thread Marco Rodolfi
From: Marco Rodolfi 

This patch also take account of the different resolution for the
aftermarket DeckHD panel, which hasn't been accounted for yet in kernel,
since these quirks are applied based on BIOS information + panel
resolution.

This patch correct that problem and make the panel oriented the right
way.

Changes in V2:
Had some issues with gmail and this mailinglist that I completely
mistyped the panel resolution in the original patch. It is still a 16:10
panel, not a 16:9, so the original one is wrong. It's fixed now.

Signed-off-by: Marco Rodolfi 
---
 drivers/gpu/drm/drm_panel_orientation_quirks.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c 
b/drivers/gpu/drm/drm_panel_orientation_quirks.c
index 3860a8ce1e2d..32582dbdc184 100644
--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -420,13 +420,20 @@ static const struct dmi_system_id orientation_data[] = {
  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"),
},
.driver_data = (void *)_rightside_up,
-   }, {/* Valve Steam Deck (Jupiter) */
+   }, {/* Valve Steam Deck (Jupiter) Stock Display */
.matches = {
  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
},
.driver_data = (void *)_rightside_up,
+   }, {/* Valve Steam Deck (Jupiter) DeckHD Display */
+   .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
+   },
+   .driver_data = (void *)_rightside_up,
}, {/* Valve Steam Deck (Galileo) */
.matches = {
  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
-- 
2.46.0



Re: [PATCH 4/5] udmabuf: add get_sg_table helper function

2024-08-01 Thread Christian König

Am 01.08.24 um 12:45 schrieb Huan Yang:

Currently, there are three duplicate pieces of code that retrieve
sg_table and update uduf->sg.

Since the sgt is used to populate the page in both mmap and vmap.It is
necessary to ensure that ubuf->sg is set correctly.


That is a really bad idea. Why are sg tables used to populated the page 
tables?


Regards,
Christian.




This patch add a helper function, if ubuf->sg exist, just return it.
Or else, try alloc a new sgt, and cmpxchg to set it.

When the swap fails, it means that another process has set sg correctly.
Therefore, we reuse the new sg. If trigger by device, need invoke map to
sync it.

Signed-off-by: Huan Yang 
---
  drivers/dma-buf/udmabuf.c | 60 ---
  1 file changed, 43 insertions(+), 17 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 7ed532342d7f..677ebb2d462f 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -38,8 +38,9 @@ struct udmabuf_folio {
struct list_head list;
  };
  
-static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,

-enum dma_data_direction direction);
+static struct sg_table *udmabuf_get_sg_table(struct device *dev,
+struct dma_buf *buf,
+enum dma_data_direction direction);
  
  static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)

  {
@@ -52,12 +53,9 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;
  
-	if (!table) {

-   table = get_sg_table(NULL, buf, 0);
-   if (IS_ERR(table))
-   return PTR_ERR(table);
-   ubuf->sg = table;
-   }
+   table = udmabuf_get_sg_table(NULL, buf, 0);
+   if (IS_ERR(table))
+   return PTR_ERR(table);
  
  	for_each_sgtable_page(table, , vma->vm_pgoff) {

struct page *page = sg_page_iter_page();
@@ -84,12 +82,9 @@ static int vmap_udmabuf(struct dma_buf *buf, struct 
iosys_map *map)
  
  	dma_resv_assert_held(buf->resv);
  
-	if (!sg) {

-   sg = get_sg_table(NULL, buf, 0);
-   if (IS_ERR(sg))
-   return PTR_ERR(sg);
-   ubuf->sg = sg;
-   }
+   sg = udmabuf_get_sg_table(NULL, buf, 0);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
  
  	pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);

if (!pages)
@@ -154,6 +149,39 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
return ERR_PTR(ret);
  }
  
+static struct sg_table *udmabuf_get_sg_table(struct device *dev,

+struct dma_buf *buf,
+enum dma_data_direction direction)
+{
+   struct udmabuf *ubuf = buf->priv;
+   struct sg_table *sg = READ_ONCE(ubuf->sg);
+   int ret = 0;
+
+   if (sg)
+   return sg;
+
+   sg = get_sg_table(dev, buf, direction);
+   if (IS_ERR(sg))
+   return sg;
+
+   // Success update ubuf's sg, just return.
+   if (!cmpxchg(>sg, NULL, sg))
+   return sg;
+
+   // use the new sg table.
+   sg_free_table(sg);
+   kfree(sg);
+   sg = READ_ONCE(ubuf->sg);
+
+   if (dev)
+   ret = dma_map_sgtable(dev, sg, direction, 0);
+
+   if (ret < 0)
+   return ERR_PTR(ret);
+
+   return sg;
+}
+
  static void put_sg_table(struct device *dev, struct sg_table *sg,
 enum dma_data_direction direction)
  {
@@ -230,12 +258,10 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
return 0;
}
  
-	sg = get_sg_table(dev, buf, direction);

+   sg = udmabuf_get_sg_table(dev, buf, direction);
if (IS_ERR(sg))
return PTR_ERR(sg);
  
-	ubuf->sg = sg;

-
return 0;
  }
  




[syzbot] [dri?] WARNING in drm_wait_one_vblank (2)

2024-08-01 Thread syzbot
Hello,

syzbot found the following issue on:

HEAD commit:6342649c33d2 Merge tag 'block-6.11-20240726' of git://git...
git tree:   upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1443cb0398
kernel config:  https://syzkaller.appspot.com/x/.config?x=5efb917b1462a973
dashboard link: https://syzkaller.appspot.com/bug?extid=147ba789658184f0ce04
compiler:   Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 
2.40

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: 
https://storage.googleapis.com/syzbot-assets/6057dd16bc1c/disk-6342649c.raw.xz
vmlinux: 
https://storage.googleapis.com/syzbot-assets/4121b87a6477/vmlinux-6342649c.xz
kernel image: 
https://storage.googleapis.com/syzbot-assets/57d676edb7cb/bzImage-6342649c.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+147ba789658184f0c...@syzkaller.appspotmail.com

[ cut here ]
platform vkms: [drm] vblank wait timed out on crtc 0
WARNING: CPU: 1 PID: 7412 at drivers/gpu/drm/drm_vblank.c:1307 
drm_wait_one_vblank+0x976/0x9f0 drivers/gpu/drm/drm_vblank.c:1307
Modules linked in:
CPU: 1 UID: 0 PID: 7412 Comm: syz.1.410 Not tainted 
6.10.0-syzkaller-12881-g6342649c33d2 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 
06/27/2024
RIP: 0010:drm_wait_one_vblank+0x976/0x9f0 drivers/gpu/drm/drm_vblank.c:1307
Code: 80 3c 08 00 74 08 4c 89 ff e8 76 0a 9c fc 49 8b 1f 48 c7 c7 e0 f4 72 8c 
4c 89 f6 48 89 da 8b 5c 24 0c 89 d9 e8 0b e1 f6 fb 90 <0f> 0b 90 90 49 be 00 00 
00 00 00 fc ff df e9 68 fb ff ff 44 89 e9
RSP: 0018:c90003f87ac0 EFLAGS: 00010246
RAX: 1af066dba6c5c900 RBX:  RCX: 0004
RDX: c900041f9000 RSI: 00031631 RDI: 00031632
RBP: c90003f87c00 R08: 815592f2 R09: fbfff1cf9f80
R10: dc00 R11: fbfff1cf9f80 R12: 1920007f0f64
R13: 2635 R14: 8c861520 R15: 888020618010
FS:  7ff6598ef6c0() GS:8880b930() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7ff6598ced58 CR3: 4b096000 CR4: 003506f0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe0ff0 DR7: 0400
Call Trace:
 
 drm_fb_helper_ioctl+0x114/0x140 drivers/gpu/drm/drm_fb_helper.c:1088
 do_fb_ioctl+0x40a/0x7b0 drivers/video/fbdev/core/fb_chrdev.c:155
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:907 [inline]
 __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:893
 do_syscall_x64 arch/x86/entry/common.c:52 [inline]
 do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7ff658b77299
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 
89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 
c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:7ff6598ef048 EFLAGS: 0246 ORIG_RAX: 0010
RAX: ffda RBX: 7ff658d05f80 RCX: 7ff658b77299
RDX:  RSI: 40044620 RDI: 0003
RBP: 7ff658be48e6 R08:  R09: 
R10:  R11: 0246 R12: 
R13: 000b R14: 7ff658d05f80 R15: 7ff658e2fa38
 


---
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 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 one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup


Re: [PATCH 3/5] udmabuf: fix vmap_udmabuf error page set

2024-08-01 Thread Christian König




Am 01.08.24 um 12:45 schrieb Huan Yang:

Currently vmap_udmabuf set page's array by each folio.
But, ubuf->folios is only contain's the folio's head page.

That mean we repeatedly mapped the folio head page to the vmalloc area.

This patch fix it, set each folio's page correct, so that pages array
contains right page, and then map into vmalloc area

Signed-off-by: Huan Yang 
---
  drivers/dma-buf/udmabuf.c | 17 +
  1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index a915714c5dce..7ed532342d7f 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -77,18 +77,27 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
  static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
  {
struct udmabuf *ubuf = buf->priv;
-   struct page **pages;
+   struct page **pages, **tmp;
+   struct sg_table *sg = ubuf->sg;
+   struct sg_page_iter piter;
void *vaddr;
-   pgoff_t pg;
  
  	dma_resv_assert_held(buf->resv);
  
+	if (!sg) {

+   sg = get_sg_table(NULL, buf, 0);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
+   ubuf->sg = sg;
+   }
+
pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
if (!pages)
return -ENOMEM;
+   tmp = pages;
  
-	for (pg = 0; pg < ubuf->pagecount; pg++)

-   pages[pg] = >folios[pg]->page;
+   for_each_sgtable_page(sg, , 0)
+   *tmp++ = sg_page_iter_page();


Again don't abuse the sg table for that!

Regards,
Christian.

  
  	vaddr = vm_map_ram(pages, ubuf->pagecount, -1);

kvfree(pages);




Re: [PATCH 2/5] udmabuf: change folios array from kmalloc to kvmalloc

2024-08-01 Thread Christian König

Am 01.08.24 um 12:45 schrieb Huan Yang:

When PAGE_SIZE 4096, MAX_PAGE_ORDER 10, 64bit machine,
page_alloc only support 4MB.
If above this, trigger this warn and return NULL.

udmabuf can change size limit, if change it to 3072(3GB), and then alloc
3GB udmabuf, will fail create.

[ 4080.876581] [ cut here ]
[ 4080.876843] WARNING: CPU: 3 PID: 2015 at mm/page_alloc.c:4556 
__alloc_pages+0x2c8/0x350
[ 4080.878839] RIP: 0010:__alloc_pages+0x2c8/0x350
[ 4080.879470] Call Trace:
[ 4080.879473]  
[ 4080.879473]  ? __alloc_pages+0x2c8/0x350
[ 4080.879475]  ? __warn.cold+0x8e/0xe8
[ 4080.880647]  ? __alloc_pages+0x2c8/0x350
[ 4080.880909]  ? report_bug+0xff/0x140
[ 4080.881175]  ? handle_bug+0x3c/0x80
[ 4080.881556]  ? exc_invalid_op+0x17/0x70
[ 4080.881559]  ? asm_exc_invalid_op+0x1a/0x20
[ 4080.882077]  ? udmabuf_create+0x131/0x400

Because MAX_PAGE_ORDER, kmalloc can max alloc 4096 * (1 << 10), 4MB
memory, each array entry is pointer(8byte), so can save 524288 pages(2GB).

Further more, costly order(order 3) may not be guaranteed that it can be
applied for, due to fragmentation.

This patch change udmabuf array use kvmalloc_array, this can fallback
alloc into vmalloc, which can guarantee allocation for any size and does
not affect the performance of kmalloc allocations.

Signed-off-by: Huan Yang 


Acked-by: Christian König 


---
  drivers/dma-buf/udmabuf.c | 26 +-
  1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index d69aeada7367..a915714c5dce 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -83,7 +83,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map 
*map)
  
  	dma_resv_assert_held(buf->resv);
  
-	pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);

+   pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
if (!pages)
return -ENOMEM;
  
@@ -91,7 +91,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)

pages[pg] = >folios[pg]->page;
  
  	vaddr = vm_map_ram(pages, ubuf->pagecount, -1);

-   kfree(pages);
+   kvfree(pages);
if (!vaddr)
return -EINVAL;
  
@@ -203,8 +203,8 @@ static void release_udmabuf(struct dma_buf *buf)

put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
  
  	unpin_all_folios(>unpin_list);

-   kfree(ubuf->offsets);
-   kfree(ubuf->folios);
+   kvfree(ubuf->offsets);
+   kvfree(ubuf->folios);
kfree(ubuf);
  }
  
@@ -330,14 +330,14 @@ static long udmabuf_create(struct miscdevice *device,

if (!ubuf->pagecount)
goto err;
  
-	ubuf->folios = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),

-   GFP_KERNEL);
+   ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),
+ GFP_KERNEL);
if (!ubuf->folios) {
ret = -ENOMEM;
goto err;
}
-   ubuf->offsets = kcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
-   GFP_KERNEL);
+   ubuf->offsets =
+   kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), GFP_KERNEL);
if (!ubuf->offsets) {
ret = -ENOMEM;
goto err;
@@ -351,7 +351,7 @@ static long udmabuf_create(struct miscdevice *device,
goto err;
  
  		pgcnt = list[i].size >> PAGE_SHIFT;

-   folios = kmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
+   folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
if (!folios) {
ret = -ENOMEM;
goto err;
@@ -361,7 +361,7 @@ static long udmabuf_create(struct miscdevice *device,
ret = memfd_pin_folios(memfd, list[i].offset, end,
   folios, pgcnt, );
if (ret <= 0) {
-   kfree(folios);
+   kvfree(folios);
if (!ret)
ret = -EINVAL;
goto err;
@@ -390,7 +390,7 @@ static long udmabuf_create(struct miscdevice *device,
}
}
  
-		kfree(folios);

+   kvfree(folios);
fput(memfd);
memfd = NULL;
}
@@ -406,8 +406,8 @@ static long udmabuf_create(struct miscdevice *device,
if (memfd)
fput(memfd);
unpin_all_folios(>unpin_list);
-   kfree(ubuf->offsets);
-   kfree(ubuf->folios);
+   kvfree(ubuf->offsets);
+   kvfree(ubuf->folios);
kfree(ubuf);
return ret;
  }




RE: [PATCH v2 3/9] dt-bindings: display: renesas,rzg2l-du: Document RZ/G2UL DU bindings

2024-08-01 Thread Biju Das
Hi Laurent Pinchart,

Thanks for the feedback.

> -Original Message-
> From: Laurent Pinchart 
> Sent: Wednesday, July 31, 2024 2:47 PM
> Subject: Re: [PATCH v2 3/9] dt-bindings: display: renesas,rzg2l-du: Document 
> RZ/G2UL DU bindings
> 
> Hi Biju,
> 
> On Mon, Jul 29, 2024 at 09:05:59AM +, Biju Das wrote:
> > On Saturday, July 27, 2024 1:50 AM, Laurent Pinchart wrote:
> > > On Tue, Jul 09, 2024 at 02:51:41PM +0100, Biju Das wrote:
> > > > Document DU found in RZ/G2UL SoC. The DU block is identical to
> > > > RZ/G2L SoC, but has only DPI interface.
> > > >
> > > > While at it, add missing required property port@1 for RZ/G2L and
> > > > RZ/V2L SoCs. Currently there is no user for the DPI interface and
> > > > hence there won't be any ABI breakage for adding port@1 as
> > > > required property for RZ/G2L and RZ/V2L SoCs.
> > > >
> > > > Signed-off-by: Biju Das 
> > > > Acked-by: Conor Dooley 
> > > > ---
> > > > v1->v2:
> > > >  * Updated commit description related to non ABI breakage.
> > > >  * Added Ack from Conor.
> > > > ---
> > > >  .../bindings/display/renesas,rzg2l-du.yaml| 32 +--
> > > >  1 file changed, 29 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
> > > > b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
> > > > index 08e5b9478051..c0fec282fa45 100644
> > > > ---
> > > > a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml
> > > > +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.y
> > > > +++ aml
> > > > @@ -18,6 +18,7 @@ properties:
> > > >compatible:
> > > >  oneOf:
> > > >- enum:
> > > > +  - renesas,r9a07g043u-du # RZ/G2UL
> > > >- renesas,r9a07g044-du # RZ/G2{L,LC}
> > > >- items:
> > > >- enum:
> > > > @@ -60,9 +61,6 @@ properties:
> > > >  $ref: /schemas/graph.yaml#/properties/port
> > > >  unevaluatedProperties: false
> > > >
> > > > -required:
> > > > -  - port@0
> > > > -
> > > >  unevaluatedProperties: false
> > > >
> > > >renesas,vsps:
> > > > @@ -88,6 +86,34 @@ required:
> > > >
> > > >  additionalProperties: false
> > > >
> > > > +allOf:
> > > > +  - if:
> > > > +  properties:
> > > > +compatible:
> > > > +  contains:
> > > > +const: renesas,r9a07g043u-du
> > > > +then:
> > > > +  properties:
> > > > +ports:
> > > > +  properties:
> > > > +port@0: false
> > > > +port@1:
> > > > +  description: DPI
> > > > +
> > > > +  required:
> > > > +- port@1
> > >
> > > Why do you use port@1 for the DPI output here, and not port@0 ?
> >
> > Currently the output is based on port number and port = 1 corresponds to 
> > DPI. See [1].
> >
> > For consistency, I documented bindings for RZ/G2L family DU's similar to 
> > RZ/G2{H,M,N,E} DU [2].
> >
> > So please let me know, are you ok with this?
> 
> I won't insist strongly, but I don't think that using the port number to 
> indicate the output type is
> the best idea. In the R-Car DU driver at least, that wouldn't have scaled. We 
> have multiple outputs of
> the same type on some SoCs. Furthemore, the same DU hardware channel number 
> (i.e.
> the offset of the registers specific to that channel in the DU register
> space) is not the same across SoCs for the same output type. I recommend 
> numbering the ports based on
> the hardware number of the output (the exact meaning of this is specific to 
> your device, I haven't
> checked what it means for RZ/G2L), not on the output type.

OK, will update the bindings to use port for RZ/G2UL and Ports for RZ/{G2L, 
V2L} as it has multiple DU outputs.
From the driver will remove using port number to indicate the output type.

-   if (rcdu->info->routes[i].port == ep.port) {
-   output = i;
+   if (i == rcdu->info->routes[i].du_output) {
+   output = rcdu->info->routes[i].du_output;
Cheers,
Biju

> 
> > [1]
> > https://elixir.bootlin.com/linux/v6.10.2/source/drivers/gpu/drm/renesa
> > s/rz-du/rzg2l_du_kms.c#L187
> >
> > [2]
> > https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tr
> > ee/Documentation/devicetree/bindings/display/renesas,du.yaml?h=next-20
> > 240729#n546
> >
> > > > +else:
> > > > +  properties:
> > > > +ports:
> > > > +  properties:
> > > > +port@0:
> > > > +  description: DSI
> > > > +port@1:
> > > > +  description: DPI
> > > > +
> > > > +  required:
> > > > +- port@0
> > > > +- port@1
> > >
> > > You're missing a blank line here.
> >
> > OK, will fix this'
> 
> --
> Regards,
> 
> Laurent Pinchart


Re: [RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen

2024-08-01 Thread John Ogness
On 2024-08-01, Jocelyn Falempe  wrote:
>  * It uses a circular buffer so the console->write() callback is very
>quick, and will never stall.
>  * Drawing is done asynchronously using a workqueue.

For CON_NBCON, neither of the above points are necessary. You can draw
directly from the write_thread() callback. See below:

> +static bool drm_log_work_draw(void)
> +{
> + unsigned int len;
> + char buf[512];
> +
> + len = drm_log_buf_read(buf, sizeof(buf));
> + if (len)
> + drm_log_draw_all(buf, len);
> + return len != 0;
> +}

For CON_NBCON, this is essentially your write_thread() callback:

void drm_log_write_thread(struct console *con,
  struct nbcon_write_context *wctxt)
{
drm_log_draw_all(wctxt->outbuf, wctxt->len);
}

You cannot implement a write_atomic() callback because the console must
be able to print directly in NMI context and must not defer. But
write_atomic() is optional, so you should be fine there.

Disclaimer: Only in PREEMPT_RT patchset at the moment.

John Ogness


Re: [PATCH 1/5] udmabuf: cancel mmap page fault, direct map it

2024-08-01 Thread Christian König

Am 01.08.24 um 12:45 schrieb Huan Yang:

The current udmabuf mmap uses a page fault mechanism to populate the vma.

However, the current udmabuf has already obtained and pinned the folio
upon completion of the creation.This means that the physical memory has
already been acquired, rather than being accessed dynamically. The
current page fault method only saves some page table memory.

As a result, the page fault mechanism has lost its purpose as a demanding
page. Due to the fact that page fault requires trapping into kernel mode
and filling in when accessing the corresponding virtual address in mmap,
this means that user mode access to virtual addresses needs to trap into
kernel mode.

Therefore, when creating a large size udmabuf, this represents a
considerable overhead.

Therefore, the current patch removes the page fault method of mmap and
instead fills it directly when mmap is triggered.

Signed-off-by: Huan Yang 
---
  drivers/dma-buf/udmabuf.c | 70 ++-
  1 file changed, 39 insertions(+), 31 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 047c3cd2ceff..d69aeada7367 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -38,36 +38,39 @@ struct udmabuf_folio {
struct list_head list;
  };
  
-static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)

-{
-   struct vm_area_struct *vma = vmf->vma;
-   struct udmabuf *ubuf = vma->vm_private_data;
-   pgoff_t pgoff = vmf->pgoff;
-   unsigned long pfn;
-
-   if (pgoff >= ubuf->pagecount)
-   return VM_FAULT_SIGBUS;
-
-   pfn = folio_pfn(ubuf->folios[pgoff]);
-   pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT;
-
-   return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
-static const struct vm_operations_struct udmabuf_vm_ops = {
-   .fault = udmabuf_vm_fault,
-};
+static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
+enum dma_data_direction direction);
  
  static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)

  {
struct udmabuf *ubuf = buf->priv;
+   struct sg_table *table = ubuf->sg;
+   unsigned long addr = vma->vm_start;
+   struct sg_page_iter piter;
+   int ret;
  
  	if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)

return -EINVAL;
  
-	vma->vm_ops = _vm_ops;

-   vma->vm_private_data = ubuf;
-   vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+   if (!table) {
+   table = get_sg_table(NULL, buf, 0);
+   if (IS_ERR(table))
+   return PTR_ERR(table);
+   ubuf->sg = table;
+   }
+
+   for_each_sgtable_page(table, , vma->vm_pgoff) {


That might not work correctly. We intentionally remove the pages from 
the sgtable when it is shared between devices.


Additional to that the sgtable is *not* a page container, but rather a 
DMA address container. So that here is also a rather bad idea from the 
design side.


Regards,
Christian.


+   struct page *page = sg_page_iter_page();
+
+   ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE,
+ vma->vm_page_prot);
+   if (ret)
+   return ret;
+   addr += PAGE_SIZE;
+   if (addr >= vma->vm_end)
+   return 0;
+   }
+
return 0;
  }
  
@@ -126,6 +129,10 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,

sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE,
 ubuf->offsets[i]);
  
+	// if dev is NULL, no need to sync.

+   if (!dev)
+   return sg;
+
ret = dma_map_sgtable(dev, sg, direction, 0);
if (ret < 0)
goto err_map;
@@ -206,20 +213,21 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
  {
struct udmabuf *ubuf = buf->priv;
struct device *dev = ubuf->device->this_device;
-   int ret = 0;
+   struct sg_table *sg;
  
-	if (!ubuf->sg) {

-   ubuf->sg = get_sg_table(dev, buf, direction);
-   if (IS_ERR(ubuf->sg)) {
-   ret = PTR_ERR(ubuf->sg);
-   ubuf->sg = NULL;
-   }
-   } else {
+   if (ubuf->sg) {
dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
direction);
+   return 0;
}
  
-	return ret;

+   sg = get_sg_table(dev, buf, direction);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
+
+   ubuf->sg = sg;
+
+   return 0;
  }
  
  static int end_cpu_udmabuf(struct dma_buf *buf,




[PATCH 5/5] udmabuf: remove folio pin list

2024-08-01 Thread Huan Yang
Currently, udmabuf handles folio by creating an unpin list to record
each folio obtained from the list and unpinning them when released. To
maintain this approach, many data structures have been established.

However, maintaining this type of data structure requires a significant
amount of memory and traversing the list is a substantial overhead,
which is not friendly to the CPU cache, TLB, and so on.

Therefore, this patch removes the relationship between the folio and its
offset in the linear address mapping.

As an alternative, udmabuf only tracks all folio structures and splits
them into individual pages when needed by traversing them in the
required locations.(mmap/vmap, sg table.)

So, udmabuf's folios_array only save the folio struct, add nr_folios to
point how many folio saved in it.

offset is removed, and add item's offset and size to replace, due to
memfd create may have offset, we must set correctly page in folio.

So, when setup sg_table, we must start correct offset in each item at
begin, and then set each folio's page into sgtable.

Both item's offset and size number just the create list number, so,
memory size will not too large.

By doing this, we can accept the overhead of the udmabuf_folio structure
and the performance loss of traversing the list during unpinning.

Signed-off-by: Huan Yang 
---
 drivers/dma-buf/udmabuf.c | 149 +-
 1 file changed, 66 insertions(+), 83 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 677ebb2d462f..1106e0b1e746 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -25,17 +25,19 @@ module_param(size_limit_mb, int, 0644);
 MODULE_PARM_DESC(size_limit_mb, "Max size of a dmabuf, in megabytes. Default 
is 64.");
 
 struct udmabuf {
+   // all page's count, pagecount * PAGE_SIZE is the udmabuf's size
pgoff_t pagecount;
+
+   // folios array only point to each folio, do not duplicate set.
struct folio **folios;
+   // folios array's number
+   pgoff_t nr_folios;
+
struct sg_table *sg;
struct miscdevice *device;
-   pgoff_t *offsets;
-   struct list_head unpin_list;
-};
 
-struct udmabuf_folio {
-   struct folio *folio;
-   struct list_head list;
+   pgoff_t *item_offset;
+   size_t *item_size;
 };
 
 static struct sg_table *udmabuf_get_sg_table(struct device *dev,
@@ -118,7 +120,10 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
struct udmabuf *ubuf = buf->priv;
struct sg_table *sg;
struct scatterlist *sgl;
-   unsigned int i = 0;
+   struct folio *folio = NULL;
+   size_t fsize, foffset;
+   unsigned int i = 0, item_idx = 0, findex = 0;
+   size_t cur_size, item_size;
int ret;
 
sg = kzalloc(sizeof(*sg), GFP_KERNEL);
@@ -129,9 +134,33 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
if (ret < 0)
goto err_alloc;
 
-   for_each_sg(sg->sgl, sgl, ubuf->pagecount, i)
-   sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE,
-ubuf->offsets[i]);
+   cur_size = 0;
+   item_size = ubuf->item_size[0];
+   foffset = ubuf->item_offset[0];
+   folio = ubuf->folios[0];
+   fsize = folio_size(folio);
+
+   for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) {
+   sg_set_folio(sgl, folio, PAGE_SIZE, foffset);
+   foffset += PAGE_SIZE;
+   cur_size += PAGE_SIZE;
+
+   // move to next folio.
+   if (foffset == fsize) {
+   ++findex;
+   folio = ubuf->folios[findex];
+   fsize = folio_size(folio);
+   foffset = 0;
+   }
+
+   // if reach to next item, must check the start offset.
+   if (cur_size == item_size) {
+   ++item_idx;
+   foffset = ubuf->item_offset[item_idx];
+   item_size = ubuf->item_size[item_idx];
+   cur_size = 0;
+   }
+   }
 
// if dev is NULL, no need to sync.
if (!dev)
@@ -203,34 +232,6 @@ static void unmap_udmabuf(struct dma_buf_attachment *at,
return put_sg_table(at->dev, sg, direction);
 }
 
-static void unpin_all_folios(struct list_head *unpin_list)
-{
-   struct udmabuf_folio *ubuf_folio;
-
-   while (!list_empty(unpin_list)) {
-   ubuf_folio = list_first_entry(unpin_list,
- struct udmabuf_folio, list);
-   unpin_folio(ubuf_folio->folio);
-
-   list_del(_folio->list);
-   kfree(ubuf_folio);
-   }
-}
-
-static int add_to_unpin_list(struct list_head *unpin_list,
-struct folio *folio)
-{
-   struct udmabuf_folio *ubuf_folio;
-
-   ubuf_folio = 

[PATCH 0/5] udmbuf bug fix and some improvements

2024-08-01 Thread Huan Yang
This patchset attempts to fix some errors in udmabuf and remove the
upin_list structure.

Some of this fix just gather the patches which I upload before.

Patch1
===
Try to remove page fault mmap and direct map it.
Due to current udmabuf has already obtained and pinned the folio
upon completion of the creation.This means that the physical memory has
already been acquired, rather than being accessed dynamically. The
current page fault method only saves some page table memory.

As a result, the page fault mechanism has lost its purpose as a demanding
page. Due to the fact that page fault requires trapping into kernel mode
and filling in when accessing the corresponding virtual address in mmap,
this means that user mode access to virtual addresses needs to trap into
kernel mode.

Therefore, when creating a large size udmabuf, this represents a
considerable overhead.

Therefore, the current patch removes the page fault method of mmap and
instead fills it directly when mmap is triggered.

This is achieved by using the scatter-gather table to establish a
linear relationship for the page. Calling remap_pfn_range does not cause
the previously set VMA flags to become invalid.

Patch2
===
This is the same to patch:
https://lore.kernel.org/all/20240725021349.580574-1-l...@vivo.com/
I just gather it to this patchset.

Patch3
===
The current implementation of udmabuf's vmap has issues.

It does not correctly set each page of the folio to the page structure,
so that when vmap is called, all pages are the head page of the folio.

This implementation is not the same as this patch:
https://lore.kernel.org/all/20240731090233.1343559-1-l...@vivo.com/

This reuse sgt table to map all page into vmalloc area.

Patch4
===
Wrap the repeated calls to get_sg_table, add a helper function to do it.
Set to udmabuf->sg use cmpxchg, It should be able to prevent concurrent
access situations. (I see mmap do not use lock)

Patch5
===
Attempt to remove unpin_list and other related data structures.

In order to adapt to Folio, we established the unpin_list data structure
to unpin all folios and maintain the page mapping relationship.

However, this data structure requires 24 bytes for each page and has low
traversal performance for the list. And maintaining the offset structure
also consumes a portion of memory.

This patch attempts to remove these data structures and modify the
semantics of some existing data structures.

udmabuf:
  folios -> folios array, which only contain's the folio, org contains
duplicate.
  add item_offset -> base on create item count, record it's start offset
in every memfd.
  add item_size -> base on create item count, record it's size in every
memfd.
  add nr_folios -> folios array number

So, when building the sg table, it is necessary to iterate in this way:
  if size cross item->size, take care of it's start offset in folio.
  if got folio, set each page into sgl until reach into folio size.

This patch also remove single folios' create on each create item, use it
be the ubuf->folios arrays' pointer, slide to fill the corresponding
folio under the item into the array.

After the modification, the various data structures in udmabuf have the
following corresponding relationships:
  pagecount * PAGESIZE = sum(folios_size(folios[i])) i=0->nr_folios
  pagecount * PAGESIZE = sum(item_size[i]) i=0, item_count (do not
record)
  item_offset use to record each memfd offset if exist, else 0.

Huan Yang (5):
  udmabuf: cancel mmap page fault, direct map it
  udmabuf: change folios array from kmalloc to kvmalloc
  udmabuf: fix vmap_udmabuf error page set
  udmabuf: add get_sg_table helper function
  udmabuf: remove folio pin list

 drivers/dma-buf/udmabuf.c | 270 +-
 1 file changed, 148 insertions(+), 122 deletions(-)


base-commit: cd19ac2f903276b820f5d0d89de0c896c27036ed
-- 
2.45.2



[PATCH 3/5] udmabuf: fix vmap_udmabuf error page set

2024-08-01 Thread Huan Yang
Currently vmap_udmabuf set page's array by each folio.
But, ubuf->folios is only contain's the folio's head page.

That mean we repeatedly mapped the folio head page to the vmalloc area.

This patch fix it, set each folio's page correct, so that pages array
contains right page, and then map into vmalloc area

Signed-off-by: Huan Yang 
---
 drivers/dma-buf/udmabuf.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index a915714c5dce..7ed532342d7f 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -77,18 +77,27 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
 static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
 {
struct udmabuf *ubuf = buf->priv;
-   struct page **pages;
+   struct page **pages, **tmp;
+   struct sg_table *sg = ubuf->sg;
+   struct sg_page_iter piter;
void *vaddr;
-   pgoff_t pg;
 
dma_resv_assert_held(buf->resv);
 
+   if (!sg) {
+   sg = get_sg_table(NULL, buf, 0);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
+   ubuf->sg = sg;
+   }
+
pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
if (!pages)
return -ENOMEM;
+   tmp = pages;
 
-   for (pg = 0; pg < ubuf->pagecount; pg++)
-   pages[pg] = >folios[pg]->page;
+   for_each_sgtable_page(sg, , 0)
+   *tmp++ = sg_page_iter_page();
 
vaddr = vm_map_ram(pages, ubuf->pagecount, -1);
kvfree(pages);
-- 
2.45.2



[PATCH 1/5] udmabuf: cancel mmap page fault, direct map it

2024-08-01 Thread Huan Yang
The current udmabuf mmap uses a page fault mechanism to populate the vma.

However, the current udmabuf has already obtained and pinned the folio
upon completion of the creation.This means that the physical memory has
already been acquired, rather than being accessed dynamically. The
current page fault method only saves some page table memory.

As a result, the page fault mechanism has lost its purpose as a demanding
page. Due to the fact that page fault requires trapping into kernel mode
and filling in when accessing the corresponding virtual address in mmap,
this means that user mode access to virtual addresses needs to trap into
kernel mode.

Therefore, when creating a large size udmabuf, this represents a
considerable overhead.

Therefore, the current patch removes the page fault method of mmap and
instead fills it directly when mmap is triggered.

Signed-off-by: Huan Yang 
---
 drivers/dma-buf/udmabuf.c | 70 ++-
 1 file changed, 39 insertions(+), 31 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 047c3cd2ceff..d69aeada7367 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -38,36 +38,39 @@ struct udmabuf_folio {
struct list_head list;
 };
 
-static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
-{
-   struct vm_area_struct *vma = vmf->vma;
-   struct udmabuf *ubuf = vma->vm_private_data;
-   pgoff_t pgoff = vmf->pgoff;
-   unsigned long pfn;
-
-   if (pgoff >= ubuf->pagecount)
-   return VM_FAULT_SIGBUS;
-
-   pfn = folio_pfn(ubuf->folios[pgoff]);
-   pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT;
-
-   return vmf_insert_pfn(vma, vmf->address, pfn);
-}
-
-static const struct vm_operations_struct udmabuf_vm_ops = {
-   .fault = udmabuf_vm_fault,
-};
+static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
+enum dma_data_direction direction);
 
 static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
 {
struct udmabuf *ubuf = buf->priv;
+   struct sg_table *table = ubuf->sg;
+   unsigned long addr = vma->vm_start;
+   struct sg_page_iter piter;
+   int ret;
 
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;
 
-   vma->vm_ops = _vm_ops;
-   vma->vm_private_data = ubuf;
-   vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+   if (!table) {
+   table = get_sg_table(NULL, buf, 0);
+   if (IS_ERR(table))
+   return PTR_ERR(table);
+   ubuf->sg = table;
+   }
+
+   for_each_sgtable_page(table, , vma->vm_pgoff) {
+   struct page *page = sg_page_iter_page();
+
+   ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE,
+ vma->vm_page_prot);
+   if (ret)
+   return ret;
+   addr += PAGE_SIZE;
+   if (addr >= vma->vm_end)
+   return 0;
+   }
+
return 0;
 }
 
@@ -126,6 +129,10 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE,
 ubuf->offsets[i]);
 
+   // if dev is NULL, no need to sync.
+   if (!dev)
+   return sg;
+
ret = dma_map_sgtable(dev, sg, direction, 0);
if (ret < 0)
goto err_map;
@@ -206,20 +213,21 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
 {
struct udmabuf *ubuf = buf->priv;
struct device *dev = ubuf->device->this_device;
-   int ret = 0;
+   struct sg_table *sg;
 
-   if (!ubuf->sg) {
-   ubuf->sg = get_sg_table(dev, buf, direction);
-   if (IS_ERR(ubuf->sg)) {
-   ret = PTR_ERR(ubuf->sg);
-   ubuf->sg = NULL;
-   }
-   } else {
+   if (ubuf->sg) {
dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
direction);
+   return 0;
}
 
-   return ret;
+   sg = get_sg_table(dev, buf, direction);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
+
+   ubuf->sg = sg;
+
+   return 0;
 }
 
 static int end_cpu_udmabuf(struct dma_buf *buf,
-- 
2.45.2



[PATCH 2/5] udmabuf: change folios array from kmalloc to kvmalloc

2024-08-01 Thread Huan Yang
When PAGE_SIZE 4096, MAX_PAGE_ORDER 10, 64bit machine,
page_alloc only support 4MB.
If above this, trigger this warn and return NULL.

udmabuf can change size limit, if change it to 3072(3GB), and then alloc
3GB udmabuf, will fail create.

[ 4080.876581] [ cut here ]
[ 4080.876843] WARNING: CPU: 3 PID: 2015 at mm/page_alloc.c:4556 
__alloc_pages+0x2c8/0x350
[ 4080.878839] RIP: 0010:__alloc_pages+0x2c8/0x350
[ 4080.879470] Call Trace:
[ 4080.879473]  
[ 4080.879473]  ? __alloc_pages+0x2c8/0x350
[ 4080.879475]  ? __warn.cold+0x8e/0xe8
[ 4080.880647]  ? __alloc_pages+0x2c8/0x350
[ 4080.880909]  ? report_bug+0xff/0x140
[ 4080.881175]  ? handle_bug+0x3c/0x80
[ 4080.881556]  ? exc_invalid_op+0x17/0x70
[ 4080.881559]  ? asm_exc_invalid_op+0x1a/0x20
[ 4080.882077]  ? udmabuf_create+0x131/0x400

Because MAX_PAGE_ORDER, kmalloc can max alloc 4096 * (1 << 10), 4MB
memory, each array entry is pointer(8byte), so can save 524288 pages(2GB).

Further more, costly order(order 3) may not be guaranteed that it can be
applied for, due to fragmentation.

This patch change udmabuf array use kvmalloc_array, this can fallback
alloc into vmalloc, which can guarantee allocation for any size and does
not affect the performance of kmalloc allocations.

Signed-off-by: Huan Yang 
---
 drivers/dma-buf/udmabuf.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index d69aeada7367..a915714c5dce 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -83,7 +83,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map 
*map)
 
dma_resv_assert_held(buf->resv);
 
-   pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
+   pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
if (!pages)
return -ENOMEM;
 
@@ -91,7 +91,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map 
*map)
pages[pg] = >folios[pg]->page;
 
vaddr = vm_map_ram(pages, ubuf->pagecount, -1);
-   kfree(pages);
+   kvfree(pages);
if (!vaddr)
return -EINVAL;
 
@@ -203,8 +203,8 @@ static void release_udmabuf(struct dma_buf *buf)
put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
 
unpin_all_folios(>unpin_list);
-   kfree(ubuf->offsets);
-   kfree(ubuf->folios);
+   kvfree(ubuf->offsets);
+   kvfree(ubuf->folios);
kfree(ubuf);
 }
 
@@ -330,14 +330,14 @@ static long udmabuf_create(struct miscdevice *device,
if (!ubuf->pagecount)
goto err;
 
-   ubuf->folios = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),
-   GFP_KERNEL);
+   ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),
+ GFP_KERNEL);
if (!ubuf->folios) {
ret = -ENOMEM;
goto err;
}
-   ubuf->offsets = kcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
-   GFP_KERNEL);
+   ubuf->offsets =
+   kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets), GFP_KERNEL);
if (!ubuf->offsets) {
ret = -ENOMEM;
goto err;
@@ -351,7 +351,7 @@ static long udmabuf_create(struct miscdevice *device,
goto err;
 
pgcnt = list[i].size >> PAGE_SHIFT;
-   folios = kmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
+   folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
if (!folios) {
ret = -ENOMEM;
goto err;
@@ -361,7 +361,7 @@ static long udmabuf_create(struct miscdevice *device,
ret = memfd_pin_folios(memfd, list[i].offset, end,
   folios, pgcnt, );
if (ret <= 0) {
-   kfree(folios);
+   kvfree(folios);
if (!ret)
ret = -EINVAL;
goto err;
@@ -390,7 +390,7 @@ static long udmabuf_create(struct miscdevice *device,
}
}
 
-   kfree(folios);
+   kvfree(folios);
fput(memfd);
memfd = NULL;
}
@@ -406,8 +406,8 @@ static long udmabuf_create(struct miscdevice *device,
if (memfd)
fput(memfd);
unpin_all_folios(>unpin_list);
-   kfree(ubuf->offsets);
-   kfree(ubuf->folios);
+   kvfree(ubuf->offsets);
+   kvfree(ubuf->folios);
kfree(ubuf);
return ret;
 }
-- 
2.45.2



[PATCH 4/5] udmabuf: add get_sg_table helper function

2024-08-01 Thread Huan Yang
Currently, there are three duplicate pieces of code that retrieve
sg_table and update uduf->sg.

Since the sgt is used to populate the page in both mmap and vmap.It is
necessary to ensure that ubuf->sg is set correctly.

This patch add a helper function, if ubuf->sg exist, just return it.
Or else, try alloc a new sgt, and cmpxchg to set it.

When the swap fails, it means that another process has set sg correctly.
Therefore, we reuse the new sg. If trigger by device, need invoke map to
sync it.

Signed-off-by: Huan Yang 
---
 drivers/dma-buf/udmabuf.c | 60 ---
 1 file changed, 43 insertions(+), 17 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 7ed532342d7f..677ebb2d462f 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -38,8 +38,9 @@ struct udmabuf_folio {
struct list_head list;
 };
 
-static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
-enum dma_data_direction direction);
+static struct sg_table *udmabuf_get_sg_table(struct device *dev,
+struct dma_buf *buf,
+enum dma_data_direction direction);
 
 static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
 {
@@ -52,12 +53,9 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;
 
-   if (!table) {
-   table = get_sg_table(NULL, buf, 0);
-   if (IS_ERR(table))
-   return PTR_ERR(table);
-   ubuf->sg = table;
-   }
+   table = udmabuf_get_sg_table(NULL, buf, 0);
+   if (IS_ERR(table))
+   return PTR_ERR(table);
 
for_each_sgtable_page(table, , vma->vm_pgoff) {
struct page *page = sg_page_iter_page();
@@ -84,12 +82,9 @@ static int vmap_udmabuf(struct dma_buf *buf, struct 
iosys_map *map)
 
dma_resv_assert_held(buf->resv);
 
-   if (!sg) {
-   sg = get_sg_table(NULL, buf, 0);
-   if (IS_ERR(sg))
-   return PTR_ERR(sg);
-   ubuf->sg = sg;
-   }
+   sg = udmabuf_get_sg_table(NULL, buf, 0);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
 
pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
if (!pages)
@@ -154,6 +149,39 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
return ERR_PTR(ret);
 }
 
+static struct sg_table *udmabuf_get_sg_table(struct device *dev,
+struct dma_buf *buf,
+enum dma_data_direction direction)
+{
+   struct udmabuf *ubuf = buf->priv;
+   struct sg_table *sg = READ_ONCE(ubuf->sg);
+   int ret = 0;
+
+   if (sg)
+   return sg;
+
+   sg = get_sg_table(dev, buf, direction);
+   if (IS_ERR(sg))
+   return sg;
+
+   // Success update ubuf's sg, just return.
+   if (!cmpxchg(>sg, NULL, sg))
+   return sg;
+
+   // use the new sg table.
+   sg_free_table(sg);
+   kfree(sg);
+   sg = READ_ONCE(ubuf->sg);
+
+   if (dev)
+   ret = dma_map_sgtable(dev, sg, direction, 0);
+
+   if (ret < 0)
+   return ERR_PTR(ret);
+
+   return sg;
+}
+
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 enum dma_data_direction direction)
 {
@@ -230,12 +258,10 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
return 0;
}
 
-   sg = get_sg_table(dev, buf, direction);
+   sg = udmabuf_get_sg_table(dev, buf, direction);
if (IS_ERR(sg))
return PTR_ERR(sg);
 
-   ubuf->sg = sg;
-
return 0;
 }
 
-- 
2.45.2



Re: [RFC PATCH 0/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen

2024-08-01 Thread John Ogness
On 2024-08-01, Jocelyn Falempe  wrote:
>  * I tried to use the new nbcon interface, but didn't get any message
>  from the write_atomic() callback, but the goal is to use that when
>  it's ready.

Be aware that the write_atomic() callback _must_ also print from NMI
context. write_thread() may be the callback you are interested
instead. Note that for CON_NBCON, write_atomic() is optional,
write_thread() is mandatory.

Disclaimer: All of this currently only available in the PREEMPT_RT
patchset. So until it hits mainline, semantics may yet change.

John Ogness


Re: [PATCH] backlight: pwm_bl: print errno for probe errors

2024-08-01 Thread Uwe Kleine-König
Hello Martin,

On Thu, Aug 01, 2024 at 09:52:01AM +, Kepplinger-Novakovic Martin wrote:
> Am Donnerstag, dem 01.08.2024 um 11:26 +0200 schrieb Uwe Kleine-König:
> > On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-Novaković
> > wrote:
> > > diff --git a/drivers/video/backlight/pwm_bl.c
> > > b/drivers/video/backlight/pwm_bl.c
> > > index f1005bd0c41e3..cc7e7af71891f 100644
> > > --- a/drivers/video/backlight/pwm_bl.c
> > > +++ b/drivers/video/backlight/pwm_bl.c
> > > @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct
> > > platform_device *pdev)
> > >   GPIOD_ASIS);
> > > if (IS_ERR(pb->enable_gpio)) {
> > > ret = dev_err_probe(>dev, PTR_ERR(pb-
> > > >enable_gpio),
> > > -   "failed to acquire enable
> > > GPIO\n");
> > > +   "failed to acquire enable GPIO:
> > > %ld\n",
> > > +   PTR_ERR(pb->enable_gpio));
> > 
> > AFAIK dev_err_probe already emits the error code passed as 2nd
> > parameter. So I wonder about this patch's benefit.
> > 
> 
> It does. Other messages only take the deferred_probe_reason without the
> error code. It's actually fine if users properly enable debugging after
> seeing an error and then this change is not needed :)

I'm unsure what you intend to say here. Do you agree that this patch
doesn't need to be applied as it doesn't add any information to the
emitted messages? Or do you think there is a value because "users don't
need to enable debugging" then. In the latter case I don't see where
users would see "failed to acquire enable GPIO" before, but not the
value of the error code.

Best regards
Uwe


signature.asc
Description: PGP signature


[RFC PATCH 3/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen

2024-08-01 Thread Jocelyn Falempe
drm_log is a simple logger that uses the drm_client API to print the
kmsg boot log on the screen. This is not a full replacement to fbcon,
as it will only print the kmsg. It will never handle user input, or a
terminal because this is better done in userspace.

Design decisions:
 * It uses the drm_client API, so it should work on all drm drivers from the 
start.
 * It doesn't scroll the message, that way it doesn't need to redraw the whole 
screen for each new message.
   It also means it doesn't have to keep drawn messages in memory, to redraw 
them when scrolling.
 * It uses a circular buffer so the console->write() callback is very quick, 
and will never stall.
 * Drawing is done asynchronously using a workqueue.
 * drm_log can only be built-in (and drm must be built-in too).
   The reason is that, if you build it as a module, then a userspace 
application will be more appropriate than this module.

Signed-off-by: Jocelyn Falempe 
---
 drivers/gpu/drm/Kconfig   |  11 +
 drivers/gpu/drm/Makefile  |   2 +
 drivers/gpu/drm/drm_drv.c |   2 +
 drivers/gpu/drm/drm_log.c | 477 ++
 drivers/gpu/drm/drm_log.h |   8 +
 5 files changed, 500 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_log.c
 create mode 100644 drivers/gpu/drm/drm_log.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c39bf143d705..b98e8b1755a9 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -185,6 +185,17 @@ config DRM_PANIC_SCREEN_QR_VERSION
  Smaller QR code are easier to read, but will contain less debugging
  data. Default is 40.
 
+config DRM_LOG
+   bool "Print the kernel boot message on the screen"
+   depends on DRM=y
+   depends on !FRAMEBUFFER_CONSOLE
+   select DRM_DRAW
+   help
+ This enable a drm logger, that will print the kernel messages to the
+ screen until the userspace is ready to take over.
+ It only makes sense to have it built-in, because otherwise it would
+ be loaded after userspace.
+
 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
 bool "Enable refcount backtrace history in the DP MST helpers"
depends on STACKTRACE_SUPPORT
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 632247cddac9..ac06b6f2aa10 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -149,6 +149,8 @@ drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
+obj-$(CONFIG_DRM_LOG) += drm_log.o
+
 #
 # Drivers and the rest
 #
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 27007b53a8c8..471960a6c0c9 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -48,6 +48,7 @@
 #include 
 
 #include "drm_crtc_internal.h"
+#include "drm_log.h"
 #include "drm_internal.h"
 
 MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
@@ -946,6 +947,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long 
flags)
goto err_unload;
}
drm_panic_register(dev);
+   drm_log_register(dev);
 
DRM_INFO("Initialized %s %d.%d.%d for %s on minor %d\n",
 driver->name, driver->major, driver->minor,
diff --git a/drivers/gpu/drm/drm_log.c b/drivers/gpu/drm/drm_log.c
new file mode 100644
index ..a5f1502e3dc3
--- /dev/null
+++ b/drivers/gpu/drm/drm_log.c
@@ -0,0 +1,477 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/*
+ * Copyright (c) 2024 Red Hat.
+ * Author: Jocelyn Falempe 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "drm_draw.h"
+#include "drm_log.h"
+
+MODULE_AUTHOR("Jocelyn Falempe");
+MODULE_DESCRIPTION("DRM boot logger");
+MODULE_LICENSE("GPL");
+
+/**
+ * DOC: overview
+ *
+ * This is a simple graphic logger, to print the kernel message on screen, 
until
+ * a userspace application is able to take over.
+ * It is only for debugging purpose.
+ */
+
+struct drm_log_scanout {
+   struct drm_client_buffer *buffer;
+   const struct font_desc *font;
+   struct iosys_map map;
+   u32 rows;
+   u32 columns;
+   u32 line;
+   u32 format;
+   u32 px_width;
+   u32 front_color;
+};
+
+struct drm_log_client {
+   struct list_head head;
+   struct drm_client_dev client;
+   u32 n_scanout;
+   struct drm_log_scanout *scanout;
+};
+
+static LIST_HEAD(drm_log_clients);
+static DEFINE_MUTEX(drm_log_lock);
+
+/*
+ * A circular buffer, with the last kmsg logs to print.
+ * 8K is more than what can be drawn on most monitors.
+ */
+#define CIRC_BUF_SIZE  (1 << 13)
+#define CIRC_BUF_MASK  (CIRC_BUF_SIZE - 1)
+struct circ_buf drm_log_buf;
+static DEFINE_SPINLOCK(drm_log_writer_lock);
+static DEFINE_SPINLOCK(drm_log_reader_lock);
+
+/*
+ * Circular buffer functions
+ 

[RFC PATCH 2/3] drm/panic: Move drawing functions to drm_draw

2024-08-01 Thread Jocelyn Falempe
Move the color conversions, blit and fill functions to drm_draw.c,
so that they can be re-used by drm_log.
drm_draw is internal to the drm subsystem, and shouldn't be used by
gpu drivers.

Signed-off-by: Jocelyn Falempe 
---
 drivers/gpu/drm/Kconfig |   5 +
 drivers/gpu/drm/Makefile|   1 +
 drivers/gpu/drm/drm_draw.c  | 216 +++
 drivers/gpu/drm/drm_draw.h  |  56 
 drivers/gpu/drm/drm_panic.c | 247 
 5 files changed, 301 insertions(+), 224 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_draw.c
 create mode 100644 drivers/gpu/drm/drm_draw.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index b3ab3ace7f8e..c39bf143d705 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -105,10 +105,15 @@ config DRM_KMS_HELPER
help
  CRTC helpers for KMS drivers.
 
+config DRM_DRAW
+   bool
+   depends on DRM
+
 config DRM_PANIC
bool "Display a user-friendly message when a kernel panic occurs"
depends on DRM
select FONT_SUPPORT
+   select DRM_DRAW
help
  Enable a drm panic handler, which will display a user-friendly message
  when a kernel panic occurs. It's useful when using a user-space
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index c62339b89d46..632247cddac9 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -89,6 +89,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
drm_privacy_screen_x86.o
 drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o
 drm-$(CONFIG_DRM_PANIC) += drm_panic.o
+drm-$(CONFIG_DRM_DRAW) += drm_draw.o
 drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o
 obj-$(CONFIG_DRM)  += drm.o
 
diff --git a/drivers/gpu/drm/drm_draw.c b/drivers/gpu/drm/drm_draw.c
new file mode 100644
index ..79fe6577d3aa
--- /dev/null
+++ b/drivers/gpu/drm/drm_draw.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/*
+ * Copyright (c) 2023 Red Hat.
+ * Author: Jocelyn Falempe 
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "drm_draw.h"
+
+/*
+ * Conversions from xrgb
+ */
+
+static u16 convert_xrgb_to_rgb565(u32 pix)
+{
+   return ((pix & 0x00F8) >> 8) |
+  ((pix & 0xFC00) >> 5) |
+  ((pix & 0x00F8) >> 3);
+}
+
+static u16 convert_xrgb_to_rgba5551(u32 pix)
+{
+   return ((pix & 0x00f8) >> 8) |
+  ((pix & 0xf800) >> 5) |
+  ((pix & 0x00f8) >> 2) |
+  BIT(0); /* set alpha bit */
+}
+
+static u16 convert_xrgb_to_xrgb1555(u32 pix)
+{
+   return ((pix & 0x00f8) >> 9) |
+  ((pix & 0xf800) >> 6) |
+  ((pix & 0x00f8) >> 3);
+}
+
+static u16 convert_xrgb_to_argb1555(u32 pix)
+{
+   return BIT(15) | /* set alpha bit */
+  ((pix & 0x00f8) >> 9) |
+  ((pix & 0xf800) >> 6) |
+  ((pix & 0x00f8) >> 3);
+}
+
+static u32 convert_xrgb_to_argb(u32 pix)
+{
+   return pix | GENMASK(31, 24); /* fill alpha bits */
+}
+
+static u32 convert_xrgb_to_xbgr(u32 pix)
+{
+   return ((pix & 0x00ff) >> 16) <<  0 |
+  ((pix & 0xff00) >>  8) <<  8 |
+  ((pix & 0x00ff) >>  0) << 16 |
+  ((pix & 0xff00) >> 24) << 24;
+}
+
+static u32 convert_xrgb_to_abgr(u32 pix)
+{
+   return ((pix & 0x00ff) >> 16) <<  0 |
+  ((pix & 0xff00) >>  8) <<  8 |
+  ((pix & 0x00ff) >>  0) << 16 |
+  GENMASK(31, 24); /* fill alpha bits */
+}
+
+static u32 convert_xrgb_to_xrgb2101010(u32 pix)
+{
+   pix = ((pix & 0x00FF) << 2) |
+ ((pix & 0xFF00) << 4) |
+ ((pix & 0x00FF) << 6);
+   return pix | ((pix >> 8) & 0x00300C03);
+}
+
+static u32 convert_xrgb_to_argb2101010(u32 pix)
+{
+   pix = ((pix & 0x00FF) << 2) |
+ ((pix & 0xFF00) << 4) |
+ ((pix & 0x00FF) << 6);
+   return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 
0x00300C03);
+}
+
+/**
+ * drm_draw_color_from_xrgb - convert one pixel from xrgb to the 
desired format
+ * @color: input color, in xrgb format
+ * @format: output format
+ *
+ * Returns:
+ * Color in the format specified, casted to u32.
+ * Or 0 if the format is not supported.
+ */
+u32 drm_draw_color_from_xrgb(u32 color, u32 format)
+{
+   switch (format) {
+   case DRM_FORMAT_RGB565:
+   return convert_xrgb_to_rgb565(color);
+   case DRM_FORMAT_RGBA5551:
+   return convert_xrgb_to_rgba5551(color);
+   case DRM_FORMAT_XRGB1555:
+   return convert_xrgb_to_xrgb1555(color);
+   case DRM_FORMAT_ARGB1555:
+   return convert_xrgb_to_argb1555(color);
+   case DRM_FORMAT_RGB888:
+   case DRM_FORMAT_XRGB:
+   return color;
+   

[RFC PATCH 1/3] [NOT FOR REVIEW] drm/panic: Squash of pending series

2024-08-01 Thread Jocelyn Falempe
This is a squashed patch of:
https://patchwork.freedesktop.org/series/136377/
https://patchwork.freedesktop.org/series/135944/

This is to avoid to rebase when they are merged.

Signed-off-by: Jocelyn Falempe 
---
 drivers/gpu/drm/Kconfig |   31 +
 drivers/gpu/drm/Makefile|1 +
 drivers/gpu/drm/drm_crtc_internal.h |8 +
 drivers/gpu/drm/drm_drv.c   |3 +
 drivers/gpu/drm/drm_panic.c |  367 --
 drivers/gpu/drm/drm_panic_qr.rs | 1003 +++
 include/drm/drm_panic.h |   21 +-
 include/drm/drm_rect.h  |   15 +
 8 files changed, 1389 insertions(+), 60 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_panic_qr.rs

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index b6ea88d228e1..b3ab3ace7f8e 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -149,6 +149,37 @@ config DRM_PANIC_SCREEN
  or by writing to /sys/module/drm/parameters/panic_screen sysfs entry
  Default is "user"
 
+config DRM_PANIC_SCREEN_QR_CODE
+   bool "Add a panic screen with a QR code"
+   depends on DRM_PANIC && RUST
+   help
+ This option adds a QR code generator, and a panic screen with a QR
+ code. The QR code will contain the last lines of kmsg and other debug
+ information. This should be easier for the user to report a kernel
+ panic, with all debug information available.
+ To use this panic screen, also set DRM_PANIC_SCREEN to "qr_code"
+
+config DRM_PANIC_SCREEN_QR_CODE_URL
+   string "Base URL of the QR code in the panic screen"
+   depends on DRM_PANIC_SCREEN_QR_CODE
+   help
+ This option sets the base URL to report the kernel panic. If it's set
+ the QR code will contain the URL and the kmsg compressed with zlib as
+ a URL parameter. If it's empty, the QR code will contain the kmsg as
+ uncompressed text only.
+ There is a demo code in javascript, to decode and uncompress the kmsg
+ data from the URL parameter at https://github.com/kdj0c/panic_report
+
+config DRM_PANIC_SCREEN_QR_VERSION
+   int "Maximum version (size) of the QR code."
+   depends on DRM_PANIC_SCREEN_QR_CODE
+   default 40
+   help
+ This option limits the version (or size) of the QR code. QR code
+ version ranges from Version 1 (21x21) to Version 40 (177x177).
+ Smaller QR code are easier to read, but will contain less debugging
+ data. Default is 40.
+
 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
 bool "Enable refcount backtrace history in the DP MST helpers"
depends on STACKTRACE_SUPPORT
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 68cc9258ffc4..c62339b89d46 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -89,6 +89,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
drm_privacy_screen_x86.o
 drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o
 drm-$(CONFIG_DRM_PANIC) += drm_panic.o
+drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o
 obj-$(CONFIG_DRM)  += drm.o
 
 obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
b/drivers/gpu/drm/drm_crtc_internal.h
index 061436361998..89706aa8232f 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -318,8 +318,16 @@ drm_edid_load_firmware(struct drm_connector *connector)
 /* drm_panic.c */
 #ifdef CONFIG_DRM_PANIC
 bool drm_panic_is_enabled(struct drm_device *dev);
+void drm_panic_register(struct drm_device *dev);
+void drm_panic_unregister(struct drm_device *dev);
+void drm_panic_init(void);
+void drm_panic_exit(void);
 #else
 static inline bool drm_panic_is_enabled(struct drm_device *dev) { return 
false; }
+static inline void drm_panic_register(struct drm_device *dev) {}
+static inline void drm_panic_unregister(struct drm_device *dev) {}
+static inline void drm_panic_init(void) {}
+static inline void drm_panic_exit(void) {}
 #endif
 
 #endif /* __DRM_CRTC_INTERNAL_H__ */
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 93543071a500..27007b53a8c8 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1067,6 +1067,7 @@ static const struct file_operations drm_stub_fops = {
 static void drm_core_exit(void)
 {
drm_privacy_screen_lookup_exit();
+   drm_panic_exit();
accel_core_exit();
unregister_chrdev(DRM_MAJOR, "drm");
debugfs_remove(drm_debugfs_root);
@@ -1099,6 +1100,8 @@ static int __init drm_core_init(void)
if (ret < 0)
goto error;
 
+   drm_panic_init();
+
drm_privacy_screen_lookup_init();
 
drm_core_init_complete = true;
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 072752b658f0..ec708ff9c40c 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ 

[RFC PATCH 0/3] drm/log: Introduce a new boot logger to draw the kmsg on the screen

2024-08-01 Thread Jocelyn Falempe
drm_log is a simple logger that uses the drm_client API to print the kmsg boot 
log on the screen.
This is not a full replacement to fbcon, as it will only print the kmsg.
It will never handle user input, or a terminal because this is better done in 
userspace.

If you're curious on how it looks like, I've put a small demo here:
https://people.redhat.com/jfalempe/drm_log/drm_log_draft_preview.webm

Design decisions:
  * It uses the drm_client API, so it should work on all drm drivers from the 
start.
  * It doesn't scroll the message, that way it doesn't need to redraw the whole 
screen for each new message.
It also means it doesn't have to keep drawn messages in memory, to redraw 
them when scrolling.
  * It uses a circular buffer so the console->write() callback is very quick, 
and will never stall.
  * Drawing is done asynchronously using a workqueue.
  * drm_log can only be built-in (and drm must be built-in too).
The reason is that, if you build it as a module, then a userspace 
application will be more appropriate than this module.

TODO items:
 * It currently only handles the first drm_client hotplug event, I need a bit 
more time to fix that. 
 * I didn't find a way to know when drm_log loses focus, I would like to 
unregister it, so it won't waste CPU cycles in the background.
 * I copied the drm_client API usage from drm_fbdev_shmem, so there might be 
some adjustment to work on DMA GPU (I didn't try yet).
 * Flicker-free boot: I don't want drm_log to introduce new modeset during the 
boot, so it may need some adjustment.
 * I tried to use the new nbcon interface, but didn't get any message from the 
write_atomic() callback, but the goal is to use that when it's ready.
 * Add color support, to make timestamp, or error message, in different color 
for better visibility.
 * If built with VT_CONSOLE=n and FRAMEBUFFER_CONSOLE=y, fbcon is taking the 
focus, and you won't see the drm_log.
   It would be nice to have drm_log for boot logs, and still use fbcon for 
terminal, when userspace is started.
 
The first patch is not for review/merge, it's a squash of my pending drm_panic 
series:
https://patchwork.freedesktop.org/series/136377/
https://patchwork.freedesktop.org/series/135944/

The second patch, moves the drawing function from drm_panic.c, to drm_draw.c, 
so they can be re-used by drm_log.
The third patch is the actual drm_log implementation.

I want to get some feedbacks before spending more time on this, and make sure 
I'm heading in the right direction.

Thanks and best regards,

-- 

Jocelyn

Jocelyn Falempe (3):
  [NOT FOR REVIEW] drm/panic: Squash of pending series
  drm/panic: Move drawing functions to drm_draw
  drm/log: Introduce a new boot logger to draw the kmsg on the screen

 drivers/gpu/drm/Kconfig |   47 ++
 drivers/gpu/drm/Makefile|4 +
 drivers/gpu/drm/drm_crtc_internal.h |8 +
 drivers/gpu/drm/drm_draw.c  |  216 ++
 drivers/gpu/drm/drm_draw.h  |   56 ++
 drivers/gpu/drm/drm_drv.c   |5 +
 drivers/gpu/drm/drm_log.c   |  477 +
 drivers/gpu/drm/drm_log.h   |8 +
 drivers/gpu/drm/drm_panic.c |  596 +---
 drivers/gpu/drm/drm_panic_qr.rs | 1003 +++
 include/drm/drm_panic.h |   21 +-
 include/drm/drm_rect.h  |   15 +
 12 files changed, 2181 insertions(+), 275 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_draw.c
 create mode 100644 drivers/gpu/drm/drm_draw.h
 create mode 100644 drivers/gpu/drm/drm_log.c
 create mode 100644 drivers/gpu/drm/drm_log.h
 create mode 100644 drivers/gpu/drm/drm_panic_qr.rs


base-commit: bb99c51bdaa846bddb85a1e7acca3a3aa5e9f082
-- 
2.45.2



Re: [PATCH v2 1/3] dt-bindings: display: rockchip: Add schema for RK3588 HDMI TX Controller

2024-08-01 Thread Cristian Ciocaltea
On 8/1/24 6:37 AM, Rob Herring (Arm) wrote:
> 
> On Thu, 01 Aug 2024 05:25:52 +0300, Cristian Ciocaltea wrote:
>> Rockchip RK3588 SoC integrates the Synopsys DesignWare HDMI 2.1
>> Quad-Pixel (QP) TX controller IP.
>>
>> Since this is a new IP block, quite different from those used in the
>> previous generations of Rockchip SoCs, add a dedicated binding file.
>>
>> Signed-off-by: Cristian Ciocaltea 
>> ---
>>  .../display/rockchip/rockchip,dw-hdmi-qp.yaml  | 188 
>> +
>>  1 file changed, 188 insertions(+)
>>
> 
> My bot found errors running 'make dt_binding_check' on your patch:

This is because the referenced synopsys,dw-hdmi-qp.yaml is provided by a
separate patchset:

https://lore.kernel.org/lkml/20240801-dw-hdmi-qp-tx-v1-1-148f542de...@collabora.com/

> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.example.dtb:
>  hdmi@fde8: False schema does not allow {'compatible': 
> ['rockchip,rk3588-dw-hdmi-qp'], 'reg': [[0, 425984, 0, 131072]], 
> 'clocks': [[4294967295, 528], [4294967295, 529], [4294967295, 530], 
> [4294967295, 564], [4294967295, 594], [4294967295, 717]], 'clock-names': 
> ['pclk', 'earc', 'ref', 'aud', 'hdp', 'hclk_vo1'], 'interrupts': [[0, 169, 4, 
> 0], [0, 170, 4, 0], [0, 171, 4, 0], [0, 172, 4, 0], [0, 360, 4, 0]], 
> 'interrupt-names': ['avp', 'cec', 'earc', 'main', 'hpd'], 'phys': 
> [[4294967295]], 'phy-names': ['hdmi'], 'power-domains': [[4294967295, 26]], 
> 'resets': [[4294967295, 462], [4294967295, 560]], 'reset-names': ['ref', 
> 'hdp'], 'rockchip,grf': [[4294967295]], 'rockchip,vo1_grf': [[4294967295]], 
> '#sound-dai-cells': 0, 'ports': {'#address-cells': 1, '#size-cells': 0, 
> 'port@0': {'reg': [[0]], 'endpoint': {'remote-endpoint': [[4294967295]]}}, 
> 'port@1': {'reg': [[1]]
>  , 'endpoint': {'remote-endpoint': [[4294967295]]}}}, '$nodename': 
> ['hdmi@fde8']}
>   from schema $id: 
> http://devicetree.org/schemas/display/rockchip/rockchip,dw-hdmi-qp.yaml#
> /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi-qp.example.dtb:
>  hdmi@fde8: Unevaluated properties are not allowed ('reg' was unexpected)
>   from schema $id: 
> http://devicetree.org/schemas/display/rockchip/rockchip,dw-hdmi-qp.yaml#
> 
> doc reference errors (make refcheckdocs):
> 
> See 
> https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240801-b4-rk3588-bridge-upstream-v2-1-9fa657a4e...@collabora.com
> 
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
> 


Re: [PATCH 2/2] drm/bridge: synopsys: Add DW HDMI QP TX Controller driver

2024-08-01 Thread Cristian Ciocaltea
On 8/1/24 11:50 AM, Krzysztof Kozlowski wrote:
> On 01/08/2024 04:05, Cristian Ciocaltea wrote:
>> The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller supports
>> the following features, among others:
> 
> ...
> 
>> +
>> +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi)
>> +{
>> +}
>> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind);
> 
> This looks like quite useless export. Drop.
> 
> 
>> +
>> +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
>> +{
>> +dw_hdmi_qp_init_hw(hdmi);
>> +}
>> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
>> +
>> +MODULE_AUTHOR("Algea Cao ");
>> +MODULE_AUTHOR("Cristian Ciocaltea ");
>> +MODULE_DESCRIPTION("DW HDMI QP transmitter driver");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:dw-hdmi-qp");
> 
> That's not a platform driver. That does not look like driver at all,
> just some helper code without any user

This is actually used to provide RK3588 HDMI output support:

https://lore.kernel.org/lkml/20240801-b4-rk3588-bridge-upstream-v2-3-9fa657a4e...@collabora.com/

> 1. Drop alias.
> 2. Provide users for this code. You cannot add some helper functions
> which nothing uses.
> 3. Fix subject, commit msg, module description - there is no driver
> here, but helper functions. Otherwise how does it bind?

Indeed, that's just a left over from the initial dw-hdmi based 
implementation.  Will clean this up for v2.

Thanks for reviewing,
Cristian


Re: [PATCH 1/2] dt-bindings: display: bridge: Add schema for Synopsys DW HDMI QP TX IP

2024-08-01 Thread Cristian Ciocaltea
On 8/1/24 11:38 AM, Krzysztof Kozlowski wrote:> On 01/08/2024 04:05, Cristian 
Ciocaltea wrote:
>> Add dt-binding schema containing the common properties for the Synopsys
>> DesignWare HDMI QP TX controller.
>>
>> Note this is not a full dt-binding specification, but is meant to be
>> referenced by platform-specific bindings for this IP core.
> 
> Please provide an user for this binding. Otherwise it is a no-op.

The first user of this is RK3588 HDMI TX Controller [1].

>>
>> Signed-off-by: Cristian Ciocaltea 
>> ---
>>  .../display/bridge/synopsys,dw-hdmi-qp.yaml| 66 
>> ++
>>  1 file changed, 66 insertions(+)
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml 
>> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml
>> new file mode 100644
>> index ..d8aee12b121d
>> --- /dev/null
>> +++ 
>> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml
>> @@ -0,0 +1,66 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/display/bridge/synopsys,dw-hdmi-qp.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Common Properties for Synopsys DesignWare HDMI QP TX Controller IP
>> +
>> +maintainers:
>> +  - Cristian Ciocaltea 
>> +
>> +description: |
>> +  This document defines device tree properties for the Synopsys DesignWare
>> +  HDMI 2.1 Quad-Pixel (QP) TX controller IP core.
>> +  It doesn't constitute a device tree binding specification by itself, but
>> +  is meant to be referenced by platform-specific device tree bindings.
>> +
>> +  When referenced from platform device tree bindings, the properties defined
>> +  in this document are defined as follows. The platform device tree bindings
>> +  are responsible for defining whether each property is required or 
>> optional.
> 
> Drop this all description and re-write it not to say what bindings are
> or are not. Describe the hardware.

I just tried to keep it similar with synopsys,dw-hdmi.yaml. 

> 
>> +
>> +properties:
>> +  reg:
>> +maxItems: 1
>> +
>> +  clocks:
>> +minItems: 4
>> +maxItems: 6
>> +items:
>> +  - description: Peripheral/APB bus clock
>> +  - description: EARC RX biphase clock
>> +  - description: Reference clock
>> +  - description: Audio interface clock
>> +additionalItems: true
> 
> ??? What's the point of such common schema if it is not common at all?

The schema is referenced by [1].
 
>> +
>> +  clock-names:
>> +minItems: 4
>> +maxItems: 6
>> +items:
>> +  - const: pclk
>> +  - const: earc
>> +  - const: ref
>> +  - const: aud
>> +additionalItems: true
>> +
>> +  interrupts:
>> +minItems: 4
>> +maxItems: 5
>> +items:
>> +  - description: AVP Unit interrupt
>> +  - description: CEC interrupt
>> +  - description: eARC RX interrupt
>> +  - description: Main Unit interrupt
>> +additionalItems: true
>> +
>> +  interrupt-names:
>> +minItems: 4
>> +maxItems: 5
>> +items:
>> +  - const: avp
>> +  - const: cec
>> +  - const: earc
>> +  - const: main
>> +additionalItems: true
> 
> Sorry, there is no user of this and nothing here is actually common
> except first entries in clocks and interrupts properties.
> 
> I don't see any benefit of this.

Sorry, I should have better indicated this is part of a larger changeset -
the cover mentions this is a reworked version of an initial (larger) series
and the split has been explicitly suggested during the review.

> Best regards,
> Krzysztof

Thanks for reviewing,
Cristian

[1]: 
https://lore.kernel.org/lkml/20240801-b4-rk3588-bridge-upstream-v2-1-9fa657a4e...@collabora.com/


Re: [PATCH] backlight: pwm_bl: print errno for probe errors

2024-08-01 Thread Uwe Kleine-König
Hello Martin,

On Thu, Aug 01, 2024 at 11:12:55AM +0200, Martin Kepplinger-Novaković wrote:
> This makes debugging often easier.
> 
> Signed-off-by: Martin Kepplinger-Novaković 
> 
> ---
>  drivers/video/backlight/pwm_bl.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/video/backlight/pwm_bl.c 
> b/drivers/video/backlight/pwm_bl.c
> index f1005bd0c41e3..cc7e7af71891f 100644
> --- a/drivers/video/backlight/pwm_bl.c
> +++ b/drivers/video/backlight/pwm_bl.c
> @@ -502,7 +502,8 @@ static int pwm_backlight_probe(struct platform_device 
> *pdev)
> GPIOD_ASIS);
>   if (IS_ERR(pb->enable_gpio)) {
>   ret = dev_err_probe(>dev, PTR_ERR(pb->enable_gpio),
> - "failed to acquire enable GPIO\n");
> + "failed to acquire enable GPIO: %ld\n",
> + PTR_ERR(pb->enable_gpio));

AFAIK dev_err_probe already emits the error code passed as 2nd
parameter. So I wonder about this patch's benefit.

Best regards
Uwe


signature.asc
Description: PGP signature


Re: [PATCH v15 01/29] drm/connector: Introduce an HDMI connector initialization function

2024-08-01 Thread Thomas Zimmermann

Hi

Am 27.05.24 um 15:57 schrieb Maxime Ripard:

A lot of the various HDMI drivers duplicate some logic that depends on
the HDMI spec itself and not really a particular hardware
implementation.

Output BPC or format selection, infoframe generation are good examples
of such areas.

This creates a lot of boilerplate, with a lot of variations, which makes
it hard for userspace to rely on, and makes it difficult to get it right
for drivers.

In the next patches, we'll add a lot of infrastructure around the
drm_connector and drm_connector_state structures, which will allow to
abstract away the duplicated logic. This infrastructure comes with a few
requirements though, and thus we need a new initialization function.

Hopefully, this will make drivers simpler to handle, and their behaviour
more consistent.

Reviewed-by: Dave Stevenson 
Reviewed-by: Sui Jingfeng 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Maxime Ripard 
---
  drivers/gpu/drm/drm_connector.c | 39 +++
  include/drm/drm_connector.h |  5 +
  2 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index b0516505f7ae..d9961cce8245 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -450,10 +450,49 @@ int drmm_connector_init(struct drm_device *dev,
  
  	return 0;

  }
  EXPORT_SYMBOL(drmm_connector_init);
  
+/**

+ * drmm_connector_hdmi_init - Init a preallocated HDMI connector
+ * @dev: DRM device
+ * @connector: A pointer to the HDMI connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: optional pointer to the associated ddc adapter
+ *
+ * Initialises a preallocated HDMI connector. Connectors can be
+ * subclassed as part of driver connector objects.
+ *
+ * Cleanup is automatically handled with a call to
+ * drm_connector_cleanup() in a DRM-managed action.
+ *
+ * The connector structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_hdmi_init(struct drm_device *dev,
+struct drm_connector *connector,
+const struct drm_connector_funcs *funcs,
+int connector_type,
+struct i2c_adapter *ddc)


I know I'm late to the review.

Wouldn't it be better to make a separate HDMI-setup helper instead of 
yet another init function? The type of init function to use is mostly 
about memory management within the driver, while the new HDMI state is 
about features.


Maybe rather add something like drm_connector_init_hdmi_state(), which 
takes an initialized connector and sets all the values coming the other 
patches. Drivers would not have to subscribe to a certain way of memory 
management. AFAICT this would also allow to protect the helper and the 
new drm_connector.hdmi field behind DRM_DISPLAY_HDMI_STATE_HELPER. Best 
regards Thomas

+{
+   int ret;
+
+   if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector_type == DRM_MODE_CONNECTOR_HDMIB))
+   return -EINVAL;
+
+   ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drmm_connector_hdmi_init);
+
  /**
   * drm_connector_attach_edid_property - attach edid property.
   * @connector: the connector
   *
   * Some connector types like DRM_MODE_CONNECTOR_VIRTUAL do not get a
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fe88d7fc6b8f..4491c4c2fb6e 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1902,10 +1902,15 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
  int drmm_connector_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
int connector_type,
struct i2c_adapter *ddc);
+int drmm_connector_hdmi_init(struct drm_device *dev,
+struct drm_connector *connector,
+const struct drm_connector_funcs *funcs,
+int connector_type,
+struct i2c_adapter *ddc);
  void drm_connector_attach_edid_property(struct drm_connector *connector);
  int drm_connector_register(struct drm_connector *connector);
  void drm_connector_unregister(struct drm_connector *connector);
  int drm_connector_attach_encoder(struct drm_connector *connector,
  struct drm_encoder *encoder);



--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: [Linux-stm32] [PATCH RESEND v3 0/3] Update STM DSI PHY driver

2024-08-01 Thread Raphaël Gallais-Pou




Le 29/07/2024 à 15:28, Yanjun Yang a écrit :

On Fri, Jul 26, 2024 at 09:55:35AM +0200, Philippe CORNU wrote:



On 7/22/24 10:38, Yanjun Yang wrote:


This patch (commit id:185f99b614427360) seems to break the dsi of
stm32f469 chip.
I'm not familiar with the drm and the clock framework, maybe it's
because there is no
   "ck_dsi_phy" defined for stm32f469.
PS:  Sorry for receiving multiple copies of this email, I forgot to
use plain text mode last time.



Hi,
Thank you for letting us know that there was this error. We should have
detected this before merging, really sorry for the problems caused by this
patch. We will investigate the issue and get back to you as soon as
possible. In the meantime, I think you can revert this patch in your git
tree.

Philippe :-)



Hi,

Hi,

FYI
DSI clock tree for stm32f469 can be found here:
https://www.st.com/resource/en/reference_manual/rm0386-stm32f469xx-and-stm32f479xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

Refer to Figure 17: DSI clock tree.

After some research I think "ck_dsi_phy" was introduced in stm32h7 
platforms. There is a mux which interfaces between various clocks (among 
ck_hse) and the byte lane clock. stm32f469 has a much simpler clock tree 
in which we did not bother to implement this "go-between" clock, even 
though they is an equivalent of the mux.



After some testing, the reason behind my problem is the parent's name of
'clk_dsi_phy' for stm32f4 is 'clk-hse' other than 'ck_hse'.  I don't
know which is the better why to fix it:
1. Change "ck_hse" to "clk-hse" in where "clk_dsi_phy" is defined.

Doing so will definitely break other platforms.


2. Use "pll_in_khz = clk_get_rate(dsi->pllref_clk) / 1000" instead of
"pll_in_khz = (unsigned int)(parent_rate / 1000)" when get the clock
rate.
dsi->pllref_clk refers to the HSE clock if you take a look in the 
device-tree. This is the reason why this work on your setup. I doubt 
nevertheless that it wouldn't work on other platforms. But this would be 
a semantic nonsense, since the DSI byte lane clock is not always derived 
from HSE clock on other platforms.


Looking again at the clk-stm32f4 driver and the DSI clock tree linked, 
we can maybe implement the desired clock even if it is not represented 
on the diagram.


Eventually if this solution does not work we will go to the second 
solution you suggested and we will test it on all platforms.


@Philippe, @Yannick
Do you agree with this workflow ?

Regards,
Raphaël




Both method can fix my problem. The first one might break other
platforms. Maybe I should change the clock name of 'clk-hse'. However,
I can't find the defination of this clock name for stm32f4.


[PULL] drm-misc-fixes

2024-08-01 Thread Maxime Ripard
Hi Dave, Daniel,

Here's this week drm-misc-fixes PR

Maxime

drm-misc-fixes-2024-08-01:
A couple drm_panic fixes, several v3d fixes to increase the new timestamp API
safety, several fixes for vmwgfx for various modesetting issues, PM fixes
for ast, async flips improvements and two fixes for nouveau to fix
resource refcounting and buffer placement.
The following changes since commit 8400291e289ee6b2bf9779ff1c83a291501f017b:

  Linux 6.11-rc1 (2024-07-28 14:19:55 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-08-01

for you to fetch changes up to 9c685f61722d30a22d55bb8a48f7a48bb2e19bcc:

  nouveau: set placement to original placement on uvmm validate. (2024-08-01 
01:22:12 +0200)


A couple drm_panic fixes, several v3d fixes to increase the new timestamp API
safety, several fixes for vmwgfx for various modesetting issues, PM fixes
for ast, async flips improvements and two fixes for nouveau to fix
resource refcounting and buffer placement.


André Almeida (2):
  drm/atomic: Allow userspace to use explicit sync with atomic async flips
  drm/atomic: Allow userspace to use damage clips with async flips

Dan Carpenter (1):
  drm/client: Fix error code in drm_client_buffer_vmap_local()

Danilo Krummrich (2):
  drm/gpuvm: fix missing dependency to DRM_EXEC
  drm/nouveau: prime: fix refcount underflow

Dave Airlie (1):
  nouveau: set placement to original placement on uvmm validate.

Dmitry Osipenko (1):
  drm/virtio: Fix type of dma-fence context variable

Ian Forbes (2):
  drm/vmwgfx: Fix overlay when using Screen Targets
  drm/vmwgfx: Trigger a modeset when the screen moves

Jammy Huang (1):
  drm/ast: Fix black screen after resume

Maxime Ripard (2):
  Merge drm/drm-fixes into drm-misc-fixes
  Merge drm-misc/drm-misc-next-fixes into drm-misc-fixes

Philip Mueller (1):
  drm: panel-orientation-quirks: Add quirk for OrangePi Neo

Qiuxu Zhuo (1):
  drm/fb-helper: Don't schedule_work() to flush frame buffer during panic()

Thomas Zimmermann (1):
  drm/ast: astdp: Wake up during connector status detection

Tvrtko Ursulin (5):
  drm/v3d: Prevent out of bounds access in performance query extensions
  drm/v3d: Fix potential memory leak in the timestamp extension
  drm/v3d: Fix potential memory leak in the performance extension
  drm/v3d: Validate passed in drm syncobj handles in the timestamp extension
  drm/v3d: Validate passed in drm syncobj handles in the performance 
extension

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

Zenghui Yu (1):
  kselftests: dmabuf-heaps: Ensure the driver name is null-terminated

 drivers/gpu/drm/Kconfig|   1 +
 drivers/gpu/drm/ast/ast_dp.c   |   7 +
 drivers/gpu/drm/ast/ast_drv.c  |   5 +
 drivers/gpu/drm/ast/ast_drv.h  |   1 +
 drivers/gpu/drm/ast/ast_mode.c |  29 +-
 drivers/gpu/drm/drm_atomic_uapi.c  |   5 +-
 drivers/gpu/drm/drm_client.c   |   2 +-
 drivers/gpu/drm/drm_fb_helper.c|  11 +
 drivers/gpu/drm/drm_panel_orientation_quirks.c |   6 +
 drivers/gpu/drm/nouveau/nouveau_prime.c|   3 +-
 drivers/gpu/drm/nouveau/nouveau_uvmm.c |   1 +
 drivers/gpu/drm/v3d/v3d_drv.h  |   4 +
 drivers/gpu/drm/v3d/v3d_sched.c|  44 +-
 drivers/gpu/drm/v3d/v3d_submit.c   | 121 +++--
 drivers/gpu/drm/virtio/virtgpu_submit.c|   2 +-
 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  |  17 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c|  62 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c| 504 +
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h|  17 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c|  14 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c|   2 +-
 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   | 174 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c| 280 +++-
 drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c   |  40 +-
 

Re: [PATCH v3 0/2] drm: minimum backlight overrides and implementation for amdgpu

2024-08-01 Thread Hans de Goede
Hi,

On 7/31/24 10:55 PM, Daniel Vetter wrote:
> On Wed, Jul 31, 2024 at 08:40:12PM +0300, Jani Nikula wrote:
>> On Wed, 31 Jul 2024, Thomas Weißschuh  wrote:
>>> The value of "min_input_signal" returned from ATIF on a Framework AMD 13
>>> is "12". This leads to a fairly bright minimum display backlight.
>>>
>>> Add a generic override helper for the user to override the settings
>>> provided by the firmware through the kernel cmdline.
>>> Also add amdgpu as a user of that helper.
>>>
>>> One solution would be a fixed firmware version, which was announced but
>>> has no timeline.
>>
>> The flip side is that if we add this now, it pretty much has a timeline:
>> We'll have to carry and support it forever.
>>
>> It's not a great prospect for something so specific. Not to mention that
>> the limits are generally there for electrical minimums that should not
>> be overridden. And before you know it, we'll have bug reports about
>> flickering screens...
> 
> Yeah I think for this specific case where a fixed firmware is already
> kinda promised, a quirk is the right fix. Otherwise we open up a can of
> worms here ... so personally I like v2 a lot more.
> -Sima

Ok, with both Jani and Sima preferring the quirk approach from v2,
I withdraw my objection against v2. So lets go with that version.

Thomas, sorry about this.

I see that other then a remark from Jeff Johnson about a missing
MODULE_DESCRIPTION() v2 does not have any reviews yet though.

So we will need to review that version now. Might be best for
visibility of the patches in people's review queue to repost
v2 as v4 with the MODULE_DESCRIPTION() fixed ?

Regards,

Hans



>>> This helper does conflict with the mode override via the cmdline.
>>> Only one can be specified.
>>> IMO the mode override can be extended to also handle "min-brightness"
>>> when that becomes necessary.
>>>
>>> ---
>>> Changes in v3:
>>> - Switch to cmdline override parameter
>>> - Link to v2: 
>>> https://lore.kernel.org/r/20240623-amdgpu-min-backlight-quirk-v2-0-cecf7f49d...@weissschuh.net
>>>
>>> Changes in v2:
>>> - Introduce proper drm backlight quirk infrastructure
>>> - Quirk by EDID and DMI instead of only DMI
>>> - Limit quirk to only single Framework 13 matte panel
>>> - Link to v1: 
>>> https://lore.kernel.org/r/20240610-amdgpu-min-backlight-quirk-v1-1-8459895a5...@weissschuh.net
>>>
>>> ---
>>> Thomas Weißschuh (2):
>>>   drm/connector: add drm_connector_get_cmdline_min_brightness_override()
>>>   drm/amd/display: implement minimum brightness override
>>>
>>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  6 
>>>  drivers/gpu/drm/drm_connector.c   | 34 
>>> +++
>>>  include/drm/drm_connector.h   |  2 ++
>>>  3 files changed, 42 insertions(+)
>>> ---
>>> base-commit: 36821612eb3091a21f7f4a907b497064725080c3
>>> change-id: 20240610-amdgpu-min-backlight-quirk-8402fd8e736a
>>>
>>> Best regards,
>>
>> -- 
>> Jani Nikula, Intel
> 



Re: [PATCH 2/2] drm/bridge: synopsys: Add DW HDMI QP TX Controller driver

2024-08-01 Thread Krzysztof Kozlowski
On 01/08/2024 04:05, Cristian Ciocaltea wrote:
> The Synopsys DesignWare HDMI 2.1 Quad-Pixel (QP) TX Controller supports
> the following features, among others:

...

> +
> +void dw_hdmi_qp_unbind(struct dw_hdmi_qp *hdmi)
> +{
> +}
> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_unbind);

This looks like quite useless export. Drop.


> +
> +void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
> +{
> + dw_hdmi_qp_init_hw(hdmi);
> +}
> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
> +
> +MODULE_AUTHOR("Algea Cao ");
> +MODULE_AUTHOR("Cristian Ciocaltea ");
> +MODULE_DESCRIPTION("DW HDMI QP transmitter driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:dw-hdmi-qp");

That's not a platform driver. That does not look like driver at all,
just some helper code without any user

1. Drop alias.
2. Provide users for this code. You cannot add some helper functions
which nothing uses.
3. Fix subject, commit msg, module description - there is no driver
here, but helper functions. Otherwise how does it bind?

Best regards,
Krzysztof



Re: [PATCH v4] drm/mediatek: dsi: Add dsi per-frame lp code for mt8188

2024-08-01 Thread AngeloGioacchino Del Regno

Il 01/08/24 10:11, Shuijing Li ha scritto:

Adding the per-frame lp function of mt8188, which can keep HFP in HS and
reduce the time required for each line to enter and exit low power.
Per Frame LP:
   |<--One Active Frame>|
--_____
   ^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^

Per Line LP:
   |<---One Active Frame--->|
--__--__--____
   ^HSA+HBP^^RGB^  ^HSA+HBP^^RGB^  ^HSA+HBP^^RGB^^HSA+HBP^^RGB^

Signed-off-by: Shuijing Li 
---
Changes in v4:
Drop the code related to bllp_en and bllp_wc, adjust ps_wc to dsi->vm.hactive *
dsi_buf_bpp.
Changes in v3:
Use function in bitfield.h and get value from phy timing, per suggestion
from previous thread:
https://patchwork.kernel.org/project/linux-mediatek/patch/20240424091639.22759-1-shuijing...@mediatek.com/
Changes in v2:
Use bitfield macros and add new function for per prame lp and improve
the format, per suggestion from previous thread:
https://patchwork.kernel.org/project/linux-mediatek/patch/20240314094238.3315-1-shuijing...@mediatek.com/
---
  drivers/gpu/drm/mediatek/mtk_dsi.c | 210 ++---
  1 file changed, 163 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b6e3c011a12d..4bda8fa17c3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -88,12 +88,16 @@
  #define DSI_HSA_WC0x50
  #define DSI_HBP_WC0x54
  #define DSI_HFP_WC0x58
+#define HFP_HS_EN  31


#define HFP_HS_VB_PS_WC GENMASK(30, 16)
#define HFP_HS_EN   BIT(31)


+#define HFP_HS_VB_PS_WC_SHIFT 16


...you don't need this definition

  
  #define DSI_CMDQ_SIZE		0x60

  #define CMDQ_SIZE 0x3f
  #define CMDQ_SIZE_SEL BIT(15)
  
  #define DSI_HSTX_CKL_WC		0x64

+#define HSTX_CKL_WCGENMASK(15, 2)




+#define HSTX_CKL_WC_SHIFT  2


This one is already defined in your GENMASK(...), and you should avoid having to
define that at all. Check below for a solution.

  
  #define DSI_RX_DATA0		0x74

  #define DSI_RX_DATA1  0x78
@@ -187,6 +191,7 @@ struct mtk_dsi_driver_data {
bool has_shadow_ctl;
bool has_size_ctl;
bool cmdq_long_packet_ctl;
+   bool support_per_frame_lp;
  };
  
  struct mtk_dsi {

@@ -426,6 +431,112 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool 
config_vact)
writel(ps_val, dsi->regs + DSI_PSCTRL);
  }
  
+static void mtk_dsi_config_vdo_timing_per_frame_lp(struct mtk_dsi *dsi)

+{
+   u32 horizontal_sync_active_byte;
+   u32 horizontal_backporch_byte;
+   u32 horizontal_frontporch_byte;
+   u32 dsi_tmp_buf_bpp;
+   unsigned int lpx, da_hs_exit, da_hs_prep, da_hs_trail;
+   unsigned int da_hs_zero, ps_wc, hs_vb_ps_wc;
+   u32 v_active_roundup, hstx_cklp_wc;
+   u32 hstx_cklp_wc_max, hstx_cklp_wc_min;
+   struct videomode *vm = >vm;
+
+   if (dsi->format == MIPI_DSI_FMT_RGB565)
+   dsi_tmp_buf_bpp = 2;
+   else
+   dsi_tmp_buf_bpp = 3;
+
+   da_hs_trail = dsi->phy_timing.da_hs_trail;
+   ps_wc = dsi->vm.hactive * dsi_tmp_buf_bpp;
+
+   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
+   horizontal_sync_active_byte =
+   vm->hsync_len * dsi_tmp_buf_bpp - 10;
+   horizontal_backporch_byte =
+   vm->hback_porch * dsi_tmp_buf_bpp - 10;
+   horizontal_frontporch_byte =
+   vm->hfront_porch * dsi_tmp_buf_bpp - 12;
+
+   v_active_roundup = (32 + horizontal_sync_active_byte +
+   horizontal_backporch_byte + ps_wc +
+   horizontal_frontporch_byte) % dsi->lanes;
+   if (v_active_roundup)
+   horizontal_backporch_byte = horizontal_backporch_byte +
+   dsi->lanes - v_active_roundup;
+   hstx_cklp_wc_min = (DIV_ROUND_UP((12 + 2 + 4 +
+   horizontal_sync_active_byte), dsi->lanes) + da_hs_trail 
+ 1)
+   * dsi->lanes / 6 - 1;
+   hstx_cklp_wc_max = (DIV_ROUND_UP((20 + 6 + 4 +
+   horizontal_sync_active_byte + horizontal_backporch_byte 
+
+   ps_wc), dsi->lanes) + da_hs_trail + 1) * dsi->lanes / 6 
- 1;
+   } else {
+   horizontal_sync_active_byte = vm->hsync_len * dsi_tmp_buf_bpp - 
4;
+
+   horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) *
+   dsi_tmp_buf_bpp - 10;
+   hstx_cklp_wc_min = (DIV_ROUND_UP(4, dsi->lanes) + da_hs_trail + 
1)
+   * dsi->lanes / 6 - 1;
+
+   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
+   

Re: [PATCH 1/2] dt-bindings: display: bridge: Add schema for Synopsys DW HDMI QP TX IP

2024-08-01 Thread Krzysztof Kozlowski
On 01/08/2024 04:05, Cristian Ciocaltea wrote:
> Add dt-binding schema containing the common properties for the Synopsys
> DesignWare HDMI QP TX controller.
> 
> Note this is not a full dt-binding specification, but is meant to be
> referenced by platform-specific bindings for this IP core.

Please provide an user for this binding. Otherwise it is a no-op.

> 
> Signed-off-by: Cristian Ciocaltea 
> ---
>  .../display/bridge/synopsys,dw-hdmi-qp.yaml| 66 
> ++
>  1 file changed, 66 insertions(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml 
> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml
> new file mode 100644
> index ..d8aee12b121d
> --- /dev/null
> +++ 
> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi-qp.yaml
> @@ -0,0 +1,66 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/synopsys,dw-hdmi-qp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Common Properties for Synopsys DesignWare HDMI QP TX Controller IP
> +
> +maintainers:
> +  - Cristian Ciocaltea 
> +
> +description: |
> +  This document defines device tree properties for the Synopsys DesignWare
> +  HDMI 2.1 Quad-Pixel (QP) TX controller IP core.
> +  It doesn't constitute a device tree binding specification by itself, but
> +  is meant to be referenced by platform-specific device tree bindings.
> +
> +  When referenced from platform device tree bindings, the properties defined
> +  in this document are defined as follows. The platform device tree bindings
> +  are responsible for defining whether each property is required or optional.

Drop this all description and re-write it not to say what bindings are
or are not. Describe the hardware.

> +
> +properties:
> +  reg:
> +maxItems: 1
> +
> +  clocks:
> +minItems: 4
> +maxItems: 6
> +items:
> +  - description: Peripheral/APB bus clock
> +  - description: EARC RX biphase clock
> +  - description: Reference clock
> +  - description: Audio interface clock
> +additionalItems: true

??? What's the point of such common schema if it is not common at all?

> +
> +  clock-names:
> +minItems: 4
> +maxItems: 6
> +items:
> +  - const: pclk
> +  - const: earc
> +  - const: ref
> +  - const: aud
> +additionalItems: true
> +
> +  interrupts:
> +minItems: 4
> +maxItems: 5
> +items:
> +  - description: AVP Unit interrupt
> +  - description: CEC interrupt
> +  - description: eARC RX interrupt
> +  - description: Main Unit interrupt
> +additionalItems: true
> +
> +  interrupt-names:
> +minItems: 4
> +maxItems: 5
> +items:
> +  - const: avp
> +  - const: cec
> +  - const: earc
> +  - const: main
> +additionalItems: true

Sorry, there is no user of this and nothing here is actually common
except first entries in clocks and interrupts properties.

I don't see any benefit of this.

Best regards,
Krzysztof



Re: [PATCH v2 1/2] drm: bridge: samsung-dsim: Initialize bridge on attach

2024-08-01 Thread Alexander Stein
Hi,

with more and more patches for TC9595 support got meged into linux-next,
only a few remain on my patch stack.

This is one of them and is necessary for DP support:
Tested-by: Alexander Stein 

Am Dienstag, 25. Juni 2024, 14:26:10 CEST schrieb Marek Vasut:
> Initialize the bridge on attach already, to force lanes into LP11
> state, since attach does trigger attach of downstream bridges which
> may trigger (e)DP AUX channel mode read.
> 
> This fixes a corner case where DSIM with TC9595 attached to it fails
> to operate the DP AUX channel, because the TC9595 enters some debug
> mode when it is released from reset without lanes in LP11 mode. By
> ensuring the DSIM lanes are in LP11, the TC9595 (tc358767.c driver)
> can be reset in its attach callback called from DSIM attach callback,
> and recovered out of the debug mode just before TC9595 performs first
> AUX channel access later in its attach callback.
> 
> Signed-off-by: Marek Vasut 
> ---
> Cc: Adam Ford 
> Cc: Alexander Stein 
> Cc: Andrzej Hajda 
> Cc: Daniel Vetter 
> Cc: David Airlie 
> Cc: Frieder Schrempf 
> Cc: Inki Dae 
> Cc: Jagan Teki 
> Cc: Jernej Skrabec 
> Cc: Jonas Karlman 
> Cc: Laurent Pinchart 
> Cc: Lucas Stach 
> Cc: Maarten Lankhorst 
> Cc: Marek Szyprowski 
> Cc: Maxime Ripard 
> Cc: Michael Walle 
> Cc: Neil Armstrong 
> Cc: Robert Foss 
> Cc: Thomas Zimmermann 
> Cc: dri-devel@lists.freedesktop.org
> Cc: ker...@dh-electronics.com
> ---
> V2: Handle case where mode is not set yet
> ---
>  drivers/gpu/drm/bridge/samsung-dsim.c | 32 ---
>  1 file changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
> b/drivers/gpu/drm/bridge/samsung-dsim.c
> index e7e53a9e42afb..22d3bbd866d97 100644
> --- a/drivers/gpu/drm/bridge/samsung-dsim.c
> +++ b/drivers/gpu/drm/bridge/samsung-dsim.c
> @@ -699,20 +699,24 @@ static unsigned long samsung_dsim_set_pll(struct 
> samsung_dsim *dsi,
>  
>  static int samsung_dsim_enable_clock(struct samsung_dsim *dsi)
>  {
> - unsigned long hs_clk, byte_clk, esc_clk, pix_clk;
> + unsigned long hs_clk, byte_clk, esc_clk;
>   unsigned long esc_div;
>   u32 reg;
>   struct drm_display_mode *m = >mode;
>   int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
>  
> - /* m->clock is in KHz */
> - pix_clk = m->clock * 1000;
> -
> - /* Use burst_clk_rate if available, otherwise use the pix_clk */
> + /*
> +  * Use burst_clk_rate if available, otherwise use the mode clock
> +  * if mode is already set and available, otherwise fall back to
> +  * PLL input clock and operate in 1:1 lowest frequency mode until
> +  * a mode is set.
> +  */
>   if (dsi->burst_clk_rate)
>   hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate);
> + else if (m) /* m->clock is in KHz */
> + hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(m->clock * 1000 
> * bpp, dsi->lanes));
>   else
> - hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, 
> dsi->lanes));
> + hs_clk = dsi->pll_clk_rate;
>  
>   if (!hs_clk) {
>   dev_err(dsi->dev, "failed to configure DSI PLL\n");
> @@ -1643,9 +1647,21 @@ static int samsung_dsim_attach(struct drm_bridge 
> *bridge,
>  enum drm_bridge_attach_flags flags)
>  {
>   struct samsung_dsim *dsi = bridge_to_dsi(bridge);
> + int ret;
>  
> - return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,
> -  flags);
> + ret = pm_runtime_resume_and_get(dsi->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = samsung_dsim_init(dsi);
> + if (ret < 0)
> + goto err;
> +
> + ret = drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,
> + flags);
> +err:
> + pm_runtime_put_sync(dsi->dev);
> + return ret;
>  }
>  
>  static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = {
> 


-- 
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/




Re: [PATCH] drm: mediatek: Drop unnecessary check for property presence

2024-08-01 Thread AngeloGioacchino Del Regno

Il 31/07/24 22:13, Rob Herring (Arm) ha scritto:

of_property_read_u32() returns -EINVAL if a property is not present, so
the preceeding check for presence with of_find_property() can be
dropped. Really, what the errno is shouldn't matter. Either the property
can be read and used or it can't and is ignored.

This is part of a larger effort to remove callers of of_find_property()
and similar functions. of_find_property() leaks the DT struct property
and data pointers which is a problem for dynamically allocated nodes
which may be freed.

Signed-off-by: Rob Herring (Arm) 


Reviewed-by: AngeloGioacchino Del Regno 





Re: [PATCH v15 00/29] drm/connector: Create HDMI Connector infrastructure

2024-08-01 Thread Maxime Ripard
Hi Hans,

On Wed, Jul 31, 2024 at 04:56:16PM GMT, Hans Verkuil wrote:
> Hi Maxime,
> 
> On 27/05/2024 15:57, Maxime Ripard wrote:
> 
> 
> > Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> > to retrieve infoframes from HDMI receiver and implementing a tool to
> > decode (and eventually check) infoframes. His current work on
> > edid-decode to enable that based on that series can be found here:
> > https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil
> 
> Since this patch series is now merged in mainline I also pushed support
> for parsing InfoFrames to the edid-decode git repo.
> 
> I believe the parsing part of the InfoFrames is complete, but the conformity
> checks for the AVI and HDMI InfoFrames are still work-in-progress. But it
> should be easier to develop this now that is merged.
> 
> The git repo for edid-decode is here: https://git.linuxtv.org/edid-decode.git/
> 
> I added test files to the test/if directory, and if you run:
> 
> edid-decode -I audio.test -I avi.test -I vendor.test -I spd.test edid.test -c
> 
> you'll get the output below.

That's awesome to hear, I'll send a patch for the KMS documentation to
mention it 

Thanks!
Maxime


signature.asc
Description: PGP signature


[PATCH v4] drm/mediatek: dsi: Add dsi per-frame lp code for mt8188

2024-08-01 Thread Shuijing Li
Adding the per-frame lp function of mt8188, which can keep HFP in HS and
reduce the time required for each line to enter and exit low power.
Per Frame LP:
  |<--One Active Frame>|
--_____
  ^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^^HSA+HBP^^RGB^^HFP^

Per Line LP:
  |<---One Active Frame--->|
--__--__--____
  ^HSA+HBP^^RGB^  ^HSA+HBP^^RGB^  ^HSA+HBP^^RGB^^HSA+HBP^^RGB^

Signed-off-by: Shuijing Li 
---
Changes in v4:
Drop the code related to bllp_en and bllp_wc, adjust ps_wc to dsi->vm.hactive *
dsi_buf_bpp.
Changes in v3:
Use function in bitfield.h and get value from phy timing, per suggestion
from previous thread:
https://patchwork.kernel.org/project/linux-mediatek/patch/20240424091639.22759-1-shuijing...@mediatek.com/
Changes in v2:
Use bitfield macros and add new function for per prame lp and improve
the format, per suggestion from previous thread:
https://patchwork.kernel.org/project/linux-mediatek/patch/20240314094238.3315-1-shuijing...@mediatek.com/
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 210 ++---
 1 file changed, 163 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b6e3c011a12d..4bda8fa17c3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -88,12 +88,16 @@
 #define DSI_HSA_WC 0x50
 #define DSI_HBP_WC 0x54
 #define DSI_HFP_WC 0x58
+#define HFP_HS_EN  31
+#define HFP_HS_VB_PS_WC_SHIFT 16
 
 #define DSI_CMDQ_SIZE  0x60
 #define CMDQ_SIZE  0x3f
 #define CMDQ_SIZE_SEL  BIT(15)
 
 #define DSI_HSTX_CKL_WC0x64
+#define HSTX_CKL_WCGENMASK(15, 2)
+#define HSTX_CKL_WC_SHIFT  2
 
 #define DSI_RX_DATA0   0x74
 #define DSI_RX_DATA1   0x78
@@ -187,6 +191,7 @@ struct mtk_dsi_driver_data {
bool has_shadow_ctl;
bool has_size_ctl;
bool cmdq_long_packet_ctl;
+   bool support_per_frame_lp;
 };
 
 struct mtk_dsi {
@@ -426,6 +431,112 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool 
config_vact)
writel(ps_val, dsi->regs + DSI_PSCTRL);
 }
 
+static void mtk_dsi_config_vdo_timing_per_frame_lp(struct mtk_dsi *dsi)
+{
+   u32 horizontal_sync_active_byte;
+   u32 horizontal_backporch_byte;
+   u32 horizontal_frontporch_byte;
+   u32 dsi_tmp_buf_bpp;
+   unsigned int lpx, da_hs_exit, da_hs_prep, da_hs_trail;
+   unsigned int da_hs_zero, ps_wc, hs_vb_ps_wc;
+   u32 v_active_roundup, hstx_cklp_wc;
+   u32 hstx_cklp_wc_max, hstx_cklp_wc_min;
+   struct videomode *vm = >vm;
+
+   if (dsi->format == MIPI_DSI_FMT_RGB565)
+   dsi_tmp_buf_bpp = 2;
+   else
+   dsi_tmp_buf_bpp = 3;
+
+   da_hs_trail = dsi->phy_timing.da_hs_trail;
+   ps_wc = dsi->vm.hactive * dsi_tmp_buf_bpp;
+
+   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
+   horizontal_sync_active_byte =
+   vm->hsync_len * dsi_tmp_buf_bpp - 10;
+   horizontal_backporch_byte =
+   vm->hback_porch * dsi_tmp_buf_bpp - 10;
+   horizontal_frontporch_byte =
+   vm->hfront_porch * dsi_tmp_buf_bpp - 12;
+
+   v_active_roundup = (32 + horizontal_sync_active_byte +
+   horizontal_backporch_byte + ps_wc +
+   horizontal_frontporch_byte) % dsi->lanes;
+   if (v_active_roundup)
+   horizontal_backporch_byte = horizontal_backporch_byte +
+   dsi->lanes - v_active_roundup;
+   hstx_cklp_wc_min = (DIV_ROUND_UP((12 + 2 + 4 +
+   horizontal_sync_active_byte), dsi->lanes) + da_hs_trail 
+ 1)
+   * dsi->lanes / 6 - 1;
+   hstx_cklp_wc_max = (DIV_ROUND_UP((20 + 6 + 4 +
+   horizontal_sync_active_byte + horizontal_backporch_byte 
+
+   ps_wc), dsi->lanes) + da_hs_trail + 1) * dsi->lanes / 6 
- 1;
+   } else {
+   horizontal_sync_active_byte = vm->hsync_len * dsi_tmp_buf_bpp - 
4;
+
+   horizontal_backporch_byte = (vm->hback_porch + vm->hsync_len) *
+   dsi_tmp_buf_bpp - 10;
+   hstx_cklp_wc_min = (DIV_ROUND_UP(4, dsi->lanes) + da_hs_trail + 
1)
+   * dsi->lanes / 6 - 1;
+
+   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
+   horizontal_frontporch_byte = (vm->hfront_porch *
+   dsi_tmp_buf_bpp - 18);
+
+   v_active_roundup = (28 + horizontal_backporch_byte + 
ps_wc +
+   horizontal_frontporch_byte) % dsi->lanes;
+   if 

Re: [PATCH v4 2/3] drm/printer: Allow NULL data in devcoredump printer

2024-08-01 Thread Jani Nikula
On Wed, 31 Jul 2024, Matthew Brost  wrote:
> Useful to determine size of devcoreump before writing it out.

I find it useful to have this special case documented, with an example,
so it's easier to see how handy this really is.

BR,
Jani.


>
> Cc: Maarten Lankhorst 
> Signed-off-by: Matthew Brost 
> ---
>  drivers/gpu/drm/drm_print.c | 13 -
>  1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> index cf24dfdeb6b2..a1a4de9f9c44 100644
> --- a/drivers/gpu/drm/drm_print.c
> +++ b/drivers/gpu/drm/drm_print.c
> @@ -100,8 +100,9 @@ void __drm_puts_coredump(struct drm_printer *p, const 
> char *str)
>   copy = iterator->remain;
>  
>   /* Copy out the bit of the string that we need */
> - memcpy(iterator->data,
> - str + (iterator->start - iterator->offset), copy);
> + if (iterator->data)
> + memcpy(iterator->data,
> + str + (iterator->start - iterator->offset), 
> copy);
>  
>   iterator->offset = iterator->start + copy;
>   iterator->remain -= copy;
> @@ -110,7 +111,8 @@ void __drm_puts_coredump(struct drm_printer *p, const 
> char *str)
>  
>   len = min_t(ssize_t, strlen(str), iterator->remain);
>  
> - memcpy(iterator->data + pos, str, len);
> + if (iterator->data)
> + memcpy(iterator->data + pos, str, len);
>  
>   iterator->offset += len;
>   iterator->remain -= len;
> @@ -140,8 +142,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct 
> va_format *vaf)
>   if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
>   ssize_t pos = iterator->offset - iterator->start;
>  
> - snprintf(((char *) iterator->data) + pos,
> - iterator->remain, "%pV", vaf);
> + if (iterator->data)
> + snprintf(((char *) iterator->data) + pos,
> + iterator->remain, "%pV", vaf);
>  
>   iterator->offset += len;
>   iterator->remain -= len;

-- 
Jani Nikula, Intel


Re: [PATCH v2] drm/edid: add CTA Video Format Data Block support

2024-08-01 Thread Jani Nikula
On Wed, 31 Jul 2024, Hamza Mahfooz  wrote:
> Video Format Data Blocks (VFDBs) contain the necessary information that
> needs to be fed to the Optimized Video Timings (OVT) Algorithm.
> Also, we require OVT support to cover modes that aren't supported by
> earlier standards (e.g. CVT). So, parse all of the relevant VFDB data
> and feed it to the OVT Algorithm, to extract all of the missing OVT
> modes.
>
> Suggested-by: Karol Herbst 
> Signed-off-by: Hamza Mahfooz 
> ---
> v2: address comments from Jani
> ---
>  drivers/gpu/drm/drm_edid.c | 456 ++---
>  1 file changed, 428 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index f68a41eeb1fa..f608ab4e32ae 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -31,6 +31,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -741,6 +742,93 @@ static const struct minimode extra_modes[] = {
>   { 2048, 1536, 60, 0 },
>  };
>  
> +struct cta_rid {
> + u16 hactive;
> + u16 vactive;
> + u8 hratio;
> + u8 vratio;
> +};
> +
> +/* CTA-861-I Table 11 - Resolution Identification (RID) */
> +static const struct cta_rid rids[] = {
> + /* RID 0-9 */
> + { 0, 0, 0, 0 },
> + { 1280, 720, 16, 9 },
> + { 1280, 720, 64, 27 },
> + { 1680, 720, 64, 27 },
> + { 1920, 1080, 16, 9 },
> + { 1920, 1080, 64, 27 },
> + { 2560, 1080, 64, 27 },
> + { 3840, 1080, 32, 9 },
> + { 2560, 1440, 16, 9 },
> + { 3440, 1440, 64, 27 },
> + /* RID 10-19 */
> + { 5120, 1440, 32, 9 },
> + { 3840, 2160, 16, 9 },
> + { 3840, 2160, 64, 27 },
> + { 5120, 2160, 64, 27 },
> + { 7680, 2160, 32, 9 },
> + { 5120, 2880, 16, 9 },
> + { 5120, 2880, 64, 27 },
> + { 6880, 2880, 64, 27 },
> + { 10240, 2880, 32, 9 },
> + { 7680, 4320, 16, 9 },
> + /* RID 20-28 */
> + { 7680, 4320, 64, 27 },
> + { 10240, 4320, 64, 27 },
> + { 15360, 4320, 32, 9 },
> + { 11520, 6480, 16, 9 },
> + { 11520, 6480, 64, 27 },
> + { 15360, 6480, 64, 27 },
> + { 15360, 8640, 16, 9 },
> + { 15360, 8640, 64, 27 },
> + { 20480, 8640, 64, 27 },
> +};
> +
> +/* CTA-861-I Table 12 - AVI InfoFrame Video Format Frame Rate */
> +static const u16 cta_vf_fr[] = {
> + /* Frame Rate 0-7 */
> + 0, 24, 25, 30, 48, 50, 60, 100,
> + /* Frame Rate 8-15 */
> + 120, 144, 200, 240, 300, 360, 400, 480,
> +};
> +
> +/* CTA-861-I Table 13 - RID To VIC Mapping */
> +static const u8 rid_to_vic[][8] = {
> + /* RID 0-9 */
> + {},
> + { 60, 61, 62, 108, 19, 4, 41, 47 },
> + { 65, 66, 67, 109, 68, 69, 70, 71 },
> + { 79, 80, 81, 110, 82, 83, 84, 85 },
> + { 32, 33, 34, 111, 31, 16, 64, 63 },
> + { 72, 73, 74, 112, 75, 76, 77, 78 },
> + { 86, 87, 88, 113, 89, 90, 91, 92 },
> + {},
> + {},
> + {},
> + /* RID 10-19 */
> + {},
> + { 93, 94, 95, 114, 96, 97, 117, 118 },
> + { 103, 104, 105, 116, 106, 107, 119, 120 },
> + { 121, 122, 123, 124, 125, 126, 127, 193 },
> + {},
> + {},
> + {},
> + {},
> + {},
> + { 194, 195, 196, 197, 198, 199, 200, 201 },
> + /* RID 20-28 */
> + { 202, 203, 204, 205, 206, 207, 208, 209 },
> + { 210, 211, 212, 213, 214, 215, 216, 217 },
> + {},
> + {},
> + {},
> + {},
> + {},
> + {},
> + {},
> +};
> +
>  /*
>   * From CEA/CTA-861 spec.
>   *
> @@ -4140,6 +4228,7 @@ static int add_detailed_modes(struct drm_connector 
> *connector,
>  #define CTA_DB_VIDEO 2
>  #define CTA_DB_VENDOR3
>  #define CTA_DB_SPEAKER   4
> +#define CTA_DB_VIDEO_FORMAT  6
>  #define CTA_DB_EXTENDED_TAG  7
>  
>  /* CTA-861-H Table 62 - CTA Extended Tag Codes */
> @@ -4981,6 +5070,16 @@ struct cea_db {
>   u8 data[];
>  } __packed;
>  
> +struct cta_vfd {
> + u8 rid;
> + u8 fr_fact;
> + bool bfr50;
> + bool fr24;
> + bool bfr60;
> + bool fr144;
> + bool fr48;
> +};
> +
>  static int cea_db_tag(const struct cea_db *db)
>  {
>   return db->tag_length >> 5;
> @@ -5306,34 +5405,6 @@ static void parse_cta_y420cmdb(struct drm_connector 
> *connector,
>   *y420cmdb_map = map;
>  }
>  
> -static int add_cea_modes(struct drm_connector *connector,
> -  const struct drm_edid *drm_edid)
> -{
> - const struct cea_db *db;
> - struct cea_db_iter iter;
> - int modes;
> -
> - /* CTA VDB block VICs parsed earlier */
> - modes = add_cta_vdb_modes(connector);
> -
> - cea_db_iter_edid_begin(drm_edid, );
> - cea_db_iter_for_each(db, ) {
> - if (cea_db_is_hdmi_vsdb(db)) {
> - modes += do_hdmi_vsdb_modes(connector, (const u8 *)db,
> - cea_db_payload_len(db));
> - } else if (cea_db_is_y420vdb(db)) {
> -  

linux-next: build warnings after merge of the drm-misc tree

2024-08-01 Thread Stephen Rothwell
Hi all,

After merging the drm-misc tree, today's linux-next build (htmldocs)
produced these warnings:

Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:1641: ERROR: 
Unexpected indentation.
Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:1643: WARNING: 
Block quote ends without a blank line; unexpected unindent.
Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2388: WARNING: 
Definition list ends without a blank line; unexpected unindent.
Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2390: ERROR: 
Unexpected indentation.
Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2412: WARNING: 
Block quote ends without a blank line; unexpected unindent.
Documentation/gpu/drm-kms:538: drivers/gpu/drm/drm_connector.c:2425: ERROR: 
Unexpected indentation.

Introduced by commits

  f592e01664b4 ("drm/drm_connector: Document Colorspace property variants")
  76299a557f36 ("drm: Introduce 'power saving policy' drm property")

-- 
Cheers,
Stephen Rothwell


pgp01cgicrMXk.pgp
Description: OpenPGP digital signature


[PULL] drm-intel-fixes

2024-08-01 Thread Joonas Lahtinen
Hi Dave & Sima,

Just three smaller fixups. CI is again all over the place after -rc1,
but below changes shouldn't make it any worse.

Regards, Joonas

***

drm-intel-fixes-2024-08-01:

- Static analysis fix for int overflow
- Fix for HDCP2_STREAM_STATUS macro and removal of PWR_CLK_STATE for gen12

The following changes since commit 8400291e289ee6b2bf9779ff1c83a291501f017b:

  Linux 6.11-rc1 (2024-07-28 14:19:55 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/i915/kernel.git 
tags/drm-intel-fixes-2024-08-01

for you to fetch changes up to 5b511572660190db1dc8ba412efd0be0d3781ab6:

  drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll() (2024-07-30 
16:57:24 +0300)


- Static analysis fix for int overflow
- Fix for HDCP2_STREAM_STATUS macro and removal of PWR_CLK_STATE for gen12


Nikita Zhandarovich (1):
  drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll()

Suraj Kandpal (1):
  drm/i915/hdcp: Fix HDCP2_STREAM_STATUS macro

Umesh Nerlige Ramappa (1):
  i915/perf: Remove code to update PWR_CLK_STATE for gen12

 drivers/gpu/drm/i915/display/intel_dpll_mgr.c  |  6 ++---
 drivers/gpu/drm/i915/display/intel_hdcp_regs.h |  2 +-
 drivers/gpu/drm/i915/i915_perf.c   | 33 --
 3 files changed, 4 insertions(+), 37 deletions(-)


Re: [PATCH v2 1/2] drm/mipi-dsi: add more multi functions for better error handling

2024-07-31 Thread Tejas Vipin



On 8/1/24 2:59 AM, Doug Anderson wrote:
> Hi,
> 
> On Mon, Jul 29, 2024 at 11:07 PM Tejas Vipin  wrote:
>> +/**
>> + * mipi_dsi_dcs_get_display_brightness_multi() - gets the current 
>> brightness value
>> + *of the display
>> + * @ctx: Context for multiple DSI transactions
>> + * @brightness: brightness value
>> + *
>> + * Like mipi_dsi_dcs_get_display_brightness() but deals with errors in a 
>> way that
>> + * makes it convenient to make several calls in a row.
>> + */
>> +void mipi_dsi_dcs_get_display_brightness_multi(struct 
>> mipi_dsi_multi_context *ctx,
>> +  u16 *brightness)
>> +{
>> +   struct mipi_dsi_device *dsi = ctx->dsi;
>> +   struct device *dev = >dev;
>> +   int ret;
>> +
>> +   if (ctx->accum_err)
>> +   return;
>> +
>> +   ret = mipi_dsi_dcs_get_display_brightness(dsi, brightness);
>> +   if (ret < 0) {
>> +   ctx->accum_err = ret;
>> +   dev_err(dev, "Failed to get display brightness: %d\n",
>> +   ctx->accum_err);
>> +   }
>> +}
>> +EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_multi);
> 
> I'd be interested in others' opinions, but this function strikes me as
> one that *shouldn't* be converted to _multi.
>

Only reason I converted the function at all was really for uniformity's
sake. But I don't think that's valid anymore seeing how there's already
other mipi_dsi funtions that I'm not converting and this function
probably wouldn't show up in the context of the other multi
functions.

> Specifically the whole point of the _multi abstraction is that you can
> fire off a whole pile of initialization commands without needing to
> check for errors constantly. You can check for errors once at the end
> of a sequence of commands and you can be sure that an error message
> was printed for the command that failed and that all of the future
> commands didn't do anything.
> 
> I have a hard time believing that _get_ brightness would be part of
> this pile of initialization commands. ...and looking at how you use it
> in the next patch I can see that, indeed, it's a bit awkward using the
> _multi variant in the case you're using it.
> 
> The one advantage of the _multi functions is that they are also
> "chatty" and we don't need to print the error everywhere. However, it
> seems like we could just make the existing function print an error
> message but still return the error directly. If this automatic
> printing an error message is a problem for someone then I guess maybe
> we've already reached the "tomorrow" [1] and need to figure out if we
> need to keep two variants of the function around instead of marking
> one as deprecated.
>

One thing that struck me as odd was that the callers of
mipi_dsi_dcs_get_display_brightness never bothered to print errors at
all? If we want to print errors for non-multi functions, then I think it
would be best to just modify the existing function. And in the case that
someone doesn't want those errors showing up, I agree with what Maxime
said [2] and let users handle it.

> NOTE: If we don't convert this then the "set" function will still be
> _multi but the "get" one won't be. I think that's fine since the "set"
> function could plausibly be in a big sequence of commands but the
> "get" function not so much...
> 
> [1] 
> https://lore.kernel.org/r/CAD=FV=wbxdnm4or3ae+nyoqw1sce0jp6fwtchshsaluefnh...@mail.gmail.com

[2] https://lore.kernel.org/all/20240726-cerise-civet-of-reverence-ebeb9d@houat/
-- 
Tejas Vipin


  1   2   3   4   5   6   7   8   9   10   >